@knocklabs/client 0.14.4 → 0.14.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/cjs/clients/feed/feed.js +1 -1
- package/dist/cjs/clients/feed/feed.js.map +1 -1
- package/dist/cjs/clients/feed/index.js +1 -1
- package/dist/cjs/clients/feed/index.js.map +1 -1
- package/dist/cjs/clients/feed/socket-manager.js +2 -0
- package/dist/cjs/clients/feed/socket-manager.js.map +1 -0
- package/dist/cjs/clients/guide/client.js +1 -1
- package/dist/cjs/clients/guide/client.js.map +1 -1
- package/dist/esm/clients/feed/feed.mjs +117 -102
- package/dist/esm/clients/feed/feed.mjs.map +1 -1
- package/dist/esm/clients/feed/index.mjs +31 -15
- package/dist/esm/clients/feed/index.mjs.map +1 -1
- package/dist/esm/clients/feed/socket-manager.mjs +81 -0
- package/dist/esm/clients/feed/socket-manager.mjs.map +1 -0
- package/dist/esm/clients/guide/client.mjs +123 -65
- package/dist/esm/clients/guide/client.mjs.map +1 -1
- package/dist/types/clients/feed/feed.d.ts +11 -6
- package/dist/types/clients/feed/feed.d.ts.map +1 -1
- package/dist/types/clients/feed/index.d.ts +2 -0
- package/dist/types/clients/feed/index.d.ts.map +1 -1
- package/dist/types/clients/feed/socket-manager.d.ts +31 -0
- package/dist/types/clients/feed/socket-manager.d.ts.map +1 -0
- package/dist/types/clients/feed/types.d.ts +4 -3
- package/dist/types/clients/feed/types.d.ts.map +1 -1
- package/dist/types/clients/guide/client.d.ts +22 -1
- package/dist/types/clients/guide/client.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/clients/feed/feed.ts +51 -41
- package/src/clients/feed/index.ts +27 -3
- package/src/clients/feed/socket-manager.ts +185 -0
- package/src/clients/feed/types.ts +5 -3
- package/src/clients/guide/client.ts +146 -2
|
@@ -2,25 +2,28 @@ import { GenericData } from '@knocklabs/types';
|
|
|
2
2
|
import { StoreApi } from 'zustand';
|
|
3
3
|
import { default as Knock } from '../../knock';
|
|
4
4
|
import { FeedClientOptions, FetchFeedOptions } from './interfaces';
|
|
5
|
+
import { FeedSocketManager, SocketEventPayload } from './socket-manager';
|
|
5
6
|
import { BindableFeedEvent, FeedEventCallback, FeedItemOrItems, FeedRealTimeCallback, FeedStoreState } from './types';
|
|
6
7
|
declare class Feed {
|
|
7
8
|
readonly knock: Knock;
|
|
8
9
|
readonly feedId: string;
|
|
10
|
+
readonly defaultOptions: FeedClientOptions;
|
|
11
|
+
readonly referenceId: string;
|
|
12
|
+
unsubscribeFromSocketEvents: (() => void) | undefined;
|
|
13
|
+
private socketManager;
|
|
9
14
|
private userFeedId;
|
|
10
|
-
private channel?;
|
|
11
15
|
private broadcaster;
|
|
12
|
-
private defaultOptions;
|
|
13
16
|
private broadcastChannel;
|
|
14
17
|
private disconnectTimer;
|
|
15
18
|
private hasSubscribedToRealTimeUpdates;
|
|
16
19
|
private visibilityChangeHandler;
|
|
17
20
|
private visibilityChangeListenerConnected;
|
|
18
21
|
store: StoreApi<FeedStoreState>;
|
|
19
|
-
constructor(knock: Knock, feedId: string, options: FeedClientOptions);
|
|
22
|
+
constructor(knock: Knock, feedId: string, options: FeedClientOptions, socketManager: FeedSocketManager | undefined);
|
|
20
23
|
/**
|
|
21
24
|
* Used to reinitialize a current feed instance, which is useful when reauthenticating users
|
|
22
25
|
*/
|
|
23
|
-
reinitialize(): void;
|
|
26
|
+
reinitialize(socketManager?: FeedSocketManager): void;
|
|
24
27
|
/**
|
|
25
28
|
* Cleans up a feed instance by destroying the store and disconnecting
|
|
26
29
|
* an open socket connection.
|
|
@@ -48,6 +51,7 @@ declare class Feed {
|
|
|
48
51
|
data: any;
|
|
49
52
|
} | undefined>;
|
|
50
53
|
fetchNextPage(options?: FetchFeedOptions): Promise<void>;
|
|
54
|
+
get socketChannelTopic(): string;
|
|
51
55
|
private broadcast;
|
|
52
56
|
private onNewMessageReceived;
|
|
53
57
|
private buildUserFeedId;
|
|
@@ -57,12 +61,13 @@ declare class Feed {
|
|
|
57
61
|
private setupBroadcastChannel;
|
|
58
62
|
private broadcastOverChannel;
|
|
59
63
|
private initializeRealtimeConnection;
|
|
64
|
+
handleSocketEvent(payload: SocketEventPayload): Promise<void>;
|
|
60
65
|
/**
|
|
61
66
|
* Listen for changes to document visibility and automatically disconnect
|
|
62
67
|
* or reconnect the socket after a delay
|
|
63
68
|
*/
|
|
64
|
-
private
|
|
65
|
-
private
|
|
69
|
+
private setUpVisibilityListeners;
|
|
70
|
+
private tearDownVisibilityListeners;
|
|
66
71
|
private emitEvent;
|
|
67
72
|
private handleVisibilityChange;
|
|
68
73
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feed.d.ts","sourceRoot":"","sources":["../../../../src/clients/feed/feed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,KAAK,MAAM,aAAa,CAAC;AAOhC,OAAO,EACL,iBAAiB,EAIjB,gBAAgB,EAEjB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"feed.d.ts","sourceRoot":"","sources":["../../../../src/clients/feed/feed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,KAAK,MAAM,aAAa,CAAC;AAOhC,OAAO,EACL,iBAAiB,EAIjB,gBAAgB,EAEjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAEnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,iBAAiB,EAEjB,iBAAiB,EAEjB,eAAe,EAEf,oBAAoB,EACpB,cAAc,EACf,MAAM,SAAS,CAAC;AAYjB,cAAM,IAAI;IAiBN,QAAQ,CAAC,KAAK,EAAE,KAAK;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM;IAjBzB,SAAgB,cAAc,EAAE,iBAAiB,CAAC;IAClD,SAAgB,WAAW,EAAE,MAAM,CAAC;IAC7B,2BAA2B,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAa;IACzE,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,eAAe,CAA8C;IACrE,OAAO,CAAC,8BAA8B,CAAkB;IACxD,OAAO,CAAC,uBAAuB,CAAwB;IACvD,OAAO,CAAC,iCAAiC,CAAkB;IAGpD,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;gBAG5B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACvB,OAAO,EAAE,iBAAiB,EAC1B,aAAa,EAAE,iBAAiB,GAAG,SAAS;IA2B9C;;OAEG;IACH,YAAY,CAAC,aAAa,CAAC,EAAE,iBAAiB;IAa9C;;;OAGG;IACH,QAAQ;IAiBR,2EAA2E;IAC3E,OAAO;IAWP,gBAAgB;IAiBhB,EAAE,CACA,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,iBAAiB,GAAG,oBAAoB;IAKpD,GAAG,CACD,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,iBAAiB,GAAG,oBAAoB;IAKpD,QAAQ;IAIF,UAAU,CAAC,WAAW,EAAE,eAAe;IAYvC,aAAa;IA0Cb,YAAY,CAAC,WAAW,EAAE,eAAe;IAWzC,UAAU,CAAC,WAAW,EAAE,eAAe;IAYvC,aAAa;IA0Cb,YAAY,CAAC,WAAW,EAAE,eAAe;IAWzC,gBAAgB,CACpB,WAAW,EAAE,eAAe,EAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAwB7B,cAAc,CAAC,WAAW,EAAE,eAAe;IAuE3C,iBAAiB;IA2BjB,qBAAqB;IA0CrB,gBAAgB,CAAC,WAAW,EAAE,eAAe;IAS7C,KAAK,CAAC,OAAO,GAAE,gBAAqB;;;;IA0FpC,aAAa,CAAC,OAAO,GAAE,gBAAqB;IAgBlD,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAED,OAAO,CAAC,SAAS;YAQH,oBAAoB;IAiBlC,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,iCAAiC;YAiD3B,gBAAgB;YAsBhB,oBAAoB;IA2BlC,OAAO,CAAC,qBAAqB;IAoC7B,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,4BAA4B;IAe9B,iBAAiB,CAAC,OAAO,EAAE,kBAAkB;IAYnD;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,2BAA2B;IAUnC,OAAO,CAAC,SAAS;IAkBjB,OAAO,CAAC,sBAAsB;CA2B/B;AAED,eAAe,IAAI,CAAC"}
|
|
@@ -4,11 +4,13 @@ import { FeedClientOptions } from './interfaces';
|
|
|
4
4
|
declare class FeedClient {
|
|
5
5
|
private instance;
|
|
6
6
|
private feedInstances;
|
|
7
|
+
private socketManager;
|
|
7
8
|
constructor(instance: Knock);
|
|
8
9
|
initialize(feedChannelId: string, options?: FeedClientOptions): Feed;
|
|
9
10
|
removeInstance(feed: Feed): void;
|
|
10
11
|
teardownInstances(): void;
|
|
11
12
|
reinitializeInstances(): void;
|
|
13
|
+
private initSocketManager;
|
|
12
14
|
}
|
|
13
15
|
export { Feed };
|
|
14
16
|
export default FeedClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/clients/feed/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,aAAa,CAAC;AAEhC,OAAO,IAAI,MAAM,QAAQ,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/clients/feed/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,aAAa,CAAC;AAEhC,OAAO,IAAI,MAAM,QAAQ,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGjD,cAAM,UAAU;IACd,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,aAAa,CAAgC;gBAEzC,QAAQ,EAAE,KAAK;IAI3B,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB;IAajE,cAAc,CAAC,IAAI,EAAE,IAAI;IAIzB,iBAAiB;IAMjB,qBAAqB;IAerB,OAAO,CAAC,iBAAiB;CAM1B;AAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAChB,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Socket } from 'phoenix';
|
|
2
|
+
import { default as Feed } from './feed';
|
|
3
|
+
import { FeedMetadata } from './interfaces';
|
|
4
|
+
export declare const SocketEventType: {
|
|
5
|
+
readonly NewMessage: "new-message";
|
|
6
|
+
};
|
|
7
|
+
type ClientReferenceId = string;
|
|
8
|
+
type NewMessageEventPayload = {
|
|
9
|
+
event: typeof SocketEventType.NewMessage;
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated Top-level feed metadata. Exists for legacy reasons.
|
|
12
|
+
*/
|
|
13
|
+
metadata: FeedMetadata;
|
|
14
|
+
/** Feed metadata, keyed by client reference id. */
|
|
15
|
+
data: Record<ClientReferenceId, {
|
|
16
|
+
metadata: FeedMetadata;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
export type SocketEventPayload = NewMessageEventPayload;
|
|
20
|
+
export declare class FeedSocketManager {
|
|
21
|
+
readonly socket: Socket;
|
|
22
|
+
private channels;
|
|
23
|
+
private params;
|
|
24
|
+
private inbox;
|
|
25
|
+
constructor(socket: Socket);
|
|
26
|
+
join(feed: Feed): () => void;
|
|
27
|
+
leave(feed: Feed): void;
|
|
28
|
+
private setInbox;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=socket-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-manager.d.ts","sourceRoot":"","sources":["../../../../src/clients/feed/socket-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,MAAM,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,IAAI,MAAM,QAAQ,CAAC;AAC1B,OAAO,KAAK,EAAqB,YAAY,EAAE,MAAM,cAAc,CAAC;AAEpE,eAAO,MAAM,eAAe;;CAElB,CAAC;AAUX,KAAK,iBAAiB,GAAG,MAAM,CAAC;AAEhC,KAAK,sBAAsB,GAAG;IAC5B,KAAK,EAAE,OAAO,eAAe,CAAC,UAAU,CAAC;IACzC;;OAEG;IACH,QAAQ,EAAE,YAAY,CAAC;IACvB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC,iBAAiB,EAAE;QAAE,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;CAC7D,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAaxD,qBAAa,iBAAiB;IAuChB,QAAQ,CAAC,MAAM,EAAE,MAAM;IApCnC,OAAO,CAAC,QAAQ,CAAgC;IAwBhD,OAAO,CAAC,MAAM,CAGZ;IAIF,OAAO,CAAC,KAAK,CAGX;gBAEmB,MAAM,EAAE,MAAM;IAMnC,IAAI,CAAC,IAAI,EAAE,IAAI;IAwDf,KAAK,CAAC,IAAI,EAAE,IAAI;IA4BhB,OAAO,CAAC,QAAQ;CAYjB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { GenericData, PageInfo } from '@knocklabs/types';
|
|
2
2
|
import { NetworkStatus } from '../../networkStatus';
|
|
3
3
|
import { FeedItem, FeedMetadata, FeedResponse } from './interfaces';
|
|
4
|
+
import { SocketEventPayload, SocketEventType } from './socket-manager';
|
|
4
5
|
export type StoreFeedResultOptions = {
|
|
5
6
|
shouldSetPage?: boolean;
|
|
6
7
|
shouldAppend?: boolean;
|
|
@@ -17,9 +18,9 @@ export interface FeedStoreState {
|
|
|
17
18
|
setItemAttrs: (itemIds: string[], attrs: object) => void;
|
|
18
19
|
resetStore: (metadata?: FeedMetadata) => void;
|
|
19
20
|
}
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
}
|
|
21
|
+
export type FeedMessagesReceivedPayload = Extract<SocketEventPayload, {
|
|
22
|
+
event: typeof SocketEventType.NewMessage;
|
|
23
|
+
}>;
|
|
23
24
|
export type FeedRealTimeEvent = "messages.new";
|
|
24
25
|
export type FeedEvent = FeedRealTimeEvent | "items.received.page" | "items.received.realtime" | "items.archived" | "items.unarchived" | "items.seen" | "items.unseen" | "items.read" | "items.unread" | "items.all_archived" | "items.all_read" | "items.all_seen";
|
|
25
26
|
export type BindableFeedEvent = FeedEvent | "items.received.*" | "items.*";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/clients/feed/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/clients/feed/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEvE,MAAM,MAAM,sBAAsB,GAAG;IACnC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC3E,WAAW,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9C,gBAAgB,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;IACzD,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,MAAM,2BAA2B,GAAG,OAAO,CAC/C,kBAAkB,EAClB;IAAE,KAAK,EAAE,OAAO,eAAe,CAAC,UAAU,CAAA;CAAE,CAC7C,CAAC;AAQF,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAE/C,MAAM,MAAM,SAAS,GACjB,iBAAiB,GACjB,qBAAqB,GACrB,yBAAyB,GACzB,gBAAgB,GAChB,kBAAkB,GAClB,YAAY,GACZ,cAAc,GACd,YAAY,GACZ,cAAc,GACd,oBAAoB,GACpB,gBAAgB,GAChB,gBAAgB,CAAC;AAGrB,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,kBAAkB,GAAG,SAAS,CAAC;AAE3E,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,WAAW;IAC/C,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACvC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;AAEhE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAEpE,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { GenericData } from '@knocklabs/types';
|
|
2
2
|
import { Store } from '@tanstack/store';
|
|
3
|
+
import { URLPattern } from 'urlpattern-polyfill';
|
|
3
4
|
import { default as Knock } from '../../knock';
|
|
4
5
|
export declare const guidesApiRootPath: (userId: string | undefined | null) => string;
|
|
5
6
|
interface StepMessageState {
|
|
@@ -18,6 +19,10 @@ interface GuideStepData {
|
|
|
18
19
|
message: StepMessageState;
|
|
19
20
|
content: any;
|
|
20
21
|
}
|
|
22
|
+
interface GuideActivationLocationRuleData {
|
|
23
|
+
directive: "allow" | "block";
|
|
24
|
+
pathname: string;
|
|
25
|
+
}
|
|
21
26
|
interface GuideData {
|
|
22
27
|
__typename: "Guide";
|
|
23
28
|
channel_id: string;
|
|
@@ -27,6 +32,7 @@ interface GuideData {
|
|
|
27
32
|
type: string;
|
|
28
33
|
semver: string;
|
|
29
34
|
steps: GuideStepData[];
|
|
35
|
+
activation_location_rules: GuideActivationLocationRuleData[];
|
|
30
36
|
inserted_at: string;
|
|
31
37
|
updated_at: string;
|
|
32
38
|
}
|
|
@@ -37,8 +43,12 @@ export interface KnockGuideStep extends GuideStepData {
|
|
|
37
43
|
}) => void;
|
|
38
44
|
markAsArchived: () => void;
|
|
39
45
|
}
|
|
46
|
+
interface KnockGuideActivationLocationRule extends GuideActivationLocationRuleData {
|
|
47
|
+
pattern: URLPattern;
|
|
48
|
+
}
|
|
40
49
|
export interface KnockGuide extends GuideData {
|
|
41
50
|
steps: KnockGuideStep[];
|
|
51
|
+
activation_location_rules: KnockGuideActivationLocationRule[];
|
|
42
52
|
}
|
|
43
53
|
type GetGuidesQueryParams = {
|
|
44
54
|
data?: string;
|
|
@@ -60,6 +70,7 @@ type QueryStatus = {
|
|
|
60
70
|
type StoreState = {
|
|
61
71
|
guides: KnockGuide[];
|
|
62
72
|
queries: Record<QueryKey, QueryStatus>;
|
|
73
|
+
location: string | undefined;
|
|
63
74
|
};
|
|
64
75
|
type QueryFilterParams = Pick<GetGuidesQueryParams, "type">;
|
|
65
76
|
export type SelectFilterParams = {
|
|
@@ -70,16 +81,23 @@ export type TargetParams = {
|
|
|
70
81
|
data?: GenericData | undefined;
|
|
71
82
|
tenant?: string | undefined;
|
|
72
83
|
};
|
|
84
|
+
type ConstructorOpts = {
|
|
85
|
+
trackLocationFromWindow?: boolean;
|
|
86
|
+
};
|
|
73
87
|
export declare class KnockGuideClient {
|
|
74
88
|
readonly knock: Knock;
|
|
75
89
|
readonly channelId: string;
|
|
76
90
|
readonly targetParams: TargetParams;
|
|
91
|
+
readonly options: ConstructorOpts;
|
|
77
92
|
store: Store<StoreState, (state: StoreState) => StoreState>;
|
|
78
93
|
private socket;
|
|
79
94
|
private socketChannel;
|
|
80
95
|
private socketChannelTopic;
|
|
81
96
|
private socketEventTypes;
|
|
82
|
-
|
|
97
|
+
private pushStateFn;
|
|
98
|
+
private replaceStateFn;
|
|
99
|
+
constructor(knock: Knock, channelId: string, targetParams?: TargetParams, options?: ConstructorOpts);
|
|
100
|
+
cleanup(): void;
|
|
83
101
|
fetch(opts?: {
|
|
84
102
|
filters?: QueryFilterParams;
|
|
85
103
|
}): Promise<QueryStatus>;
|
|
@@ -98,6 +116,9 @@ export declare class KnockGuideClient {
|
|
|
98
116
|
private addGuide;
|
|
99
117
|
private replaceOrAddGuide;
|
|
100
118
|
private removeGuide;
|
|
119
|
+
private handleLocationChange;
|
|
120
|
+
private listenForLocationChangesFromWindow;
|
|
121
|
+
private removeEventListeners;
|
|
101
122
|
}
|
|
102
123
|
export {};
|
|
103
124
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/clients/guide/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/clients/guide/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,MAAM,aAAa,CAAC;AAchC,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,GAAG,SAAS,GAAG,IAAI,WACrC,CAAC;AAE/B,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,gBAAgB,CAAC;IAE1B,OAAO,EAAE,GAAG,CAAC;CACd;AAED,UAAU,+BAA+B;IACvC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,SAAS;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,yBAAyB,EAAE,+BAA+B,EAAE,CAAC;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,gBAAgB,EAAE,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,UAAU,gCACR,SAAQ,+BAA+B;IACvC,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,yBAAyB,EAAE,gCAAgC,EAAE,CAAC;CAC/D;AAED,KAAK,oBAAoB,GAAG;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAMF,MAAM,MAAM,8BAA8B,GAAG;IAE3C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AA6CF,KAAK,QAAQ,GAAG,MAAM,CAAC;AAEvB,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACvC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,KAAK,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AAE5D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC,CAAC;AAEF,qBAAa,gBAAgB;IAczB,QAAQ,CAAC,KAAK,EAAE,KAAK;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,YAAY,EAAE,YAAY;IACnC,QAAQ,CAAC,OAAO,EAAE,eAAe;IAhB5B,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,UAAU,CAAC,CAAC;IAGnE,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,gBAAgB,CAAqD;IAG7E,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,cAAc,CAAsC;gBAGjD,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,MAAM,EACjB,YAAY,GAAE,YAAiB,EAC/B,OAAO,GAAE,eAAoB;IA0BxC,OAAO;IAKD,KAAK,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,iBAAiB,CAAA;KAAE;IA+ClD,SAAS;IA+BT,WAAW;IAcX,OAAO,CAAC,iBAAiB;IAwBzB,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB;IAyDpD,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa;IAyBhD,gBAAgB,CACpB,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,aAAa,EACnB,QAAQ,CAAC,EAAE,WAAW;IA0BlB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa;IAwB1D,OAAO,CAAC,SAAS;IA+CjB,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,8BAA8B;IAatC,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,iBAAiB;IAmBzB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,kCAAkC;IAwC1C,OAAO,CAAC,oBAAoB;CAa7B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knocklabs/client",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.6",
|
|
4
4
|
"description": "The clientside library for interacting with Knock",
|
|
5
5
|
"homepage": "https://github.com/knocklabs/javascript/tree/main/packages/client",
|
|
6
6
|
"author": "@knocklabs",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
|
53
53
|
"@babel/plugin-proposal-object-rest-spread": "^7.16.7",
|
|
54
54
|
"@babel/plugin-transform-runtime": "^7.25.4",
|
|
55
|
-
"@babel/preset-env": "^7.
|
|
55
|
+
"@babel/preset-env": "^7.27.1",
|
|
56
56
|
"@babel/preset-typescript": "^7.27.0",
|
|
57
57
|
"@types/jsonwebtoken": "^9.0.9",
|
|
58
58
|
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"rimraf": "^6.0.1",
|
|
66
66
|
"rollup": "^4.34.8",
|
|
67
67
|
"typescript": "^5.8.3",
|
|
68
|
-
"vite": "^5.4.
|
|
68
|
+
"vite": "^5.4.19",
|
|
69
69
|
"vitest": "^3.1.1"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
@@ -77,7 +77,9 @@
|
|
|
77
77
|
"axios-retry": "^4.5.0",
|
|
78
78
|
"eventemitter2": "^6.4.5",
|
|
79
79
|
"jwt-decode": "^4.0.0",
|
|
80
|
+
"nanoid": "^5.1.5",
|
|
80
81
|
"phoenix": "1.7.19",
|
|
82
|
+
"urlpattern-polyfill": "^10.0.0",
|
|
81
83
|
"zustand": "^4.5.6"
|
|
82
84
|
}
|
|
83
85
|
}
|
package/src/clients/feed/feed.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GenericData } from "@knocklabs/types";
|
|
2
2
|
import EventEmitter from "eventemitter2";
|
|
3
|
-
import {
|
|
3
|
+
import { nanoid } from "nanoid";
|
|
4
4
|
import type { StoreApi } from "zustand";
|
|
5
5
|
|
|
6
6
|
import { isValidUuid } from "../../helpers";
|
|
@@ -19,6 +19,11 @@ import {
|
|
|
19
19
|
FetchFeedOptions,
|
|
20
20
|
FetchFeedOptionsForRequest,
|
|
21
21
|
} from "./interfaces";
|
|
22
|
+
import {
|
|
23
|
+
FeedSocketManager,
|
|
24
|
+
SocketEventPayload,
|
|
25
|
+
SocketEventType,
|
|
26
|
+
} from "./socket-manager";
|
|
22
27
|
import createStore from "./store";
|
|
23
28
|
import {
|
|
24
29
|
BindableFeedEvent,
|
|
@@ -39,11 +44,15 @@ const feedClientDefaults: Pick<FeedClientOptions, "archived"> = {
|
|
|
39
44
|
|
|
40
45
|
const DEFAULT_DISCONNECT_DELAY = 2000;
|
|
41
46
|
|
|
47
|
+
const CLIENT_REF_ID_PREFIX = "client_";
|
|
48
|
+
|
|
42
49
|
class Feed {
|
|
50
|
+
public readonly defaultOptions: FeedClientOptions;
|
|
51
|
+
public readonly referenceId: string;
|
|
52
|
+
public unsubscribeFromSocketEvents: (() => void) | undefined = undefined;
|
|
53
|
+
private socketManager: FeedSocketManager | undefined;
|
|
43
54
|
private userFeedId: string;
|
|
44
|
-
private channel?: Channel;
|
|
45
55
|
private broadcaster: EventEmitter;
|
|
46
|
-
private defaultOptions: FeedClientOptions;
|
|
47
56
|
private broadcastChannel!: BroadcastChannel | null;
|
|
48
57
|
private disconnectTimer: ReturnType<typeof setTimeout> | null = null;
|
|
49
58
|
private hasSubscribedToRealTimeUpdates: boolean = false;
|
|
@@ -57,6 +66,7 @@ class Feed {
|
|
|
57
66
|
readonly knock: Knock,
|
|
58
67
|
readonly feedId: string,
|
|
59
68
|
options: FeedClientOptions,
|
|
69
|
+
socketManager: FeedSocketManager | undefined,
|
|
60
70
|
) {
|
|
61
71
|
if (!feedId || !isValidUuid(feedId)) {
|
|
62
72
|
this.knock.log(
|
|
@@ -67,6 +77,8 @@ class Feed {
|
|
|
67
77
|
|
|
68
78
|
this.feedId = feedId;
|
|
69
79
|
this.userFeedId = this.buildUserFeedId();
|
|
80
|
+
this.referenceId = CLIENT_REF_ID_PREFIX + nanoid();
|
|
81
|
+
this.socketManager = socketManager;
|
|
70
82
|
this.store = createStore();
|
|
71
83
|
this.broadcaster = new EventEmitter({ wildcard: true, delimiter: "." });
|
|
72
84
|
this.defaultOptions = {
|
|
@@ -84,7 +96,9 @@ class Feed {
|
|
|
84
96
|
/**
|
|
85
97
|
* Used to reinitialize a current feed instance, which is useful when reauthenticating users
|
|
86
98
|
*/
|
|
87
|
-
reinitialize() {
|
|
99
|
+
reinitialize(socketManager?: FeedSocketManager) {
|
|
100
|
+
this.socketManager = socketManager;
|
|
101
|
+
|
|
88
102
|
// Reinitialize the user feed id incase the userId changed
|
|
89
103
|
this.userFeedId = this.buildUserFeedId();
|
|
90
104
|
|
|
@@ -102,12 +116,9 @@ class Feed {
|
|
|
102
116
|
teardown() {
|
|
103
117
|
this.knock.log("[Feed] Tearing down feed instance");
|
|
104
118
|
|
|
105
|
-
|
|
106
|
-
this.channel.leave();
|
|
107
|
-
this.channel.off("new-message");
|
|
108
|
-
}
|
|
119
|
+
this.socketManager?.leave(this);
|
|
109
120
|
|
|
110
|
-
this.
|
|
121
|
+
this.tearDownVisibilityListeners();
|
|
111
122
|
|
|
112
123
|
if (this.disconnectTimer) {
|
|
113
124
|
clearTimeout(this.disconnectTimer);
|
|
@@ -144,17 +155,7 @@ class Feed {
|
|
|
144
155
|
return;
|
|
145
156
|
}
|
|
146
157
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// Connect the socket only if we don't already have a connection
|
|
150
|
-
if (maybeSocket && !maybeSocket.isConnected()) {
|
|
151
|
-
maybeSocket.connect();
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Only join the channel if we're not already in a joining state
|
|
155
|
-
if (this.channel && ["closed", "errored"].includes(this.channel.state)) {
|
|
156
|
-
this.channel.join();
|
|
157
|
-
}
|
|
158
|
+
this.unsubscribeFromSocketEvents = this.socketManager?.join(this);
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
/* Binds a handler to be invoked when event occurs */
|
|
@@ -587,6 +588,10 @@ class Feed {
|
|
|
587
588
|
});
|
|
588
589
|
}
|
|
589
590
|
|
|
591
|
+
get socketChannelTopic(): string {
|
|
592
|
+
return `feeds:${this.userFeedId}`;
|
|
593
|
+
}
|
|
594
|
+
|
|
590
595
|
private broadcast(
|
|
591
596
|
eventName: FeedEvent,
|
|
592
597
|
data: FeedResponse | FeedEventPayload,
|
|
@@ -595,15 +600,19 @@ class Feed {
|
|
|
595
600
|
}
|
|
596
601
|
|
|
597
602
|
// Invoked when a new real-time message comes in from the socket
|
|
598
|
-
private async onNewMessageReceived({
|
|
599
|
-
metadata,
|
|
600
|
-
}: FeedMessagesReceivedPayload) {
|
|
603
|
+
private async onNewMessageReceived({ data }: FeedMessagesReceivedPayload) {
|
|
601
604
|
this.knock.log("[Feed] Received new real-time message");
|
|
605
|
+
|
|
602
606
|
// Handle the new message coming in
|
|
603
607
|
const { items, ...state } = this.store.getState();
|
|
604
608
|
const currentHead: FeedItem | undefined = items[0];
|
|
609
|
+
|
|
605
610
|
// Optimistically set the badge counts
|
|
606
|
-
|
|
611
|
+
const metadata = data[this.referenceId]?.metadata;
|
|
612
|
+
if (metadata) {
|
|
613
|
+
state.setMetadata(metadata);
|
|
614
|
+
}
|
|
615
|
+
|
|
607
616
|
// Fetch the items before the current head (if it exists)
|
|
608
617
|
this.fetch({ before: currentHead?.__cursor, __fetchSource: "socket" });
|
|
609
618
|
}
|
|
@@ -767,28 +776,29 @@ class Feed {
|
|
|
767
776
|
}
|
|
768
777
|
|
|
769
778
|
private initializeRealtimeConnection() {
|
|
770
|
-
const { socket: maybeSocket } = this.knock.client();
|
|
771
|
-
|
|
772
779
|
// In server environments we might not have a socket connection
|
|
773
|
-
if (!
|
|
774
|
-
|
|
775
|
-
// Reinitialize channel connections incase the socket changed
|
|
776
|
-
this.channel = maybeSocket.channel(
|
|
777
|
-
`feeds:${this.userFeedId}`,
|
|
778
|
-
this.defaultOptions,
|
|
779
|
-
);
|
|
780
|
-
|
|
781
|
-
this.channel.on("new-message", (resp) => this.onNewMessageReceived(resp));
|
|
780
|
+
if (!this.socketManager) return;
|
|
782
781
|
|
|
783
782
|
if (this.defaultOptions.auto_manage_socket_connection) {
|
|
784
|
-
this.
|
|
783
|
+
this.setUpVisibilityListeners();
|
|
785
784
|
}
|
|
786
785
|
|
|
787
786
|
// If we're initializing but they have previously opted to listen to real-time updates
|
|
788
787
|
// then we will automatically reconnect on their behalf
|
|
789
788
|
if (this.hasSubscribedToRealTimeUpdates && this.knock.isAuthenticated()) {
|
|
790
|
-
|
|
791
|
-
|
|
789
|
+
this.unsubscribeFromSocketEvents = this.socketManager?.join(this);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
async handleSocketEvent(payload: SocketEventPayload) {
|
|
794
|
+
switch (payload.event) {
|
|
795
|
+
case SocketEventType.NewMessage:
|
|
796
|
+
this.onNewMessageReceived(payload);
|
|
797
|
+
return;
|
|
798
|
+
default: {
|
|
799
|
+
const _exhaustiveCheck: never = payload.event;
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
792
802
|
}
|
|
793
803
|
}
|
|
794
804
|
|
|
@@ -796,7 +806,7 @@ class Feed {
|
|
|
796
806
|
* Listen for changes to document visibility and automatically disconnect
|
|
797
807
|
* or reconnect the socket after a delay
|
|
798
808
|
*/
|
|
799
|
-
private
|
|
809
|
+
private setUpVisibilityListeners() {
|
|
800
810
|
if (
|
|
801
811
|
typeof document === "undefined" ||
|
|
802
812
|
this.visibilityChangeListenerConnected
|
|
@@ -809,7 +819,7 @@ class Feed {
|
|
|
809
819
|
document.addEventListener("visibilitychange", this.visibilityChangeHandler);
|
|
810
820
|
}
|
|
811
821
|
|
|
812
|
-
private
|
|
822
|
+
private tearDownVisibilityListeners() {
|
|
813
823
|
if (typeof document === "undefined") return;
|
|
814
824
|
|
|
815
825
|
document.removeEventListener(
|
|
@@ -860,7 +870,7 @@ class Feed {
|
|
|
860
870
|
|
|
861
871
|
// If the socket is not connected, try to reconnect
|
|
862
872
|
if (!client.socket?.isConnected()) {
|
|
863
|
-
|
|
873
|
+
client.socket?.connect();
|
|
864
874
|
}
|
|
865
875
|
}
|
|
866
876
|
}
|
|
@@ -2,19 +2,27 @@ import Knock from "../../knock";
|
|
|
2
2
|
|
|
3
3
|
import Feed from "./feed";
|
|
4
4
|
import { FeedClientOptions } from "./interfaces";
|
|
5
|
+
import { FeedSocketManager } from "./socket-manager";
|
|
5
6
|
|
|
6
7
|
class FeedClient {
|
|
7
8
|
private instance: Knock;
|
|
8
9
|
private feedInstances: Feed[] = [];
|
|
10
|
+
private socketManager: FeedSocketManager | undefined;
|
|
9
11
|
|
|
10
12
|
constructor(instance: Knock) {
|
|
11
13
|
this.instance = instance;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
initialize(feedChannelId: string, options: FeedClientOptions = {}) {
|
|
15
|
-
|
|
17
|
+
this.initSocketManager();
|
|
18
|
+
|
|
19
|
+
const feedInstance = new Feed(
|
|
20
|
+
this.instance,
|
|
21
|
+
feedChannelId,
|
|
22
|
+
options,
|
|
23
|
+
this.socketManager,
|
|
24
|
+
);
|
|
16
25
|
this.feedInstances.push(feedInstance);
|
|
17
|
-
|
|
18
26
|
return feedInstance;
|
|
19
27
|
}
|
|
20
28
|
|
|
@@ -30,7 +38,23 @@ class FeedClient {
|
|
|
30
38
|
|
|
31
39
|
reinitializeInstances() {
|
|
32
40
|
for (const feed of this.feedInstances) {
|
|
33
|
-
|
|
41
|
+
this.socketManager?.leave(feed);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// The API client has a new socket once it's reinitialized,
|
|
45
|
+
// so we need to set up a new socket manager
|
|
46
|
+
this.socketManager = undefined;
|
|
47
|
+
this.initSocketManager();
|
|
48
|
+
|
|
49
|
+
for (const feed of this.feedInstances) {
|
|
50
|
+
feed.reinitialize(this.socketManager);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private initSocketManager() {
|
|
55
|
+
const socket = this.instance.client().socket;
|
|
56
|
+
if (socket && !this.socketManager) {
|
|
57
|
+
this.socketManager = new FeedSocketManager(socket);
|
|
34
58
|
}
|
|
35
59
|
}
|
|
36
60
|
}
|