@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.
Files changed (168) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/@react-bindings/contexts/StreamFeedContext.d.ts +1 -1
  3. package/dist/@react-bindings/contexts/StreamFeedsContext.d.ts +1 -1
  4. package/dist/@react-bindings/hooks/feed-state-hooks/useComments.d.ts +1 -1
  5. package/dist/@react-bindings/hooks/feed-state-hooks/useFeedActivities.d.ts +1 -1
  6. package/dist/@react-bindings/hooks/feed-state-hooks/useFeedMetadata.d.ts +1 -1
  7. package/dist/@react-bindings/hooks/feed-state-hooks/useFollowers.d.ts +1 -1
  8. package/dist/@react-bindings/hooks/feed-state-hooks/useFollowing.d.ts +1 -1
  9. package/dist/@react-bindings/hooks/feed-state-hooks/useOwnCapabilities.d.ts +1 -1
  10. package/dist/@react-bindings/hooks/feed-state-hooks/useOwnFollows.d.ts +1 -1
  11. package/dist/@react-bindings/hooks/useCreateFeedsClient.d.ts +1 -1
  12. package/dist/@react-bindings/wrappers/StreamFeed.d.ts +1 -1
  13. package/dist/index-react-bindings.browser.cjs +1720 -1601
  14. package/dist/index-react-bindings.browser.cjs.map +1 -1
  15. package/dist/index-react-bindings.browser.js +1720 -1601
  16. package/dist/index-react-bindings.browser.js.map +1 -1
  17. package/dist/index-react-bindings.node.cjs +1720 -1601
  18. package/dist/index-react-bindings.node.cjs.map +1 -1
  19. package/dist/index-react-bindings.node.js +1720 -1601
  20. package/dist/index-react-bindings.node.js.map +1 -1
  21. package/dist/index.browser.cjs +1724 -1602
  22. package/dist/index.browser.cjs.map +1 -1
  23. package/dist/index.browser.js +1722 -1603
  24. package/dist/index.browser.js.map +1 -1
  25. package/dist/index.d.ts +2 -2
  26. package/dist/index.node.cjs +1724 -1602
  27. package/dist/index.node.cjs.map +1 -1
  28. package/dist/index.node.js +1722 -1603
  29. package/dist/index.node.js.map +1 -1
  30. package/dist/src/common/ActivitySearchSource.d.ts +1 -1
  31. package/dist/src/common/FeedSearchSource.d.ts +2 -2
  32. package/dist/src/common/Poll.d.ts +1 -1
  33. package/dist/src/common/UserSearchSource.d.ts +1 -1
  34. package/dist/src/common/real-time/StableWSConnection.d.ts +3 -3
  35. package/dist/src/feed/event-handlers/activity/handle-activity-added.d.ts +7 -0
  36. package/dist/src/feed/event-handlers/activity/handle-activity-deleted.d.ts +8 -0
  37. package/dist/src/feed/event-handlers/activity/handle-activity-reaction-added.d.ts +8 -0
  38. package/dist/src/feed/event-handlers/activity/handle-activity-reaction-deleted.d.ts +8 -0
  39. package/dist/src/feed/event-handlers/activity/handle-activity-removed-from-feed.d.ts +3 -0
  40. package/dist/src/feed/event-handlers/activity/handle-activity-updated.d.ts +8 -0
  41. package/dist/src/feed/event-handlers/activity/index.d.ts +6 -0
  42. package/dist/src/feed/event-handlers/bookmark/handle-bookmark-added.d.ts +8 -0
  43. package/dist/src/feed/event-handlers/bookmark/handle-bookmark-deleted.d.ts +9 -0
  44. package/dist/src/feed/event-handlers/bookmark/handle-bookmark-updated.d.ts +8 -0
  45. package/dist/src/feed/event-handlers/bookmark/index.d.ts +3 -0
  46. package/dist/src/feed/event-handlers/comment/handle-comment-added.d.ts +3 -0
  47. package/dist/src/feed/event-handlers/comment/handle-comment-deleted.d.ts +3 -0
  48. package/dist/src/feed/event-handlers/comment/handle-comment-reaction.d.ts +3 -0
  49. package/dist/src/feed/event-handlers/comment/handle-comment-updated.d.ts +3 -0
  50. package/dist/src/feed/event-handlers/comment/index.d.ts +4 -0
  51. package/dist/src/feed/event-handlers/feed/handle-feed-updated.d.ts +3 -0
  52. package/dist/src/feed/event-handlers/feed/index.d.ts +1 -0
  53. package/dist/src/feed/event-handlers/feed-member/handle-feed-member-added.d.ts +3 -0
  54. package/dist/src/feed/event-handlers/feed-member/handle-feed-member-removed.d.ts +3 -0
  55. package/dist/src/feed/event-handlers/feed-member/handle-feed-member-updated.d.ts +3 -0
  56. package/dist/src/feed/event-handlers/feed-member/index.d.ts +3 -0
  57. package/dist/src/feed/event-handlers/follow/handle-follow-created.d.ts +7 -0
  58. package/dist/src/feed/event-handlers/follow/handle-follow-deleted.d.ts +7 -0
  59. package/dist/src/feed/event-handlers/follow/handle-follow-updated.d.ts +3 -0
  60. package/dist/src/feed/event-handlers/follow/index.d.ts +3 -0
  61. package/dist/src/feed/event-handlers/index.d.ts +8 -0
  62. package/dist/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts +3 -0
  63. package/dist/src/feed/event-handlers/notification-feed/index.d.ts +1 -0
  64. package/dist/src/feed/event-handlers/watch/handle-watch-started.d.ts +2 -0
  65. package/dist/src/feed/event-handlers/watch/handle-watch-stopped.d.ts +2 -0
  66. package/dist/src/feed/event-handlers/watch/index.d.ts +2 -0
  67. package/dist/src/{Feed.d.ts → feed/feed.d.ts} +16 -43
  68. package/dist/src/feed/index.d.ts +2 -0
  69. package/dist/src/feeds-client/event-handlers/index.d.ts +1 -0
  70. package/dist/src/feeds-client/event-handlers/user/handle-user-updated.d.ts +3 -0
  71. package/dist/src/feeds-client/feeds-client.d.ts +76 -0
  72. package/dist/src/feeds-client/index.d.ts +2 -0
  73. package/dist/src/gen/feeds/FeedsApi.d.ts +27 -23
  74. package/dist/src/gen/models/index.d.ts +168 -23
  75. package/dist/src/gen-imports.d.ts +1 -1
  76. package/dist/src/test-utils/index.d.ts +1 -0
  77. package/dist/src/test-utils/response-generators.d.ts +9 -0
  78. package/dist/src/types-internal.d.ts +7 -0
  79. package/dist/src/types.d.ts +1 -1
  80. package/dist/src/utils/check-has-another-page.d.ts +1 -0
  81. package/dist/src/utils/constants.d.ts +3 -0
  82. package/dist/src/utils/index.d.ts +5 -0
  83. package/dist/src/utils/state-update-queue.d.ts +6 -0
  84. package/dist/src/utils/type-assertions.d.ts +7 -0
  85. package/dist/src/utils/unique-array-merge.d.ts +1 -0
  86. package/dist/tsconfig.tsbuildinfo +1 -1
  87. package/index.ts +2 -2
  88. package/package.json +3 -2
  89. package/src/common/ActivitySearchSource.ts +1 -1
  90. package/src/common/FeedSearchSource.ts +2 -2
  91. package/src/common/Poll.ts +1 -1
  92. package/src/common/UserSearchSource.ts +1 -1
  93. package/src/{state-updates → feed/event-handlers/activity}/activity-reaction-utils.test.ts +12 -2
  94. package/src/{state-updates → feed/event-handlers/activity}/activity-utils.test.ts +3 -2
  95. package/src/{state-updates/activity-utils.ts → feed/event-handlers/activity/handle-activity-added.ts} +16 -36
  96. package/src/feed/event-handlers/activity/handle-activity-deleted.ts +30 -0
  97. package/src/feed/event-handlers/activity/handle-activity-reaction-added.ts +67 -0
  98. package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.ts +75 -0
  99. package/src/feed/event-handlers/activity/handle-activity-removed-from-feed.ts +16 -0
  100. package/src/feed/event-handlers/activity/handle-activity-updated.ts +47 -0
  101. package/src/feed/event-handlers/activity/index.ts +6 -0
  102. package/src/{state-updates → feed/event-handlers/bookmark}/bookmark-utils.test.ts +2 -2
  103. package/src/feed/event-handlers/bookmark/handle-bookmark-added.ts +63 -0
  104. package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.ts +84 -0
  105. package/src/feed/event-handlers/bookmark/handle-bookmark-updated.ts +76 -0
  106. package/src/feed/event-handlers/bookmark/index.ts +3 -0
  107. package/src/feed/event-handlers/comment/handle-comment-added.ts +38 -0
  108. package/src/feed/event-handlers/comment/handle-comment-deleted.ts +35 -0
  109. package/src/feed/event-handlers/comment/handle-comment-reaction.ts +61 -0
  110. package/src/feed/event-handlers/comment/handle-comment-updated.ts +35 -0
  111. package/src/feed/event-handlers/comment/index.ts +4 -0
  112. package/src/feed/event-handlers/feed/handle-feed-updated.ts +9 -0
  113. package/src/feed/event-handlers/feed/index.ts +1 -0
  114. package/src/feed/event-handlers/feed-member/handle-feed-member-added.ts +31 -0
  115. package/src/feed/event-handlers/feed-member/handle-feed-member-removed.ts +24 -0
  116. package/src/feed/event-handlers/feed-member/handle-feed-member-updated.ts +40 -0
  117. package/src/feed/event-handlers/feed-member/index.ts +3 -0
  118. package/src/feed/event-handlers/follow/handle-follow-created.test.ts +250 -0
  119. package/src/feed/event-handlers/follow/handle-follow-created.ts +90 -0
  120. package/src/feed/event-handlers/follow/handle-follow-deleted.test.ts +268 -0
  121. package/src/feed/event-handlers/follow/handle-follow-deleted.ts +95 -0
  122. package/src/feed/event-handlers/follow/handle-follow-updated.test.ts +174 -0
  123. package/src/feed/event-handlers/follow/handle-follow-updated.ts +85 -0
  124. package/src/feed/event-handlers/follow/index.ts +3 -0
  125. package/src/feed/event-handlers/index.ts +8 -0
  126. package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.ts +10 -0
  127. package/src/feed/event-handlers/notification-feed/index.ts +1 -0
  128. package/src/feed/event-handlers/watch/handle-watch-started.ts +5 -0
  129. package/src/feed/event-handlers/watch/handle-watch-stopped.ts +5 -0
  130. package/src/feed/event-handlers/watch/index.ts +2 -0
  131. package/src/{Feed.ts → feed/feed.ts} +87 -516
  132. package/src/feed/index.ts +2 -0
  133. package/src/feeds-client/event-handlers/index.ts +1 -0
  134. package/src/feeds-client/event-handlers/user/handle-user-updated.test.ts +53 -0
  135. package/src/feeds-client/event-handlers/user/handle-user-updated.ts +28 -0
  136. package/src/{FeedsClient.ts → feeds-client/feeds-client.ts} +63 -36
  137. package/src/feeds-client/index.ts +2 -0
  138. package/src/gen/feeds/FeedsApi.ts +164 -138
  139. package/src/gen/model-decoders/decoders.ts +22 -0
  140. package/src/gen/models/index.ts +288 -29
  141. package/src/gen-imports.ts +1 -1
  142. package/src/test-utils/index.ts +1 -0
  143. package/src/test-utils/response-generators.ts +101 -0
  144. package/src/types-internal.ts +11 -0
  145. package/src/types.ts +1 -1
  146. package/src/utils/check-has-another-page.ts +6 -0
  147. package/src/utils/constants.ts +3 -0
  148. package/src/utils/index.ts +5 -0
  149. package/src/{state-updates → utils}/state-update-queue.test.ts +6 -6
  150. package/src/utils/state-update-queue.ts +42 -0
  151. package/src/utils/type-assertions.ts +22 -0
  152. package/src/{utils.test.ts → utils/unique-array-merge.test.ts} +7 -3
  153. package/src/utils/unique-array-merge.ts +19 -0
  154. package/dist/src/FeedsClient.d.ts +0 -75
  155. package/dist/src/state-updates/activity-reaction-utils.d.ts +0 -10
  156. package/dist/src/state-updates/activity-utils.d.ts +0 -13
  157. package/dist/src/state-updates/bookmark-utils.d.ts +0 -14
  158. package/dist/src/state-updates/follow-utils.d.ts +0 -19
  159. package/dist/src/state-updates/state-update-queue.d.ts +0 -15
  160. package/dist/src/utils.d.ts +0 -10
  161. package/src/state-updates/activity-reaction-utils.ts +0 -107
  162. package/src/state-updates/bookmark-utils.ts +0 -167
  163. package/src/state-updates/follow-utils.test.ts +0 -552
  164. package/src/state-updates/follow-utils.ts +0 -126
  165. package/src/state-updates/state-update-queue.ts +0 -35
  166. package/src/utils.ts +0 -48
  167. /package/dist/src/{ModerationClient.d.ts → moderation-client.d.ts} +0 -0
  168. /package/src/{ModerationClient.ts → moderation-client.ts} +0 -0
@@ -1,3 +1,3 @@
1
1
  export type { ApiClient } from './common/ApiClient';
2
2
  export type { StreamResponse } from './common/types';
3
- export { FeedsClient as FeedsApi } from './FeedsClient';
3
+ export { FeedsClient as FeedsApi } from './feeds-client';
@@ -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
+ };
@@ -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 './FeedsClient';
11
+ import { FeedsClient } from './feeds-client';
12
12
 
13
13
  export type FeedsEvent = WSEvent | ConnectionChangedEvent | NetworkChangedEvent;
14
14
  export type ActivityIdOrCommentId = string;
@@ -0,0 +1,6 @@
1
+ export const checkHasAnotherPage = <T extends unknown | undefined>(
2
+ v: T,
3
+ cursor: string | undefined,
4
+ ) =>
5
+ (typeof v === 'undefined' && typeof cursor === 'undefined') ||
6
+ typeof cursor === 'string';
@@ -0,0 +1,3 @@
1
+ export const Constants = {
2
+ DEFAULT_COMMENT_PAGINATION: 'first',
3
+ } as const;
@@ -0,0 +1,5 @@
1
+ export * from './check-has-another-page';
2
+ export * from './unique-array-merge';
3
+ export * from './constants';
4
+ export * from './type-assertions';
5
+ export * from './state-update-queue';
@@ -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
- stateUpdateId: 'test-id',
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 stateUpdateId is not in queue', () => {
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
- stateUpdateId: 'test-id',
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 stateUpdateId from queue when watch is true and stateUpdateId is in queue', () => {
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
- stateUpdateId: 'test-id',
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
- stateUpdateId: 'test-id',
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 './utils';
3
+ import { uniqueArrayMerge } from './unique-array-merge';
4
4
 
5
5
  describe('utils', () => {
6
- describe('uniqueMerge', () => {
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(existingArray, arrayToMerge, getKeyByEmail);
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;
@@ -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
- };