@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.
- package/@react-bindings/index.ts +2 -0
- package/CHANGELOG.md +44 -0
- package/LICENSE +219 -0
- package/README.md +9 -0
- package/dist/@react-bindings/hooks/useComments.d.ts +12 -0
- package/dist/@react-bindings/hooks/useStateStore.d.ts +3 -0
- package/dist/@react-bindings/index.d.ts +2 -0
- package/dist/index-react-bindings.browser.cjs +56 -0
- package/dist/index-react-bindings.browser.cjs.map +1 -0
- package/dist/index-react-bindings.browser.js +53 -0
- package/dist/index-react-bindings.browser.js.map +1 -0
- package/dist/index-react-bindings.node.cjs +56 -0
- package/dist/index-react-bindings.node.cjs.map +1 -0
- package/dist/index-react-bindings.node.js +53 -0
- package/dist/index-react-bindings.node.js.map +1 -0
- package/dist/index.browser.cjs +5799 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.js +5782 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.node.cjs +5799 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.js +5782 -0
- package/dist/index.node.js.map +1 -0
- package/dist/src/Feed.d.ts +109 -0
- package/dist/src/FeedsClient.d.ts +63 -0
- package/dist/src/ModerationClient.d.ts +3 -0
- package/dist/src/common/ActivitySearchSource.d.ts +17 -0
- package/dist/src/common/ApiClient.d.ts +20 -0
- package/dist/src/common/BaseSearchSource.d.ts +87 -0
- package/dist/src/common/ConnectionIdManager.d.ts +11 -0
- package/dist/src/common/EventDispatcher.d.ts +11 -0
- package/dist/src/common/FeedSearchSource.d.ts +17 -0
- package/dist/src/common/Poll.d.ts +34 -0
- package/dist/src/common/SearchController.d.ts +41 -0
- package/dist/src/common/StateStore.d.ts +124 -0
- package/dist/src/common/TokenManager.d.ts +29 -0
- package/dist/src/common/UserSearchSource.d.ts +17 -0
- package/dist/src/common/gen-imports.d.ts +2 -0
- package/dist/src/common/rate-limit.d.ts +2 -0
- package/dist/src/common/real-time/StableWSConnection.d.ts +144 -0
- package/dist/src/common/real-time/event-models.d.ts +36 -0
- package/dist/src/common/types.d.ts +29 -0
- package/dist/src/common/utils.d.ts +54 -0
- package/dist/src/gen/feeds/FeedApi.d.ts +26 -0
- package/dist/src/gen/feeds/FeedsApi.d.ts +237 -0
- package/dist/src/gen/model-decoders/decoders.d.ts +3 -0
- package/dist/src/gen/model-decoders/event-decoder-mapping.d.ts +6 -0
- package/dist/src/gen/models/index.d.ts +3437 -0
- package/dist/src/gen/moderation/ModerationApi.d.ts +21 -0
- package/dist/src/gen-imports.d.ts +3 -0
- package/dist/src/state-updates/activity-reaction-utils.d.ts +10 -0
- package/dist/src/state-updates/activity-utils.d.ts +13 -0
- package/dist/src/state-updates/bookmark-utils.d.ts +14 -0
- package/dist/src/types-internal.d.ts +4 -0
- package/dist/src/types.d.ts +13 -0
- package/dist/src/utils.d.ts +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/index.ts +13 -0
- package/package.json +85 -0
- package/src/Feed.ts +1070 -0
- package/src/FeedsClient.ts +352 -0
- package/src/ModerationClient.ts +3 -0
- package/src/common/ActivitySearchSource.ts +46 -0
- package/src/common/ApiClient.ts +197 -0
- package/src/common/BaseSearchSource.ts +238 -0
- package/src/common/ConnectionIdManager.ts +51 -0
- package/src/common/EventDispatcher.ts +52 -0
- package/src/common/FeedSearchSource.ts +94 -0
- package/src/common/Poll.ts +313 -0
- package/src/common/SearchController.ts +152 -0
- package/src/common/StateStore.ts +314 -0
- package/src/common/TokenManager.ts +112 -0
- package/src/common/UserSearchSource.ts +93 -0
- package/src/common/gen-imports.ts +2 -0
- package/src/common/rate-limit.ts +23 -0
- package/src/common/real-time/StableWSConnection.ts +761 -0
- package/src/common/real-time/event-models.ts +38 -0
- package/src/common/types.ts +40 -0
- package/src/common/utils.ts +194 -0
- package/src/gen/feeds/FeedApi.ts +129 -0
- package/src/gen/feeds/FeedsApi.ts +2192 -0
- package/src/gen/model-decoders/decoders.ts +1877 -0
- package/src/gen/model-decoders/event-decoder-mapping.ts +150 -0
- package/src/gen/models/index.ts +5882 -0
- package/src/gen/moderation/ModerationApi.ts +270 -0
- package/src/gen-imports.ts +3 -0
- package/src/state-updates/activity-reaction-utils.test.ts +348 -0
- package/src/state-updates/activity-reaction-utils.ts +107 -0
- package/src/state-updates/activity-utils.test.ts +257 -0
- package/src/state-updates/activity-utils.ts +80 -0
- package/src/state-updates/bookmark-utils.test.ts +383 -0
- package/src/state-updates/bookmark-utils.ts +157 -0
- package/src/types-internal.ts +5 -0
- package/src/types.ts +20 -0
- 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,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
|
+
}
|