@stream-io/feeds-client 0.1.10 → 0.2.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/CHANGELOG.md +30 -0
- package/dist/@react-bindings/contexts/StreamFeedContext.d.ts +1 -1
- package/dist/@react-bindings/contexts/StreamFeedsContext.d.ts +1 -1
- package/dist/@react-bindings/hooks/feed-state-hooks/useComments.d.ts +1 -1
- package/dist/@react-bindings/hooks/feed-state-hooks/useFeedActivities.d.ts +1 -1
- package/dist/@react-bindings/hooks/feed-state-hooks/useFeedMetadata.d.ts +1 -1
- package/dist/@react-bindings/hooks/feed-state-hooks/useFollowers.d.ts +1 -1
- package/dist/@react-bindings/hooks/feed-state-hooks/useFollowing.d.ts +1 -1
- package/dist/@react-bindings/hooks/feed-state-hooks/useOwnCapabilities.d.ts +1 -1
- package/dist/@react-bindings/hooks/feed-state-hooks/useOwnFollows.d.ts +1 -1
- package/dist/@react-bindings/hooks/useCreateFeedsClient.d.ts +1 -1
- package/dist/@react-bindings/wrappers/StreamFeed.d.ts +1 -1
- package/dist/index-react-bindings.browser.cjs +1720 -1601
- package/dist/index-react-bindings.browser.cjs.map +1 -1
- package/dist/index-react-bindings.browser.js +1720 -1601
- package/dist/index-react-bindings.browser.js.map +1 -1
- package/dist/index-react-bindings.node.cjs +1720 -1601
- package/dist/index-react-bindings.node.cjs.map +1 -1
- package/dist/index-react-bindings.node.js +1720 -1601
- package/dist/index-react-bindings.node.js.map +1 -1
- package/dist/index.browser.cjs +1724 -1602
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +1722 -1603
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.node.cjs +1724 -1602
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +1722 -1603
- package/dist/index.node.js.map +1 -1
- package/dist/src/common/ActivitySearchSource.d.ts +1 -1
- package/dist/src/common/FeedSearchSource.d.ts +2 -2
- package/dist/src/common/Poll.d.ts +1 -1
- package/dist/src/common/UserSearchSource.d.ts +1 -1
- package/dist/src/common/real-time/StableWSConnection.d.ts +3 -3
- package/dist/src/feed/event-handlers/activity/handle-activity-added.d.ts +7 -0
- package/dist/src/feed/event-handlers/activity/handle-activity-deleted.d.ts +8 -0
- package/dist/src/feed/event-handlers/activity/handle-activity-reaction-added.d.ts +8 -0
- package/dist/src/feed/event-handlers/activity/handle-activity-reaction-deleted.d.ts +8 -0
- package/dist/src/feed/event-handlers/activity/handle-activity-removed-from-feed.d.ts +3 -0
- package/dist/src/feed/event-handlers/activity/handle-activity-updated.d.ts +8 -0
- package/dist/src/feed/event-handlers/activity/index.d.ts +6 -0
- package/dist/src/feed/event-handlers/bookmark/handle-bookmark-added.d.ts +8 -0
- package/dist/src/feed/event-handlers/bookmark/handle-bookmark-deleted.d.ts +9 -0
- package/dist/src/feed/event-handlers/bookmark/handle-bookmark-updated.d.ts +8 -0
- package/dist/src/feed/event-handlers/bookmark/index.d.ts +3 -0
- package/dist/src/feed/event-handlers/comment/handle-comment-added.d.ts +3 -0
- package/dist/src/feed/event-handlers/comment/handle-comment-deleted.d.ts +3 -0
- package/dist/src/feed/event-handlers/comment/handle-comment-reaction.d.ts +3 -0
- package/dist/src/feed/event-handlers/comment/handle-comment-updated.d.ts +3 -0
- package/dist/src/feed/event-handlers/comment/index.d.ts +4 -0
- package/dist/src/feed/event-handlers/feed/handle-feed-updated.d.ts +3 -0
- package/dist/src/feed/event-handlers/feed/index.d.ts +1 -0
- package/dist/src/feed/event-handlers/feed-member/handle-feed-member-added.d.ts +3 -0
- package/dist/src/feed/event-handlers/feed-member/handle-feed-member-removed.d.ts +3 -0
- package/dist/src/feed/event-handlers/feed-member/handle-feed-member-updated.d.ts +3 -0
- package/dist/src/feed/event-handlers/feed-member/index.d.ts +3 -0
- package/dist/src/feed/event-handlers/follow/handle-follow-created.d.ts +7 -0
- package/dist/src/feed/event-handlers/follow/handle-follow-deleted.d.ts +7 -0
- package/dist/src/feed/event-handlers/follow/handle-follow-updated.d.ts +3 -0
- package/dist/src/feed/event-handlers/follow/index.d.ts +3 -0
- package/dist/src/feed/event-handlers/index.d.ts +8 -0
- package/dist/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts +3 -0
- package/dist/src/feed/event-handlers/notification-feed/index.d.ts +1 -0
- package/dist/src/feed/event-handlers/watch/handle-watch-started.d.ts +2 -0
- package/dist/src/feed/event-handlers/watch/handle-watch-stopped.d.ts +2 -0
- package/dist/src/feed/event-handlers/watch/index.d.ts +2 -0
- package/dist/src/{Feed.d.ts → feed/feed.d.ts} +16 -43
- package/dist/src/feed/index.d.ts +2 -0
- package/dist/src/feeds-client/event-handlers/index.d.ts +1 -0
- package/dist/src/feeds-client/event-handlers/user/handle-user-updated.d.ts +3 -0
- package/dist/src/feeds-client/feeds-client.d.ts +76 -0
- package/dist/src/feeds-client/index.d.ts +2 -0
- package/dist/src/gen/feeds/FeedsApi.d.ts +27 -23
- package/dist/src/gen/models/index.d.ts +168 -23
- package/dist/src/gen-imports.d.ts +1 -1
- package/dist/src/test-utils/index.d.ts +1 -0
- package/dist/src/test-utils/response-generators.d.ts +9 -0
- package/dist/src/types-internal.d.ts +7 -0
- package/dist/src/types.d.ts +1 -1
- package/dist/src/utils/check-has-another-page.d.ts +1 -0
- package/dist/src/utils/constants.d.ts +3 -0
- package/dist/src/utils/index.d.ts +5 -0
- package/dist/src/utils/state-update-queue.d.ts +6 -0
- package/dist/src/utils/type-assertions.d.ts +7 -0
- package/dist/src/utils/unique-array-merge.d.ts +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +2 -2
- package/package.json +3 -2
- package/src/common/ActivitySearchSource.ts +1 -1
- package/src/common/FeedSearchSource.ts +2 -2
- package/src/common/Poll.ts +1 -1
- package/src/common/UserSearchSource.ts +1 -1
- package/src/{state-updates → feed/event-handlers/activity}/activity-reaction-utils.test.ts +12 -2
- package/src/{state-updates → feed/event-handlers/activity}/activity-utils.test.ts +3 -2
- package/src/{state-updates/activity-utils.ts → feed/event-handlers/activity/handle-activity-added.ts} +16 -36
- package/src/feed/event-handlers/activity/handle-activity-deleted.ts +30 -0
- package/src/feed/event-handlers/activity/handle-activity-reaction-added.ts +67 -0
- package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.ts +75 -0
- package/src/feed/event-handlers/activity/handle-activity-removed-from-feed.ts +16 -0
- package/src/feed/event-handlers/activity/handle-activity-updated.ts +47 -0
- package/src/feed/event-handlers/activity/index.ts +6 -0
- package/src/{state-updates → feed/event-handlers/bookmark}/bookmark-utils.test.ts +2 -2
- package/src/feed/event-handlers/bookmark/handle-bookmark-added.ts +63 -0
- package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.ts +84 -0
- package/src/feed/event-handlers/bookmark/handle-bookmark-updated.ts +76 -0
- package/src/feed/event-handlers/bookmark/index.ts +3 -0
- package/src/feed/event-handlers/comment/handle-comment-added.ts +38 -0
- package/src/feed/event-handlers/comment/handle-comment-deleted.ts +35 -0
- package/src/feed/event-handlers/comment/handle-comment-reaction.ts +61 -0
- package/src/feed/event-handlers/comment/handle-comment-updated.ts +35 -0
- package/src/feed/event-handlers/comment/index.ts +4 -0
- package/src/feed/event-handlers/feed/handle-feed-updated.ts +9 -0
- package/src/feed/event-handlers/feed/index.ts +1 -0
- package/src/feed/event-handlers/feed-member/handle-feed-member-added.ts +31 -0
- package/src/feed/event-handlers/feed-member/handle-feed-member-removed.ts +24 -0
- package/src/feed/event-handlers/feed-member/handle-feed-member-updated.ts +40 -0
- package/src/feed/event-handlers/feed-member/index.ts +3 -0
- package/src/feed/event-handlers/follow/handle-follow-created.test.ts +250 -0
- package/src/feed/event-handlers/follow/handle-follow-created.ts +90 -0
- package/src/feed/event-handlers/follow/handle-follow-deleted.test.ts +268 -0
- package/src/feed/event-handlers/follow/handle-follow-deleted.ts +95 -0
- package/src/feed/event-handlers/follow/handle-follow-updated.test.ts +174 -0
- package/src/feed/event-handlers/follow/handle-follow-updated.ts +85 -0
- package/src/feed/event-handlers/follow/index.ts +3 -0
- package/src/feed/event-handlers/index.ts +8 -0
- package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.ts +10 -0
- package/src/feed/event-handlers/notification-feed/index.ts +1 -0
- package/src/feed/event-handlers/watch/handle-watch-started.ts +5 -0
- package/src/feed/event-handlers/watch/handle-watch-stopped.ts +5 -0
- package/src/feed/event-handlers/watch/index.ts +2 -0
- package/src/{Feed.ts → feed/feed.ts} +87 -516
- package/src/feed/index.ts +2 -0
- package/src/feeds-client/event-handlers/index.ts +1 -0
- package/src/feeds-client/event-handlers/user/handle-user-updated.test.ts +53 -0
- package/src/feeds-client/event-handlers/user/handle-user-updated.ts +28 -0
- package/src/{FeedsClient.ts → feeds-client/feeds-client.ts} +63 -36
- package/src/feeds-client/index.ts +2 -0
- package/src/gen/feeds/FeedsApi.ts +164 -138
- package/src/gen/model-decoders/decoders.ts +22 -0
- package/src/gen/models/index.ts +288 -29
- package/src/gen-imports.ts +1 -1
- package/src/test-utils/index.ts +1 -0
- package/src/test-utils/response-generators.ts +101 -0
- package/src/types-internal.ts +11 -0
- package/src/types.ts +1 -1
- package/src/utils/check-has-another-page.ts +6 -0
- package/src/utils/constants.ts +3 -0
- package/src/utils/index.ts +5 -0
- package/src/{state-updates → utils}/state-update-queue.test.ts +6 -6
- package/src/utils/state-update-queue.ts +42 -0
- package/src/utils/type-assertions.ts +22 -0
- package/src/{utils.test.ts → utils/unique-array-merge.test.ts} +7 -3
- package/src/utils/unique-array-merge.ts +19 -0
- package/dist/src/FeedsClient.d.ts +0 -75
- package/dist/src/state-updates/activity-reaction-utils.d.ts +0 -10
- package/dist/src/state-updates/activity-utils.d.ts +0 -13
- package/dist/src/state-updates/bookmark-utils.d.ts +0 -14
- package/dist/src/state-updates/follow-utils.d.ts +0 -19
- package/dist/src/state-updates/state-update-queue.d.ts +0 -15
- package/dist/src/utils.d.ts +0 -10
- package/src/state-updates/activity-reaction-utils.ts +0 -107
- package/src/state-updates/bookmark-utils.ts +0 -167
- package/src/state-updates/follow-utils.test.ts +0 -552
- package/src/state-updates/follow-utils.ts +0 -126
- package/src/state-updates/state-update-queue.ts +0 -35
- package/src/utils.ts +0 -48
- /package/dist/src/{ModerationClient.d.ts → moderation-client.d.ts} +0 -0
- /package/src/{ModerationClient.ts → moderation-client.ts} +0 -0
package/src/gen-imports.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './response-generators';
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FeedResponse,
|
|
3
|
+
FollowResponse,
|
|
4
|
+
OwnUser,
|
|
5
|
+
OwnUserResponse,
|
|
6
|
+
UserResponse,
|
|
7
|
+
} from '../gen/models';
|
|
8
|
+
import { humanId } from 'human-id';
|
|
9
|
+
|
|
10
|
+
export const getHumanId = () => humanId({ capitalize: false, separator: '-' });
|
|
11
|
+
|
|
12
|
+
export const generateUserResponse = (
|
|
13
|
+
overrides: Partial<UserResponse> = {},
|
|
14
|
+
): UserResponse => ({
|
|
15
|
+
id: `user-${getHumanId()}`,
|
|
16
|
+
name: humanId({ separator: ' ' }),
|
|
17
|
+
created_at: new Date(),
|
|
18
|
+
updated_at: new Date(),
|
|
19
|
+
banned: false,
|
|
20
|
+
language: 'en',
|
|
21
|
+
online: false,
|
|
22
|
+
role: 'user',
|
|
23
|
+
blocked_user_ids: [],
|
|
24
|
+
teams: [],
|
|
25
|
+
custom: {},
|
|
26
|
+
...overrides,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export const generateOwnUserResponse = (
|
|
30
|
+
overrides: Partial<OwnUserResponse> = {},
|
|
31
|
+
): OwnUserResponse => ({
|
|
32
|
+
...generateUserResponse({
|
|
33
|
+
id: `own-user-${getHumanId()}`,
|
|
34
|
+
}),
|
|
35
|
+
invisible: false,
|
|
36
|
+
total_unread_count: 0,
|
|
37
|
+
unread_channels: 0,
|
|
38
|
+
unread_count: 0,
|
|
39
|
+
unread_threads: 0,
|
|
40
|
+
channel_mutes: [],
|
|
41
|
+
devices: [],
|
|
42
|
+
mutes: [],
|
|
43
|
+
...overrides,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const generateOwnUser = (overrides: Partial<OwnUser> = {}): OwnUser => ({
|
|
47
|
+
...generateOwnUserResponse(),
|
|
48
|
+
devices: [],
|
|
49
|
+
mutes: [],
|
|
50
|
+
total_unread_count_by_team: {},
|
|
51
|
+
...overrides,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export const generateFeedResponse = (
|
|
55
|
+
overrides: Omit<Partial<FeedResponse>, 'created_by' | 'fid'> & {
|
|
56
|
+
created_by?: Partial<UserResponse>;
|
|
57
|
+
} = {},
|
|
58
|
+
): FeedResponse => {
|
|
59
|
+
const id = overrides.id || `feed-${getHumanId()}`;
|
|
60
|
+
const groupId = overrides.group_id || 'user';
|
|
61
|
+
const feed = `${groupId}:${id}`;
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
id,
|
|
65
|
+
group_id: groupId,
|
|
66
|
+
created_at: new Date(),
|
|
67
|
+
updated_at: new Date(),
|
|
68
|
+
description: humanId({
|
|
69
|
+
addAdverb: true,
|
|
70
|
+
adjectiveCount: 4,
|
|
71
|
+
separator: ' ',
|
|
72
|
+
}),
|
|
73
|
+
follower_count: 0,
|
|
74
|
+
following_count: 0,
|
|
75
|
+
member_count: 0,
|
|
76
|
+
name: humanId({ separator: ' ' }),
|
|
77
|
+
pin_count: 0,
|
|
78
|
+
custom: {},
|
|
79
|
+
...overrides,
|
|
80
|
+
feed,
|
|
81
|
+
created_by: generateUserResponse(overrides.created_by),
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const generateFollowResponse = (
|
|
86
|
+
overrides: Partial<FollowResponse> = {},
|
|
87
|
+
): FollowResponse => {
|
|
88
|
+
const sourceFeedResponse = generateFeedResponse();
|
|
89
|
+
const targetFeedResponse = generateFeedResponse();
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
created_at: new Date(),
|
|
93
|
+
updated_at: new Date(),
|
|
94
|
+
follower_role: 'user',
|
|
95
|
+
push_preference: 'all',
|
|
96
|
+
status: 'accepted',
|
|
97
|
+
source_feed: sourceFeedResponse,
|
|
98
|
+
target_feed: targetFeedResponse,
|
|
99
|
+
...overrides,
|
|
100
|
+
};
|
|
101
|
+
};
|
package/src/types-internal.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
+
import { WSEvent } from './gen/models';
|
|
2
|
+
|
|
1
3
|
export type UpdateStateResult<T> = T & {
|
|
2
4
|
changed: boolean;
|
|
3
5
|
};
|
|
4
6
|
|
|
5
7
|
export type FromArray<T> = T extends Array<infer L> ? L : never;
|
|
8
|
+
|
|
9
|
+
export type EventPayload<T extends WSEvent['type']> = Extract<
|
|
10
|
+
WSEvent,
|
|
11
|
+
{ type: T }
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export type PartializeAllBut<T, K extends keyof T> = Pick<T, K> & {
|
|
15
|
+
[key in K]?: T[key];
|
|
16
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
ActivityResponse,
|
|
9
9
|
CommentResponse,
|
|
10
10
|
} from './gen/models';
|
|
11
|
-
import { FeedsClient } from './
|
|
11
|
+
import { FeedsClient } from './feeds-client';
|
|
12
12
|
|
|
13
13
|
export type FeedsEvent = WSEvent | ConnectionChangedEvent | NetworkChangedEvent;
|
|
14
14
|
export type ActivityIdOrCommentId = string;
|
|
@@ -6,7 +6,7 @@ describe('state-update-queue', () => {
|
|
|
6
6
|
describe('shouldUpdateState', () => {
|
|
7
7
|
it('should return true when watch is false', () => {
|
|
8
8
|
const result = shouldUpdateState({
|
|
9
|
-
|
|
9
|
+
stateUpdateQueueId: 'test-id',
|
|
10
10
|
stateUpdateQueue: new Set(['other-id']),
|
|
11
11
|
watch: false,
|
|
12
12
|
});
|
|
@@ -14,11 +14,11 @@ describe('state-update-queue', () => {
|
|
|
14
14
|
expect(result).toBe(true);
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it('should return true when watch is true but
|
|
17
|
+
it('should return true when watch is true but queueId is not in queue', () => {
|
|
18
18
|
const stateUpdateQueue = new Set(['other-id-1', 'other-id-2']);
|
|
19
19
|
|
|
20
20
|
const result = shouldUpdateState({
|
|
21
|
-
|
|
21
|
+
stateUpdateQueueId: 'test-id',
|
|
22
22
|
stateUpdateQueue: stateUpdateQueue,
|
|
23
23
|
watch: true,
|
|
24
24
|
});
|
|
@@ -27,11 +27,11 @@ describe('state-update-queue', () => {
|
|
|
27
27
|
expect(result).toBe(true);
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
it('should return false and remove
|
|
30
|
+
it('should return false and remove queueId from queue when watch is true and queueId is in queue', () => {
|
|
31
31
|
const stateUpdateQueue = new Set(['test-id', 'other-id']);
|
|
32
32
|
|
|
33
33
|
const result = shouldUpdateState({
|
|
34
|
-
|
|
34
|
+
stateUpdateQueueId: 'test-id',
|
|
35
35
|
stateUpdateQueue,
|
|
36
36
|
watch: true,
|
|
37
37
|
});
|
|
@@ -42,7 +42,7 @@ describe('state-update-queue', () => {
|
|
|
42
42
|
|
|
43
43
|
it('should handle empty queue when watch is true', () => {
|
|
44
44
|
const result = shouldUpdateState({
|
|
45
|
-
|
|
45
|
+
stateUpdateQueueId: 'test-id',
|
|
46
46
|
stateUpdateQueue: new Set(),
|
|
47
47
|
watch: true,
|
|
48
48
|
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { isFollowResponse } from './type-assertions';
|
|
2
|
+
|
|
3
|
+
export const shouldUpdateState = ({
|
|
4
|
+
stateUpdateQueueId,
|
|
5
|
+
stateUpdateQueue,
|
|
6
|
+
watch,
|
|
7
|
+
}: {
|
|
8
|
+
stateUpdateQueueId: string;
|
|
9
|
+
stateUpdateQueue: Set<string>;
|
|
10
|
+
watch: boolean;
|
|
11
|
+
}) => {
|
|
12
|
+
if (!watch) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (watch && stateUpdateQueue.has(stateUpdateQueueId)) {
|
|
17
|
+
stateUpdateQueue.delete(stateUpdateQueueId);
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
stateUpdateQueue.add(stateUpdateQueueId);
|
|
22
|
+
return true;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function getStateUpdateQueueId(
|
|
26
|
+
data: object,
|
|
27
|
+
prefix?: 'deleted' | 'updated' | 'created' | (string & {}),
|
|
28
|
+
) {
|
|
29
|
+
if (isFollowResponse(data)) {
|
|
30
|
+
const toJoin = [data.source_feed.feed, data.target_feed.feed];
|
|
31
|
+
if (prefix) {
|
|
32
|
+
toJoin.unshift(prefix);
|
|
33
|
+
}
|
|
34
|
+
return toJoin.join('-');
|
|
35
|
+
}
|
|
36
|
+
// else if (isMemberResponse(data)) {
|
|
37
|
+
// }
|
|
38
|
+
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Cannot create state update queueId for data: ${JSON.stringify(data)}`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CommentResponse, FollowResponse } from '../gen/models';
|
|
2
|
+
import { StreamFile } from '../types';
|
|
3
|
+
import { CommentParent } from '../types';
|
|
4
|
+
|
|
5
|
+
export const isFollowResponse = (data: object): data is FollowResponse => {
|
|
6
|
+
return 'source_feed' in data && 'target_feed' in data;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const isCommentResponse = (
|
|
10
|
+
entity: CommentParent,
|
|
11
|
+
): entity is CommentResponse => {
|
|
12
|
+
return typeof (entity as CommentResponse)?.object_id === 'string';
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const isImageFile = (file: StreamFile) => {
|
|
16
|
+
// photoshop files begin with 'image/'
|
|
17
|
+
return file.type.startsWith('image/') && !file.type.endsWith('.photoshop');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const isVideoFile = (file: StreamFile) => {
|
|
21
|
+
return file.type.startsWith('video/');
|
|
22
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
|
|
3
|
-
import { uniqueArrayMerge } from './
|
|
3
|
+
import { uniqueArrayMerge } from './unique-array-merge';
|
|
4
4
|
|
|
5
5
|
describe('utils', () => {
|
|
6
|
-
describe(
|
|
6
|
+
describe(uniqueArrayMerge.name, () => {
|
|
7
7
|
it('should merge arrays with unique objects based on key', () => {
|
|
8
8
|
const existingArray = [
|
|
9
9
|
{ id: '1', name: 'Alice' },
|
|
@@ -123,7 +123,11 @@ describe('utils', () => {
|
|
|
123
123
|
email: string;
|
|
124
124
|
}) => item.email;
|
|
125
125
|
|
|
126
|
-
const result = uniqueArrayMerge(
|
|
126
|
+
const result = uniqueArrayMerge(
|
|
127
|
+
existingArray,
|
|
128
|
+
arrayToMerge,
|
|
129
|
+
getKeyByEmail,
|
|
130
|
+
);
|
|
127
131
|
|
|
128
132
|
expect(result).toEqual([
|
|
129
133
|
{ id: '1', name: 'Alice', email: 'alice@example.com' },
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const uniqueArrayMerge = <T>(
|
|
2
|
+
existingArray: T[],
|
|
3
|
+
arrayToMerge: T[],
|
|
4
|
+
getKey: (v: T) => string,
|
|
5
|
+
) => {
|
|
6
|
+
const existing = new Set<string>();
|
|
7
|
+
|
|
8
|
+
existingArray.forEach((value) => {
|
|
9
|
+
const key = getKey(value);
|
|
10
|
+
existing.add(key);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const filteredArrayToMerge = arrayToMerge.filter((value) => {
|
|
14
|
+
const key = getKey(value);
|
|
15
|
+
return !existing.has(key);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return existingArray.concat(filteredArrayToMerge);
|
|
19
|
+
};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { FeedsApi } from './gen/feeds/FeedsApi';
|
|
2
|
-
import { ActivityResponse, FileUploadRequest, FollowBatchRequest, ImageUploadRequest, OwnUser, PollResponse, PollVotesResponse, QueryFeedsRequest, QueryPollVotesRequest, SingleFollowRequest, UserRequest } from './gen/models';
|
|
3
|
-
import { FeedsEvent, StreamFile, TokenOrProvider } 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
|
-
connected_user: OwnUser | undefined;
|
|
11
|
-
is_ws_connection_healthy: boolean;
|
|
12
|
-
};
|
|
13
|
-
export declare class FeedsClient extends FeedsApi {
|
|
14
|
-
readonly state: StateStore<FeedsClientState>;
|
|
15
|
-
readonly moderation: ModerationClient;
|
|
16
|
-
private readonly tokenManager;
|
|
17
|
-
private wsConnection?;
|
|
18
|
-
private readonly connectionIdManager;
|
|
19
|
-
private readonly eventDispatcher;
|
|
20
|
-
private readonly polls_by_id;
|
|
21
|
-
private activeFeeds;
|
|
22
|
-
private healthyConnectionChangedEventCount;
|
|
23
|
-
constructor(apiKey: string, options?: FeedsClientOptions);
|
|
24
|
-
pollFromState: (id: string) => StreamPoll | undefined;
|
|
25
|
-
hydratePollCache(activities: ActivityResponse[]): void;
|
|
26
|
-
connectUser: (user: UserRequest, tokenProvider: TokenOrProvider) => Promise<void>;
|
|
27
|
-
devToken: (userId: string) => string;
|
|
28
|
-
closePoll: (request: {
|
|
29
|
-
poll_id: string;
|
|
30
|
-
}) => Promise<StreamResponse<PollResponse>>;
|
|
31
|
-
uploadFile: (request: Omit<FileUploadRequest, "file"> & {
|
|
32
|
-
file: StreamFile;
|
|
33
|
-
}) => Promise<StreamResponse<import("./gen/models").FileUploadResponse>>;
|
|
34
|
-
uploadImage: (request: Omit<ImageUploadRequest, "file"> & {
|
|
35
|
-
file: StreamFile;
|
|
36
|
-
}) => Promise<StreamResponse<import("./gen/models").ImageUploadResponse>>;
|
|
37
|
-
queryPollAnswers: (request: QueryPollVotesRequest & {
|
|
38
|
-
poll_id: string;
|
|
39
|
-
user_id?: string;
|
|
40
|
-
}) => Promise<StreamResponse<PollVotesResponse>>;
|
|
41
|
-
queryPollOptionVotes: (request: QueryPollVotesRequest & {
|
|
42
|
-
filter: QueryPollVotesRequest["filter"] & {
|
|
43
|
-
option_id: string;
|
|
44
|
-
};
|
|
45
|
-
poll_id: string;
|
|
46
|
-
user_id?: string;
|
|
47
|
-
}) => Promise<StreamResponse<PollVotesResponse>>;
|
|
48
|
-
disconnectUser: () => Promise<void>;
|
|
49
|
-
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.bookmark_folder.deleted" | "feeds.bookmark_folder.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.notification_feed.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
|
-
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.bookmark_folder.deleted" | "feeds.bookmark_folder.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.notification_feed.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 & {
|
|
53
|
-
fid?: string;
|
|
54
|
-
}) => void) => void;
|
|
55
|
-
feed: (groupId: string, id: string) => Feed;
|
|
56
|
-
queryFeeds(request?: QueryFeedsRequest): Promise<{
|
|
57
|
-
feeds: Feed[];
|
|
58
|
-
next: string | undefined;
|
|
59
|
-
prev: string | undefined;
|
|
60
|
-
metadata: import("./common/types").RequestMetadata;
|
|
61
|
-
duration: string;
|
|
62
|
-
}>;
|
|
63
|
-
updateNetworkConnectionStatus: (event: {
|
|
64
|
-
type: "online" | "offline";
|
|
65
|
-
} | Event) => void;
|
|
66
|
-
follow(request: SingleFollowRequest): Promise<StreamResponse<import("./gen/models").SingleFollowResponse>>;
|
|
67
|
-
followBatch(request: FollowBatchRequest): Promise<StreamResponse<import("./gen/models").FollowBatchResponse>>;
|
|
68
|
-
unfollow(request: SingleFollowRequest): Promise<StreamResponse<import("./gen/models").UnfollowResponse>>;
|
|
69
|
-
stopWatchingFeed(request: {
|
|
70
|
-
feed_group_id: string;
|
|
71
|
-
feed_id: string;
|
|
72
|
-
}): Promise<StreamResponse<import("./gen/models").Response>>;
|
|
73
|
-
private readonly getOrCreateActiveFeed;
|
|
74
|
-
private findActiveFeedByActivityId;
|
|
75
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ActivityReactionAddedEvent, ActivityReactionDeletedEvent, ActivityResponse } from '../gen/models';
|
|
2
|
-
import { UpdateStateResult } from '../types-internal';
|
|
3
|
-
export declare const addReactionToActivity: (event: ActivityReactionAddedEvent, activity: ActivityResponse, isCurrentUser: boolean) => UpdateStateResult<ActivityResponse>;
|
|
4
|
-
export declare const removeReactionFromActivity: (event: ActivityReactionDeletedEvent, activity: ActivityResponse, isCurrentUser: boolean) => UpdateStateResult<ActivityResponse>;
|
|
5
|
-
export declare const addReactionToActivities: (event: ActivityReactionAddedEvent, activities: ActivityResponse[] | undefined, isCurrentUser: boolean) => UpdateStateResult<{
|
|
6
|
-
activities: ActivityResponse[];
|
|
7
|
-
}>;
|
|
8
|
-
export declare const removeReactionFromActivities: (event: ActivityReactionDeletedEvent, activities: ActivityResponse[] | undefined, isCurrentUser: boolean) => UpdateStateResult<{
|
|
9
|
-
activities: ActivityResponse[];
|
|
10
|
-
}>;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { ActivityResponse } from '../gen/models';
|
|
2
|
-
import { UpdateStateResult } from '../types-internal';
|
|
3
|
-
export declare const addActivitiesToState: (newActivities: ActivityResponse[], activities: ActivityResponse[] | undefined, position: "start" | "end") => UpdateStateResult<{
|
|
4
|
-
activities: ActivityResponse[];
|
|
5
|
-
}>;
|
|
6
|
-
export declare const updateActivityInState: (updatedActivityResponse: ActivityResponse, activities: ActivityResponse[]) => {
|
|
7
|
-
changed: boolean;
|
|
8
|
-
activities: ActivityResponse[];
|
|
9
|
-
};
|
|
10
|
-
export declare const removeActivityFromState: (activityResponse: ActivityResponse, activities: ActivityResponse[]) => {
|
|
11
|
-
changed: boolean;
|
|
12
|
-
activities: ActivityResponse[];
|
|
13
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { BookmarkAddedEvent, BookmarkDeletedEvent, BookmarkUpdatedEvent, ActivityResponse } from '../gen/models';
|
|
2
|
-
import { UpdateStateResult } from '../types-internal';
|
|
3
|
-
export declare const addBookmarkToActivity: (event: BookmarkAddedEvent, activity: ActivityResponse, isCurrentUser: boolean) => UpdateStateResult<ActivityResponse>;
|
|
4
|
-
export declare const removeBookmarkFromActivity: (event: BookmarkDeletedEvent, activity: ActivityResponse, isCurrentUser: boolean) => UpdateStateResult<ActivityResponse>;
|
|
5
|
-
export declare const updateBookmarkInActivity: (event: BookmarkUpdatedEvent, activity: ActivityResponse, isCurrentUser: boolean) => UpdateStateResult<ActivityResponse>;
|
|
6
|
-
export declare const addBookmarkToActivities: (event: BookmarkAddedEvent, activities: ActivityResponse[] | undefined, isCurrentUser: boolean) => UpdateStateResult<{
|
|
7
|
-
activities: ActivityResponse[];
|
|
8
|
-
}>;
|
|
9
|
-
export declare const removeBookmarkFromActivities: (event: BookmarkDeletedEvent, activities: ActivityResponse[] | undefined, isCurrentUser: boolean) => UpdateStateResult<{
|
|
10
|
-
activities: ActivityResponse[];
|
|
11
|
-
}>;
|
|
12
|
-
export declare const updateBookmarkInActivities: (event: BookmarkUpdatedEvent, activities: ActivityResponse[] | undefined, isCurrentUser: boolean) => UpdateStateResult<{
|
|
13
|
-
activities: ActivityResponse[];
|
|
14
|
-
}>;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { FeedState } from '../Feed';
|
|
2
|
-
import { FollowResponse } from '../gen/models';
|
|
3
|
-
import { UpdateStateResult } from '../types-internal';
|
|
4
|
-
export declare const handleFollowCreated: (follow: FollowResponse, currentState: FeedState, currentFeedId: string, connectedUserId?: string) => UpdateStateResult<{
|
|
5
|
-
data: FeedState;
|
|
6
|
-
}>;
|
|
7
|
-
export declare const handleFollowDeleted: (follow: FollowResponse | {
|
|
8
|
-
source_feed: {
|
|
9
|
-
fid: string;
|
|
10
|
-
};
|
|
11
|
-
target_feed: {
|
|
12
|
-
fid: string;
|
|
13
|
-
};
|
|
14
|
-
}, currentState: FeedState, currentFeedId: string, connectedUserId?: string) => UpdateStateResult<{
|
|
15
|
-
data: FeedState;
|
|
16
|
-
}>;
|
|
17
|
-
export declare const handleFollowUpdated: (currentState: FeedState) => UpdateStateResult<{
|
|
18
|
-
data: FeedState;
|
|
19
|
-
}>;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { FollowResponse } from '../gen/models';
|
|
2
|
-
export declare const shouldUpdateState: ({ stateUpdateId, stateUpdateQueue, watch, }: {
|
|
3
|
-
stateUpdateId: string;
|
|
4
|
-
stateUpdateQueue: Set<string>;
|
|
5
|
-
watch: boolean;
|
|
6
|
-
}) => boolean;
|
|
7
|
-
export declare const getStateUpdateQueueIdForFollow: (follow: FollowResponse) => string;
|
|
8
|
-
export declare const getStateUpdateQueueIdForUnfollow: (follow: FollowResponse | {
|
|
9
|
-
source_feed: {
|
|
10
|
-
fid: string;
|
|
11
|
-
};
|
|
12
|
-
target_feed: {
|
|
13
|
-
fid: string;
|
|
14
|
-
};
|
|
15
|
-
}) => string;
|
package/dist/src/utils.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { CommentParent, StreamFile } from './types';
|
|
2
|
-
import type { CommentResponse } from './gen/models';
|
|
3
|
-
export declare const isImageFile: (file: StreamFile) => boolean;
|
|
4
|
-
export declare const isVideoFile: (file: StreamFile) => boolean;
|
|
5
|
-
export declare const checkHasAnotherPage: <T extends unknown | undefined>(v: T, cursor: string | undefined) => boolean;
|
|
6
|
-
export declare const isCommentResponse: (entity: CommentParent) => entity is CommentResponse;
|
|
7
|
-
export declare const Constants: {
|
|
8
|
-
readonly DEFAULT_COMMENT_PAGINATION: "first";
|
|
9
|
-
};
|
|
10
|
-
export declare const uniqueArrayMerge: <T>(existingArray: T[], arrayToMerge: T[], getKey: (v: T) => string) => T[];
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ActivityReactionAddedEvent,
|
|
3
|
-
ActivityReactionDeletedEvent,
|
|
4
|
-
ActivityResponse,
|
|
5
|
-
} from '../gen/models';
|
|
6
|
-
import { UpdateStateResult } from '../types-internal';
|
|
7
|
-
|
|
8
|
-
const updateActivityInActivities = (
|
|
9
|
-
updatedActivity: ActivityResponse,
|
|
10
|
-
activities: ActivityResponse[],
|
|
11
|
-
): UpdateStateResult<{ activities: ActivityResponse[] }> => {
|
|
12
|
-
const index = activities.findIndex((a) => a.id === updatedActivity.id);
|
|
13
|
-
if (index !== -1) {
|
|
14
|
-
const newActivities = [...activities];
|
|
15
|
-
newActivities[index] = updatedActivity;
|
|
16
|
-
return { changed: true, activities: newActivities };
|
|
17
|
-
} else {
|
|
18
|
-
return { changed: false, activities };
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const addReactionToActivity = (
|
|
23
|
-
event: ActivityReactionAddedEvent,
|
|
24
|
-
activity: ActivityResponse,
|
|
25
|
-
isCurrentUser: boolean,
|
|
26
|
-
): UpdateStateResult<ActivityResponse> => {
|
|
27
|
-
// Update own_reactions if the reaction is from the current user
|
|
28
|
-
const ownReactions = [...(activity.own_reactions || [])];
|
|
29
|
-
if (isCurrentUser) {
|
|
30
|
-
ownReactions.push(event.reaction);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
...activity,
|
|
35
|
-
own_reactions: ownReactions,
|
|
36
|
-
latest_reactions: event.activity.latest_reactions,
|
|
37
|
-
reaction_groups: event.activity.reaction_groups,
|
|
38
|
-
changed: true,
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const removeReactionFromActivity = (
|
|
43
|
-
event: ActivityReactionDeletedEvent,
|
|
44
|
-
activity: ActivityResponse,
|
|
45
|
-
isCurrentUser: boolean,
|
|
46
|
-
): UpdateStateResult<ActivityResponse> => {
|
|
47
|
-
// Update own_reactions if the reaction is from the current user
|
|
48
|
-
const ownReactions = isCurrentUser
|
|
49
|
-
? (activity.own_reactions || []).filter(
|
|
50
|
-
(r) =>
|
|
51
|
-
!(
|
|
52
|
-
r.type === event.reaction.type &&
|
|
53
|
-
r.user.id === event.reaction.user.id
|
|
54
|
-
),
|
|
55
|
-
)
|
|
56
|
-
: activity.own_reactions;
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
...activity,
|
|
60
|
-
own_reactions: ownReactions,
|
|
61
|
-
latest_reactions: event.activity.latest_reactions,
|
|
62
|
-
reaction_groups: event.activity.reaction_groups,
|
|
63
|
-
changed: true,
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export const addReactionToActivities = (
|
|
68
|
-
event: ActivityReactionAddedEvent,
|
|
69
|
-
activities: ActivityResponse[] | undefined,
|
|
70
|
-
isCurrentUser: boolean,
|
|
71
|
-
): UpdateStateResult<{ activities: ActivityResponse[] }> => {
|
|
72
|
-
if (!activities) {
|
|
73
|
-
return { changed: false, activities: [] };
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const activityIndex = activities.findIndex((a) => a.id === event.activity.id);
|
|
77
|
-
if (activityIndex === -1) {
|
|
78
|
-
return { changed: false, activities };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const activity = activities[activityIndex];
|
|
82
|
-
const updatedActivity = addReactionToActivity(event, activity, isCurrentUser);
|
|
83
|
-
return updateActivityInActivities(updatedActivity, activities);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export const removeReactionFromActivities = (
|
|
87
|
-
event: ActivityReactionDeletedEvent,
|
|
88
|
-
activities: ActivityResponse[] | undefined,
|
|
89
|
-
isCurrentUser: boolean,
|
|
90
|
-
): UpdateStateResult<{ activities: ActivityResponse[] }> => {
|
|
91
|
-
if (!activities) {
|
|
92
|
-
return { changed: false, activities: [] };
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const activityIndex = activities.findIndex((a) => a.id === event.activity.id);
|
|
96
|
-
if (activityIndex === -1) {
|
|
97
|
-
return { changed: false, activities };
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const activity = activities[activityIndex];
|
|
101
|
-
const updatedActivity = removeReactionFromActivity(
|
|
102
|
-
event,
|
|
103
|
-
activity,
|
|
104
|
-
isCurrentUser,
|
|
105
|
-
);
|
|
106
|
-
return updateActivityInActivities(updatedActivity, activities);
|
|
107
|
-
};
|