@stream-io/feeds-client 0.2.12 → 0.2.14
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 +14 -0
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react-bindings.js +22 -14
- package/dist/cjs/react-bindings.js.map +1 -1
- package/dist/es/index.mjs +3 -2
- package/dist/es/react-bindings.mjs +22 -14
- package/dist/es/react-bindings.mjs.map +1 -1
- package/dist/{index-o7AeSkxa.js → index-B08vVRSZ.js} +159 -9
- package/dist/index-B08vVRSZ.js.map +1 -0
- package/dist/{index-D7QtnkUs.mjs → index-B3HHiF9S.mjs} +159 -9
- package/dist/index-B3HHiF9S.mjs.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/bindings/react/hooks/feed-state-hooks/useAggregatedActivities.d.ts +9 -4
- package/dist/types/bindings/react/hooks/feed-state-hooks/useAggregatedActivities.d.ts.map +1 -1
- package/dist/types/bindings/react/hooks/feed-state-hooks/useIsAggregatedActivityRead.d.ts.map +1 -1
- package/dist/types/common/real-time/StableWSConnection.d.ts +3 -3
- package/dist/types/common/real-time/StableWSConnection.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.d.ts +24 -0
- package/dist/types/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts +2 -0
- package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/index.d.ts +1 -1
- package/dist/types/feed/event-handlers/index.d.ts.map +1 -1
- package/dist/types/feed/feed.d.ts +2 -2
- package/dist/types/feed/feed.d.ts.map +1 -1
- package/dist/types/feeds-client/feeds-client.d.ts +2 -2
- package/dist/types/gen/model-decoders/event-decoder-mapping.d.ts.map +1 -1
- package/dist/types/gen/models/index.d.ts +17 -1
- package/dist/types/gen/models/index.d.ts.map +1 -1
- package/dist/types/utils/unique-array-merge.d.ts +1 -0
- package/dist/types/utils/unique-array-merge.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/bindings/react/hooks/feed-state-hooks/useAggregatedActivities.ts +28 -4
- package/src/bindings/react/hooks/feed-state-hooks/useIsAggregatedActivityRead.ts +4 -5
- package/src/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.test.ts +644 -0
- package/src/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.ts +193 -0
- package/src/feed/event-handlers/aggregated-feed/index.ts +1 -0
- package/src/feed/event-handlers/index.ts +1 -1
- package/src/feed/feed.ts +23 -1
- package/src/gen/model-decoders/decoders.ts +14 -0
- package/src/gen/model-decoders/event-decoder-mapping.ts +3 -0
- package/src/gen/models/index.ts +26 -2
- package/src/utils/unique-array-merge.ts +30 -0
- package/dist/index-D7QtnkUs.mjs.map +0 -1
- package/dist/index-o7AeSkxa.js.map +0 -1
- package/dist/types/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts +0 -11
- package/dist/types/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts.map +0 -1
- package/dist/types/feed/event-handlers/notification-feed/index.d.ts +0 -2
- package/dist/types/feed/event-handlers/notification-feed/index.d.ts.map +0 -1
- package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.test.ts +0 -120
- package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.ts +0 -54
- package/src/feed/event-handlers/notification-feed/index.ts +0 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import type { Feed } from '../..';
|
|
2
|
+
import type {
|
|
3
|
+
AggregatedActivityResponse,
|
|
4
|
+
NotificationFeedUpdatedEvent,
|
|
5
|
+
NotificationStatusResponse,
|
|
6
|
+
StoriesFeedUpdatedEvent,
|
|
7
|
+
} from '../../../gen/models';
|
|
8
|
+
import type { EventPayload, UpdateStateResult } from '../../../types-internal';
|
|
9
|
+
import { replaceUniqueArrayMerge, uniqueArrayMerge } from '../../../utils';
|
|
10
|
+
|
|
11
|
+
export const addAggregatedActivitiesToState = (
|
|
12
|
+
newAggregatedActivities: AggregatedActivityResponse[],
|
|
13
|
+
aggregatedActivities: AggregatedActivityResponse[] | undefined,
|
|
14
|
+
position: 'start' | 'end' | 'replace',
|
|
15
|
+
) => {
|
|
16
|
+
let result: UpdateStateResult<{
|
|
17
|
+
aggregated_activities: AggregatedActivityResponse[];
|
|
18
|
+
}>;
|
|
19
|
+
if (newAggregatedActivities.length === 0) {
|
|
20
|
+
result = {
|
|
21
|
+
changed: false,
|
|
22
|
+
aggregated_activities: [],
|
|
23
|
+
};
|
|
24
|
+
} else {
|
|
25
|
+
result = {
|
|
26
|
+
changed: true,
|
|
27
|
+
aggregated_activities: [],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
switch (position) {
|
|
32
|
+
case 'start':
|
|
33
|
+
result.aggregated_activities = uniqueArrayMerge(
|
|
34
|
+
newAggregatedActivities,
|
|
35
|
+
aggregatedActivities ?? [],
|
|
36
|
+
(a) => a.group,
|
|
37
|
+
);
|
|
38
|
+
break;
|
|
39
|
+
case 'end':
|
|
40
|
+
result.aggregated_activities = uniqueArrayMerge(
|
|
41
|
+
aggregatedActivities ?? [],
|
|
42
|
+
newAggregatedActivities,
|
|
43
|
+
(a) => a.group,
|
|
44
|
+
);
|
|
45
|
+
break;
|
|
46
|
+
case 'replace':
|
|
47
|
+
result.aggregated_activities = replaceUniqueArrayMerge(
|
|
48
|
+
aggregatedActivities ?? [],
|
|
49
|
+
newAggregatedActivities,
|
|
50
|
+
(a) => a.group,
|
|
51
|
+
);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const updateNotificationStatus = (
|
|
59
|
+
newNotificationStatus?: NotificationStatusResponse,
|
|
60
|
+
currentNotificationStatus?: NotificationStatusResponse,
|
|
61
|
+
) => {
|
|
62
|
+
if (!newNotificationStatus && !currentNotificationStatus) {
|
|
63
|
+
return {
|
|
64
|
+
changed: false,
|
|
65
|
+
notification_status: undefined,
|
|
66
|
+
};
|
|
67
|
+
} else if (!newNotificationStatus) {
|
|
68
|
+
return {
|
|
69
|
+
changed: false,
|
|
70
|
+
notification_status: currentNotificationStatus,
|
|
71
|
+
};
|
|
72
|
+
} else {
|
|
73
|
+
return {
|
|
74
|
+
changed: true,
|
|
75
|
+
notification_status: {
|
|
76
|
+
...newNotificationStatus,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const updateNotificationFeedFromEvent = (
|
|
83
|
+
event: NotificationFeedUpdatedEvent,
|
|
84
|
+
currentAggregatedActivities?: AggregatedActivityResponse[],
|
|
85
|
+
currentNotificationStatus?: NotificationStatusResponse,
|
|
86
|
+
): UpdateStateResult<{
|
|
87
|
+
data?: {
|
|
88
|
+
notification_status?: NotificationStatusResponse;
|
|
89
|
+
aggregated_activities?: AggregatedActivityResponse[];
|
|
90
|
+
};
|
|
91
|
+
}> => {
|
|
92
|
+
const updates: {
|
|
93
|
+
notification_status?: NotificationStatusResponse;
|
|
94
|
+
aggregated_activities?: AggregatedActivityResponse[];
|
|
95
|
+
} = {};
|
|
96
|
+
|
|
97
|
+
if (event.notification_status && currentNotificationStatus) {
|
|
98
|
+
const notificationStatusResult = updateNotificationStatus(
|
|
99
|
+
event.notification_status,
|
|
100
|
+
currentNotificationStatus,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
if (notificationStatusResult.changed) {
|
|
104
|
+
updates.notification_status =
|
|
105
|
+
notificationStatusResult.notification_status;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (event.aggregated_activities && currentAggregatedActivities) {
|
|
110
|
+
const aggregatedActivitiesResult = addAggregatedActivitiesToState(
|
|
111
|
+
event.aggregated_activities,
|
|
112
|
+
currentAggregatedActivities,
|
|
113
|
+
'start',
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
if (aggregatedActivitiesResult.changed) {
|
|
117
|
+
updates.aggregated_activities =
|
|
118
|
+
aggregatedActivitiesResult.aggregated_activities;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (Object.keys(updates).length > 0) {
|
|
123
|
+
return {
|
|
124
|
+
changed: true,
|
|
125
|
+
data: updates,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
changed: false,
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export function handleNotificationFeedUpdated(
|
|
135
|
+
this: Feed,
|
|
136
|
+
event: EventPayload<'feeds.notification_feed.updated'>,
|
|
137
|
+
) {
|
|
138
|
+
const result = updateNotificationFeedFromEvent(
|
|
139
|
+
event,
|
|
140
|
+
this.currentState.aggregated_activities,
|
|
141
|
+
this.currentState.notification_status,
|
|
142
|
+
);
|
|
143
|
+
if (result.changed) {
|
|
144
|
+
this.state.partialNext({
|
|
145
|
+
notification_status: result.data?.notification_status,
|
|
146
|
+
aggregated_activities: result.data?.aggregated_activities,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function updateStoriesFeedFromEvent(
|
|
152
|
+
aggregatedActivities: AggregatedActivityResponse[] | undefined,
|
|
153
|
+
event: StoriesFeedUpdatedEvent,
|
|
154
|
+
): UpdateStateResult<{
|
|
155
|
+
data?: {
|
|
156
|
+
aggregated_activities?: AggregatedActivityResponse[];
|
|
157
|
+
};
|
|
158
|
+
}> {
|
|
159
|
+
if (!aggregatedActivities) {
|
|
160
|
+
return {
|
|
161
|
+
changed: false,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (event.aggregated_activities) {
|
|
166
|
+
const result = addAggregatedActivitiesToState(
|
|
167
|
+
event.aggregated_activities,
|
|
168
|
+
aggregatedActivities,
|
|
169
|
+
'replace',
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
changed: false,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function handleStoriesFeedUpdated(
|
|
181
|
+
this: Feed,
|
|
182
|
+
event: EventPayload<'feeds.stories_feed.updated'>,
|
|
183
|
+
) {
|
|
184
|
+
const result = updateStoriesFeedFromEvent(
|
|
185
|
+
this.currentState.aggregated_activities,
|
|
186
|
+
event,
|
|
187
|
+
);
|
|
188
|
+
if (result.changed) {
|
|
189
|
+
this.state.partialNext({
|
|
190
|
+
aggregated_activities: result.data?.aggregated_activities,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './handle-aggregated-feed-updated';
|
package/src/feed/feed.ts
CHANGED
|
@@ -44,6 +44,9 @@ import {
|
|
|
44
44
|
handleActivityReactionDeleted,
|
|
45
45
|
handleCommentReactionAdded,
|
|
46
46
|
handleCommentReactionDeleted,
|
|
47
|
+
addAggregatedActivitiesToState,
|
|
48
|
+
updateNotificationStatus,
|
|
49
|
+
handleStoriesFeedUpdated,
|
|
47
50
|
} from './event-handlers';
|
|
48
51
|
import { capitalize } from '../common/utils';
|
|
49
52
|
import type {
|
|
@@ -175,6 +178,7 @@ export class Feed extends FeedApi {
|
|
|
175
178
|
'feeds.feed_member.removed': handleFeedMemberRemoved.bind(this),
|
|
176
179
|
'feeds.feed_member.updated': handleFeedMemberUpdated.bind(this),
|
|
177
180
|
'feeds.notification_feed.updated': handleNotificationFeedUpdated.bind(this),
|
|
181
|
+
'feeds.stories_feed.updated': handleStoriesFeedUpdated.bind(this),
|
|
178
182
|
// the poll events should be removed from here
|
|
179
183
|
'feeds.poll.closed': Feed.noop,
|
|
180
184
|
'feeds.poll.deleted': Feed.noop,
|
|
@@ -279,9 +283,27 @@ export class Feed extends FeedApi {
|
|
|
279
283
|
'end',
|
|
280
284
|
);
|
|
281
285
|
|
|
282
|
-
|
|
286
|
+
const aggregatedActivitiesResult = addAggregatedActivitiesToState(
|
|
287
|
+
response.aggregated_activities,
|
|
288
|
+
this.currentState.aggregated_activities,
|
|
289
|
+
'end',
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
const notificationStatusResult = updateNotificationStatus(
|
|
293
|
+
response.notification_status,
|
|
294
|
+
this.currentState.notification_status,
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
if (
|
|
298
|
+
result.changed ||
|
|
299
|
+
aggregatedActivitiesResult.changed ||
|
|
300
|
+
notificationStatusResult.changed
|
|
301
|
+
) {
|
|
283
302
|
this.state.partialNext({
|
|
284
303
|
activities: result.activities,
|
|
304
|
+
aggregated_activities:
|
|
305
|
+
aggregatedActivitiesResult.aggregated_activities,
|
|
306
|
+
notification_status: notificationStatusResult.notification_status,
|
|
285
307
|
next: response.next,
|
|
286
308
|
prev: response.prev,
|
|
287
309
|
});
|
|
@@ -1739,6 +1739,20 @@ decoders.SingleFollowResponse = (input?: Record<string, any>) => {
|
|
|
1739
1739
|
return decode(typeMappings, input);
|
|
1740
1740
|
};
|
|
1741
1741
|
|
|
1742
|
+
decoders.StoriesFeedUpdatedEvent = (input?: Record<string, any>) => {
|
|
1743
|
+
const typeMappings: TypeMapping = {
|
|
1744
|
+
created_at: { type: 'DatetimeType', isSingle: true },
|
|
1745
|
+
|
|
1746
|
+
received_at: { type: 'DatetimeType', isSingle: true },
|
|
1747
|
+
|
|
1748
|
+
aggregated_activities: {
|
|
1749
|
+
type: 'AggregatedActivityResponse',
|
|
1750
|
+
isSingle: false,
|
|
1751
|
+
},
|
|
1752
|
+
};
|
|
1753
|
+
return decode(typeMappings, input);
|
|
1754
|
+
};
|
|
1755
|
+
|
|
1742
1756
|
decoders.SubmitActionResponse = (input?: Record<string, any>) => {
|
|
1743
1757
|
const typeMappings: TypeMapping = {
|
|
1744
1758
|
item: { type: 'ReviewQueueItemResponse', isSingle: true },
|
|
@@ -124,6 +124,9 @@ const eventDecoderMapping: Record<
|
|
|
124
124
|
'feeds.poll.vote_removed': (data: Record<string, any>) =>
|
|
125
125
|
decoders.PollVoteRemovedFeedEvent(data),
|
|
126
126
|
|
|
127
|
+
'feeds.stories_feed.updated': (data: Record<string, any>) =>
|
|
128
|
+
decoders.StoriesFeedUpdatedEvent(data),
|
|
129
|
+
|
|
127
130
|
'health.check': (data: Record<string, any>) =>
|
|
128
131
|
decoders.HealthCheckEvent(data),
|
|
129
132
|
|
package/src/gen/models/index.ts
CHANGED
|
@@ -463,6 +463,8 @@ export interface ActivityResponse {
|
|
|
463
463
|
|
|
464
464
|
hidden?: boolean;
|
|
465
465
|
|
|
466
|
+
is_watched?: boolean;
|
|
467
|
+
|
|
466
468
|
text?: string;
|
|
467
469
|
|
|
468
470
|
visibility_tag?: string;
|
|
@@ -680,6 +682,8 @@ export interface AggregatedActivityResponse {
|
|
|
680
682
|
user_count_truncated: boolean;
|
|
681
683
|
|
|
682
684
|
activities: ActivityResponse[];
|
|
685
|
+
|
|
686
|
+
is_watched?: boolean;
|
|
683
687
|
}
|
|
684
688
|
|
|
685
689
|
export interface AggregationConfig {
|
|
@@ -5548,9 +5552,27 @@ export interface SpeechSegmentConfig {
|
|
|
5548
5552
|
}
|
|
5549
5553
|
|
|
5550
5554
|
export interface StoriesConfig {
|
|
5551
|
-
expiration_behaviour?: 'hide_for_everyone' | 'visible_for_author';
|
|
5552
|
-
|
|
5553
5555
|
skip_watched?: boolean;
|
|
5556
|
+
|
|
5557
|
+
track_watched?: boolean;
|
|
5558
|
+
}
|
|
5559
|
+
|
|
5560
|
+
export interface StoriesFeedUpdatedEvent {
|
|
5561
|
+
created_at: Date;
|
|
5562
|
+
|
|
5563
|
+
fid: string;
|
|
5564
|
+
|
|
5565
|
+
custom: Record<string, any>;
|
|
5566
|
+
|
|
5567
|
+
type: string;
|
|
5568
|
+
|
|
5569
|
+
feed_visibility?: string;
|
|
5570
|
+
|
|
5571
|
+
received_at?: Date;
|
|
5572
|
+
|
|
5573
|
+
aggregated_activities?: AggregatedActivityResponse[];
|
|
5574
|
+
|
|
5575
|
+
user?: UserResponseCommonFields;
|
|
5554
5576
|
}
|
|
5555
5577
|
|
|
5556
5578
|
export interface SubmitActionRequest {
|
|
@@ -6571,6 +6593,7 @@ export type WSClientEvent =
|
|
|
6571
6593
|
| ({ type: 'feeds.poll.vote_casted' } & PollVoteCastedFeedEvent)
|
|
6572
6594
|
| ({ type: 'feeds.poll.vote_changed' } & PollVoteChangedFeedEvent)
|
|
6573
6595
|
| ({ type: 'feeds.poll.vote_removed' } & PollVoteRemovedFeedEvent)
|
|
6596
|
+
| ({ type: 'feeds.stories_feed.updated' } & StoriesFeedUpdatedEvent)
|
|
6574
6597
|
| ({ type: 'health.check' } & HealthCheckEvent)
|
|
6575
6598
|
| ({ type: 'user.updated' } & UserUpdatedEvent);
|
|
6576
6599
|
|
|
@@ -6617,6 +6640,7 @@ export type WSEvent =
|
|
|
6617
6640
|
| ({ type: 'feeds.poll.vote_casted' } & PollVoteCastedFeedEvent)
|
|
6618
6641
|
| ({ type: 'feeds.poll.vote_changed' } & PollVoteChangedFeedEvent)
|
|
6619
6642
|
| ({ type: 'feeds.poll.vote_removed' } & PollVoteRemovedFeedEvent)
|
|
6643
|
+
| ({ type: 'feeds.stories_feed.updated' } & StoriesFeedUpdatedEvent)
|
|
6620
6644
|
| ({ type: 'health.check' } & HealthCheckEvent)
|
|
6621
6645
|
| ({ type: 'moderation.custom_action' } & ModerationCustomActionEvent)
|
|
6622
6646
|
| ({ type: 'moderation.flagged' } & ModerationFlaggedEvent)
|
|
@@ -17,3 +17,33 @@ export const uniqueArrayMerge = <T>(
|
|
|
17
17
|
|
|
18
18
|
return existingArray.concat(filteredArrayToMerge);
|
|
19
19
|
};
|
|
20
|
+
|
|
21
|
+
export const replaceUniqueArrayMerge = <T>(
|
|
22
|
+
existingArray: T[],
|
|
23
|
+
arrayToMerge: T[],
|
|
24
|
+
getKey: (v: T) => string,
|
|
25
|
+
) => {
|
|
26
|
+
const existingMap = new Map<string, T>();
|
|
27
|
+
(existingArray ?? []).forEach((item) => {
|
|
28
|
+
existingMap.set(getKey(item), item);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const result: T[] = [];
|
|
32
|
+
arrayToMerge.forEach((item) => {
|
|
33
|
+
existingMap.set(getKey(item), item);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
existingArray.forEach((originalItem) => {
|
|
37
|
+
const updatedItem = existingMap.get(getKey(originalItem));
|
|
38
|
+
if (updatedItem) {
|
|
39
|
+
result.push(updatedItem);
|
|
40
|
+
existingMap.delete(getKey(originalItem));
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
existingMap.forEach((item) => {
|
|
45
|
+
result.push(item);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return result;
|
|
49
|
+
};
|