@stream-io/feeds-client 0.1.0

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.
Files changed (96) hide show
  1. package/@react-bindings/index.ts +2 -0
  2. package/CHANGELOG.md +44 -0
  3. package/LICENSE +219 -0
  4. package/README.md +9 -0
  5. package/dist/@react-bindings/hooks/useComments.d.ts +12 -0
  6. package/dist/@react-bindings/hooks/useStateStore.d.ts +3 -0
  7. package/dist/@react-bindings/index.d.ts +2 -0
  8. package/dist/index-react-bindings.browser.cjs +56 -0
  9. package/dist/index-react-bindings.browser.cjs.map +1 -0
  10. package/dist/index-react-bindings.browser.js +53 -0
  11. package/dist/index-react-bindings.browser.js.map +1 -0
  12. package/dist/index-react-bindings.node.cjs +56 -0
  13. package/dist/index-react-bindings.node.cjs.map +1 -0
  14. package/dist/index-react-bindings.node.js +53 -0
  15. package/dist/index-react-bindings.node.js.map +1 -0
  16. package/dist/index.browser.cjs +5799 -0
  17. package/dist/index.browser.cjs.map +1 -0
  18. package/dist/index.browser.js +5782 -0
  19. package/dist/index.browser.js.map +1 -0
  20. package/dist/index.d.ts +13 -0
  21. package/dist/index.node.cjs +5799 -0
  22. package/dist/index.node.cjs.map +1 -0
  23. package/dist/index.node.js +5782 -0
  24. package/dist/index.node.js.map +1 -0
  25. package/dist/src/Feed.d.ts +109 -0
  26. package/dist/src/FeedsClient.d.ts +63 -0
  27. package/dist/src/ModerationClient.d.ts +3 -0
  28. package/dist/src/common/ActivitySearchSource.d.ts +17 -0
  29. package/dist/src/common/ApiClient.d.ts +20 -0
  30. package/dist/src/common/BaseSearchSource.d.ts +87 -0
  31. package/dist/src/common/ConnectionIdManager.d.ts +11 -0
  32. package/dist/src/common/EventDispatcher.d.ts +11 -0
  33. package/dist/src/common/FeedSearchSource.d.ts +17 -0
  34. package/dist/src/common/Poll.d.ts +34 -0
  35. package/dist/src/common/SearchController.d.ts +41 -0
  36. package/dist/src/common/StateStore.d.ts +124 -0
  37. package/dist/src/common/TokenManager.d.ts +29 -0
  38. package/dist/src/common/UserSearchSource.d.ts +17 -0
  39. package/dist/src/common/gen-imports.d.ts +2 -0
  40. package/dist/src/common/rate-limit.d.ts +2 -0
  41. package/dist/src/common/real-time/StableWSConnection.d.ts +144 -0
  42. package/dist/src/common/real-time/event-models.d.ts +36 -0
  43. package/dist/src/common/types.d.ts +29 -0
  44. package/dist/src/common/utils.d.ts +54 -0
  45. package/dist/src/gen/feeds/FeedApi.d.ts +26 -0
  46. package/dist/src/gen/feeds/FeedsApi.d.ts +237 -0
  47. package/dist/src/gen/model-decoders/decoders.d.ts +3 -0
  48. package/dist/src/gen/model-decoders/event-decoder-mapping.d.ts +6 -0
  49. package/dist/src/gen/models/index.d.ts +3437 -0
  50. package/dist/src/gen/moderation/ModerationApi.d.ts +21 -0
  51. package/dist/src/gen-imports.d.ts +3 -0
  52. package/dist/src/state-updates/activity-reaction-utils.d.ts +10 -0
  53. package/dist/src/state-updates/activity-utils.d.ts +13 -0
  54. package/dist/src/state-updates/bookmark-utils.d.ts +14 -0
  55. package/dist/src/types-internal.d.ts +4 -0
  56. package/dist/src/types.d.ts +13 -0
  57. package/dist/src/utils.d.ts +1 -0
  58. package/dist/tsconfig.tsbuildinfo +1 -0
  59. package/index.ts +13 -0
  60. package/package.json +85 -0
  61. package/src/Feed.ts +1070 -0
  62. package/src/FeedsClient.ts +352 -0
  63. package/src/ModerationClient.ts +3 -0
  64. package/src/common/ActivitySearchSource.ts +46 -0
  65. package/src/common/ApiClient.ts +197 -0
  66. package/src/common/BaseSearchSource.ts +238 -0
  67. package/src/common/ConnectionIdManager.ts +51 -0
  68. package/src/common/EventDispatcher.ts +52 -0
  69. package/src/common/FeedSearchSource.ts +94 -0
  70. package/src/common/Poll.ts +313 -0
  71. package/src/common/SearchController.ts +152 -0
  72. package/src/common/StateStore.ts +314 -0
  73. package/src/common/TokenManager.ts +112 -0
  74. package/src/common/UserSearchSource.ts +93 -0
  75. package/src/common/gen-imports.ts +2 -0
  76. package/src/common/rate-limit.ts +23 -0
  77. package/src/common/real-time/StableWSConnection.ts +761 -0
  78. package/src/common/real-time/event-models.ts +38 -0
  79. package/src/common/types.ts +40 -0
  80. package/src/common/utils.ts +194 -0
  81. package/src/gen/feeds/FeedApi.ts +129 -0
  82. package/src/gen/feeds/FeedsApi.ts +2192 -0
  83. package/src/gen/model-decoders/decoders.ts +1877 -0
  84. package/src/gen/model-decoders/event-decoder-mapping.ts +150 -0
  85. package/src/gen/models/index.ts +5882 -0
  86. package/src/gen/moderation/ModerationApi.ts +270 -0
  87. package/src/gen-imports.ts +3 -0
  88. package/src/state-updates/activity-reaction-utils.test.ts +348 -0
  89. package/src/state-updates/activity-reaction-utils.ts +107 -0
  90. package/src/state-updates/activity-utils.test.ts +257 -0
  91. package/src/state-updates/activity-utils.ts +80 -0
  92. package/src/state-updates/bookmark-utils.test.ts +383 -0
  93. package/src/state-updates/bookmark-utils.ts +157 -0
  94. package/src/types-internal.ts +5 -0
  95. package/src/types.ts +20 -0
  96. package/src/utils.ts +4 -0
@@ -0,0 +1,109 @@
1
+ import { ActivityRequest, FeedResponse, GetOrCreateFeedRequest, GetOrCreateFeedResponse, QueryFollowsRequest, WSEvent, ActivityResponse, CommentResponse, SingleFollowRequest } from './gen/models';
2
+ import { StateStore } from './common/StateStore';
3
+ import { EventDispatcher } from './common/EventDispatcher';
4
+ import { FeedApi } from './gen/feeds/FeedApi';
5
+ import { FeedsClient } from './FeedsClient';
6
+ import { StreamResponse } from './gen-imports';
7
+ import type { ActivityIdOrCommentId, GetCommentsRepliesRequest, GetCommentsRequest, LoadingStates, PagerResponseWithLoadingStates } from './types';
8
+ export type FeedState = Omit<Partial<GetOrCreateFeedResponse & FeedResponse>, 'feed' | 'duration'> & {
9
+ /**
10
+ * True when loading state using `getOrCreate`
11
+ */
12
+ is_loading: boolean;
13
+ /**
14
+ * True when loading activities using `getOrCreate` or `getNextPage`
15
+ */
16
+ is_loading_activities: boolean;
17
+ comments_by_entity_id: Record<ActivityIdOrCommentId, {
18
+ pagination?: PagerResponseWithLoadingStates & {
19
+ sort?: string;
20
+ };
21
+ /**
22
+ * Id of the "store" where the actual parent is stored in the comments array.
23
+ *
24
+ * Example:
25
+ * ```
26
+ * // top-level comment:
27
+ * const comment1 = {
28
+ * id: 'comment-1',
29
+ * object_id: 'activity-1',
30
+ * }
31
+ * // child comment:
32
+ * const comment2 = {
33
+ * id: 'comment-2',
34
+ * object_id: 'activity-1',
35
+ * parent_id: 'comment-1',
36
+ * }
37
+ * ```
38
+ * When these comments are loaded, they're stored in the state like this:
39
+ * ```
40
+ * {
41
+ * comments_by_entity_id: {
42
+ * 'activity-1': {
43
+ * comments: [comment1],
44
+ * parent_id: undefined,
45
+ * },
46
+ * 'comment-1': {
47
+ * comments: [comment2],
48
+ * parent_id: 'activity-1', // parent store where "comment-1" is located in "comments" array
49
+ * }
50
+ * }
51
+ * }
52
+ * ```
53
+ */
54
+ parent_id?: ActivityIdOrCommentId;
55
+ comments?: CommentResponse[];
56
+ } | undefined>;
57
+ followers_pagination?: LoadingStates & {
58
+ sort?: string;
59
+ };
60
+ following_pagination?: LoadingStates & {
61
+ sort?: string;
62
+ };
63
+ };
64
+ export declare class Feed extends FeedApi {
65
+ readonly state: StateStore<FeedState>;
66
+ private static readonly noop;
67
+ private readonly eventHandlers;
68
+ protected eventDispatcher: EventDispatcher<WSEvent['type'], WSEvent>;
69
+ constructor(client: FeedsClient, groupId: 'user' | 'timeline' | (string & {}), id: string, data?: FeedResponse);
70
+ private readonly client;
71
+ get fid(): string;
72
+ get currentState(): FeedState;
73
+ private handleCommentReactionEvent;
74
+ getOrCreate(request?: GetOrCreateFeedRequest): Promise<StreamResponse<GetOrCreateFeedResponse>>;
75
+ private handleBookmarkAdded;
76
+ private handleBookmarkDeleted;
77
+ private handleBookmarkUpdated;
78
+ /**
79
+ * Returns index of the provided comment object.
80
+ */
81
+ private getCommentIndex;
82
+ private getActivityIndex;
83
+ private updateActivityInState;
84
+ private loadNextPageComments;
85
+ loadNextPageActivityComments(activity: ActivityResponse, request?: Partial<Omit<GetCommentsRequest, 'object_id' | 'object_type' | 'next'>>): Promise<void>;
86
+ loadNextPageCommentReplies(comment: CommentResponse, request?: Partial<Omit<GetCommentsRepliesRequest, 'comment_id' | 'next'>>): Promise<void>;
87
+ private loadNextPageFollows;
88
+ loadNextPageFollowers(request: Pick<QueryFollowsRequest, 'limit'>): Promise<void>;
89
+ loadNextPageFollowing(request: Pick<QueryFollowsRequest, 'limit'>): Promise<void>;
90
+ /**
91
+ * Method which queries followers of this feed (feeds which target this feed).
92
+ *
93
+ * _Note: Useful only for feeds with `groupId` of `user` value._
94
+ */
95
+ queryFollowers(request: Omit<QueryFollowsRequest, 'filter'>): Promise<StreamResponse<import("./gen/models").QueryFollowsResponse>>;
96
+ /**
97
+ * Method which queries following of this feed (target feeds of this feed).
98
+ *
99
+ * _Note: Useful only for feeds with `groupId` of `timeline` value._
100
+ */
101
+ queryFollowing(request: Omit<QueryFollowsRequest, 'filter'>): Promise<StreamResponse<import("./gen/models").QueryFollowsResponse>>;
102
+ follow(feedOrFid: Feed | string, options?: Omit<SingleFollowRequest, 'source' | 'target'>): Promise<StreamResponse<import("./gen/models").SingleFollowResponse>>;
103
+ unfollow(feedOrFid: Feed | string): Promise<StreamResponse<import("./gen/models").UnfollowResponse>>;
104
+ getNextPage(): Promise<StreamResponse<GetOrCreateFeedResponse>>;
105
+ addActivity(request: Omit<ActivityRequest, 'fids'>): Promise<StreamResponse<import("./gen/models").AddActivityResponse>>;
106
+ on: (eventName: "all" | "app.updated" | "feeds.activity.added" | "feeds.activity.deleted" | "feeds.activity.marked" | "feeds.activity.pinned" | "feeds.activity.reaction.added" | "feeds.activity.reaction.deleted" | "feeds.activity.reaction.updated" | "feeds.activity.removed_from_feed" | "feeds.activity.unpinned" | "feeds.activity.updated" | "feeds.bookmark.added" | "feeds.bookmark.deleted" | "feeds.bookmark.updated" | "feeds.comment.added" | "feeds.comment.deleted" | "feeds.comment.reaction.added" | "feeds.comment.reaction.deleted" | "feeds.comment.reaction.updated" | "feeds.comment.updated" | "feeds.feed.created" | "feeds.feed.deleted" | "feeds.feed.updated" | "feeds.feed_group.changed" | "feeds.feed_group.deleted" | "feeds.feed_member.added" | "feeds.feed_member.removed" | "feeds.feed_member.updated" | "feeds.follow.created" | "feeds.follow.deleted" | "feeds.follow.updated" | "feeds.poll.closed" | "feeds.poll.deleted" | "feeds.poll.updated" | "feeds.poll.vote_casted" | "feeds.poll.vote_changed" | "feeds.poll.vote_removed" | "health.check" | "user.updated" | "moderation.custom_action" | "moderation.flagged" | "moderation.mark_reviewed" | "user.banned" | "user.deactivated" | "user.muted" | "user.reactivated", handler: (event: WSEvent) => void) => () => void;
107
+ off: (eventName: "all" | "app.updated" | "feeds.activity.added" | "feeds.activity.deleted" | "feeds.activity.marked" | "feeds.activity.pinned" | "feeds.activity.reaction.added" | "feeds.activity.reaction.deleted" | "feeds.activity.reaction.updated" | "feeds.activity.removed_from_feed" | "feeds.activity.unpinned" | "feeds.activity.updated" | "feeds.bookmark.added" | "feeds.bookmark.deleted" | "feeds.bookmark.updated" | "feeds.comment.added" | "feeds.comment.deleted" | "feeds.comment.reaction.added" | "feeds.comment.reaction.deleted" | "feeds.comment.reaction.updated" | "feeds.comment.updated" | "feeds.feed.created" | "feeds.feed.deleted" | "feeds.feed.updated" | "feeds.feed_group.changed" | "feeds.feed_group.deleted" | "feeds.feed_member.added" | "feeds.feed_member.removed" | "feeds.feed_member.updated" | "feeds.follow.created" | "feeds.follow.deleted" | "feeds.follow.updated" | "feeds.poll.closed" | "feeds.poll.deleted" | "feeds.poll.updated" | "feeds.poll.vote_casted" | "feeds.poll.vote_changed" | "feeds.poll.vote_removed" | "health.check" | "user.updated" | "moderation.custom_action" | "moderation.flagged" | "moderation.mark_reviewed" | "user.banned" | "user.deactivated" | "user.muted" | "user.reactivated", handler: (event: WSEvent) => void) => void;
108
+ handleWSEvent(event: WSEvent): void;
109
+ }
@@ -0,0 +1,63 @@
1
+ import { FeedsApi } from './gen/feeds/FeedsApi';
2
+ import { ActivityResponse, FileUploadRequest, ImageUploadRequest, OwnUser, PollResponse, PollVotesResponse, QueryFeedsRequest, QueryPollVotesRequest, UserRequest } from './gen/models';
3
+ import { FeedsEvent } from './types';
4
+ import { StateStore } from './common/StateStore';
5
+ import { Feed } from './Feed';
6
+ import { FeedsClientOptions, StreamResponse } from './common/types';
7
+ import { ModerationClient } from './ModerationClient';
8
+ import { StreamPoll } from './common/Poll';
9
+ export type FeedsClientState = {
10
+ connectedUser: OwnUser | undefined;
11
+ };
12
+ export declare class FeedsClient extends FeedsApi {
13
+ readonly state: StateStore<FeedsClientState>;
14
+ readonly moderation: ModerationClient;
15
+ private readonly tokenManager;
16
+ private wsConnection?;
17
+ private readonly connectionIdManager;
18
+ private readonly eventDispatcher;
19
+ private readonly polls_by_id;
20
+ private activeFeeds;
21
+ constructor(apiKey: string, options?: FeedsClientOptions);
22
+ pollFromState: (id: string) => StreamPoll | undefined;
23
+ hydratePollCache(activities: ActivityResponse[]): void;
24
+ connectUser: (user: UserRequest, tokenProvider: string | (() => Promise<string>)) => Promise<void>;
25
+ closePoll: (request: {
26
+ poll_id: string;
27
+ }) => Promise<StreamResponse<PollResponse>>;
28
+ uploadFile: (request: Omit<FileUploadRequest, "file"> & {
29
+ file: File;
30
+ }) => Promise<StreamResponse<import("./gen/models").FileUploadResponse>>;
31
+ uploadImage: (request: Omit<ImageUploadRequest, "file"> & {
32
+ file: File;
33
+ }) => Promise<StreamResponse<import("./gen/models").ImageUploadResponse>>;
34
+ queryPollAnswers: (request: QueryPollVotesRequest & {
35
+ poll_id: string;
36
+ user_id?: string;
37
+ }) => Promise<StreamResponse<PollVotesResponse>>;
38
+ queryPollOptionVotes: (request: QueryPollVotesRequest & {
39
+ filter: QueryPollVotesRequest["filter"] & {
40
+ option_id: string;
41
+ };
42
+ poll_id: string;
43
+ user_id?: string;
44
+ }) => Promise<StreamResponse<PollVotesResponse>>;
45
+ disconnectUser: () => Promise<void>;
46
+ on: (eventName: "all" | "app.updated" | "feeds.activity.added" | "feeds.activity.deleted" | "feeds.activity.marked" | "feeds.activity.pinned" | "feeds.activity.reaction.added" | "feeds.activity.reaction.deleted" | "feeds.activity.reaction.updated" | "feeds.activity.removed_from_feed" | "feeds.activity.unpinned" | "feeds.activity.updated" | "feeds.bookmark.added" | "feeds.bookmark.deleted" | "feeds.bookmark.updated" | "feeds.comment.added" | "feeds.comment.deleted" | "feeds.comment.reaction.added" | "feeds.comment.reaction.deleted" | "feeds.comment.reaction.updated" | "feeds.comment.updated" | "feeds.feed.created" | "feeds.feed.deleted" | "feeds.feed.updated" | "feeds.feed_group.changed" | "feeds.feed_group.deleted" | "feeds.feed_member.added" | "feeds.feed_member.removed" | "feeds.feed_member.updated" | "feeds.follow.created" | "feeds.follow.deleted" | "feeds.follow.updated" | "feeds.poll.closed" | "feeds.poll.deleted" | "feeds.poll.updated" | "feeds.poll.vote_casted" | "feeds.poll.vote_changed" | "feeds.poll.vote_removed" | "health.check" | "user.updated" | "moderation.custom_action" | "moderation.flagged" | "moderation.mark_reviewed" | "user.banned" | "user.deactivated" | "user.muted" | "user.reactivated" | "connection.changed" | "network.changed", handler: (event: FeedsEvent & {
47
+ fid?: string;
48
+ }) => void) => () => void;
49
+ off: (eventName: "all" | "app.updated" | "feeds.activity.added" | "feeds.activity.deleted" | "feeds.activity.marked" | "feeds.activity.pinned" | "feeds.activity.reaction.added" | "feeds.activity.reaction.deleted" | "feeds.activity.reaction.updated" | "feeds.activity.removed_from_feed" | "feeds.activity.unpinned" | "feeds.activity.updated" | "feeds.bookmark.added" | "feeds.bookmark.deleted" | "feeds.bookmark.updated" | "feeds.comment.added" | "feeds.comment.deleted" | "feeds.comment.reaction.added" | "feeds.comment.reaction.deleted" | "feeds.comment.reaction.updated" | "feeds.comment.updated" | "feeds.feed.created" | "feeds.feed.deleted" | "feeds.feed.updated" | "feeds.feed_group.changed" | "feeds.feed_group.deleted" | "feeds.feed_member.added" | "feeds.feed_member.removed" | "feeds.feed_member.updated" | "feeds.follow.created" | "feeds.follow.deleted" | "feeds.follow.updated" | "feeds.poll.closed" | "feeds.poll.deleted" | "feeds.poll.updated" | "feeds.poll.vote_casted" | "feeds.poll.vote_changed" | "feeds.poll.vote_removed" | "health.check" | "user.updated" | "moderation.custom_action" | "moderation.flagged" | "moderation.mark_reviewed" | "user.banned" | "user.deactivated" | "user.muted" | "user.reactivated" | "connection.changed" | "network.changed", handler: (event: FeedsEvent & {
50
+ fid?: string;
51
+ }) => void) => void;
52
+ feed: (groupId: string, id: string) => Feed;
53
+ queryFeeds(request?: QueryFeedsRequest): Promise<{
54
+ feeds: Feed[];
55
+ next: string | undefined;
56
+ prev: string | undefined;
57
+ metadata: import("./common/types").RequestMetadata;
58
+ duration: string;
59
+ }>;
60
+ private readonly getOrCreateActiveFeed;
61
+ private readonly updateNetworkConnectionStatus;
62
+ private findActiveFeedByActivityId;
63
+ }
@@ -0,0 +1,3 @@
1
+ import { ModerationApi } from './gen/moderation/ModerationApi';
2
+ export declare class ModerationClient extends ModerationApi {
3
+ }
@@ -0,0 +1,17 @@
1
+ import { BaseSearchSource } from './BaseSearchSource';
2
+ import type { SearchSourceOptions } from './BaseSearchSource';
3
+ import { FeedsClient } from '../FeedsClient';
4
+ import { ActivityResponse } from '../gen/models';
5
+ export declare class ActivitySearchSource extends BaseSearchSource<ActivityResponse> {
6
+ readonly type: "activity";
7
+ private readonly client;
8
+ constructor(client: FeedsClient, options?: SearchSourceOptions);
9
+ protected query(searchQuery: string): Promise<{
10
+ items: never[];
11
+ next?: undefined;
12
+ } | {
13
+ items: ActivityResponse[];
14
+ next: string | undefined;
15
+ }>;
16
+ protected filterQueryResults(items: ActivityResponse[]): ActivityResponse[];
17
+ }
@@ -0,0 +1,20 @@
1
+ import { RequestMetadata, FeedsClientOptions } from './types';
2
+ import { TokenManager } from './TokenManager';
3
+ import { ConnectionIdManager } from './ConnectionIdManager';
4
+ export declare class ApiClient {
5
+ readonly apiKey: string;
6
+ private readonly tokenManager;
7
+ private readonly connectionIdManager;
8
+ readonly baseUrl: string;
9
+ private readonly axiosInstance;
10
+ constructor(apiKey: string, tokenManager: TokenManager, connectionIdManager: ConnectionIdManager, options?: FeedsClientOptions);
11
+ sendRequest: <T>(method: string, url: string, pathParams?: Record<string, string>, queryParams?: Record<string, any>, body?: any, requestContentType?: string) => Promise<{
12
+ body: T;
13
+ metadata: RequestMetadata;
14
+ }>;
15
+ get webSocketBaseUrl(): string;
16
+ private get commonHeaders();
17
+ private isAxiosError;
18
+ private readonly queryParamsStringify;
19
+ private readonly getRequestMetadata;
20
+ }
@@ -0,0 +1,87 @@
1
+ import { StateStore } from './StateStore';
2
+ import { type DebouncedFunc } from './utils';
3
+ export type SearchSourceType = 'channels' | 'users' | 'messages' | (string & {});
4
+ export type QueryReturnValue<T> = {
5
+ items: T[];
6
+ next?: string | null;
7
+ };
8
+ export type DebounceOptions = {
9
+ debounceMs: number;
10
+ };
11
+ type DebouncedExecQueryFunction = DebouncedFunc<(searchString?: string) => Promise<void>>;
12
+ export interface SearchSource<T = any> {
13
+ activate(): void;
14
+ cancelScheduledQuery(): void;
15
+ canExecuteQuery(newSearchString?: string): boolean;
16
+ deactivate(): void;
17
+ readonly hasNext: boolean;
18
+ readonly hasResults: boolean;
19
+ readonly initialState: SearchSourceState<T>;
20
+ readonly isActive: boolean;
21
+ readonly isLoading: boolean;
22
+ readonly items: T[] | undefined;
23
+ readonly lastQueryError: Error | undefined;
24
+ readonly next: string | undefined | null;
25
+ readonly offset: number | undefined;
26
+ resetState(): void;
27
+ search(text?: string): Promise<void> | undefined;
28
+ readonly searchQuery: string;
29
+ setDebounceOptions(options: DebounceOptions): void;
30
+ readonly state: StateStore<SearchSourceState<T>>;
31
+ readonly type: SearchSourceType;
32
+ }
33
+ export type SearchSourceState<T = any> = {
34
+ hasNext: boolean;
35
+ isActive: boolean;
36
+ isLoading: boolean;
37
+ items: T[] | undefined;
38
+ searchQuery: string;
39
+ lastQueryError?: Error;
40
+ next?: string | null;
41
+ offset?: number;
42
+ };
43
+ export type SearchSourceOptions = {
44
+ /** The number of milliseconds to debounce the search query. The default interval is 300ms. */
45
+ debounceMs?: number;
46
+ pageSize?: number;
47
+ };
48
+ export declare abstract class BaseSearchSource<T> implements SearchSource<T> {
49
+ state: StateStore<SearchSourceState<T>>;
50
+ protected pageSize: number;
51
+ abstract readonly type: SearchSourceType;
52
+ protected searchDebounced: DebouncedExecQueryFunction;
53
+ protected constructor(options?: SearchSourceOptions);
54
+ get lastQueryError(): Error | undefined;
55
+ get hasNext(): boolean;
56
+ get hasResults(): boolean;
57
+ get isActive(): boolean;
58
+ get isLoading(): boolean;
59
+ get initialState(): {
60
+ hasNext: boolean;
61
+ isActive: boolean;
62
+ isLoading: boolean;
63
+ items: undefined;
64
+ lastQueryError: undefined;
65
+ next: undefined;
66
+ offset: number;
67
+ searchQuery: string;
68
+ };
69
+ get items(): T[] | undefined;
70
+ get next(): string | null | undefined;
71
+ get offset(): number | undefined;
72
+ get searchQuery(): string;
73
+ protected abstract query(searchQuery: string): Promise<QueryReturnValue<T>>;
74
+ protected abstract filterQueryResults(items: T[]): T[] | Promise<T[]>;
75
+ setDebounceOptions: ({ debounceMs }: DebounceOptions) => void;
76
+ activate: () => void;
77
+ deactivate: () => void;
78
+ canExecuteQuery: (newSearchString?: string) => boolean;
79
+ protected getStateBeforeFirstQuery(newSearchString: string): SearchSourceState<T>;
80
+ protected getStateAfterQuery(stateUpdate: Partial<SearchSourceState<T>>, isFirstPage: boolean): SearchSourceState<T>;
81
+ executeQuery(newSearchString?: string): Promise<void>;
82
+ search: (searchQuery?: string) => Promise<void> | undefined;
83
+ cancelScheduledQuery(): void;
84
+ resetState(): void;
85
+ resetStateAndActivate(): void;
86
+ }
87
+ export {};
@@ -0,0 +1,11 @@
1
+ export declare class ConnectionIdManager {
2
+ loadConnectionIdPromise: Promise<string> | undefined;
3
+ connectionId?: string;
4
+ private resolve?;
5
+ private reject?;
6
+ reset: () => void;
7
+ resetConnectionIdPromise: () => void;
8
+ resolveConnectionidPromise: (connectionId: string) => void;
9
+ rejectConnectionIdPromise: (reason: any) => void;
10
+ getConnectionId: () => string | Promise<string>;
11
+ }
@@ -0,0 +1,11 @@
1
+ import { FeedsEvent } from '../types';
2
+ export declare class EventDispatcher<Type extends string = FeedsEvent['type'], Event extends {
3
+ type: string;
4
+ } = FeedsEvent> {
5
+ private subscribers;
6
+ private readonly logger;
7
+ dispatch: (event: Event) => void;
8
+ on: (eventName: Type | "all", handler: (event: Event) => void) => () => void;
9
+ off: (eventName: Type | "all", handler: (event: Event) => void) => void;
10
+ offAll: (eventName?: Type | "all") => void;
11
+ }
@@ -0,0 +1,17 @@
1
+ import { BaseSearchSource } from './BaseSearchSource';
2
+ import type { SearchSourceOptions } from './BaseSearchSource';
3
+ import { FeedsClient } from '../FeedsClient';
4
+ import { Feed } from '../Feed';
5
+ export declare class FeedSearchSource extends BaseSearchSource<Feed> {
6
+ readonly type: "feed";
7
+ private readonly client;
8
+ constructor(client: FeedsClient, options?: SearchSourceOptions);
9
+ protected query(searchQuery: string): Promise<{
10
+ items: never[];
11
+ next?: undefined;
12
+ } | {
13
+ items: Feed[];
14
+ next: string | undefined;
15
+ }>;
16
+ protected filterQueryResults(items: Feed[]): Feed[];
17
+ }
@@ -0,0 +1,34 @@
1
+ import { StateStore } from './StateStore';
2
+ import type { FeedsClient } from '../FeedsClient';
3
+ import type { PollVote, QueryPollVotesRequest, PollUpdatedFeedEvent, PollClosedFeedEvent, PollVoteCastedFeedEvent, PollVoteChangedFeedEvent, PollVoteRemovedFeedEvent, Poll as PollType } from '../gen/models';
4
+ export declare const isVoteAnswer: (vote: PollVote) => boolean;
5
+ export type PollAnswersQueryParams = QueryPollVotesRequest & {
6
+ poll_id: string;
7
+ user_id?: string;
8
+ };
9
+ type OptionId = string;
10
+ export type PollState = Omit<PollType, 'own_votes' | 'id'> & {
11
+ last_activity_at: Date;
12
+ max_voted_option_ids: OptionId[];
13
+ own_votes_by_option_id: Record<OptionId, PollVote>;
14
+ own_answer?: PollVote;
15
+ };
16
+ type PollInitOptions = {
17
+ client: FeedsClient;
18
+ poll: PollType;
19
+ };
20
+ export declare class StreamPoll {
21
+ readonly state: StateStore<PollState>;
22
+ id: string;
23
+ private readonly client;
24
+ constructor({ client, poll }: PollInitOptions);
25
+ private readonly getInitialStateFromPollResponse;
26
+ reinitializeState: (poll: PollInitOptions["poll"]) => void;
27
+ get data(): PollState;
28
+ handlePollUpdated: (event: PollUpdatedFeedEvent) => void;
29
+ handlePollClosed: (event: PollClosedFeedEvent) => void;
30
+ handleVoteCasted: (event: PollVoteCastedFeedEvent) => void;
31
+ handleVoteChanged: (event: PollVoteChangedFeedEvent) => void;
32
+ handleVoteRemoved: (event: PollVoteRemovedFeedEvent) => void;
33
+ }
34
+ export {};
@@ -0,0 +1,41 @@
1
+ import { StateStore } from './StateStore';
2
+ import type { SearchSource } from './BaseSearchSource';
3
+ export type SearchControllerState = {
4
+ isActive: boolean;
5
+ searchQuery: string;
6
+ sources: SearchSource[];
7
+ };
8
+ export type InternalSearchControllerState = {};
9
+ export type SearchControllerConfig = {
10
+ keepSingleActiveSource: boolean;
11
+ };
12
+ export type SearchControllerOptions = {
13
+ config?: Partial<SearchControllerConfig>;
14
+ sources?: SearchSource[];
15
+ };
16
+ export declare class SearchController {
17
+ /**
18
+ * Not intended for direct use by integrators, might be removed without notice resulting in
19
+ * broken integrations.
20
+ */
21
+ _internalState: StateStore<InternalSearchControllerState>;
22
+ state: StateStore<SearchControllerState>;
23
+ config: SearchControllerConfig;
24
+ constructor({ config, sources }?: SearchControllerOptions);
25
+ get hasNext(): boolean;
26
+ get sources(): SearchSource<any>[];
27
+ get activeSources(): SearchSource<any>[];
28
+ get isActive(): boolean;
29
+ get searchQuery(): string;
30
+ get searchSourceTypes(): Array<SearchSource['type']>;
31
+ addSource: (source: SearchSource) => void;
32
+ getSource: (sourceType: SearchSource["type"]) => SearchSource<any> | undefined;
33
+ removeSource: (sourceType: SearchSource["type"]) => void;
34
+ activateSource: (sourceType: SearchSource["type"]) => void;
35
+ deactivateSource: (sourceType: SearchSource["type"]) => void;
36
+ activate: () => void;
37
+ search: (searchQuery?: string) => Promise<void>;
38
+ cancelSearchQueries: () => void;
39
+ clear: () => void;
40
+ exit: () => void;
41
+ }
@@ -0,0 +1,124 @@
1
+ export type Patch<T> = (value: T) => T;
2
+ export type ValueOrPatch<T> = T | Patch<T>;
3
+ export type Handler<T> = (nextValue: T, previousValue: T | undefined) => void;
4
+ export type Unsubscribe = () => void;
5
+ export type RemovePreprocessor = Unsubscribe;
6
+ export type Preprocessor<T> = Handler<T>;
7
+ export declare const isPatch: <T>(value: ValueOrPatch<T>) => value is Patch<T>;
8
+ export declare class StateStore<T extends Record<string, unknown>> {
9
+ protected value: T;
10
+ protected handlers: Set<Handler<T>>;
11
+ protected preprocessors: Set<Preprocessor<T>>;
12
+ constructor(value: T);
13
+ /**
14
+ * Allows merging two stores only if their keys differ otherwise there's no way to ensure the data type stability.
15
+ * @experimental
16
+ * This method is experimental and may change in future versions.
17
+ */
18
+ merge<Q extends StateStore<any>>(stateStore: Q extends StateStore<infer L> ? Extract<keyof T, keyof L> extends never ? Q : never : never): MergedStateStore<T, Q extends StateStore<infer L extends Record<string, unknown>> ? L : never>;
19
+ next(newValueOrPatch: ValueOrPatch<T>): void;
20
+ partialNext: (partial: Partial<T>) => void;
21
+ getLatestValue(): T;
22
+ subscribe(handler: Handler<T>): Unsubscribe;
23
+ subscribeWithSelector: <O extends Readonly<Record<string, unknown>> | readonly unknown[]>(selector: (nextValue: T) => O, handler: Handler<O>) => Unsubscribe;
24
+ /**
25
+ * Registers a preprocessor function that will be called before the state is updated.
26
+ *
27
+ * Preprocessors are invoked with the new and previous values whenever `next` or `partialNext` methods
28
+ * are called, allowing you to mutate or react to the new value before it is set. Preprocessors run in the
29
+ * order they were registered.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const store = new StateStore<{ count: number; isMaxValue: bool; }>({ count: 0, isMaxValue: false });
34
+ *
35
+ * store.addPreprocessor((nextValue, prevValue) => {
36
+ * if (nextValue.count > 10) {
37
+ * nextValue.count = 10; // Clamp the value to a maximum of 10
38
+ * }
39
+ *
40
+ * if (nextValue.count === 10) {
41
+ * nextValue.isMaxValue = true; // Set isMaxValue to true if count is 10
42
+ * } else {
43
+ * nextValue.isMaxValue = false; // Reset isMaxValue otherwise
44
+ * }
45
+ * });
46
+ *
47
+ * store.partialNext({ count: 15 });
48
+ *
49
+ * store.getLatestValue(); // { count: 10, isMaxValue: true }
50
+ *
51
+ * store.partialNext({ count: 5 });
52
+ *
53
+ * store.getLatestValue(); // { count: 5, isMaxValue: false }
54
+ * ```
55
+ *
56
+ * @param preprocessor - The function to be called with the next and previous values before the state is updated.
57
+ * @returns A `RemovePreprocessor` function that removes the preprocessor when called.
58
+ */
59
+ addPreprocessor(preprocessor: Preprocessor<T>): RemovePreprocessor;
60
+ }
61
+ /**
62
+ * Represents a merged state store that combines two separate state stores into one.
63
+ *
64
+ * The MergedStateStore allows combining two stores with non-overlapping keys.
65
+ * It extends StateStore with the combined type of both source stores.
66
+ * Changes to either the original or merged store will propagate to the combined store.
67
+ *
68
+ * Note: Direct mutations (next, partialNext, addPreprocessor) are disabled on the merged store.
69
+ * You should instead call these methods on the original or merged stores.
70
+ *
71
+ * @template O The type of the original state store
72
+ * @template M The type of the merged state store
73
+ *
74
+ * @experimental
75
+ * This class is experimental and may change in future versions.
76
+ */
77
+ export declare class MergedStateStore<O extends Record<string, unknown>, M extends Record<string, unknown>> extends StateStore<O & M> {
78
+ readonly original: StateStore<O>;
79
+ readonly merged: StateStore<M>;
80
+ private cachedOriginalValue;
81
+ private cachedMergedValue;
82
+ constructor({ original, merged, }: {
83
+ original: StateStore<O>;
84
+ merged: StateStore<M>;
85
+ });
86
+ /**
87
+ * Subscribes to changes in the merged state store.
88
+ *
89
+ * This method extends the base subscribe functionality to handle the merged nature of this store:
90
+ * 1. The first subscriber triggers registration of helper subscribers that listen to both source stores
91
+ * 2. Changes from either source store are propagated to this merged store
92
+ * 3. Source store values are cached to prevent unnecessary updates
93
+ *
94
+ * When the first subscriber is added, the method sets up listeners on both original and merged stores.
95
+ * These listeners update the combined store value whenever either source store changes.
96
+ * All subscriptions (helpers and the actual handler) are tracked so they can be properly cleaned up.
97
+ *
98
+ * @param handler - The callback function that will be executed when the state changes
99
+ * @returns An unsubscribe function that, when called, removes the subscription and any helper subscriptions
100
+ */
101
+ subscribe(handler: Handler<O & M>): () => void;
102
+ /**
103
+ * Retrieves the latest combined state from both original and merged stores.
104
+ *
105
+ * This method extends the base getLatestValue functionality to ensure the merged store
106
+ * remains in sync with its source stores even when there are no active subscribers.
107
+ *
108
+ * When there are no handlers registered, the method:
109
+ * 1. Fetches the latest values from both source stores
110
+ * 2. Compares them with the cached values to detect changes
111
+ * 3. If changes are detected, updates the internal value and caches
112
+ * the new source values to maintain consistency
113
+ *
114
+ * This approach ensures that calling getLatestValue() always returns the most
115
+ * up-to-date combined state, even if the merged store hasn't been actively
116
+ * receiving updates through subscriptions.
117
+ *
118
+ * @returns The latest combined state from both original and merged stores
119
+ */
120
+ getLatestValue(): O & M;
121
+ next: () => void;
122
+ partialNext: () => void;
123
+ addPreprocessor(): () => void;
124
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * TokenManager
3
+ *
4
+ * Handles all the operations around user token.
5
+ */
6
+ export declare class TokenManager {
7
+ loadTokenPromise: Promise<string> | null;
8
+ type: 'static' | 'provider';
9
+ token?: string;
10
+ tokenProvider?: string | (() => Promise<string>);
11
+ constructor();
12
+ /**
13
+ * Set the static string token or token provider.
14
+ * Token provider should return a token string or a promise which resolves to string token.
15
+ *
16
+ * @param {TokenOrProvider} tokenOrProvider - the token or token provider.
17
+ * @param {UserResponse} user - the user object.
18
+ * @param {boolean} isAnonymous - whether the user is anonymous or not.
19
+ */
20
+ setTokenOrProvider: (tokenOrProvider?: string | (() => Promise<string>)) => void;
21
+ /**
22
+ * Resets the token manager.
23
+ * Useful for client disconnection or switching user.
24
+ */
25
+ reset: () => void;
26
+ loadToken: () => Promise<string>;
27
+ getToken: () => string | Promise<string>;
28
+ isStatic: () => boolean;
29
+ }
@@ -0,0 +1,17 @@
1
+ import { BaseSearchSource } from './BaseSearchSource';
2
+ import type { SearchSourceOptions } from './BaseSearchSource';
3
+ import { FeedsClient } from '../FeedsClient';
4
+ import { UserResponse } from '../gen/models';
5
+ export declare class UserSearchSource extends BaseSearchSource<UserResponse> {
6
+ readonly type: "user";
7
+ private readonly client;
8
+ constructor(client: FeedsClient, options?: SearchSourceOptions);
9
+ protected query(searchQuery: string): Promise<{
10
+ items: never[];
11
+ next?: undefined;
12
+ } | {
13
+ items: import("../gen/models").FullUserResponse[];
14
+ next: undefined;
15
+ }>;
16
+ protected filterQueryResults(items: UserResponse[]): UserResponse[];
17
+ }
@@ -0,0 +1,2 @@
1
+ export type { ApiClient } from './ApiClient';
2
+ export type { StreamResponse } from './types';
@@ -0,0 +1,2 @@
1
+ import { RateLimit } from './types';
2
+ export declare const getRateLimitFromResponseHeader: (response_headers: Record<string, string>) => RateLimit;