@stream-io/feeds-client 0.3.32 → 0.3.34

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 (58) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +3 -2
  3. package/dist/cjs/index.js +3 -2
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/react-bindings.js +40 -36
  6. package/dist/cjs/react-bindings.js.map +1 -1
  7. package/dist/es/index.mjs +4 -3
  8. package/dist/es/index.mjs.map +1 -1
  9. package/dist/es/react-bindings.mjs +40 -36
  10. package/dist/es/react-bindings.mjs.map +1 -1
  11. package/dist/{feeds-client-BNhvggk2.mjs → feeds-client-C-2_fdH1.mjs} +229 -209
  12. package/dist/feeds-client-C-2_fdH1.mjs.map +1 -0
  13. package/dist/{feeds-client-B9rwEWH3.js → feeds-client-Xj6kDjVH.js} +229 -209
  14. package/dist/feeds-client-Xj6kDjVH.js.map +1 -0
  15. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  16. package/dist/types/activity-with-state-updates/activity-with-state-updates.d.ts +4 -2
  17. package/dist/types/activity-with-state-updates/activity-with-state-updates.d.ts.map +1 -1
  18. package/dist/types/bindings/react/hooks/feed-state-hooks/index.d.ts +1 -0
  19. package/dist/types/bindings/react/hooks/feed-state-hooks/index.d.ts.map +1 -1
  20. package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.d.ts.map +1 -1
  21. package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnFollowings.d.ts +8 -0
  22. package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnFollowings.d.ts.map +1 -0
  23. package/dist/types/bindings/react/hooks/useCreateFeedsClient.d.ts.map +1 -1
  24. package/dist/types/common/types.d.ts +1 -1
  25. package/dist/types/common/types.d.ts.map +1 -1
  26. package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts.map +1 -1
  27. package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -1
  28. package/dist/types/feed/feed.d.ts +2 -1
  29. package/dist/types/feed/feed.d.ts.map +1 -1
  30. package/dist/types/feeds-client/active-activity.d.ts +2 -1
  31. package/dist/types/feeds-client/active-activity.d.ts.map +1 -1
  32. package/dist/types/feeds-client/feeds-client.d.ts +14 -12
  33. package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
  34. package/dist/types/utils/check-own-fields-equality.d.ts +2 -0
  35. package/dist/types/utils/check-own-fields-equality.d.ts.map +1 -1
  36. package/dist/types/utils/throttling/index.d.ts +1 -1
  37. package/dist/types/utils/throttling/index.d.ts.map +1 -1
  38. package/dist/types/utils/throttling/throttled-get-batched-own-fields.d.ts +14 -0
  39. package/dist/types/utils/throttling/throttled-get-batched-own-fields.d.ts.map +1 -0
  40. package/package.json +1 -1
  41. package/src/activity-with-state-updates/activity-with-state-updates.ts +17 -3
  42. package/src/bindings/react/hooks/feed-state-hooks/index.ts +1 -0
  43. package/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts +14 -23
  44. package/src/bindings/react/hooks/feed-state-hooks/useOwnFollowings.ts +18 -0
  45. package/src/bindings/react/hooks/useCreateFeedsClient.ts +1 -3
  46. package/src/common/types.ts +1 -1
  47. package/src/feed/event-handlers/activity/handle-activity-added.ts +0 -6
  48. package/src/feed/event-handlers/activity/handle-activity-updated.ts +0 -4
  49. package/src/feed/feed.ts +53 -39
  50. package/src/feeds-client/active-activity.ts +8 -4
  51. package/src/feeds-client/feeds-client.ts +110 -114
  52. package/src/utils/check-own-fields-equality.ts +37 -10
  53. package/src/utils/throttling/index.ts +1 -1
  54. package/src/utils/throttling/{throttled-get-batched-own-capabilities.ts → throttled-get-batched-own-fields.ts} +10 -10
  55. package/dist/feeds-client-B9rwEWH3.js.map +0 -1
  56. package/dist/feeds-client-BNhvggk2.mjs.map +0 -1
  57. package/dist/types/utils/throttling/throttled-get-batched-own-capabilities.d.ts +0 -14
  58. package/dist/types/utils/throttling/throttled-get-batched-own-capabilities.d.ts.map +0 -1
@@ -3923,7 +3923,7 @@ const getRateLimitFromResponseHeader = (response_headers) => {
3923
3923
  };
3924
3924
  return result;
3925
3925
  };
3926
- const version = "0.3.32";
3926
+ const version = "0.3.34";
3927
3927
  const axios = axiosImport.default ?? axiosImport;
3928
3928
  class ApiClient {
3929
3929
  constructor(apiKey, tokenManager, connectionIdManager, options) {
@@ -4785,7 +4785,6 @@ function updateEntityInArray({
4785
4785
  updatedEntities[index] = newEntity;
4786
4786
  return { changed: true, entities: updatedEntities };
4787
4787
  }
4788
- const ownFeedFields = ["own_capabilities", "own_follows", "own_membership"];
4789
4788
  const updateStateFollowCreated = (follow, currentState, currentFeedId, connectedUserId) => {
4790
4789
  if (follow.status !== "accepted") {
4791
4790
  return { changed: false, data: currentState };
@@ -5536,10 +5535,6 @@ function handleActivityAdded(event) {
5536
5535
  if (result.changed) {
5537
5536
  const activity = event.activity;
5538
5537
  this.client.hydratePollCache([activity]);
5539
- const currentFeed = activity.current_feed;
5540
- if (currentFeed) {
5541
- this.client.hydrateCapabilitiesCache([currentFeed]);
5542
- }
5543
5538
  this.state.partialNext({ activities: result.activities });
5544
5539
  }
5545
5540
  }
@@ -5651,9 +5646,6 @@ function handleActivityUpdated(payload, fromWs) {
5651
5646
  ];
5652
5647
  if (result1?.changed || result2.changed) {
5653
5648
  this.client.hydratePollCache([payload.activity]);
5654
- if (payload.activity.current_feed) {
5655
- this.client.hydrateCapabilitiesCache([payload.activity.current_feed]);
5656
- }
5657
5649
  this.state.partialNext({
5658
5650
  activities: result1?.changed ? result1.entities : currentActivities,
5659
5651
  pinned_activities: result2.entities
@@ -6238,6 +6230,91 @@ const deepEqual = (x, y) => {
6238
6230
  function getOrCreateActiveFeed(...args) {
6239
6231
  return this.getOrCreateActiveFeed(...args);
6240
6232
  }
6233
+ const throttle = (fn, timeout = 200, {
6234
+ leading = true,
6235
+ trailing = false
6236
+ } = {}) => {
6237
+ let timer = null;
6238
+ let storedArgs = null;
6239
+ let storedThis = null;
6240
+ let lastInvokeTime;
6241
+ const invoke = (args, thisArg) => {
6242
+ lastInvokeTime = Date.now();
6243
+ fn.apply(thisArg, args);
6244
+ };
6245
+ const scheduleTrailing = (delay) => {
6246
+ if (timer) return;
6247
+ timer = setTimeout(() => {
6248
+ timer = null;
6249
+ if (trailing && storedArgs) {
6250
+ invoke(storedArgs, storedThis);
6251
+ storedArgs = null;
6252
+ storedThis = null;
6253
+ }
6254
+ }, delay);
6255
+ };
6256
+ return {
6257
+ throttledFn: function(...args) {
6258
+ const now = Date.now();
6259
+ const hasBeenInvoked = lastInvokeTime != null;
6260
+ if (!hasBeenInvoked && !leading) lastInvokeTime = now;
6261
+ const timeSinceLast = hasBeenInvoked ? now - lastInvokeTime : timeout;
6262
+ const remaining = timeout - timeSinceLast;
6263
+ if (trailing) {
6264
+ storedArgs = args;
6265
+ storedThis = this;
6266
+ }
6267
+ if (remaining <= 0) {
6268
+ if (timer) {
6269
+ clearTimeout(timer);
6270
+ timer = null;
6271
+ }
6272
+ if (leading) {
6273
+ if (trailing) {
6274
+ if (storedArgs === args) {
6275
+ storedArgs = null;
6276
+ storedThis = null;
6277
+ }
6278
+ }
6279
+ invoke(args, this);
6280
+ } else {
6281
+ if (trailing) scheduleTrailing(timeout);
6282
+ }
6283
+ return;
6284
+ }
6285
+ if (trailing && !timer) {
6286
+ scheduleTrailing(remaining);
6287
+ }
6288
+ },
6289
+ cancelTimer: () => {
6290
+ if (timer) {
6291
+ clearTimeout(timer);
6292
+ timer = null;
6293
+ }
6294
+ }
6295
+ };
6296
+ };
6297
+ const BATCH_OWN_FIELDS_API_LIMIT = 100;
6298
+ const DEFAULT_BATCH_OWN_FIELDS_THROTTLING_INTERVAL = 2e3;
6299
+ const queuedFeeds = /* @__PURE__ */ new Set();
6300
+ function queueBatchedOwnFields({ feeds }) {
6301
+ for (const feed of feeds) {
6302
+ queuedFeeds.add(feed);
6303
+ }
6304
+ if (queuedFeeds.size > 0) {
6305
+ this.throttledGetBatchOwnFields(
6306
+ [...queuedFeeds].slice(0, BATCH_OWN_FIELDS_API_LIMIT),
6307
+ (feedsToClear) => {
6308
+ for (const feed of feedsToClear) {
6309
+ queuedFeeds.delete(feed);
6310
+ }
6311
+ }
6312
+ );
6313
+ }
6314
+ }
6315
+ function clearQueuedFeeds() {
6316
+ queuedFeeds.clear();
6317
+ }
6241
6318
  const _Feed = class _Feed extends FeedApi {
6242
6319
  constructor(client, groupId, id, data, watch = false, addNewActivitiesTo = "start", activityAddedEventFilter) {
6243
6320
  super(client, groupId, id);
@@ -6372,10 +6449,6 @@ const _Feed = class _Feed extends FeedApi {
6372
6449
  currentActivityFeeds.push(activity.current_feed);
6373
6450
  }
6374
6451
  }
6375
- this.client.hydrateCapabilitiesCache([
6376
- response.feed,
6377
- ...currentActivityFeeds
6378
- ]);
6379
6452
  if (request?.next) {
6380
6453
  const { activities: currentActivities = [] } = this.currentState;
6381
6454
  const result = addActivitiesToState.bind(this)(
@@ -6802,29 +6875,18 @@ const _Feed = class _Feed extends FeedApi {
6802
6875
  ...request,
6803
6876
  feeds: [this.feed]
6804
6877
  });
6805
- const currentFeed = response.activity.current_feed;
6806
- if (currentFeed) {
6807
- this.client.hydrateCapabilitiesCache([currentFeed]);
6808
- }
6809
6878
  return response;
6810
6879
  }
6811
6880
  handleWSEvent(event) {
6812
6881
  const eventHandler = this.eventHandlers[event.type];
6813
6882
  if (eventHandler !== _Feed.noop) {
6814
- if ("activity" in event && this.hasActivity(event.activity.id)) {
6883
+ if ("activity" in event && event.activity.feeds.length > 1 && this.hasActivity(event.activity.id)) {
6815
6884
  const currentActivity = this.currentState.activities?.find(
6816
6885
  (a) => a.id === event.activity.id
6817
6886
  );
6818
- if (event.activity.feeds.length > 1 && !event.activity.current_feed && currentActivity?.current_feed) {
6887
+ if (!event.activity.current_feed && currentActivity?.current_feed) {
6819
6888
  event.activity.current_feed = currentActivity.current_feed;
6820
6889
  }
6821
- if (event.activity.feeds.length === 1 && event.activity.current_feed && currentActivity?.current_feed) {
6822
- ownFeedFields.forEach((field) => {
6823
- if (field in currentActivity.current_feed) {
6824
- event.activity.current_feed[field] = currentActivity.current_feed[field];
6825
- }
6826
- });
6827
- }
6828
6890
  }
6829
6891
  eventHandler?.(event);
6830
6892
  }
@@ -6839,7 +6901,7 @@ const _Feed = class _Feed extends FeedApi {
6839
6901
  }
6840
6902
  getOrCreateFeeds(activities, options) {
6841
6903
  const enrichmentOptions = this.currentState.last_get_or_create_request_config?.enrichment_options;
6842
- if (!enrichmentOptions?.skip_activity_current_feed && !enrichmentOptions?.skip_all) {
6904
+ if (this.shouldAddToActiveFeeds(enrichmentOptions)) {
6843
6905
  const feedsToGetOrCreate = /* @__PURE__ */ new Map();
6844
6906
  activities.forEach((activity) => {
6845
6907
  if (activity.current_feed && !feedsToGetOrCreate.has(activity.current_feed.feed)) {
@@ -6849,16 +6911,47 @@ const _Feed = class _Feed extends FeedApi {
6849
6911
  );
6850
6912
  }
6851
6913
  });
6852
- Array.from(feedsToGetOrCreate.values()).forEach((feed) => {
6914
+ const newFeeds = Array.from(feedsToGetOrCreate.values());
6915
+ const fieldsToUpdate = [];
6916
+ if (!options.fromWebSocket) {
6917
+ fieldsToUpdate.push("own_membership");
6918
+ if (!enrichmentOptions?.skip_own_capabilities) {
6919
+ fieldsToUpdate.push("own_capabilities");
6920
+ }
6921
+ if (!enrichmentOptions?.skip_own_follows) {
6922
+ fieldsToUpdate.push("own_follows");
6923
+ }
6924
+ if (enrichmentOptions?.enrich_own_followings) {
6925
+ fieldsToUpdate.push("own_followings");
6926
+ }
6927
+ }
6928
+ newFeeds.forEach((feed) => {
6853
6929
  getOrCreateActiveFeed.bind(this.client)({
6854
6930
  group: feed.group_id,
6855
6931
  id: feed.id,
6856
6932
  data: feed,
6857
- fromWebSocket: options.fromWebSocket
6933
+ fieldsToUpdate
6858
6934
  });
6859
6935
  });
6936
+ if (options.fromWebSocket) {
6937
+ const uninitializedFeeds = newFeeds.filter((feedResponse) => {
6938
+ const feed = this.client.feed(feedResponse.group_id, feedResponse.id);
6939
+ return feed.currentState.own_capabilities === void 0;
6940
+ });
6941
+ if (uninitializedFeeds.length > 0) {
6942
+ queueBatchedOwnFields.bind(this.client)({
6943
+ feeds: uninitializedFeeds.map((feed) => feed.feed)
6944
+ });
6945
+ }
6946
+ }
6860
6947
  }
6861
6948
  }
6949
+ shouldAddToActiveFeeds(enrichmentOptions) {
6950
+ if (!enrichmentOptions) {
6951
+ return true;
6952
+ }
6953
+ return !enrichmentOptions?.skip_activity && !enrichmentOptions?.skip_activity_current_feed && !enrichmentOptions?.skip_all;
6954
+ }
6862
6955
  };
6863
6956
  _Feed.noop = () => {
6864
6957
  };
@@ -6912,91 +7005,6 @@ function updateCommentCount({
6912
7005
  }, false);
6913
7006
  }
6914
7007
  }
6915
- const throttle = (fn, timeout = 200, {
6916
- leading = true,
6917
- trailing = false
6918
- } = {}) => {
6919
- let timer = null;
6920
- let storedArgs = null;
6921
- let storedThis = null;
6922
- let lastInvokeTime;
6923
- const invoke = (args, thisArg) => {
6924
- lastInvokeTime = Date.now();
6925
- fn.apply(thisArg, args);
6926
- };
6927
- const scheduleTrailing = (delay) => {
6928
- if (timer) return;
6929
- timer = setTimeout(() => {
6930
- timer = null;
6931
- if (trailing && storedArgs) {
6932
- invoke(storedArgs, storedThis);
6933
- storedArgs = null;
6934
- storedThis = null;
6935
- }
6936
- }, delay);
6937
- };
6938
- return {
6939
- throttledFn: function(...args) {
6940
- const now = Date.now();
6941
- const hasBeenInvoked = lastInvokeTime != null;
6942
- if (!hasBeenInvoked && !leading) lastInvokeTime = now;
6943
- const timeSinceLast = hasBeenInvoked ? now - lastInvokeTime : timeout;
6944
- const remaining = timeout - timeSinceLast;
6945
- if (trailing) {
6946
- storedArgs = args;
6947
- storedThis = this;
6948
- }
6949
- if (remaining <= 0) {
6950
- if (timer) {
6951
- clearTimeout(timer);
6952
- timer = null;
6953
- }
6954
- if (leading) {
6955
- if (trailing) {
6956
- if (storedArgs === args) {
6957
- storedArgs = null;
6958
- storedThis = null;
6959
- }
6960
- }
6961
- invoke(args, this);
6962
- } else {
6963
- if (trailing) scheduleTrailing(timeout);
6964
- }
6965
- return;
6966
- }
6967
- if (trailing && !timer) {
6968
- scheduleTrailing(remaining);
6969
- }
6970
- },
6971
- cancelTimer: () => {
6972
- if (timer) {
6973
- clearTimeout(timer);
6974
- timer = null;
6975
- }
6976
- }
6977
- };
6978
- };
6979
- const BATCH_OWN_CAPABILITIES_API_LIMIT = 100;
6980
- const DEFAULT_BATCH_OWN_CAPABILITIES_THROTTLING_INTERVAL = 2e3;
6981
- const queuedFeeds = /* @__PURE__ */ new Set();
6982
- function queueBatchedOwnCapabilities({ feeds }) {
6983
- for (const feed of feeds) {
6984
- queuedFeeds.add(feed);
6985
- }
6986
- if (queuedFeeds.size > 0) {
6987
- this.throttledGetBatchOwnCapabilities(
6988
- [...queuedFeeds].slice(0, BATCH_OWN_CAPABILITIES_API_LIMIT),
6989
- (feedsToClear) => {
6990
- for (const feed of feedsToClear) {
6991
- queuedFeeds.delete(feed);
6992
- }
6993
- }
6994
- );
6995
- }
6996
- }
6997
- function clearQueuedFeeds() {
6998
- queuedFeeds.clear();
6999
- }
7000
7008
  function connectActivityToFeed({
7001
7009
  fid
7002
7010
  }) {
@@ -7020,14 +7028,14 @@ function isAnyFeedWatched(fids) {
7020
7028
  }
7021
7029
  return false;
7022
7030
  }
7023
- function disconnectActivityFromFeed(id) {
7024
- const activeFeed = this.activeActivities[id];
7025
- if (activeFeed) {
7026
- delete this.activeActivities[id];
7031
+ function disconnectActivityFromFeed(activity) {
7032
+ const index = this.activeActivities.indexOf(activity);
7033
+ if (index !== -1) {
7034
+ this.activeActivities.splice(index, 1);
7027
7035
  }
7028
7036
  }
7029
7037
  class ActivityWithStateUpdates {
7030
- constructor(id, feedsClient) {
7038
+ constructor(id, feedsClient, { fromResponse } = { fromResponse: void 0 }) {
7031
7039
  this.id = id;
7032
7040
  this.feedsClient = feedsClient;
7033
7041
  this.state = new StateStore({
@@ -7035,6 +7043,13 @@ class ActivityWithStateUpdates {
7035
7043
  comments_by_entity_id: {},
7036
7044
  is_loading: false
7037
7045
  });
7046
+ if (fromResponse) {
7047
+ this.setFeed({
7048
+ fid: fromResponse.feeds[0],
7049
+ initialState: fromResponse
7050
+ });
7051
+ this.subscribeToFeedState();
7052
+ }
7038
7053
  }
7039
7054
  get currentState() {
7040
7055
  return this.state.getLatestValue();
@@ -7103,7 +7118,7 @@ class ActivityWithStateUpdates {
7103
7118
  }
7104
7119
  dispose() {
7105
7120
  this.unsubscribeFromFeedState?.();
7106
- disconnectActivityFromFeed.call(this.feedsClient, this.id);
7121
+ disconnectActivityFromFeed.call(this.feedsClient, this);
7107
7122
  }
7108
7123
  /**
7109
7124
  * @internal
@@ -7121,8 +7136,13 @@ class ActivityWithStateUpdates {
7121
7136
  initialState
7122
7137
  }) {
7123
7138
  this.feed = connectActivityToFeed.call(this.feedsClient, { fid });
7139
+ const { activities } = addActivitiesToState.bind(this.feed)(
7140
+ [initialState],
7141
+ [],
7142
+ "start"
7143
+ );
7124
7144
  this.feed?.state.partialNext({
7125
- activities: [initialState]
7145
+ activities
7126
7146
  });
7127
7147
  }
7128
7148
  subscribeToFeedState() {
@@ -7147,20 +7167,20 @@ class ActivityWithStateUpdates {
7147
7167
  function getFeed() {
7148
7168
  return this.feed;
7149
7169
  }
7150
- const isOwnFollowsEqual = (currentState, newState) => {
7170
+ const areFollowArraysEqual = (currentFollows, newFollows) => {
7151
7171
  const existingFollows = new Set(
7152
- currentState.own_follows?.map(
7172
+ currentFollows?.map(
7153
7173
  (f) => `${f.source_feed.feed}:${f.target_feed.feed}:${f.updated_at.getTime()}`
7154
7174
  )
7155
7175
  );
7156
- const newFollows = new Set(
7157
- newState.own_follows?.map(
7176
+ const newFollowsSet = new Set(
7177
+ newFollows?.map(
7158
7178
  (f) => `${f.source_feed.feed}:${f.target_feed.feed}:${f.updated_at.getTime()}`
7159
7179
  )
7160
7180
  );
7161
- if (existingFollows.size === newFollows.size) {
7181
+ if (existingFollows.size === newFollowsSet.size) {
7162
7182
  const areEqual = Array.from(existingFollows).every(
7163
- (f) => newFollows.has(f)
7183
+ (f) => newFollowsSet.has(f)
7164
7184
  );
7165
7185
  if (areEqual) {
7166
7186
  return true;
@@ -7168,9 +7188,21 @@ const isOwnFollowsEqual = (currentState, newState) => {
7168
7188
  }
7169
7189
  return false;
7170
7190
  };
7191
+ const isOwnFollowsEqual = (currentState, newState) => {
7192
+ return areFollowArraysEqual(currentState.own_follows, newState.own_follows);
7193
+ };
7171
7194
  const isOwnMembershipEqual = (currentState, newState) => {
7172
7195
  return (currentState.own_membership?.updated_at.getTime() ?? 0) === (newState.own_membership?.updated_at.getTime() ?? 0);
7173
7196
  };
7197
+ const isOwnCapabilitiesEqual = (currentState, newState) => {
7198
+ return [...currentState.own_capabilities ?? []].sort().join(",") === [...newState.own_capabilities ?? []].sort().join(",");
7199
+ };
7200
+ const isOwnFollowingsEqual = (currentState, newState) => {
7201
+ return areFollowArraysEqual(
7202
+ currentState.own_followings,
7203
+ newState.own_followings
7204
+ );
7205
+ };
7174
7206
  class FeedsClient extends FeedsApi {
7175
7207
  constructor(apiKey, options) {
7176
7208
  const tokenManager = new TokenManager();
@@ -7183,14 +7215,11 @@ class FeedsClient extends FeedsApi {
7183
7215
  );
7184
7216
  super(apiClient);
7185
7217
  this.eventDispatcher = new EventDispatcher();
7186
- this.activeActivities = {};
7218
+ this.activeActivities = [];
7187
7219
  this.activeFeeds = {};
7188
7220
  this.healthyConnectionChangedEventCount = 0;
7189
- this.setGetBatchOwnCapabilitiesThrottlingInterval = (throttlingMs) => {
7190
- const {
7191
- throttledFn: throttledGetBatchOwnCapabilities,
7192
- cancelTimer: cancel
7193
- } = throttle(
7221
+ this.setGetBatchOwnFieldsThrottlingInterval = (throttlingMs) => {
7222
+ const { throttledFn: throttledGetBatchOwnFields, cancelTimer: cancel } = throttle(
7194
7223
  (feeds, callback) => {
7195
7224
  this.ownBatch({
7196
7225
  feeds
@@ -7206,23 +7235,22 @@ class FeedsClient extends FeedsApi {
7206
7235
  throttlingMs,
7207
7236
  { trailing: true }
7208
7237
  );
7209
- this.throttledGetBatchOwnCapabilities = throttledGetBatchOwnCapabilities;
7210
- this.cancelGetBatchOwnCapabilitiesTimer = cancel;
7238
+ this.throttledGetBatchOwnFields = throttledGetBatchOwnFields;
7239
+ this.cancelGetBatchOwnFieldsTimer = cancel;
7211
7240
  };
7212
7241
  this.recoverOnReconnect = async () => {
7213
7242
  this.healthyConnectionChangedEventCount++;
7214
7243
  if (this.healthyConnectionChangedEventCount > 1) {
7215
7244
  const feedEntries = Object.entries(this.activeFeeds);
7216
- const activityEntries = Object.entries(this.activeActivities);
7217
7245
  const results = await Promise.allSettled([
7218
7246
  ...feedEntries.map(([, feed]) => feed.synchronize()),
7219
- ...activityEntries.map(([, activity]) => activity.synchronize())
7247
+ ...this.activeActivities.map((activity) => activity.synchronize())
7220
7248
  ]);
7221
7249
  const failures = results.flatMap((result, index) => {
7222
7250
  if (result.status === "fulfilled") {
7223
7251
  return [];
7224
7252
  }
7225
- const activity = activityEntries[index - feedEntries.length]?.[1];
7253
+ const activity = this.activeActivities[index - feedEntries.length];
7226
7254
  const feed = feedEntries[index]?.[0] ?? (activity && getFeed.call(activity)?.feed);
7227
7255
  return [{ feed, reason: result.reason, activity_id: activity?.id }];
7228
7256
  });
@@ -7239,8 +7267,8 @@ class FeedsClient extends FeedsApi {
7239
7267
  throw new Error(`Can't connect a new user, call "disconnectUser" first`);
7240
7268
  }
7241
7269
  this.tokenManager.setTokenOrProvider(tokenProvider);
7242
- this.setGetBatchOwnCapabilitiesThrottlingInterval(
7243
- this.query_batch_own_capabilties_throttling_interval
7270
+ this.setGetBatchOwnFieldsThrottlingInterval(
7271
+ this.query_batch_own_fields_throttling_interval
7244
7272
  );
7245
7273
  try {
7246
7274
  addConnectionEventListeners(this.updateNetworkConnectionStatus);
@@ -7408,14 +7436,13 @@ class FeedsClient extends FeedsApi {
7408
7436
  this.connectionIdManager.reset();
7409
7437
  this.tokenManager.reset();
7410
7438
  this.polls_by_id.clear();
7411
- this.activeActivities = {};
7439
+ this.activeActivities = [];
7412
7440
  this.activeFeeds = {};
7413
7441
  this.state.partialNext({
7414
7442
  connected_user: void 0,
7415
- is_ws_connection_healthy: false,
7416
- own_capabilities_by_fid: {}
7443
+ is_ws_connection_healthy: false
7417
7444
  });
7418
- this.cancelGetBatchOwnCapabilitiesTimer();
7445
+ this.cancelGetBatchOwnFieldsTimer();
7419
7446
  clearQueuedFeeds();
7420
7447
  };
7421
7448
  this.on = this.eventDispatcher.on;
@@ -7424,15 +7451,15 @@ class FeedsClient extends FeedsApi {
7424
7451
  return this.getOrCreateActiveFeed({
7425
7452
  group: groupId,
7426
7453
  id,
7427
- options: options2
7454
+ options: options2,
7455
+ fieldsToUpdate: []
7428
7456
  });
7429
7457
  };
7430
- this.activityWithStateUpdates = (id) => {
7431
- let activity = this.activeActivities[id];
7432
- if (!activity) {
7433
- activity = new ActivityWithStateUpdates(id, this);
7434
- this.activeActivities[id] = activity;
7435
- }
7458
+ this.activityWithStateUpdates = (id, { fromResponse } = {
7459
+ fromResponse: void 0
7460
+ }) => {
7461
+ const activity = new ActivityWithStateUpdates(id, this, { fromResponse });
7462
+ this.activeActivities.push(activity);
7436
7463
  return activity;
7437
7464
  };
7438
7465
  this.updateNetworkConnectionStatus = (event) => {
@@ -7448,7 +7475,7 @@ class FeedsClient extends FeedsApi {
7448
7475
  data,
7449
7476
  watch,
7450
7477
  options: options2,
7451
- fromWebSocket = false
7478
+ fieldsToUpdate
7452
7479
  }) => {
7453
7480
  const fid = `${group}:${id}`;
7454
7481
  let isCreated = false;
@@ -7477,23 +7504,28 @@ class FeedsClient extends FeedsApi {
7477
7504
  if (!isCreated && data) {
7478
7505
  if ((feed.currentState.updated_at?.getTime() ?? 0) < data.updated_at.getTime()) {
7479
7506
  handleFeedUpdated.call(feed, { feed: data });
7480
- } else if ((feed.currentState.updated_at?.getTime() ?? 0) === data.updated_at.getTime() && !fromWebSocket) {
7481
- const fieldsToUpdate = [];
7482
- if (!isOwnFollowsEqual(feed.currentState, data)) {
7483
- fieldsToUpdate.push("own_follows");
7484
- }
7485
- if (!isOwnMembershipEqual(feed.currentState, data)) {
7486
- fieldsToUpdate.push("own_membership");
7487
- }
7488
- if (fieldsToUpdate.length > 0) {
7489
- const fieldsToUpdateData = fieldsToUpdate.reduce(
7507
+ } else if ((feed.currentState.updated_at?.getTime() ?? 0) === data.updated_at.getTime()) {
7508
+ const fieldsToUpdateData = [];
7509
+ const fieldChecks = [
7510
+ ["own_capabilities", isOwnCapabilitiesEqual],
7511
+ ["own_follows", isOwnFollowsEqual],
7512
+ ["own_membership", isOwnMembershipEqual],
7513
+ ["own_followings", isOwnFollowingsEqual]
7514
+ ];
7515
+ fieldChecks.forEach(([field, isEqual]) => {
7516
+ if (fieldsToUpdate.includes(field) && !isEqual(feed.currentState, data)) {
7517
+ fieldsToUpdateData.push(field);
7518
+ }
7519
+ });
7520
+ if (fieldsToUpdateData.length > 0) {
7521
+ const fieldsToUpdatePayload = fieldsToUpdateData.reduce(
7490
7522
  (acc, field) => {
7491
7523
  acc[field] = data[field];
7492
7524
  return acc;
7493
7525
  },
7494
7526
  {}
7495
7527
  );
7496
- feed.state.partialNext(fieldsToUpdateData);
7528
+ feed.state.partialNext(fieldsToUpdatePayload);
7497
7529
  }
7498
7530
  }
7499
7531
  }
@@ -7503,14 +7535,13 @@ class FeedsClient extends FeedsApi {
7503
7535
  };
7504
7536
  this.state = new StateStore({
7505
7537
  connected_user: void 0,
7506
- is_ws_connection_healthy: false,
7507
- own_capabilities_by_fid: {}
7538
+ is_ws_connection_healthy: false
7508
7539
  });
7509
7540
  this.moderation = new ModerationClient(apiClient);
7510
7541
  this.tokenManager = tokenManager;
7511
7542
  this.connectionIdManager = connectionIdManager;
7512
7543
  this.polls_by_id = /* @__PURE__ */ new Map();
7513
- this.query_batch_own_capabilties_throttling_interval = options?.query_batch_own_capabilties_throttling_interval ?? DEFAULT_BATCH_OWN_CAPABILITIES_THROTTLING_INTERVAL;
7544
+ this.query_batch_own_fields_throttling_interval = options?.query_batch_own_fields_throttling_interval ?? DEFAULT_BATCH_OWN_FIELDS_THROTTLING_INTERVAL;
7514
7545
  feedsLoggerSystem.configureLoggers(options?.configure_loggers_options);
7515
7546
  this.on("all", (event) => {
7516
7547
  const fid = event.fid;
@@ -7533,7 +7564,8 @@ class FeedsClient extends FeedsApi {
7533
7564
  this.getOrCreateActiveFeed({
7534
7565
  group: event.feed.group_id,
7535
7566
  id: event.feed.id,
7536
- data: event.feed
7567
+ data: event.feed,
7568
+ fieldsToUpdate: []
7537
7569
  });
7538
7570
  break;
7539
7571
  }
@@ -7541,12 +7573,9 @@ class FeedsClient extends FeedsApi {
7541
7573
  feeds.forEach((f) => f.handleWSEvent(event));
7542
7574
  if (typeof fid === "string") {
7543
7575
  delete this.activeFeeds[fid];
7544
- Object.keys(this.activeActivities).forEach((activityId) => {
7545
- const activity = this.activeActivities[activityId];
7546
- if (getFeed.call(activity)?.feed === fid) {
7547
- delete this.activeActivities[activityId];
7548
- }
7549
- });
7576
+ this.activeActivities = this.activeActivities.filter(
7577
+ (activity) => getFeed.call(activity)?.feed !== fid
7578
+ );
7550
7579
  }
7551
7580
  break;
7552
7581
  }
@@ -7624,7 +7653,9 @@ class FeedsClient extends FeedsApi {
7624
7653
  default: {
7625
7654
  feeds.forEach((f) => f.handleWSEvent(event));
7626
7655
  if (event.type === "feeds.activity.deleted") {
7627
- delete this.activeActivities[event.activity.id];
7656
+ this.activeActivities = this.activeActivities.filter(
7657
+ (activity) => activity.id !== event.activity.id
7658
+ );
7628
7659
  }
7629
7660
  }
7630
7661
  }
@@ -7651,25 +7682,6 @@ class FeedsClient extends FeedsApi {
7651
7682
  }
7652
7683
  }
7653
7684
  }
7654
- hydrateCapabilitiesCache(feedResponses) {
7655
- let ownCapabilitiesCache = this.state.getLatestValue().own_capabilities_by_fid;
7656
- const capabilitiesToFetchQueue = [];
7657
- for (const feedResponse of feedResponses) {
7658
- const { feed, own_capabilities } = feedResponse;
7659
- if (!Object.prototype.hasOwnProperty.call(ownCapabilitiesCache, feed)) {
7660
- if (own_capabilities) {
7661
- ownCapabilitiesCache = {
7662
- ...ownCapabilitiesCache,
7663
- [feed]: own_capabilities
7664
- };
7665
- } else {
7666
- capabilitiesToFetchQueue.push(feed);
7667
- }
7668
- }
7669
- }
7670
- queueBatchedOwnCapabilities.bind(this)({ feeds: capabilitiesToFetchQueue });
7671
- this.state.partialNext({ own_capabilities_by_fid: ownCapabilitiesCache });
7672
- }
7673
7685
  async queryFeeds(request) {
7674
7686
  const response = await this._queryFeeds(request);
7675
7687
  const feedResponses = response.feeds;
@@ -7678,10 +7690,15 @@ class FeedsClient extends FeedsApi {
7678
7690
  group: feedResponse.group_id,
7679
7691
  id: feedResponse.id,
7680
7692
  data: feedResponse,
7681
- watch: request?.watch
7693
+ watch: request?.watch,
7694
+ fieldsToUpdate: [
7695
+ "own_capabilities",
7696
+ "own_follows",
7697
+ "own_membership",
7698
+ "own_followings"
7699
+ ]
7682
7700
  })
7683
7701
  );
7684
- this.hydrateCapabilitiesCache(feedResponses);
7685
7702
  return {
7686
7703
  feeds,
7687
7704
  next: response.next,
@@ -7692,13 +7709,12 @@ class FeedsClient extends FeedsApi {
7692
7709
  }
7693
7710
  async ownBatch(request) {
7694
7711
  const response = await super.ownBatch(request);
7695
- const feedResponses = Object.entries(response.data).map(
7696
- ([feed, ownFields]) => ({
7697
- feed,
7698
- own_capabilities: ownFields.own_capabilities
7699
- })
7700
- );
7701
- this.hydrateCapabilitiesCache(feedResponses);
7712
+ Object.entries(response.data).forEach(([fid, ownFields]) => {
7713
+ const feed = this.activeFeeds[fid];
7714
+ if (feed) {
7715
+ feed.state.partialNext(ownFields);
7716
+ }
7717
+ });
7702
7718
  return response;
7703
7719
  }
7704
7720
  async updateFollow(request) {
@@ -7757,7 +7773,6 @@ class FeedsClient extends FeedsApi {
7757
7773
  }
7758
7774
  async getOrCreateFeed(request) {
7759
7775
  const response = await super.getOrCreateFeed(request);
7760
- this.hydrateCapabilitiesCache([response.feed]);
7761
7776
  if (request.watch) {
7762
7777
  const feeds = this.findAllActiveFeedsByFid(
7763
7778
  `${request.feed_group_id}:${request.feed_id}`
@@ -7768,14 +7783,20 @@ class FeedsClient extends FeedsApi {
7768
7783
  }
7769
7784
  async getFollowSuggestions(...params) {
7770
7785
  const response = await super.getFollowSuggestions(...params);
7771
- response.suggestions.forEach((suggestion) => {
7772
- this.getOrCreateActiveFeed({
7786
+ const feeds = response.suggestions.map((suggestion) => {
7787
+ return this.getOrCreateActiveFeed({
7773
7788
  group: suggestion.group_id,
7774
7789
  id: suggestion.id,
7775
- data: suggestion
7790
+ data: suggestion,
7791
+ fieldsToUpdate: [
7792
+ "own_capabilities",
7793
+ "own_follows",
7794
+ "own_membership",
7795
+ "own_followings"
7796
+ ]
7776
7797
  });
7777
7798
  });
7778
- return response;
7799
+ return { ...response, feeds };
7779
7800
  }
7780
7801
  findAllActiveFeedsByActivityId(activityId) {
7781
7802
  return [
@@ -7854,9 +7875,8 @@ export {
7854
7875
  updateEntityInArray as l,
7855
7876
  feedsLoggerSystem as m,
7856
7877
  ensureExhausted as n,
7857
- ownFeedFields as o,
7858
7878
  replaceUniqueArrayMerge as r,
7859
7879
  shouldUpdateState as s,
7860
7880
  uniqueArrayMerge as u
7861
7881
  };
7862
- //# sourceMappingURL=feeds-client-BNhvggk2.mjs.map
7882
+ //# sourceMappingURL=feeds-client-C-2_fdH1.mjs.map