Skip to content

Commit cae5e9b

Browse files
Draft - target factories
1 parent 1c064e5 commit cae5e9b

File tree

2 files changed

+58
-5
lines changed

2 files changed

+58
-5
lines changed

src/client.ts

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@ function isString(x: unknown): x is string {
218218
return typeof x === 'string' || x instanceof String;
219219
}
220220

221+
export type TargetFactory<
222+
SCG extends ExtendableGenerics = DefaultGenerics,
223+
T extends Exclude<EventTypes, 'all'> = Exclude<EventTypes, 'all'>
224+
> = (event: Event<SCG>) => `${T}${string}` | `${string}${T}` | `${string}${T}${string}` | null;
225+
221226
export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {
222227
private static _instance?: unknown | StreamChat; // type is undefined|StreamChat, unknown is due to TS limitations with statics
223228

@@ -269,6 +274,7 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
269274
defaultWSTimeoutWithFallback: number;
270275
defaultWSTimeout: number;
271276
private nextRequestAbortController: AbortController | null = null;
277+
private targetFactoriesByType = new Map<Exclude<EventTypes, 'all'>, Set<TargetFactory<StreamChatGenerics>>>();
272278

273279
/**
274280
* Initialize a client
@@ -909,6 +915,28 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
909915
return JWTUserToken(this.secret, userID, extra, {});
910916
}
911917

918+
public registerTargetFactory = <T extends Exclude<EventTypes, 'all'>>(
919+
eventType: T,
920+
factory: TargetFactory<StreamChatGenerics, T>,
921+
) => {
922+
let set = this.targetFactoriesByType.get(eventType);
923+
924+
if (!set) {
925+
set = new Set();
926+
this.targetFactoriesByType.set(eventType, set);
927+
}
928+
929+
set.add(factory);
930+
931+
return () => {
932+
set.delete(factory);
933+
934+
if (!set.size) {
935+
this.targetFactoriesByType.delete(eventType);
936+
}
937+
};
938+
};
939+
912940
/**
913941
* on - Listen to events on all channels and users your watching
914942
*
@@ -936,6 +964,7 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
936964
tags: ['event', 'client'],
937965
});
938966
this.listeners[key].push(callback);
967+
939968
return {
940969
unsubscribe: () => {
941970
this.logger('info', `Removing listener for ${key} event`, {
@@ -1364,8 +1393,21 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
13641393
if (client.listeners.all) {
13651394
listeners.push(...client.listeners.all);
13661395
}
1367-
if (client.listeners[event.type]) {
1368-
listeners.push(...client.listeners[event.type]);
1396+
1397+
const eventTypes: string[] = [event.type];
1398+
1399+
// factories
1400+
const factorySet = client.targetFactoriesByType.get(event.type as Exclude<EventTypes, 'all'>);
1401+
factorySet?.forEach((factory) => {
1402+
// a specific value could be missing from the event payload so factory can return "null" to be skipped
1403+
const targetedEventType = factory(event);
1404+
if (targetedEventType) eventTypes.push(targetedEventType);
1405+
});
1406+
1407+
for (const eventType of eventTypes) {
1408+
if (client.listeners[eventType]) {
1409+
listeners.push(...client.listeners[eventType]);
1410+
}
13691411
}
13701412

13711413
// call the event and send it to the listeners

src/thread.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Channel } from './channel';
2-
import type { StreamChat } from './client';
2+
import type { StreamChat, TargetFactory } from './client';
33
import { StateStore } from './store';
44
import type {
55
AscDesc,
@@ -62,6 +62,14 @@ export type ThreadReadState<SCG extends ExtendableGenerics = DefaultGenerics> =
6262
ThreadUserReadState<SCG> | undefined
6363
>;
6464

65+
// TODO: figure out generics here
66+
const messageNewFactory: TargetFactory<DefaultGenerics, 'message.new'> = (event) => {
67+
return event.parent_id ? `message.new-${event.parent_id}` : null;
68+
};
69+
const threadMessageReadFactory: TargetFactory<DefaultGenerics, 'message.read'> = (event) => {
70+
return event.thread ? `message.read-${event.thread.parent_message_id}` : null;
71+
};
72+
6573
const DEFAULT_PAGE_LIMIT = 50;
6674
const DEFAULT_SORT: { created_at: AscDesc }[] = [{ created_at: -1 }];
6775
const MARK_AS_READ_THROTTLE_TIMEOUT = 1000;
@@ -186,6 +194,9 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
186194
return;
187195
}
188196

197+
this.unsubscribeFunctions.add(this.client.registerTargetFactory('message.new', messageNewFactory));
198+
this.unsubscribeFunctions.add(this.client.registerTargetFactory('message.read', threadMessageReadFactory));
199+
189200
this.unsubscribeFunctions.add(this.subscribeMarkActiveThreadRead());
190201
this.unsubscribeFunctions.add(this.subscribeReloadActiveStaleThread());
191202
this.unsubscribeFunctions.add(this.subscribeMarkThreadStale());
@@ -230,7 +241,7 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
230241
}).unsubscribe;
231242

232243
private subscribeNewReplies = () =>
233-
this.client.on('message.new', (event) => {
244+
this.client.on(`message.new-${this.id}`, (event) => {
234245
if (!this.client.userID || event.message?.parent_id !== this.id) {
235246
return;
236247
}
@@ -284,7 +295,7 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
284295
}).unsubscribe;
285296

286297
private subscribeRepliesRead = () =>
287-
this.client.on('message.read', (event) => {
298+
this.client.on(`message.read-${this.id}`, (event) => {
288299
if (!event.user || !event.created_at || !event.thread) return;
289300
if (event.thread.parent_message_id !== this.id) return;
290301

0 commit comments

Comments
 (0)