@stream-io/feeds-client 0.3.31 → 0.3.33
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 +15 -0
- package/dist/cjs/index.js +3 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react-bindings.js +39 -33
- package/dist/cjs/react-bindings.js.map +1 -1
- package/dist/es/index.mjs +4 -3
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/react-bindings.mjs +39 -33
- package/dist/es/react-bindings.mjs.map +1 -1
- package/dist/{feeds-client-DYnxEI2D.mjs → feeds-client-C-6NrDBy.mjs} +196 -182
- package/dist/feeds-client-C-6NrDBy.mjs.map +1 -0
- package/dist/{feeds-client-BUsd5D-y.js → feeds-client-CyaHg6lu.js} +196 -182
- package/dist/feeds-client-CyaHg6lu.js.map +1 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/types/activity-with-state-updates/activity-with-state-updates.d.ts +1 -1
- package/dist/types/activity-with-state-updates/activity-with-state-updates.d.ts.map +1 -1
- package/dist/types/bindings/react/hooks/feed-state-hooks/index.d.ts +1 -0
- package/dist/types/bindings/react/hooks/feed-state-hooks/index.d.ts.map +1 -1
- package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.d.ts.map +1 -1
- package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnFollowings.d.ts +8 -0
- package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnFollowings.d.ts.map +1 -0
- package/dist/types/common/types.d.ts +1 -1
- package/dist/types/common/types.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -1
- package/dist/types/feed/feed.d.ts +2 -1
- package/dist/types/feed/feed.d.ts.map +1 -1
- package/dist/types/feeds-client/feeds-client.d.ts +7 -9
- package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
- package/dist/types/gen/models/index.d.ts +4 -0
- package/dist/types/gen/models/index.d.ts.map +1 -1
- package/dist/types/utils/check-own-fields-equality.d.ts +2 -0
- package/dist/types/utils/check-own-fields-equality.d.ts.map +1 -1
- package/dist/types/utils/throttling/index.d.ts +1 -1
- package/dist/types/utils/throttling/index.d.ts.map +1 -1
- package/dist/types/utils/throttling/throttled-get-batched-own-fields.d.ts +14 -0
- package/dist/types/utils/throttling/throttled-get-batched-own-fields.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/activity-with-state-updates/activity-with-state-updates.ts +7 -2
- package/src/bindings/react/hooks/feed-state-hooks/index.ts +1 -0
- package/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts +14 -23
- package/src/bindings/react/hooks/feed-state-hooks/useOwnFollowings.ts +18 -0
- package/src/common/types.ts +1 -1
- package/src/feed/event-handlers/activity/handle-activity-added.ts +0 -6
- package/src/feed/event-handlers/activity/handle-activity-updated.ts +0 -4
- package/src/feed/feed.ts +51 -39
- package/src/feeds-client/feeds-client.ts +88 -91
- package/src/gen/models/index.ts +8 -0
- package/src/utils/check-own-fields-equality.ts +37 -10
- package/src/utils/throttling/index.ts +1 -1
- package/src/utils/throttling/{throttled-get-batched-own-capabilities.ts → throttled-get-batched-own-fields.ts} +10 -10
- package/dist/feeds-client-BUsd5D-y.js.map +0 -1
- package/dist/feeds-client-DYnxEI2D.mjs.map +0 -1
- package/dist/types/utils/throttling/throttled-get-batched-own-capabilities.d.ts +0 -14
- package/dist/types/utils/throttling/throttled-get-batched-own-capabilities.d.ts.map +0 -1
|
@@ -1,38 +1,29 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
1
|
import { useStateStore } from '@stream-io/state-store/react-bindings';
|
|
3
2
|
|
|
4
3
|
import { useFeedContext } from '../../contexts/StreamFeedContext';
|
|
5
|
-
import {
|
|
6
|
-
import type { Feed } from '../../../../feed';
|
|
4
|
+
import type { Feed, FeedState } from '../../../../feed';
|
|
7
5
|
import type { FeedOwnCapability } from '../../../../gen/models';
|
|
8
|
-
import
|
|
6
|
+
import { useFeedsClient } from '../../contexts/StreamFeedsContext';
|
|
9
7
|
|
|
10
8
|
const stableEmptyArray: readonly FeedOwnCapability[] = [];
|
|
11
9
|
|
|
10
|
+
const selector = (currentState: FeedState) => {
|
|
11
|
+
return {
|
|
12
|
+
feedOwnCapabilities: currentState.own_capabilities ?? stableEmptyArray,
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
12
16
|
export const useOwnCapabilities = (feedFromProps?: Feed | string) => {
|
|
13
17
|
const client = useFeedsClient();
|
|
14
18
|
const feedFromContext = useFeedContext();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (!fid) {
|
|
21
|
-
return { feedOwnCapabilities: stableEmptyArray };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
feedOwnCapabilities:
|
|
26
|
-
currentState.own_capabilities_by_fid[fid] ?? stableEmptyArray,
|
|
27
|
-
};
|
|
28
|
-
},
|
|
29
|
-
[fid],
|
|
30
|
-
);
|
|
19
|
+
let feed = feedFromProps ?? feedFromContext;
|
|
20
|
+
if (typeof feed === 'string') {
|
|
21
|
+
const [groupId, id] = feed.split(':');
|
|
22
|
+
feed = groupId && id ? client?.feed(groupId, id) : undefined;
|
|
23
|
+
}
|
|
31
24
|
|
|
32
25
|
const { feedOwnCapabilities = stableEmptyArray } =
|
|
33
|
-
useStateStore(
|
|
34
|
-
|
|
35
|
-
// console.log('GETTING CAPA: ', feed?.feed, feedOwnCapabilities);
|
|
26
|
+
useStateStore(feed?.state, selector) ?? {};
|
|
36
27
|
|
|
37
28
|
return feedOwnCapabilities;
|
|
38
29
|
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useStateStore } from '@stream-io/state-store/react-bindings';
|
|
2
|
+
|
|
3
|
+
import { useFeedContext } from '../../contexts/StreamFeedContext';
|
|
4
|
+
import type { Feed, FeedState } from '../../../../feed';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A React hook that returns a reactive array of feeds that the feeds's owner is following and is owned by the current user.
|
|
8
|
+
*/
|
|
9
|
+
export const useOwnFollowings = (feedFromProps?: Feed) => {
|
|
10
|
+
const feedFromContext = useFeedContext();
|
|
11
|
+
const feed = feedFromProps ?? feedFromContext;
|
|
12
|
+
|
|
13
|
+
return useStateStore(feed?.state, selector);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const selector = ({ own_followings }: FeedState) => ({
|
|
17
|
+
own_followings,
|
|
18
|
+
});
|
package/src/common/types.ts
CHANGED
|
@@ -6,7 +6,7 @@ export type FeedsClientOptions = {
|
|
|
6
6
|
base_url?: string;
|
|
7
7
|
timeout?: number;
|
|
8
8
|
configure_loggers_options?: ConfigureLoggersOptions;
|
|
9
|
-
|
|
9
|
+
query_batch_own_fields_throttling_interval?: number;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
export type RateLimit = {
|
|
@@ -62,12 +62,6 @@ export function handleActivityAdded(
|
|
|
62
62
|
const activity = event.activity;
|
|
63
63
|
this.client.hydratePollCache([activity]);
|
|
64
64
|
|
|
65
|
-
const currentFeed = activity.current_feed;
|
|
66
|
-
|
|
67
|
-
if (currentFeed) {
|
|
68
|
-
this.client.hydrateCapabilitiesCache([currentFeed]);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
65
|
this.state.partialNext({ activities: result.activities });
|
|
72
66
|
}
|
|
73
67
|
}
|
|
@@ -92,10 +92,6 @@ export function handleActivityUpdated(
|
|
|
92
92
|
if (result1?.changed || result2.changed) {
|
|
93
93
|
this.client.hydratePollCache([payload.activity]);
|
|
94
94
|
|
|
95
|
-
if (payload.activity.current_feed) {
|
|
96
|
-
this.client.hydrateCapabilitiesCache([payload.activity.current_feed]);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
95
|
this.state.partialNext({
|
|
100
96
|
activities: result1?.changed ? result1.entities : currentActivities,
|
|
101
97
|
pinned_activities: result2.entities,
|
package/src/feed/feed.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
FollowRequest,
|
|
15
15
|
QueryCommentsRequest,
|
|
16
16
|
ActivityAddedEvent,
|
|
17
|
+
EnrichmentOptions,
|
|
17
18
|
} from '../gen/models';
|
|
18
19
|
import type { StreamResponse } from '../gen-imports';
|
|
19
20
|
import { StateStore } from '@stream-io/state-store';
|
|
@@ -63,16 +64,16 @@ import {
|
|
|
63
64
|
checkHasAnotherPage,
|
|
64
65
|
Constants,
|
|
65
66
|
feedsLoggerSystem,
|
|
66
|
-
ownFeedFields,
|
|
67
67
|
uniqueArrayMerge,
|
|
68
68
|
} from '../utils';
|
|
69
69
|
import { handleActivityFeedback } from './event-handlers/activity/handle-activity-feedback';
|
|
70
70
|
import { deepEqual } from '../utils/deep-equal';
|
|
71
71
|
import { getOrCreateActiveFeed } from '../feeds-client/get-or-create-active-feed';
|
|
72
|
+
import { queueBatchedOwnFields } from '../utils/throttling';
|
|
72
73
|
|
|
73
74
|
export type FeedState = Omit<
|
|
74
75
|
Partial<GetOrCreateFeedResponse & FeedResponse>,
|
|
75
|
-
'feed' | '
|
|
76
|
+
'feed' | 'duration'
|
|
76
77
|
> & {
|
|
77
78
|
/**
|
|
78
79
|
* True when loading state using `getOrCreate`
|
|
@@ -333,11 +334,6 @@ export class Feed extends FeedApi {
|
|
|
333
334
|
}
|
|
334
335
|
}
|
|
335
336
|
|
|
336
|
-
this.client.hydrateCapabilitiesCache([
|
|
337
|
-
response.feed,
|
|
338
|
-
...currentActivityFeeds,
|
|
339
|
-
]);
|
|
340
|
-
|
|
341
337
|
if (request?.next) {
|
|
342
338
|
const { activities: currentActivities = [] } = this.currentState;
|
|
343
339
|
|
|
@@ -919,10 +915,7 @@ export class Feed extends FeedApi {
|
|
|
919
915
|
...request,
|
|
920
916
|
feeds: [this.feed],
|
|
921
917
|
});
|
|
922
|
-
|
|
923
|
-
if (currentFeed) {
|
|
924
|
-
this.client.hydrateCapabilitiesCache([currentFeed]);
|
|
925
|
-
}
|
|
918
|
+
|
|
926
919
|
return response;
|
|
927
920
|
}
|
|
928
921
|
|
|
@@ -934,34 +927,19 @@ export class Feed extends FeedApi {
|
|
|
934
927
|
|
|
935
928
|
// no need to run noop function
|
|
936
929
|
if (eventHandler !== Feed.noop) {
|
|
937
|
-
if
|
|
930
|
+
// Backfill current_feed if activity is posted to multiple feeds
|
|
931
|
+
if (
|
|
932
|
+
'activity' in event &&
|
|
933
|
+
event.activity.feeds.length > 1 &&
|
|
934
|
+
this.hasActivity(event.activity.id)
|
|
935
|
+
) {
|
|
938
936
|
const currentActivity = this.currentState.activities?.find(
|
|
939
937
|
(a) => a.id === event.activity.id,
|
|
940
938
|
);
|
|
941
939
|
|
|
942
|
-
|
|
943
|
-
if (
|
|
944
|
-
event.activity.feeds.length > 1 &&
|
|
945
|
-
!event.activity.current_feed &&
|
|
946
|
-
currentActivity?.current_feed
|
|
947
|
-
) {
|
|
940
|
+
if (!event.activity.current_feed && currentActivity?.current_feed) {
|
|
948
941
|
event.activity.current_feed = currentActivity.current_feed;
|
|
949
942
|
}
|
|
950
|
-
|
|
951
|
-
// Backfill own_ fields if activity is posted to a single feed
|
|
952
|
-
if (
|
|
953
|
-
event.activity.feeds.length === 1 &&
|
|
954
|
-
event.activity.current_feed &&
|
|
955
|
-
currentActivity?.current_feed
|
|
956
|
-
) {
|
|
957
|
-
ownFeedFields.forEach((field) => {
|
|
958
|
-
if (field in currentActivity.current_feed!) {
|
|
959
|
-
// @ts-expect-error TODO: fix this
|
|
960
|
-
event.activity.current_feed![field] =
|
|
961
|
-
currentActivity.current_feed![field];
|
|
962
|
-
}
|
|
963
|
-
});
|
|
964
|
-
}
|
|
965
943
|
}
|
|
966
944
|
// @ts-expect-error intersection of handler arguments results to never
|
|
967
945
|
eventHandler?.(event);
|
|
@@ -994,10 +972,7 @@ export class Feed extends FeedApi {
|
|
|
994
972
|
) {
|
|
995
973
|
const enrichmentOptions =
|
|
996
974
|
this.currentState.last_get_or_create_request_config?.enrichment_options;
|
|
997
|
-
if (
|
|
998
|
-
!enrichmentOptions?.skip_activity_current_feed &&
|
|
999
|
-
!enrichmentOptions?.skip_all
|
|
1000
|
-
) {
|
|
975
|
+
if (this.shouldAddToActiveFeeds(enrichmentOptions)) {
|
|
1001
976
|
const feedsToGetOrCreate = new Map<string, FeedResponse>();
|
|
1002
977
|
activities.forEach((activity) => {
|
|
1003
978
|
if (
|
|
@@ -1010,14 +985,51 @@ export class Feed extends FeedApi {
|
|
|
1010
985
|
);
|
|
1011
986
|
}
|
|
1012
987
|
});
|
|
1013
|
-
Array.from(feedsToGetOrCreate.values())
|
|
988
|
+
const newFeeds = Array.from(feedsToGetOrCreate.values());
|
|
989
|
+
const fieldsToUpdate: Array<
|
|
990
|
+
'own_capabilities' | 'own_follows' | 'own_followings' | 'own_membership'
|
|
991
|
+
> = [];
|
|
992
|
+
if (!options.fromWebSocket) {
|
|
993
|
+
fieldsToUpdate.push(
|
|
994
|
+
'own_capabilities',
|
|
995
|
+
'own_follows',
|
|
996
|
+
'own_membership',
|
|
997
|
+
);
|
|
998
|
+
if (enrichmentOptions?.enrich_own_followings) {
|
|
999
|
+
fieldsToUpdate.push('own_followings');
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
newFeeds.forEach((feed) => {
|
|
1014
1003
|
getOrCreateActiveFeed.bind(this.client)({
|
|
1015
1004
|
group: feed.group_id,
|
|
1016
1005
|
id: feed.id,
|
|
1017
1006
|
data: feed,
|
|
1018
|
-
|
|
1007
|
+
fieldsToUpdate,
|
|
1019
1008
|
});
|
|
1020
1009
|
});
|
|
1010
|
+
if (options.fromWebSocket) {
|
|
1011
|
+
const uninitializedFeeds = newFeeds.filter((feedResponse) => {
|
|
1012
|
+
const feed = this.client.feed(feedResponse.group_id, feedResponse.id);
|
|
1013
|
+
// own_capabilities can only be undefined if we haven't fetched it yet
|
|
1014
|
+
return feed.currentState.own_capabilities === undefined;
|
|
1015
|
+
});
|
|
1016
|
+
if (uninitializedFeeds.length > 0) {
|
|
1017
|
+
queueBatchedOwnFields.bind(this.client)({
|
|
1018
|
+
feeds: uninitializedFeeds.map((feed) => feed.feed),
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1021
1022
|
}
|
|
1022
1023
|
}
|
|
1024
|
+
|
|
1025
|
+
private shouldAddToActiveFeeds(enrichmentOptions?: EnrichmentOptions) {
|
|
1026
|
+
if (!enrichmentOptions) {
|
|
1027
|
+
return true;
|
|
1028
|
+
}
|
|
1029
|
+
return (
|
|
1030
|
+
!enrichmentOptions?.skip_activity &&
|
|
1031
|
+
!enrichmentOptions?.skip_activity_current_feed &&
|
|
1032
|
+
!enrichmentOptions?.skip_all
|
|
1033
|
+
);
|
|
1034
|
+
}
|
|
1023
1035
|
}
|
|
@@ -60,6 +60,7 @@ import { ModerationClient } from '../moderation-client';
|
|
|
60
60
|
import { StreamPoll } from '../common/Poll';
|
|
61
61
|
import {
|
|
62
62
|
Feed,
|
|
63
|
+
type FeedState,
|
|
63
64
|
handleActivityReactionAdded,
|
|
64
65
|
handleActivityReactionDeleted,
|
|
65
66
|
handleActivityReactionUpdated,
|
|
@@ -86,15 +87,16 @@ import { feedsLoggerSystem } from '../utils';
|
|
|
86
87
|
import { handleCommentReactionUpdated } from '../feed/event-handlers/comment/handle-comment-reaction-updated';
|
|
87
88
|
import {
|
|
88
89
|
throttle,
|
|
89
|
-
DEFAULT_BATCH_OWN_CAPABILITIES_THROTTLING_INTERVAL,
|
|
90
|
-
type GetBatchedOwnCapabilitiesThrottledCallback,
|
|
91
|
-
queueBatchedOwnCapabilities,
|
|
92
|
-
type ThrottledGetBatchedOwnCapabilities,
|
|
93
90
|
clearQueuedFeeds,
|
|
91
|
+
type ThrottledGetBatchedOwnFields,
|
|
92
|
+
type GetBatchedOwnFieldsThrottledCallback,
|
|
93
|
+
DEFAULT_BATCH_OWN_FIELDS_THROTTLING_INTERVAL,
|
|
94
94
|
} from '../utils/throttling';
|
|
95
95
|
import { ActivityWithStateUpdates } from '../activity-with-state-updates/activity-with-state-updates';
|
|
96
96
|
import { getFeed } from '../activity-with-state-updates/get-feed';
|
|
97
97
|
import {
|
|
98
|
+
isOwnCapabilitiesEqual,
|
|
99
|
+
isOwnFollowingsEqual,
|
|
98
100
|
isOwnFollowsEqual,
|
|
99
101
|
isOwnMembershipEqual,
|
|
100
102
|
} from '../utils/check-own-fields-equality';
|
|
@@ -102,7 +104,6 @@ import {
|
|
|
102
104
|
export type FeedsClientState = {
|
|
103
105
|
connected_user: ConnectedUser | undefined;
|
|
104
106
|
is_ws_connection_healthy: boolean;
|
|
105
|
-
own_capabilities_by_fid: Record<string, FeedResponse['own_capabilities']>;
|
|
106
107
|
};
|
|
107
108
|
|
|
108
109
|
type FID = string;
|
|
@@ -128,9 +129,9 @@ export class FeedsClient extends FeedsApi {
|
|
|
128
129
|
|
|
129
130
|
private healthyConnectionChangedEventCount = 0;
|
|
130
131
|
|
|
131
|
-
protected
|
|
132
|
-
private
|
|
133
|
-
private
|
|
132
|
+
protected throttledGetBatchOwnFields!: ThrottledGetBatchedOwnFields;
|
|
133
|
+
private cancelGetBatchOwnFieldsTimer!: () => void;
|
|
134
|
+
private query_batch_own_fields_throttling_interval!: number;
|
|
134
135
|
|
|
135
136
|
constructor(apiKey: string, options?: FeedsClientOptions) {
|
|
136
137
|
const tokenManager = new TokenManager();
|
|
@@ -145,16 +146,15 @@ export class FeedsClient extends FeedsApi {
|
|
|
145
146
|
this.state = new StateStore<FeedsClientState>({
|
|
146
147
|
connected_user: undefined,
|
|
147
148
|
is_ws_connection_healthy: false,
|
|
148
|
-
own_capabilities_by_fid: {},
|
|
149
149
|
});
|
|
150
150
|
this.moderation = new ModerationClient(apiClient);
|
|
151
151
|
this.tokenManager = tokenManager;
|
|
152
152
|
this.connectionIdManager = connectionIdManager;
|
|
153
153
|
this.polls_by_id = new Map();
|
|
154
154
|
|
|
155
|
-
this.
|
|
156
|
-
options?.
|
|
157
|
-
|
|
155
|
+
this.query_batch_own_fields_throttling_interval =
|
|
156
|
+
options?.query_batch_own_fields_throttling_interval ??
|
|
157
|
+
DEFAULT_BATCH_OWN_FIELDS_THROTTLING_INTERVAL;
|
|
158
158
|
|
|
159
159
|
feedsLoggerSystem.configureLoggers(options?.configure_loggers_options);
|
|
160
160
|
|
|
@@ -184,6 +184,7 @@ export class FeedsClient extends FeedsApi {
|
|
|
184
184
|
group: event.feed.group_id,
|
|
185
185
|
id: event.feed.id,
|
|
186
186
|
data: event.feed,
|
|
187
|
+
fieldsToUpdate: [],
|
|
187
188
|
});
|
|
188
189
|
|
|
189
190
|
break;
|
|
@@ -284,30 +285,27 @@ export class FeedsClient extends FeedsApi {
|
|
|
284
285
|
});
|
|
285
286
|
}
|
|
286
287
|
|
|
287
|
-
private
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
error_type: UnhandledErrorType.FetchingOwnCapabilitiesOnNewActivity,
|
|
301
|
-
error,
|
|
288
|
+
private setGetBatchOwnFieldsThrottlingInterval = (throttlingMs: number) => {
|
|
289
|
+
const { throttledFn: throttledGetBatchOwnFields, cancelTimer: cancel } =
|
|
290
|
+
throttle<GetBatchedOwnFieldsThrottledCallback>(
|
|
291
|
+
(feeds, callback) => {
|
|
292
|
+
this.ownBatch({
|
|
293
|
+
feeds,
|
|
294
|
+
}).catch((error) => {
|
|
295
|
+
this.eventDispatcher.dispatch({
|
|
296
|
+
type: 'errors.unhandled',
|
|
297
|
+
error_type:
|
|
298
|
+
UnhandledErrorType.FetchingOwnCapabilitiesOnNewActivity,
|
|
299
|
+
error,
|
|
300
|
+
});
|
|
302
301
|
});
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
this.
|
|
310
|
-
this.cancelGetBatchOwnCapabilitiesTimer = cancel;
|
|
302
|
+
callback(feeds);
|
|
303
|
+
},
|
|
304
|
+
throttlingMs,
|
|
305
|
+
{ trailing: true },
|
|
306
|
+
);
|
|
307
|
+
this.throttledGetBatchOwnFields = throttledGetBatchOwnFields;
|
|
308
|
+
this.cancelGetBatchOwnFieldsTimer = cancel;
|
|
311
309
|
};
|
|
312
310
|
|
|
313
311
|
private recoverOnReconnect = async () => {
|
|
@@ -369,34 +367,6 @@ export class FeedsClient extends FeedsApi {
|
|
|
369
367
|
}
|
|
370
368
|
}
|
|
371
369
|
|
|
372
|
-
public hydrateCapabilitiesCache(
|
|
373
|
-
feedResponses: Array<Pick<FeedResponse, 'feed' | 'own_capabilities'>>,
|
|
374
|
-
) {
|
|
375
|
-
let ownCapabilitiesCache =
|
|
376
|
-
this.state.getLatestValue().own_capabilities_by_fid;
|
|
377
|
-
|
|
378
|
-
const capabilitiesToFetchQueue: string[] = [];
|
|
379
|
-
|
|
380
|
-
for (const feedResponse of feedResponses) {
|
|
381
|
-
const { feed, own_capabilities } = feedResponse;
|
|
382
|
-
|
|
383
|
-
if (!Object.prototype.hasOwnProperty.call(ownCapabilitiesCache, feed)) {
|
|
384
|
-
if (own_capabilities) {
|
|
385
|
-
ownCapabilitiesCache = {
|
|
386
|
-
...ownCapabilitiesCache,
|
|
387
|
-
[feed]: own_capabilities,
|
|
388
|
-
};
|
|
389
|
-
} else {
|
|
390
|
-
capabilitiesToFetchQueue.push(feed);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
queueBatchedOwnCapabilities.bind(this)({ feeds: capabilitiesToFetchQueue });
|
|
396
|
-
|
|
397
|
-
this.state.partialNext({ own_capabilities_by_fid: ownCapabilitiesCache });
|
|
398
|
-
}
|
|
399
|
-
|
|
400
370
|
connectUser = async (user: UserRequest, tokenProvider?: TokenOrProvider) => {
|
|
401
371
|
if (
|
|
402
372
|
this.state.getLatestValue().connected_user !== undefined ||
|
|
@@ -407,8 +377,8 @@ export class FeedsClient extends FeedsApi {
|
|
|
407
377
|
|
|
408
378
|
this.tokenManager.setTokenOrProvider(tokenProvider);
|
|
409
379
|
|
|
410
|
-
this.
|
|
411
|
-
this.
|
|
380
|
+
this.setGetBatchOwnFieldsThrottlingInterval(
|
|
381
|
+
this.query_batch_own_fields_throttling_interval,
|
|
412
382
|
);
|
|
413
383
|
|
|
414
384
|
try {
|
|
@@ -649,10 +619,9 @@ export class FeedsClient extends FeedsApi {
|
|
|
649
619
|
this.state.partialNext({
|
|
650
620
|
connected_user: undefined,
|
|
651
621
|
is_ws_connection_healthy: false,
|
|
652
|
-
own_capabilities_by_fid: {},
|
|
653
622
|
});
|
|
654
623
|
|
|
655
|
-
this.
|
|
624
|
+
this.cancelGetBatchOwnFieldsTimer();
|
|
656
625
|
clearQueuedFeeds();
|
|
657
626
|
};
|
|
658
627
|
|
|
@@ -680,6 +649,7 @@ export class FeedsClient extends FeedsApi {
|
|
|
680
649
|
group: groupId,
|
|
681
650
|
id,
|
|
682
651
|
options,
|
|
652
|
+
fieldsToUpdate: [],
|
|
683
653
|
});
|
|
684
654
|
};
|
|
685
655
|
|
|
@@ -711,11 +681,15 @@ export class FeedsClient extends FeedsApi {
|
|
|
711
681
|
id: feedResponse.id,
|
|
712
682
|
data: feedResponse,
|
|
713
683
|
watch: request?.watch,
|
|
684
|
+
fieldsToUpdate: [
|
|
685
|
+
'own_capabilities',
|
|
686
|
+
'own_follows',
|
|
687
|
+
'own_membership',
|
|
688
|
+
'own_followings',
|
|
689
|
+
],
|
|
714
690
|
}),
|
|
715
691
|
);
|
|
716
692
|
|
|
717
|
-
this.hydrateCapabilitiesCache(feedResponses);
|
|
718
|
-
|
|
719
693
|
return {
|
|
720
694
|
feeds,
|
|
721
695
|
next: response.next,
|
|
@@ -727,13 +701,12 @@ export class FeedsClient extends FeedsApi {
|
|
|
727
701
|
|
|
728
702
|
async ownBatch(request: OwnBatchRequest) {
|
|
729
703
|
const response = await super.ownBatch(request);
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
}
|
|
735
|
-
);
|
|
736
|
-
this.hydrateCapabilitiesCache(feedResponses);
|
|
704
|
+
Object.entries(response.data).forEach(([fid, ownFields]) => {
|
|
705
|
+
const feed = this.activeFeeds[fid];
|
|
706
|
+
if (feed) {
|
|
707
|
+
feed.state.partialNext(ownFields);
|
|
708
|
+
}
|
|
709
|
+
});
|
|
737
710
|
return response;
|
|
738
711
|
}
|
|
739
712
|
|
|
@@ -826,7 +799,6 @@ export class FeedsClient extends FeedsApi {
|
|
|
826
799
|
},
|
|
827
800
|
) {
|
|
828
801
|
const response = await super.getOrCreateFeed(request);
|
|
829
|
-
this.hydrateCapabilitiesCache([response.feed]);
|
|
830
802
|
|
|
831
803
|
if (request.watch) {
|
|
832
804
|
const feeds = this.findAllActiveFeedsByFid(
|
|
@@ -848,6 +820,12 @@ export class FeedsClient extends FeedsApi {
|
|
|
848
820
|
group: suggestion.group_id,
|
|
849
821
|
id: suggestion.id,
|
|
850
822
|
data: suggestion,
|
|
823
|
+
fieldsToUpdate: [
|
|
824
|
+
'own_capabilities',
|
|
825
|
+
'own_follows',
|
|
826
|
+
'own_membership',
|
|
827
|
+
'own_followings',
|
|
828
|
+
],
|
|
851
829
|
});
|
|
852
830
|
});
|
|
853
831
|
|
|
@@ -861,7 +839,7 @@ export class FeedsClient extends FeedsApi {
|
|
|
861
839
|
data,
|
|
862
840
|
watch,
|
|
863
841
|
options,
|
|
864
|
-
|
|
842
|
+
fieldsToUpdate,
|
|
865
843
|
}: {
|
|
866
844
|
group: string;
|
|
867
845
|
id: string;
|
|
@@ -871,7 +849,9 @@ export class FeedsClient extends FeedsApi {
|
|
|
871
849
|
addNewActivitiesTo?: 'start' | 'end';
|
|
872
850
|
activityAddedEventFilter?: (event: ActivityAddedEvent) => boolean;
|
|
873
851
|
};
|
|
874
|
-
|
|
852
|
+
fieldsToUpdate: Array<
|
|
853
|
+
'own_capabilities' | 'own_follows' | 'own_followings' | 'own_membership'
|
|
854
|
+
>;
|
|
875
855
|
}) => {
|
|
876
856
|
const fid = `${group}:${id}`;
|
|
877
857
|
let isCreated = false;
|
|
@@ -909,18 +889,35 @@ export class FeedsClient extends FeedsApi {
|
|
|
909
889
|
handleFeedUpdated.call(feed, { feed: data });
|
|
910
890
|
} else if (
|
|
911
891
|
(feed.currentState.updated_at?.getTime() ?? 0) ===
|
|
912
|
-
|
|
913
|
-
!fromWebSocket
|
|
892
|
+
data.updated_at.getTime()
|
|
914
893
|
) {
|
|
915
|
-
const
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
894
|
+
const fieldsToUpdateData: Array<keyof FeedResponse> = [];
|
|
895
|
+
const fieldChecks: Array<
|
|
896
|
+
[
|
|
897
|
+
(
|
|
898
|
+
| 'own_capabilities'
|
|
899
|
+
| 'own_follows'
|
|
900
|
+
| 'own_membership'
|
|
901
|
+
| 'own_followings'
|
|
902
|
+
),
|
|
903
|
+
(currentState: FeedState, newState: FeedResponse) => boolean,
|
|
904
|
+
]
|
|
905
|
+
> = [
|
|
906
|
+
['own_capabilities', isOwnCapabilitiesEqual],
|
|
907
|
+
['own_follows', isOwnFollowsEqual],
|
|
908
|
+
['own_membership', isOwnMembershipEqual],
|
|
909
|
+
['own_followings', isOwnFollowingsEqual],
|
|
910
|
+
];
|
|
911
|
+
fieldChecks.forEach(([field, isEqual]) => {
|
|
912
|
+
if (
|
|
913
|
+
fieldsToUpdate.includes(field) &&
|
|
914
|
+
!isEqual(feed.currentState, data)
|
|
915
|
+
) {
|
|
916
|
+
fieldsToUpdateData.push(field);
|
|
917
|
+
}
|
|
918
|
+
});
|
|
919
|
+
if (fieldsToUpdateData.length > 0) {
|
|
920
|
+
const fieldsToUpdatePayload = fieldsToUpdateData.reduce(
|
|
924
921
|
(acc: Partial<FeedResponse>, field) => {
|
|
925
922
|
// @ts-expect-error TODO: fix this
|
|
926
923
|
acc[field] = data[field];
|
|
@@ -928,7 +925,7 @@ export class FeedsClient extends FeedsApi {
|
|
|
928
925
|
},
|
|
929
926
|
{},
|
|
930
927
|
);
|
|
931
|
-
feed.state.partialNext(
|
|
928
|
+
feed.state.partialNext(fieldsToUpdatePayload);
|
|
932
929
|
}
|
|
933
930
|
}
|
|
934
931
|
}
|
package/src/gen/models/index.ts
CHANGED
|
@@ -614,6 +614,8 @@ export interface AddCommentReactionResponse {
|
|
|
614
614
|
comment: CommentResponse;
|
|
615
615
|
|
|
616
616
|
reaction: FeedsReactionResponse;
|
|
617
|
+
|
|
618
|
+
notification_created?: boolean;
|
|
617
619
|
}
|
|
618
620
|
|
|
619
621
|
export interface AddCommentRequest {
|
|
@@ -644,6 +646,8 @@ export interface AddCommentResponse {
|
|
|
644
646
|
duration: string;
|
|
645
647
|
|
|
646
648
|
comment: CommentResponse;
|
|
649
|
+
|
|
650
|
+
notification_created?: boolean;
|
|
647
651
|
}
|
|
648
652
|
|
|
649
653
|
export interface AddCommentsBatchRequest {
|
|
@@ -680,6 +684,8 @@ export interface AddReactionResponse {
|
|
|
680
684
|
activity: ActivityResponse;
|
|
681
685
|
|
|
682
686
|
reaction: FeedsReactionResponse;
|
|
687
|
+
|
|
688
|
+
notification_created?: boolean;
|
|
683
689
|
}
|
|
684
690
|
|
|
685
691
|
export interface AggregatedActivityResponse {
|
|
@@ -5258,6 +5264,8 @@ export interface SingleFollowResponse {
|
|
|
5258
5264
|
duration: string;
|
|
5259
5265
|
|
|
5260
5266
|
follow: FollowResponse;
|
|
5267
|
+
|
|
5268
|
+
notification_created?: boolean;
|
|
5261
5269
|
}
|
|
5262
5270
|
|
|
5263
5271
|
export interface SortParam {
|