@stream-io/feeds-client 0.2.17 → 0.2.19
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 +24 -0
- package/dist/cjs/index.js +94 -25
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react-bindings.js +26 -55
- package/dist/cjs/react-bindings.js.map +1 -1
- package/dist/es/index.mjs +86 -17
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/react-bindings.mjs +19 -48
- package/dist/es/react-bindings.mjs.map +1 -1
- package/dist/{index-nq6SDtbt.js → feeds-client-C09giTf1.js} +322 -133
- package/dist/feeds-client-C09giTf1.js.map +1 -0
- package/dist/{index-BZL77zNq.mjs → feeds-client-CFadXO-B.mjs} +335 -146
- package/dist/feeds-client-CFadXO-B.mjs.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.d.ts +2 -32
- package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.d.ts.map +1 -1
- package/dist/types/common/real-time/StableWSConnection.d.ts +3 -3
- package/dist/types/common/real-time/event-models.d.ts +7 -2
- package/dist/types/common/real-time/event-models.d.ts.map +1 -1
- package/dist/types/common/types.d.ts +1 -0
- package/dist/types/common/types.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts +4 -3
- 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/event-handlers/activity-updater.d.ts +44 -0
- package/dist/types/feed/event-handlers/activity-updater.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/add-aggregated-activities-to-state.d.ts +6 -0
- package/dist/types/feed/event-handlers/add-aggregated-activities-to-state.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/index.d.ts +3 -1
- package/dist/types/feed/event-handlers/index.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/{aggregated-feed/handle-aggregated-feed-updated.d.ts → notification-feed/handle-notification-feed-updated.d.ts} +2 -11
- package/dist/types/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/notification-feed/index.d.ts +2 -0
- package/dist/types/feed/event-handlers/notification-feed/index.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/story-feeds/handle-story-feeds-updated.d.ts +15 -0
- package/dist/types/feed/event-handlers/story-feeds/handle-story-feeds-updated.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/story-feeds/index.d.ts +2 -0
- package/dist/types/feed/event-handlers/story-feeds/index.d.ts.map +1 -0
- package/dist/types/feed/feed.d.ts +10 -4
- package/dist/types/feed/feed.d.ts.map +1 -1
- package/dist/types/feeds-client/feeds-client.d.ts +14 -4
- package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
- package/dist/types/gen/feeds/FeedsApi.d.ts.map +1 -1
- package/dist/types/gen/models/index.d.ts +42 -451
- package/dist/types/gen/models/index.d.ts.map +1 -1
- package/dist/types/utils/throttling/index.d.ts +3 -0
- package/dist/types/utils/throttling/index.d.ts.map +1 -0
- package/dist/types/utils/throttling/throttle.d.ts +34 -0
- package/dist/types/utils/throttling/throttle.d.ts.map +1 -0
- package/dist/types/utils/throttling/throttled-get-batched-own-capabilities.d.ts +14 -0
- package/dist/types/utils/throttling/throttled-get-batched-own-capabilities.d.ts.map +1 -0
- package/package.json +7 -3
- package/react-bindings.d.ts +11 -0
- package/react-bindings.js +7 -0
- package/react-bindings.mjs +11 -0
- package/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts +21 -73
- package/src/common/real-time/event-models.ts +8 -2
- package/src/common/types.ts +1 -0
- package/src/feed/event-handlers/activity/handle-activity-added.ts +18 -12
- package/src/feed/event-handlers/activity/handle-activity-updated.ts +12 -16
- package/src/feed/event-handlers/activity-updater.ts +15 -0
- package/src/feed/event-handlers/add-aggregated-activities-to-state.ts +72 -0
- package/src/feed/event-handlers/index.ts +3 -1
- package/src/feed/event-handlers/{aggregated-feed/handle-aggregated-feed-updated.ts → notification-feed/handle-notification-feed-updated.ts} +2 -94
- package/src/feed/event-handlers/notification-feed/index.ts +1 -0
- package/src/feed/event-handlers/story-feeds/handle-story-feeds-updated.ts +122 -0
- package/src/feed/event-handlers/story-feeds/index.ts +1 -0
- package/src/feed/feed.ts +30 -3
- package/src/feeds-client/feeds-client.ts +127 -6
- package/src/gen/feeds/FeedsApi.ts +5 -0
- package/src/gen/model-decoders/decoders.ts +10 -4
- package/src/gen/models/index.ts +75 -834
- package/src/test-utils/response-generators.ts +37 -1
- package/src/utils/throttling/index.ts +2 -0
- package/src/utils/throttling/throttle.ts +123 -0
- package/src/utils/throttling/throttled-get-batched-own-capabilities.ts +42 -0
- package/dist/index-BZL77zNq.mjs.map +0 -1
- package/dist/index-nq6SDtbt.js.map +0 -1
- package/dist/types/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.d.ts.map +0 -1
- package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts +0 -2
- package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts.map +0 -1
- package/src/feed/event-handlers/activity/activity-marked-utils.test.ts +0 -208
- package/src/feed/event-handlers/activity/activity-reaction-utils.test.ts +0 -371
- package/src/feed/event-handlers/activity/activity-utils.test.ts +0 -252
- package/src/feed/event-handlers/activity/handle-activity-added.test.ts +0 -86
- package/src/feed/event-handlers/activity/handle-activity-deleted.test.ts +0 -117
- package/src/feed/event-handlers/activity/handle-activity-pinned.test.ts +0 -60
- package/src/feed/event-handlers/activity/handle-activity-reaction-added.test.ts +0 -257
- package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.test.ts +0 -317
- package/src/feed/event-handlers/activity/handle-activity-reaction-updated.test.ts +0 -282
- package/src/feed/event-handlers/activity/handle-activity-unpinned.test.ts +0 -95
- package/src/feed/event-handlers/activity/handle-activity-updated.test.ts +0 -245
- package/src/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.test.ts +0 -644
- package/src/feed/event-handlers/aggregated-feed/index.ts +0 -1
- package/src/feed/event-handlers/bookmark/bookmark-utils.test.ts +0 -521
- package/src/feed/event-handlers/bookmark/handle-bookmark-added.test.ts +0 -178
- package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.test.ts +0 -188
- package/src/feed/event-handlers/bookmark/handle-bookmark-updated.test.ts +0 -196
- package/src/feed/event-handlers/comment/handle-comment-added.test.ts +0 -271
- package/src/feed/event-handlers/comment/handle-comment-deleted.test.ts +0 -255
- package/src/feed/event-handlers/comment/handle-comment-reaction-added.test.ts +0 -329
- package/src/feed/event-handlers/comment/handle-comment-reaction-deleted.test.ts +0 -343
- package/src/feed/event-handlers/comment/handle-comment-reaction-updated.test.ts +0 -350
- package/src/feed/event-handlers/comment/handle-comment-updated.test.ts +0 -267
- package/src/feed/event-handlers/comment/utils/update-comment-count.test.ts +0 -322
- package/src/feed/event-handlers/feed-member/handle-feed-member-added.test.ts +0 -75
- package/src/feed/event-handlers/feed-member/handle-feed-member-removed.test.ts +0 -82
- package/src/feed/event-handlers/feed-member/handle-feed-member-updated.test.ts +0 -84
- package/src/feed/event-handlers/follow/follow-state-update-queue.test.ts +0 -219
- package/src/feed/event-handlers/follow/handle-follow-created.test.ts +0 -250
- package/src/feed/event-handlers/follow/handle-follow-deleted.test.ts +0 -268
- package/src/feed/event-handlers/follow/handle-follow-updated.test.ts +0 -131
- package/src/feed/feed.test.ts +0 -90
- package/src/feeds-client/event-handlers/user/handle-user-updated.test.ts +0 -53
- package/src/utils/event-triggered-by-connected-user.test.ts +0 -73
- package/src/utils/state-update-queue.test.ts +0 -129
- package/src/utils/unique-array-merge.test.ts +0 -179
|
@@ -11,7 +11,11 @@ import type {
|
|
|
11
11
|
OwnUser,
|
|
12
12
|
OwnUserResponse,
|
|
13
13
|
PinActivityResponse,
|
|
14
|
-
UserResponse,
|
|
14
|
+
UserResponse,
|
|
15
|
+
UserResponseCommonFields,
|
|
16
|
+
NotificationFeedUpdatedEvent,
|
|
17
|
+
NotificationStatusResponse,
|
|
18
|
+
AggregatedActivityResponse,
|
|
15
19
|
} from '../gen/models';
|
|
16
20
|
import { humanId } from 'human-id';
|
|
17
21
|
import type { EventPayload } from '../types-internal';
|
|
@@ -667,3 +671,35 @@ export function generateActivityPinnedEvent(
|
|
|
667
671
|
user,
|
|
668
672
|
};
|
|
669
673
|
}
|
|
674
|
+
|
|
675
|
+
export const createMockNotificationFeedUpdatedEvent = (
|
|
676
|
+
overrides: Partial<NotificationFeedUpdatedEvent> = {},
|
|
677
|
+
): NotificationFeedUpdatedEvent => ({
|
|
678
|
+
created_at: new Date(),
|
|
679
|
+
fid: 'user:notification',
|
|
680
|
+
custom: {},
|
|
681
|
+
type: 'feeds.notification_feed.updated',
|
|
682
|
+
...overrides,
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
export const createMockNotificationStatus = (
|
|
686
|
+
overrides: Partial<NotificationStatusResponse> = {},
|
|
687
|
+
): NotificationStatusResponse => ({
|
|
688
|
+
unread: 0,
|
|
689
|
+
unseen: 0,
|
|
690
|
+
...overrides,
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
export const createMockAggregatedActivity = (
|
|
694
|
+
overrides: Partial<AggregatedActivityResponse> = {},
|
|
695
|
+
): AggregatedActivityResponse => ({
|
|
696
|
+
activity_count: 1,
|
|
697
|
+
created_at: new Date(),
|
|
698
|
+
group: 'test-group',
|
|
699
|
+
user_count_truncated: false,
|
|
700
|
+
score: 1,
|
|
701
|
+
updated_at: new Date(),
|
|
702
|
+
user_count: 1,
|
|
703
|
+
activities: [],
|
|
704
|
+
...overrides,
|
|
705
|
+
});
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
export type ThrottledCallback = (...args: unknown[]) => unknown;
|
|
2
|
+
|
|
3
|
+
export type ThrottledFunction<T extends unknown[]> = (...args: T) => void;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Throttle a function so it runs at most once per `timeout` ms.
|
|
7
|
+
*
|
|
8
|
+
* - `leading`: fire immediately when the window opens
|
|
9
|
+
* - `trailing`: remember the latest args/this and fire once when the window closes
|
|
10
|
+
*
|
|
11
|
+
* defaults: `{ leading: true, trailing: false }`
|
|
12
|
+
*
|
|
13
|
+
* notes:
|
|
14
|
+
* - make one throttled instance and reuse it; re-creating it resets internal state
|
|
15
|
+
*
|
|
16
|
+
* @typeParam T - the function type being throttled
|
|
17
|
+
* @param fn - function to throttle
|
|
18
|
+
* @param timeout - minimum time between invocations (ms)
|
|
19
|
+
* @param options - behavior switches
|
|
20
|
+
* @param options.leading - call on the leading edge (default: true)
|
|
21
|
+
* @param options.trailing - call once at the end of the window with the latest args (default: false)
|
|
22
|
+
* @returns a throttled function with the same call signature as `fn`
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const send = (payload: Data) => api.post('/endpoint', payload);
|
|
26
|
+
* const sendThrottled = throttle(send, 2000, { leading: true, trailing: true });
|
|
27
|
+
* // call `sendThrottled` freely; it won’t invoke `send` more than once every 2s
|
|
28
|
+
*/
|
|
29
|
+
export const throttle = <T extends unknown[]>(
|
|
30
|
+
fn: (...args: T) => void,
|
|
31
|
+
timeout = 200,
|
|
32
|
+
{
|
|
33
|
+
leading = true,
|
|
34
|
+
trailing = false,
|
|
35
|
+
}: { leading?: boolean; trailing?: boolean } = {},
|
|
36
|
+
) => {
|
|
37
|
+
let timer: NodeJS.Timeout | null = null;
|
|
38
|
+
let storedArgs: T | null = null;
|
|
39
|
+
let storedThis: unknown = null;
|
|
40
|
+
let lastInvokeTime: number | undefined; // timestamp of last actual invocation
|
|
41
|
+
|
|
42
|
+
const invoke = (args: T, thisArg: unknown) => {
|
|
43
|
+
lastInvokeTime = Date.now();
|
|
44
|
+
fn.apply(thisArg, args);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const scheduleTrailing = (delay: number) => {
|
|
48
|
+
if (timer) return;
|
|
49
|
+
timer = setTimeout(() => {
|
|
50
|
+
timer = null;
|
|
51
|
+
if (trailing && storedArgs) {
|
|
52
|
+
invoke(storedArgs, storedThis);
|
|
53
|
+
storedArgs = null;
|
|
54
|
+
storedThis = null;
|
|
55
|
+
}
|
|
56
|
+
}, delay);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
throttledFn: function (this: unknown, ...args: T) {
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
|
|
63
|
+
const hasBeenInvoked = lastInvokeTime != null;
|
|
64
|
+
|
|
65
|
+
// if we have never invoked and `leading` is `false`, treat `lastInvokeTime` as now
|
|
66
|
+
if (!hasBeenInvoked && !leading) lastInvokeTime = now;
|
|
67
|
+
|
|
68
|
+
const timeSinceLast = hasBeenInvoked ? now - lastInvokeTime! : timeout;
|
|
69
|
+
const remaining = timeout - timeSinceLast;
|
|
70
|
+
|
|
71
|
+
// capture latest args for possible trailing invocation
|
|
72
|
+
if (trailing) {
|
|
73
|
+
storedArgs = args;
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
75
|
+
storedThis = this;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// if enough time has passed, invoke immediately
|
|
79
|
+
if (remaining <= 0) {
|
|
80
|
+
// if there's a pending timer, clear it because we're invoking now
|
|
81
|
+
if (timer) {
|
|
82
|
+
clearTimeout(timer);
|
|
83
|
+
timer = null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// leading: call now
|
|
87
|
+
if (leading) {
|
|
88
|
+
// if trailing is also `true`, we've already stored args above;
|
|
89
|
+
// make sure we don't call the same args twice
|
|
90
|
+
if (trailing) {
|
|
91
|
+
// if the `storedArgs` are exactly the args we're about to call,
|
|
92
|
+
// clear storedArgs to avoid double invocation by trailing (comparing
|
|
93
|
+
// by reference is fine because the `args` array is new each call)
|
|
94
|
+
if (storedArgs === args) {
|
|
95
|
+
storedArgs = null;
|
|
96
|
+
storedThis = null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
invoke(args, this);
|
|
100
|
+
} else {
|
|
101
|
+
// not leading but trailing: schedule a trailing call after `timeout`
|
|
102
|
+
if (trailing) scheduleTrailing(timeout);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// not enough time passed: we're in cooldown, so if
|
|
109
|
+
// trailing is requested, ensure a trailing invocation
|
|
110
|
+
// is scheduled at the end of the remaining time
|
|
111
|
+
if (trailing && !timer) {
|
|
112
|
+
scheduleTrailing(remaining);
|
|
113
|
+
}
|
|
114
|
+
// if `trailing` is `false`, we simply drop the call (throttle)
|
|
115
|
+
},
|
|
116
|
+
cancelTimer: () => {
|
|
117
|
+
if (timer) {
|
|
118
|
+
clearTimeout(timer);
|
|
119
|
+
timer = null;
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { FeedsClient } from '@self';
|
|
2
|
+
import type { ThrottledFunction } from './throttle';
|
|
3
|
+
|
|
4
|
+
export type GetBatchedOwnCapabilities = {
|
|
5
|
+
feeds: string[];
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type GetBatchedOwnCapabilitiesThrottledCallback = [
|
|
9
|
+
feeds: string[],
|
|
10
|
+
callback: (feedsToClear: string[]) => void | Promise<void>,
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
export type ThrottledGetBatchedOwnCapabilities =
|
|
14
|
+
ThrottledFunction<GetBatchedOwnCapabilitiesThrottledCallback>;
|
|
15
|
+
|
|
16
|
+
export const DEFAULT_BATCH_OWN_CAPABILITIES_THROTTLING_INTERVAL = 2000;
|
|
17
|
+
|
|
18
|
+
const queuedFeeds: Set<string> = new Set();
|
|
19
|
+
|
|
20
|
+
export function queueBatchedOwnCapabilities(
|
|
21
|
+
this: FeedsClient,
|
|
22
|
+
{ feeds }: GetBatchedOwnCapabilities,
|
|
23
|
+
) {
|
|
24
|
+
for (const feed of feeds) {
|
|
25
|
+
queuedFeeds.add(feed);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (queuedFeeds.size > 0) {
|
|
29
|
+
this.throttledGetBatchOwnCapabilities(
|
|
30
|
+
[...queuedFeeds],
|
|
31
|
+
(feedsToClear: string[]) => {
|
|
32
|
+
for (const feed of feedsToClear) {
|
|
33
|
+
queuedFeeds.delete(feed);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function clearQueuedFeeds() {
|
|
41
|
+
queuedFeeds.clear();
|
|
42
|
+
}
|