@stream-io/feeds-client 0.3.7 → 0.3.9
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 +76 -14
- package/dist/cjs/react-bindings.js.map +1 -1
- package/dist/es/index.mjs +3 -2
- package/dist/es/react-bindings.mjs +76 -14
- package/dist/es/react-bindings.mjs.map +1 -1
- package/dist/{feeds-client-3aXF89xy.mjs → feeds-client-CI-WG0y0.mjs} +280 -52
- package/dist/feeds-client-CI-WG0y0.mjs.map +1 -0
- package/dist/{feeds-client-DLiLkrA0.js → feeds-client-DvR7ZYd1.js} +280 -52
- package/dist/feeds-client-DvR7ZYd1.js.map +1 -0
- package/dist/types/activity-with-state-updates/activity-with-state-updates.d.ts +49 -0
- package/dist/types/activity-with-state-updates/activity-with-state-updates.d.ts.map +1 -0
- package/dist/types/activity-with-state-updates/get-feed.d.ts +3 -0
- package/dist/types/activity-with-state-updates/get-feed.d.ts.map +1 -0
- 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/useActivityComments.d.ts +32 -0
- package/dist/types/bindings/react/hooks/feed-state-hooks/useActivityComments.d.ts.map +1 -0
- package/dist/types/bindings/react/hooks/feed-state-hooks/useComments.d.ts +4 -0
- package/dist/types/bindings/react/hooks/feed-state-hooks/useComments.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/useCreateFeedsClient.d.ts.map +1 -1
- package/dist/types/common/real-time/event-models.d.ts +1 -0
- package/dist/types/common/real-time/event-models.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 +1 -1
- package/dist/types/feed/feed.d.ts.map +1 -1
- package/dist/types/feeds-client/active-activity.d.ts +8 -0
- package/dist/types/feeds-client/active-activity.d.ts.map +1 -0
- package/dist/types/feeds-client/feeds-client.d.ts +36 -3
- package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/activity-with-state-updates/activity-with-state-updates.ts +190 -0
- package/src/activity-with-state-updates/get-feed.ts +5 -0
- package/src/bindings/react/hooks/feed-state-hooks/index.ts +1 -0
- package/src/bindings/react/hooks/feed-state-hooks/useActivityComments.ts +113 -0
- package/src/bindings/react/hooks/feed-state-hooks/useComments.ts +4 -0
- package/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts +12 -9
- package/src/bindings/react/hooks/useCreateFeedsClient.ts +0 -6
- package/src/common/real-time/event-models.ts +5 -1
- package/src/feed/event-handlers/activity/handle-activity-updated.ts +11 -0
- package/src/feed/feed.ts +16 -6
- package/src/feeds-client/active-activity.ts +42 -0
- package/src/feeds-client/feeds-client.ts +162 -53
- package/src/index.ts +1 -0
- package/src/test-utils/response-generators.ts +1 -0
- package/src/types.ts +8 -10
- package/dist/feeds-client-3aXF89xy.mjs.map +0 -1
- package/dist/feeds-client-DLiLkrA0.js.map +0 -1
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
type ActivityResponse,
|
|
4
|
+
type CommentResponse,
|
|
5
|
+
type Feed,
|
|
6
|
+
type FeedState,
|
|
7
|
+
checkHasAnotherPage,
|
|
8
|
+
type ActivityWithStateUpdates,
|
|
9
|
+
type ActivityState,
|
|
10
|
+
type StateStore,
|
|
11
|
+
} from '@self';
|
|
12
|
+
import { useFeedContext } from '../../contexts/StreamFeedContext';
|
|
13
|
+
import { useStateStore } from '@stream-io/state-store/react-bindings';
|
|
14
|
+
|
|
15
|
+
const canLoadComments = (
|
|
16
|
+
feedOrActivity: Feed | ActivityResponse | ActivityWithStateUpdates,
|
|
17
|
+
): feedOrActivity is ActivityWithStateUpdates | Feed => {
|
|
18
|
+
return (
|
|
19
|
+
'loadNextPageCommentReplies' in feedOrActivity &&
|
|
20
|
+
'loadNextPageActivityComments' in feedOrActivity
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type UseCommentsReturnType<T extends ActivityResponse | CommentResponse> = {
|
|
25
|
+
comments: NonNullable<
|
|
26
|
+
FeedState['comments_by_entity_id'][T['id']]
|
|
27
|
+
>['comments'];
|
|
28
|
+
comments_pagination: NonNullable<
|
|
29
|
+
FeedState['comments_by_entity_id'][T['id']]
|
|
30
|
+
>['pagination'];
|
|
31
|
+
has_next_page: boolean;
|
|
32
|
+
is_loading_next_page: boolean;
|
|
33
|
+
loadNextPage: (
|
|
34
|
+
request?: T extends CommentResponse
|
|
35
|
+
? Parameters<Feed['loadNextPageCommentReplies']>[1]
|
|
36
|
+
: Parameters<Feed['loadNextPageActivityComments']>[1],
|
|
37
|
+
) => Promise<void>;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export function useActivityComments({
|
|
41
|
+
feed: feedFromProps,
|
|
42
|
+
parentComment,
|
|
43
|
+
activity,
|
|
44
|
+
}: {
|
|
45
|
+
feed?: Feed;
|
|
46
|
+
parentComment?: CommentResponse;
|
|
47
|
+
activity?: ActivityResponse | ActivityWithStateUpdates;
|
|
48
|
+
}) {
|
|
49
|
+
const feedFromContext = useFeedContext();
|
|
50
|
+
const feed = feedFromProps ?? feedFromContext;
|
|
51
|
+
const feedOrActivity = feed ?? activity;
|
|
52
|
+
|
|
53
|
+
if (!feedOrActivity) {
|
|
54
|
+
throw new Error('Feed or activity is required');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!canLoadComments(feedOrActivity)) {
|
|
58
|
+
throw new Error('Feed or activity does not support loading comments');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!(activity || parentComment)) {
|
|
62
|
+
throw new Error('Activity or parent comment is required');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const entityId = parentComment?.id ?? activity?.id ?? '';
|
|
66
|
+
const selector = useCallback(
|
|
67
|
+
(state: FeedState | ActivityState) => ({
|
|
68
|
+
comments: state.comments_by_entity_id?.[entityId]?.comments,
|
|
69
|
+
comments_pagination: state.comments_by_entity_id?.[entityId]?.pagination,
|
|
70
|
+
}),
|
|
71
|
+
[entityId],
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const data = useStateStore(
|
|
75
|
+
feedOrActivity.state as StateStore<FeedState | ActivityState>,
|
|
76
|
+
selector,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const loadNextPage = useCallback<
|
|
80
|
+
UseCommentsReturnType<ActivityResponse | CommentResponse>['loadNextPage']
|
|
81
|
+
>(
|
|
82
|
+
(request) => {
|
|
83
|
+
if (parentComment) {
|
|
84
|
+
return feedOrActivity.loadNextPageCommentReplies(
|
|
85
|
+
parentComment,
|
|
86
|
+
request,
|
|
87
|
+
);
|
|
88
|
+
} else {
|
|
89
|
+
if (activity && canLoadComments(activity)) {
|
|
90
|
+
return activity.loadNextPageActivityComments(request);
|
|
91
|
+
} else if (feed) {
|
|
92
|
+
return feed.loadNextPageActivityComments(activity?.id ?? '', request);
|
|
93
|
+
} else {
|
|
94
|
+
throw new Error('Activity or feed is required');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
[feedOrActivity, feed, parentComment, activity],
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
return useMemo(() => {
|
|
102
|
+
return {
|
|
103
|
+
...data,
|
|
104
|
+
has_next_page: checkHasAnotherPage(
|
|
105
|
+
data.comments,
|
|
106
|
+
data.comments_pagination?.next,
|
|
107
|
+
),
|
|
108
|
+
is_loading_next_page:
|
|
109
|
+
data?.comments_pagination?.loading_next_page ?? false,
|
|
110
|
+
loadNextPage,
|
|
111
|
+
};
|
|
112
|
+
}, [data, loadNextPage]);
|
|
113
|
+
}
|
|
@@ -27,6 +27,10 @@ type UseCommentsReturnType<T extends ActivityResponse | CommentResponse> = {
|
|
|
27
27
|
) => Promise<void>;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Use `useActivityComments` instead.
|
|
32
|
+
* @param
|
|
33
|
+
*/
|
|
30
34
|
export function useComments<T extends CommentParent>(_: {
|
|
31
35
|
feed: Feed;
|
|
32
36
|
parent: T;
|
|
@@ -12,16 +12,19 @@ export const useOwnCapabilities = (feedFromProps?: Feed) => {
|
|
|
12
12
|
const feed = feedFromProps ?? feedFromContext;
|
|
13
13
|
const fid = feed?.feed;
|
|
14
14
|
|
|
15
|
-
const selector = useCallback(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const selector = useCallback(
|
|
16
|
+
(currentState: FeedsClientState) => {
|
|
17
|
+
if (!fid) {
|
|
18
|
+
return { feedOwnCapabilities: stableEmptyArray };
|
|
19
|
+
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
return {
|
|
22
|
+
feedOwnCapabilities:
|
|
23
|
+
currentState.own_capabilities_by_fid[fid] ?? stableEmptyArray,
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
[fid],
|
|
27
|
+
);
|
|
25
28
|
|
|
26
29
|
const { feedOwnCapabilities = stableEmptyArray } =
|
|
27
30
|
useStateStore(client?.state, selector) ?? {};
|
|
@@ -43,7 +43,6 @@ export const useCreateFeedsClient = ({
|
|
|
43
43
|
.connectUser(cachedUserData, tokenOrProvider)
|
|
44
44
|
.then(() => {
|
|
45
45
|
setError(null);
|
|
46
|
-
console.log('Successfully connected user: ', cachedUserData.id);
|
|
47
46
|
})
|
|
48
47
|
.catch((err) => {
|
|
49
48
|
setError(err);
|
|
@@ -60,11 +59,6 @@ export const useCreateFeedsClient = ({
|
|
|
60
59
|
})
|
|
61
60
|
.catch((err) => {
|
|
62
61
|
setError(err);
|
|
63
|
-
})
|
|
64
|
-
.then(() => {
|
|
65
|
-
console.log(
|
|
66
|
-
`Connection for user "${cachedUserData.id}" has been closed`,
|
|
67
|
-
);
|
|
68
62
|
});
|
|
69
63
|
};
|
|
70
64
|
}, [apiKey, cachedUserData, cachedOptions, tokenOrProvider]);
|
|
@@ -43,7 +43,11 @@ export enum UnhandledErrorType {
|
|
|
43
43
|
FetchingOwnCapabilitiesOnNewActivity = 'fetching-own-capabilities-on-new-activity',
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
export type SyncFailure = {
|
|
46
|
+
export type SyncFailure = {
|
|
47
|
+
feed: string;
|
|
48
|
+
reason: unknown;
|
|
49
|
+
activity_id?: string;
|
|
50
|
+
};
|
|
47
51
|
|
|
48
52
|
export type UnhandledErrorEvent = {
|
|
49
53
|
type: 'errors.unhandled';
|
|
@@ -82,6 +82,17 @@ export function handleActivityUpdated(
|
|
|
82
82
|
pinned_activities: currentPinnedActivities,
|
|
83
83
|
} = this.currentState;
|
|
84
84
|
|
|
85
|
+
const currentActivity = currentActivities?.find(
|
|
86
|
+
(a) => a.id === payload.activity.id,
|
|
87
|
+
);
|
|
88
|
+
if (
|
|
89
|
+
!payload.activity.current_feed &&
|
|
90
|
+
payload.activity.feeds.length === 1 &&
|
|
91
|
+
currentActivity?.current_feed
|
|
92
|
+
) {
|
|
93
|
+
payload.activity.current_feed = currentActivity.current_feed;
|
|
94
|
+
}
|
|
95
|
+
|
|
85
96
|
const [result1, result2] = [
|
|
86
97
|
this.hasActivity(payload.activity.id)
|
|
87
98
|
? updateActivityInState(payload, currentActivities)
|
package/src/feed/feed.ts
CHANGED
|
@@ -59,7 +59,12 @@ import type {
|
|
|
59
59
|
LoadingStates,
|
|
60
60
|
PagerResponseWithLoadingStates,
|
|
61
61
|
} from '../types';
|
|
62
|
-
import {
|
|
62
|
+
import {
|
|
63
|
+
checkHasAnotherPage,
|
|
64
|
+
Constants,
|
|
65
|
+
feedsLoggerSystem,
|
|
66
|
+
uniqueArrayMerge,
|
|
67
|
+
} from '../utils';
|
|
63
68
|
import { handleActivityFeedback } from './event-handlers/activity/handle-activity-feedback';
|
|
64
69
|
import { deepEqual } from '../utils/deep-equal';
|
|
65
70
|
|
|
@@ -595,13 +600,15 @@ export class Feed extends FeedApi {
|
|
|
595
600
|
}
|
|
596
601
|
|
|
597
602
|
public async loadNextPageActivityComments(
|
|
598
|
-
activity: ActivityResponse,
|
|
603
|
+
activity: ActivityResponse | string,
|
|
599
604
|
request?: Partial<
|
|
600
605
|
Omit<GetCommentsRequest, 'object_id' | 'object_type' | 'next'>
|
|
601
606
|
>,
|
|
602
607
|
) {
|
|
603
608
|
const currentEntityState =
|
|
604
|
-
this.currentState.comments_by_entity_id[
|
|
609
|
+
this.currentState.comments_by_entity_id[
|
|
610
|
+
typeof activity === 'string' ? activity : activity.id
|
|
611
|
+
];
|
|
605
612
|
const currentPagination = currentEntityState?.pagination;
|
|
606
613
|
const currentNextCursor = currentPagination?.next;
|
|
607
614
|
const currentSort = currentPagination?.sort;
|
|
@@ -617,13 +624,14 @@ export class Feed extends FeedApi {
|
|
|
617
624
|
return;
|
|
618
625
|
}
|
|
619
626
|
|
|
627
|
+
const entityId = typeof activity === 'string' ? activity : activity.id;
|
|
620
628
|
await this.loadNextPageComments({
|
|
621
|
-
entityId:
|
|
629
|
+
entityId: entityId,
|
|
622
630
|
base: () =>
|
|
623
631
|
this.client.getComments({
|
|
624
632
|
...request,
|
|
625
633
|
sort,
|
|
626
|
-
object_id:
|
|
634
|
+
object_id: entityId,
|
|
627
635
|
object_type: 'activity',
|
|
628
636
|
next: currentNextCursor,
|
|
629
637
|
}),
|
|
@@ -929,7 +937,9 @@ export class Feed extends FeedApi {
|
|
|
929
937
|
}
|
|
930
938
|
|
|
931
939
|
if (typeof eventHandler === 'undefined') {
|
|
932
|
-
|
|
940
|
+
feedsLoggerSystem
|
|
941
|
+
.getLogger('event-dispatcher')
|
|
942
|
+
.warn(`Received unknown feed event, type: ${event.type}`, event);
|
|
933
943
|
}
|
|
934
944
|
|
|
935
945
|
this.eventDispatcher.dispatch(event);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Feed } from '../feed';
|
|
2
|
+
import type { FeedsClient } from './feeds-client';
|
|
3
|
+
|
|
4
|
+
export function connectActivityToFeed(
|
|
5
|
+
this: FeedsClient,
|
|
6
|
+
{
|
|
7
|
+
fid,
|
|
8
|
+
}: {
|
|
9
|
+
fid: string;
|
|
10
|
+
},
|
|
11
|
+
) {
|
|
12
|
+
const [group, id] = fid.split(':');
|
|
13
|
+
const activeFeed = this.activeFeeds[fid];
|
|
14
|
+
|
|
15
|
+
const feed = new Feed(
|
|
16
|
+
this,
|
|
17
|
+
group,
|
|
18
|
+
id,
|
|
19
|
+
undefined,
|
|
20
|
+
activeFeed?.currentState.watch,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
return feed;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function isAnyFeedWatched(this: FeedsClient, fids: string[]) {
|
|
27
|
+
for (const fid of fids) {
|
|
28
|
+
const feed = this.activeFeeds[fid];
|
|
29
|
+
if (feed && feed.currentState.last_get_or_create_request_config?.watch) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function disconnectActivityFromFeed(this: FeedsClient, id: string) {
|
|
38
|
+
const activeFeed = this.activeActivities[id];
|
|
39
|
+
if (activeFeed) {
|
|
40
|
+
delete this.activeActivities[id];
|
|
41
|
+
}
|
|
42
|
+
}
|