@stream-io/feeds-client 0.3.16 → 0.3.18

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 (41) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +27 -0
  3. package/dist/cjs/index.js +1 -1
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/react-bindings.js +5 -11
  6. package/dist/cjs/react-bindings.js.map +1 -1
  7. package/dist/es/index.mjs +2 -2
  8. package/dist/es/index.mjs.map +1 -1
  9. package/dist/es/react-bindings.mjs +5 -11
  10. package/dist/es/react-bindings.mjs.map +1 -1
  11. package/dist/{feeds-client-B6L006tr.js → feeds-client-Be5gS8Xx.js} +154 -139
  12. package/dist/feeds-client-Be5gS8Xx.js.map +1 -0
  13. package/dist/{feeds-client-Bh01VLai.mjs → feeds-client-DT_p8LU4.mjs} +154 -139
  14. package/dist/feeds-client-DT_p8LU4.mjs.map +1 -0
  15. package/dist/types/bindings/react/hooks/useCreateFeedsClient.d.ts +3 -3
  16. package/dist/types/bindings/react/hooks/useCreateFeedsClient.d.ts.map +1 -1
  17. package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -1
  18. package/dist/types/feed/event-handlers/activity-updater.d.ts.map +1 -1
  19. package/dist/types/feed/event-handlers/bookmark/handle-bookmark-added.d.ts.map +1 -1
  20. package/dist/types/feed/event-handlers/bookmark/handle-bookmark-deleted.d.ts.map +1 -1
  21. package/dist/types/feed/feed.d.ts.map +1 -1
  22. package/dist/types/feeds-client/feeds-client.d.ts +16 -8
  23. package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
  24. package/dist/types/gen/feeds/FeedsApi.d.ts +6 -4
  25. package/dist/types/gen/feeds/FeedsApi.d.ts.map +1 -1
  26. package/dist/types/gen/models/index.d.ts +26 -7
  27. package/dist/types/gen/models/index.d.ts.map +1 -1
  28. package/package.json +1 -1
  29. package/src/bindings/react/hooks/useCreateFeedsClient.ts +12 -23
  30. package/src/feed/event-handlers/activity/handle-activity-updated.ts +0 -11
  31. package/src/feed/event-handlers/activity-updater.ts +0 -8
  32. package/src/feed/event-handlers/bookmark/handle-bookmark-added.ts +2 -10
  33. package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.ts +2 -10
  34. package/src/feed/event-handlers/bookmark/handle-bookmark-updated.ts +2 -2
  35. package/src/feed/feed.ts +28 -0
  36. package/src/feeds-client/feeds-client.ts +52 -45
  37. package/src/gen/feeds/FeedsApi.ts +60 -11
  38. package/src/gen/model-decoders/decoders.ts +26 -78
  39. package/src/gen/models/index.ts +39 -9
  40. package/dist/feeds-client-B6L006tr.js.map +0 -1
  41. package/dist/feeds-client-Bh01VLai.mjs.map +0 -1
@@ -38,18 +38,10 @@ const sharedUpdateActivity = ({
38
38
  );
39
39
  }
40
40
 
41
- if (
42
- !event.bookmark.activity.current_feed &&
43
- event.bookmark.activity.feeds.length === 1 &&
44
- currentActivity.current_feed
45
- ) {
46
- event.bookmark.activity.current_feed = currentActivity.current_feed;
47
- }
48
-
49
41
  return {
50
- ...event.bookmark.activity,
42
+ ...currentActivity,
43
+ bookmark_count: event.bookmark.activity.bookmark_count,
51
44
  own_bookmarks: newOwnBookmarks,
52
- own_reactions: currentActivity.own_reactions,
53
45
  };
54
46
  };
55
47
 
@@ -32,9 +32,9 @@ const sharedUpdateActivity = ({
32
32
  }
33
33
 
34
34
  return {
35
- ...event.bookmark.activity,
35
+ ...currentActivity,
36
+ bookmark_count: event.bookmark.activity.bookmark_count,
36
37
  own_bookmarks: newOwnBookmarks,
37
- own_reactions: currentActivity.own_reactions,
38
38
  };
39
39
  };
40
40
 
package/src/feed/feed.ts CHANGED
@@ -932,6 +932,34 @@ export class Feed extends FeedApi {
932
932
 
933
933
  // no need to run noop function
934
934
  if (eventHandler !== Feed.noop) {
935
+ if ('activity' in event && this.hasActivity(event.activity.id)) {
936
+ const currentActivity = this.currentState.activities?.find(
937
+ (a) => a.id === event.activity.id,
938
+ );
939
+
940
+ // Backfill current_feed if activity is posted to multiple feeds
941
+ if (
942
+ event.activity.feeds.length > 1 &&
943
+ !event.activity.current_feed &&
944
+ currentActivity?.current_feed
945
+ ) {
946
+ event.activity.current_feed = currentActivity.current_feed;
947
+ }
948
+
949
+ // Backfill own_ fields if activity is posted to a single feed
950
+ if (
951
+ event.activity.feeds.length === 1 &&
952
+ event.activity.current_feed &&
953
+ currentActivity?.current_feed
954
+ ) {
955
+ event.activity.current_feed.own_capabilities =
956
+ currentActivity.current_feed.own_capabilities;
957
+ event.activity.current_feed.own_follows =
958
+ currentActivity.current_feed.own_follows;
959
+ event.activity.current_feed.own_membership =
960
+ currentActivity.current_feed.own_membership;
961
+ }
962
+ }
935
963
  // @ts-expect-error intersection of handler arguments results to never
936
964
  eventHandler?.(event);
937
965
  }
@@ -14,13 +14,15 @@ import type {
14
14
  FileUploadRequest,
15
15
  FollowBatchRequest,
16
16
  FollowRequest,
17
+ FollowResponse,
17
18
  GetOrCreateFeedRequest,
18
19
  ImageUploadRequest,
19
- OwnCapabilitiesBatchRequest,
20
+ OwnBatchRequest,
20
21
  PollResponse,
21
22
  PollVotesResponse,
22
23
  QueryFeedsRequest,
23
24
  QueryPollVotesRequest,
25
+ UnfollowBatchRequest,
24
26
  UpdateActivityRequest,
25
27
  UpdateActivityResponse,
26
28
  UpdateCommentRequest,
@@ -93,7 +95,6 @@ import { getFeed } from '../activity-with-state-updates/get-feed';
93
95
 
94
96
  export type FeedsClientState = {
95
97
  connected_user: ConnectedUser | undefined;
96
- is_anonymous: boolean;
97
98
  is_ws_connection_healthy: boolean;
98
99
  own_capabilities_by_fid: Record<string, FeedResponse['own_capabilities']>;
99
100
  };
@@ -137,7 +138,6 @@ export class FeedsClient extends FeedsApi {
137
138
  super(apiClient);
138
139
  this.state = new StateStore<FeedsClientState>({
139
140
  connected_user: undefined,
140
- is_anonymous: false,
141
141
  is_ws_connection_healthy: false,
142
142
  own_capabilities_by_fid: {},
143
143
  });
@@ -286,7 +286,7 @@ export class FeedsClient extends FeedsApi {
286
286
  cancelTimer: cancel,
287
287
  } = throttle<GetBatchedOwnCapabilitiesThrottledCallback>(
288
288
  (feeds, callback) => {
289
- this.ownCapabilitiesBatch({
289
+ this.ownBatch({
290
290
  feeds,
291
291
  }).catch((error) => {
292
292
  this.eventDispatcher.dispatch({
@@ -393,25 +393,7 @@ export class FeedsClient extends FeedsApi {
393
393
  this.state.partialNext({ own_capabilities_by_fid: ownCapabilitiesCache });
394
394
  }
395
395
 
396
- connectAnonymous = () => {
397
- this.connectionIdManager.resolveConnectionidPromise();
398
- this.tokenManager.setTokenOrProvider(undefined);
399
- this.setGetBatchOwnCapabilitiesThrottlingInterval(
400
- this.query_batch_own_capabilties_throttling_interval,
401
- );
402
- this.state.partialNext({
403
- connected_user: undefined,
404
- is_anonymous: true,
405
- is_ws_connection_healthy: false,
406
- });
407
-
408
- return Promise.resolve();
409
- };
410
-
411
- connectUser = async (
412
- user: UserRequest | { id: '!anon' },
413
- tokenProvider?: TokenOrProvider,
414
- ) => {
396
+ connectUser = async (user: UserRequest, tokenProvider?: TokenOrProvider) => {
415
397
  if (
416
398
  this.state.getLatestValue().connected_user !== undefined ||
417
399
  this.wsConnection
@@ -745,12 +727,12 @@ export class FeedsClient extends FeedsApi {
745
727
  };
746
728
  }
747
729
 
748
- async ownCapabilitiesBatch(request: OwnCapabilitiesBatchRequest) {
749
- const response = await super.ownCapabilitiesBatch(request);
750
- const feedResponses = Object.entries(response.capabilities).map(
751
- ([feed, own_capabilities]) => ({
730
+ async ownBatch(request: OwnBatchRequest) {
731
+ const response = await super.ownBatch(request);
732
+ const feedResponses = Object.entries(response.data).map(
733
+ ([feed, ownFields]) => ({
752
734
  feed,
753
- own_capabilities,
735
+ own_capabilities: ownFields.own_capabilities,
754
736
  }),
755
737
  );
756
738
  this.hydrateCapabilitiesCache(feedResponses);
@@ -784,36 +766,41 @@ export class FeedsClient extends FeedsApi {
784
766
  // For follow API endpoints we update the state after HTTP response to allow queryFeeds with watch: false
785
767
  async follow(request: FollowRequest) {
786
768
  const response = await super.follow(request);
787
-
788
- [
789
- response.follow.source_feed.feed,
790
- response.follow.target_feed.feed,
791
- ].forEach((fid) => {
792
- const feeds = this.findAllActiveFeedsByFid(fid);
793
- feeds.forEach((f) => handleFollowCreated.bind(f)(response, false));
794
- });
769
+ this.updateStateFromFollows([response.follow]);
795
770
 
796
771
  return response;
797
772
  }
798
773
 
774
+ /**
775
+ * @deprecated Use getOrCreateFollows instead
776
+ * @param request
777
+ * @returns
778
+ */
799
779
  async followBatch(request: FollowBatchRequest) {
800
780
  const response = await super.followBatch(request);
781
+ this.updateStateFromFollows(response.follows);
801
782
 
802
- response.follows.forEach((follow) => {
803
- const feeds = this.findAllActiveFeedsByFid(follow.source_feed.feed);
804
- feeds.forEach((f) => handleFollowCreated.bind(f)({ follow }, false));
805
- });
783
+ return response;
784
+ }
785
+
786
+ async getOrCreateFollows(request: FollowBatchRequest) {
787
+ const response = await super.getOrCreateFollows(request);
788
+
789
+ this.updateStateFromFollows(response.created);
806
790
 
807
791
  return response;
808
792
  }
809
793
 
810
- async unfollow(request: FollowRequest) {
794
+ async unfollow(request: { source: string; target: string }) {
811
795
  const response = await super.unfollow(request);
796
+ this.updateStateFromUnfollows([response.follow]);
812
797
 
813
- [request.source, request.target].forEach((fid) => {
814
- const feeds = this.findAllActiveFeedsByFid(fid);
815
- feeds.forEach((f) => handleFollowDeleted.bind(f)(response, false));
816
- });
798
+ return response;
799
+ }
800
+
801
+ async getOrCreateUnfollows(request: UnfollowBatchRequest) {
802
+ const response = await super.getOrCreateUnfollows(request);
803
+ this.updateStateFromUnfollows(response.follows);
817
804
 
818
805
  return response;
819
806
  }
@@ -942,4 +929,24 @@ export class FeedsClient extends FeedsApi {
942
929
  .map((a) => getFeed.call(a)!),
943
930
  ];
944
931
  }
932
+
933
+ private updateStateFromFollows(follows: FollowResponse[]) {
934
+ follows.forEach((follow) => {
935
+ const feeds = [
936
+ ...this.findAllActiveFeedsByFid(follow.source_feed.feed),
937
+ ...this.findAllActiveFeedsByFid(follow.target_feed.feed),
938
+ ];
939
+ feeds.forEach((f) => handleFollowCreated.bind(f)({ follow }, false));
940
+ });
941
+ }
942
+
943
+ private updateStateFromUnfollows(follows: FollowResponse[]) {
944
+ follows.forEach((follow) => {
945
+ const feeds = [
946
+ ...this.findAllActiveFeedsByFid(follow.source_feed.feed),
947
+ ...this.findAllActiveFeedsByFid(follow.target_feed.feed),
948
+ ];
949
+ feeds.forEach((f) => handleFollowDeleted.bind(f)({ follow }, false));
950
+ });
951
+ }
945
952
  }
@@ -62,8 +62,8 @@ import type {
62
62
  ListBlockListResponse,
63
63
  ListDevicesResponse,
64
64
  MarkActivityRequest,
65
- OwnCapabilitiesBatchRequest,
66
- OwnCapabilitiesBatchResponse,
65
+ OwnBatchRequest,
66
+ OwnBatchResponse,
67
67
  PinActivityRequest,
68
68
  PinActivityResponse,
69
69
  PollOptionResponse,
@@ -104,6 +104,8 @@ import type {
104
104
  SingleFollowResponse,
105
105
  UnblockUsersRequest,
106
106
  UnblockUsersResponse,
107
+ UnfollowBatchRequest,
108
+ UnfollowBatchResponse,
107
109
  UnfollowResponse,
108
110
  UnpinActivityResponse,
109
111
  UpdateActivityPartialRequest,
@@ -979,14 +981,14 @@ export class FeedsApi {
979
981
  }
980
982
 
981
983
  async addComment(
982
- request: AddCommentRequest,
984
+ request?: AddCommentRequest,
983
985
  ): Promise<StreamResponse<AddCommentResponse>> {
984
986
  const body = {
985
- object_id: request?.object_id,
986
- object_type: request?.object_type,
987
987
  comment: request?.comment,
988
988
  create_notification_activity: request?.create_notification_activity,
989
989
  id: request?.id,
990
+ object_id: request?.object_id,
991
+ object_type: request?.object_type,
990
992
  parent_id: request?.parent_id,
991
993
  skip_enrich_url: request?.skip_enrich_url,
992
994
  skip_push: request?.skip_push,
@@ -1621,28 +1623,29 @@ export class FeedsApi {
1621
1623
  return { ...response.body, metadata: response.metadata };
1622
1624
  }
1623
1625
 
1624
- async ownCapabilitiesBatch(
1625
- request: OwnCapabilitiesBatchRequest & { connection_id?: string },
1626
- ): Promise<StreamResponse<OwnCapabilitiesBatchResponse>> {
1626
+ async ownBatch(
1627
+ request: OwnBatchRequest & { connection_id?: string },
1628
+ ): Promise<StreamResponse<OwnBatchResponse>> {
1627
1629
  const queryParams = {
1628
1630
  connection_id: request?.connection_id,
1629
1631
  };
1630
1632
  const body = {
1631
1633
  feeds: request?.feeds,
1634
+ fields: request?.fields,
1632
1635
  };
1633
1636
 
1634
1637
  const response = await this.apiClient.sendRequest<
1635
- StreamResponse<OwnCapabilitiesBatchResponse>
1638
+ StreamResponse<OwnBatchResponse>
1636
1639
  >(
1637
1640
  'POST',
1638
- '/api/v2/feeds/feeds/own_capabilities/batch',
1641
+ '/api/v2/feeds/feeds/own/batch',
1639
1642
  undefined,
1640
1643
  queryParams,
1641
1644
  body,
1642
1645
  'application/json',
1643
1646
  );
1644
1647
 
1645
- decoders.OwnCapabilitiesBatchResponse?.(response.body);
1648
+ decoders.OwnBatchResponse?.(response.body);
1646
1649
 
1647
1650
  return { ...response.body, metadata: response.metadata };
1648
1651
  }
@@ -1783,6 +1786,29 @@ export class FeedsApi {
1783
1786
  return { ...response.body, metadata: response.metadata };
1784
1787
  }
1785
1788
 
1789
+ async getOrCreateFollows(
1790
+ request: FollowBatchRequest,
1791
+ ): Promise<StreamResponse<FollowBatchResponse>> {
1792
+ const body = {
1793
+ follows: request?.follows,
1794
+ };
1795
+
1796
+ const response = await this.apiClient.sendRequest<
1797
+ StreamResponse<FollowBatchResponse>
1798
+ >(
1799
+ 'POST',
1800
+ '/api/v2/feeds/follows/batch/upsert',
1801
+ undefined,
1802
+ undefined,
1803
+ body,
1804
+ 'application/json',
1805
+ );
1806
+
1807
+ decoders.FollowBatchResponse?.(response.body);
1808
+
1809
+ return { ...response.body, metadata: response.metadata };
1810
+ }
1811
+
1786
1812
  async queryFollows(
1787
1813
  request?: QueryFollowsRequest,
1788
1814
  ): Promise<StreamResponse<QueryFollowsResponse>> {
@@ -1857,6 +1883,29 @@ export class FeedsApi {
1857
1883
  return { ...response.body, metadata: response.metadata };
1858
1884
  }
1859
1885
 
1886
+ async getOrCreateUnfollows(
1887
+ request: UnfollowBatchRequest,
1888
+ ): Promise<StreamResponse<UnfollowBatchResponse>> {
1889
+ const body = {
1890
+ follows: request?.follows,
1891
+ };
1892
+
1893
+ const response = await this.apiClient.sendRequest<
1894
+ StreamResponse<UnfollowBatchResponse>
1895
+ >(
1896
+ 'POST',
1897
+ '/api/v2/feeds/unfollow/batch/upsert',
1898
+ undefined,
1899
+ undefined,
1900
+ body,
1901
+ 'application/json',
1902
+ );
1903
+
1904
+ decoders.UnfollowBatchResponse?.(response.body);
1905
+
1906
+ return { ...response.body, metadata: response.metadata };
1907
+ }
1908
+
1860
1909
  async createGuest(
1861
1910
  request: CreateGuestRequest,
1862
1911
  ): Promise<StreamResponse<CreateGuestResponse>> {