@stream-io/feeds-client 0.3.50 → 1.0.0

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 (54) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/index.js +2 -1
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/react-bindings.js +1 -1
  5. package/dist/es/index.mjs +15 -14
  6. package/dist/es/index.mjs.map +1 -1
  7. package/dist/es/react-bindings.mjs +1 -1
  8. package/dist/{feeds-client-BHpmg4_E.mjs → feeds-client-B03y08Kq.mjs} +219 -77
  9. package/dist/feeds-client-B03y08Kq.mjs.map +1 -0
  10. package/dist/{feeds-client-CKxvuiKz.js → feeds-client-tw63OGrd.js} +213 -71
  11. package/dist/feeds-client-tw63OGrd.js.map +1 -0
  12. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  13. package/dist/types/activity-with-state-updates/activity-with-state-updates.d.ts.map +1 -1
  14. package/dist/types/feed/activity-filter.d.ts +11 -0
  15. package/dist/types/feed/activity-filter.d.ts.map +1 -0
  16. package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts +3 -2
  17. package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts.map +1 -1
  18. package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -1
  19. package/dist/types/feed/event-handlers/comment/handle-comment-updated.d.ts.map +1 -1
  20. package/dist/types/feed/event-handlers/follow/handle-follow-created.d.ts +2 -2
  21. package/dist/types/feed/event-handlers/follow/handle-follow-created.d.ts.map +1 -1
  22. package/dist/types/feed/feed.d.ts +20 -13
  23. package/dist/types/feed/feed.d.ts.map +1 -1
  24. package/dist/types/feeds-client/apply-new-activity-to-active-feeds.d.ts +4 -0
  25. package/dist/types/feeds-client/apply-new-activity-to-active-feeds.d.ts.map +1 -0
  26. package/dist/types/feeds-client/feeds-client.d.ts +7 -8
  27. package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
  28. package/dist/types/gen/feeds/FeedApi.d.ts +1 -0
  29. package/dist/types/gen/feeds/FeedApi.d.ts.map +1 -1
  30. package/dist/types/gen/feeds/FeedsApi.d.ts +3 -0
  31. package/dist/types/gen/feeds/FeedsApi.d.ts.map +1 -1
  32. package/dist/types/gen/models/index.d.ts +15 -0
  33. package/dist/types/gen/models/index.d.ts.map +1 -1
  34. package/dist/types/index.d.ts +1 -0
  35. package/dist/types/index.d.ts.map +1 -1
  36. package/dist/types/types.d.ts +15 -0
  37. package/dist/types/types.d.ts.map +1 -1
  38. package/package.json +2 -1
  39. package/src/activity-with-state-updates/activity-with-state-updates.ts +8 -2
  40. package/src/feed/activity-filter.ts +44 -0
  41. package/src/feed/event-handlers/activity/handle-activity-added.ts +22 -8
  42. package/src/feed/event-handlers/activity/handle-activity-updated.ts +5 -1
  43. package/src/feed/event-handlers/comment/handle-comment-updated.ts +11 -10
  44. package/src/feed/event-handlers/follow/handle-follow-created.ts +18 -1
  45. package/src/feed/feed.ts +77 -22
  46. package/src/feeds-client/apply-new-activity-to-active-feeds.ts +9 -0
  47. package/src/feeds-client/feeds-client.ts +46 -28
  48. package/src/gen/feeds/FeedApi.ts +1 -0
  49. package/src/gen/feeds/FeedsApi.ts +33 -4
  50. package/src/gen/models/index.ts +31 -1
  51. package/src/index.ts +1 -0
  52. package/src/types.ts +17 -0
  53. package/dist/feeds-client-BHpmg4_E.mjs.map +0 -1
  54. package/dist/feeds-client-CKxvuiKz.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { StateStore } from "@stream-io/state-store";
2
2
  import * as loggerInternal from "@stream-io/logger";
3
3
  import axiosImport from "axios";
4
+ import { itemMatchesFilter, resolveDotPathValue } from "@stream-io/filter";
4
5
  const decoders = {};
5
6
  const decodeDatetimeType = (input) => typeof input === "number" ? new Date(Math.floor(input / 1e6)) : new Date(input);
6
7
  decoders.DatetimeType = decodeDatetimeType;
@@ -1632,6 +1633,7 @@ class FeedsApi {
1632
1633
  feeds: request?.feeds,
1633
1634
  copy_custom_to_notification: request?.copy_custom_to_notification,
1634
1635
  create_notification_activity: request?.create_notification_activity,
1636
+ enrich_own_fields: request?.enrich_own_fields,
1635
1637
  expires_at: request?.expires_at,
1636
1638
  id: request?.id,
1637
1639
  parent_id: request?.parent_id,
@@ -1664,7 +1666,8 @@ class FeedsApi {
1664
1666
  }
1665
1667
  async upsertActivities(request) {
1666
1668
  const body = {
1667
- activities: request?.activities
1669
+ activities: request?.activities,
1670
+ enrich_own_fields: request?.enrich_own_fields
1668
1671
  };
1669
1672
  const response = await this.apiClient.sendRequest(
1670
1673
  "POST",
@@ -1696,6 +1699,7 @@ class FeedsApi {
1696
1699
  }
1697
1700
  async queryActivities(request) {
1698
1701
  const body = {
1702
+ enrich_own_fields: request?.enrich_own_fields,
1699
1703
  limit: request?.limit,
1700
1704
  next: request?.next,
1701
1705
  prev: request?.prev,
@@ -1915,6 +1919,7 @@ class FeedsApi {
1915
1919
  };
1916
1920
  const body = {
1917
1921
  copy_custom_to_notification: request?.copy_custom_to_notification,
1922
+ enrich_own_fields: request?.enrich_own_fields,
1918
1923
  handle_mention_notifications: request?.handle_mention_notifications,
1919
1924
  run_activity_processors: request?.run_activity_processors,
1920
1925
  unset: request?.unset,
@@ -1937,6 +1942,7 @@ class FeedsApi {
1937
1942
  };
1938
1943
  const body = {
1939
1944
  copy_custom_to_notification: request?.copy_custom_to_notification,
1945
+ enrich_own_fields: request?.enrich_own_fields,
1940
1946
  expires_at: request?.expires_at,
1941
1947
  handle_mention_notifications: request?.handle_mention_notifications,
1942
1948
  poll_id: request?.poll_id,
@@ -1968,6 +1974,9 @@ class FeedsApi {
1968
1974
  return { ...response.body, metadata: response.metadata };
1969
1975
  }
1970
1976
  async restoreActivity(request) {
1977
+ const queryParams = {
1978
+ enrich_own_fields: request?.enrich_own_fields
1979
+ };
1971
1980
  const pathParams = {
1972
1981
  id: request?.id
1973
1982
  };
@@ -1976,7 +1985,7 @@ class FeedsApi {
1976
1985
  "POST",
1977
1986
  "/api/v2/feeds/activities/{id}/restore",
1978
1987
  pathParams,
1979
- void 0,
1988
+ queryParams,
1980
1989
  body,
1981
1990
  "application/json"
1982
1991
  );
@@ -2036,6 +2045,7 @@ class FeedsApi {
2036
2045
  }
2037
2046
  async queryBookmarks(request) {
2038
2047
  const body = {
2048
+ enrich_own_fields: request?.enrich_own_fields,
2039
2049
  limit: request?.limit,
2040
2050
  next: request?.next,
2041
2051
  prev: request?.prev,
@@ -2357,6 +2367,7 @@ class FeedsApi {
2357
2367
  };
2358
2368
  const body = {
2359
2369
  description: request?.description,
2370
+ enrich_own_fields: request?.enrich_own_fields,
2360
2371
  name: request?.name,
2361
2372
  filter_tags: request?.filter_tags,
2362
2373
  custom: request?.custom
@@ -2396,6 +2407,9 @@ class FeedsApi {
2396
2407
  return { ...response.body, metadata: response.metadata };
2397
2408
  }
2398
2409
  async unpinActivity(request) {
2410
+ const queryParams = {
2411
+ enrich_own_fields: request?.enrich_own_fields
2412
+ };
2399
2413
  const pathParams = {
2400
2414
  feed_group_id: request?.feed_group_id,
2401
2415
  feed_id: request?.feed_id,
@@ -2405,7 +2419,7 @@ class FeedsApi {
2405
2419
  "DELETE",
2406
2420
  "/api/v2/feeds/feed_groups/{feed_group_id}/feeds/{feed_id}/activities/{activity_id}/pin",
2407
2421
  pathParams,
2408
- void 0
2422
+ queryParams
2409
2423
  );
2410
2424
  decoders.UnpinActivityResponse?.(response.body);
2411
2425
  return { ...response.body, metadata: response.metadata };
@@ -2416,7 +2430,9 @@ class FeedsApi {
2416
2430
  feed_id: request?.feed_id,
2417
2431
  activity_id: request?.activity_id
2418
2432
  };
2419
- const body = {};
2433
+ const body = {
2434
+ enrich_own_fields: request?.enrich_own_fields
2435
+ };
2420
2436
  const response = await this.apiClient.sendRequest(
2421
2437
  "POST",
2422
2438
  "/api/v2/feeds/feed_groups/{feed_group_id}/feeds/{feed_id}/activities/{activity_id}/pin",
@@ -2514,6 +2530,7 @@ class FeedsApi {
2514
2530
  feed_id: request?.feed_id
2515
2531
  };
2516
2532
  const body = {
2533
+ enrich_own_fields: request?.enrich_own_fields,
2517
2534
  limit: request?.limit,
2518
2535
  next: request?.next,
2519
2536
  prev: request?.prev,
@@ -2566,7 +2583,8 @@ class FeedsApi {
2566
2583
  }
2567
2584
  async createFeedsBatch(request) {
2568
2585
  const body = {
2569
- feeds: request?.feeds
2586
+ feeds: request?.feeds,
2587
+ enrich_own_fields: request?.enrich_own_fields
2570
2588
  };
2571
2589
  const response = await this.apiClient.sendRequest(
2572
2590
  "POST",
@@ -2603,6 +2621,7 @@ class FeedsApi {
2603
2621
  connection_id: request?.connection_id
2604
2622
  };
2605
2623
  const body = {
2624
+ enrich_own_fields: request?.enrich_own_fields,
2606
2625
  limit: request?.limit,
2607
2626
  next: request?.next,
2608
2627
  prev: request?.prev,
@@ -2627,6 +2646,7 @@ class FeedsApi {
2627
2646
  target: request?.target,
2628
2647
  copy_custom_to_notification: request?.copy_custom_to_notification,
2629
2648
  create_notification_activity: request?.create_notification_activity,
2649
+ enrich_own_fields: request?.enrich_own_fields,
2630
2650
  follower_role: request?.follower_role,
2631
2651
  push_preference: request?.push_preference,
2632
2652
  skip_push: request?.skip_push,
@@ -2649,6 +2669,7 @@ class FeedsApi {
2649
2669
  target: request?.target,
2650
2670
  copy_custom_to_notification: request?.copy_custom_to_notification,
2651
2671
  create_notification_activity: request?.create_notification_activity,
2672
+ enrich_own_fields: request?.enrich_own_fields,
2652
2673
  push_preference: request?.push_preference,
2653
2674
  skip_push: request?.skip_push,
2654
2675
  custom: request?.custom
@@ -2683,7 +2704,8 @@ class FeedsApi {
2683
2704
  }
2684
2705
  async followBatch(request) {
2685
2706
  const body = {
2686
- follows: request?.follows
2707
+ follows: request?.follows,
2708
+ enrich_own_fields: request?.enrich_own_fields
2687
2709
  };
2688
2710
  const response = await this.apiClient.sendRequest(
2689
2711
  "POST",
@@ -2698,7 +2720,8 @@ class FeedsApi {
2698
2720
  }
2699
2721
  async getOrCreateFollows(request) {
2700
2722
  const body = {
2701
- follows: request?.follows
2723
+ follows: request?.follows,
2724
+ enrich_own_fields: request?.enrich_own_fields
2702
2725
  };
2703
2726
  const response = await this.apiClient.sendRequest(
2704
2727
  "POST",
@@ -2748,7 +2771,8 @@ class FeedsApi {
2748
2771
  }
2749
2772
  async unfollow(request) {
2750
2773
  const queryParams = {
2751
- delete_notification_activity: request?.delete_notification_activity
2774
+ delete_notification_activity: request?.delete_notification_activity,
2775
+ enrich_own_fields: request?.enrich_own_fields
2752
2776
  };
2753
2777
  const pathParams = {
2754
2778
  source: request?.source,
@@ -2766,7 +2790,8 @@ class FeedsApi {
2766
2790
  async getOrCreateUnfollows(request) {
2767
2791
  const body = {
2768
2792
  follows: request?.follows,
2769
- delete_notification_activity: request?.delete_notification_activity
2793
+ delete_notification_activity: request?.delete_notification_activity,
2794
+ enrich_own_fields: request?.enrich_own_fields
2770
2795
  };
2771
2796
  const response = await this.apiClient.sendRequest(
2772
2797
  "POST",
@@ -4086,7 +4111,7 @@ const getRateLimitFromResponseHeader = (response_headers) => {
4086
4111
  };
4087
4112
  return result;
4088
4113
  };
4089
- const version = "0.3.50";
4114
+ const version = "1.0.0";
4090
4115
  const axios = axiosImport.default ?? axiosImport;
4091
4116
  class ApiClient {
4092
4117
  constructor(apiKey, tokenManager, connectionIdManager, options) {
@@ -5021,7 +5046,7 @@ function updateEntityInArray({
5021
5046
  updatedEntities[index] = newEntity;
5022
5047
  return { changed: true, entities: updatedEntities };
5023
5048
  }
5024
- const updateStateFollowCreated = (follow, currentState, currentFeedId, connectedUserId) => {
5049
+ const updateStateFollowCreated = (follow, currentState, currentFeedId, connectedUserId, hasOwnFields = false) => {
5025
5050
  if (follow.status !== "accepted") {
5026
5051
  return { changed: false, data: currentState };
5027
5052
  }
@@ -5030,7 +5055,12 @@ const updateStateFollowCreated = (follow, currentState, currentFeedId, connected
5030
5055
  newState = {
5031
5056
  ...newState,
5032
5057
  // Update FeedResponse fields, that has the new follower/following count
5033
- ...follow.source_feed
5058
+ ...follow.source_feed,
5059
+ ...hasOwnFields ? {
5060
+ own_capabilities: follow.source_feed.own_capabilities,
5061
+ own_follows: follow.source_feed.own_follows,
5062
+ own_followings: follow.source_feed.own_followings
5063
+ } : {}
5034
5064
  };
5035
5065
  if (currentState.following !== void 0) {
5036
5066
  newState.following = [follow, ...currentState.following];
@@ -5043,9 +5073,14 @@ const updateStateFollowCreated = (follow, currentState, currentFeedId, connected
5043
5073
  newState = {
5044
5074
  ...newState,
5045
5075
  // Update FeedResponse fields, that has the new follower/following count
5046
- ...follow.target_feed
5047
- };
5048
- if (source.created_by.id === connectedUserId) {
5076
+ ...follow.target_feed,
5077
+ ...hasOwnFields ? {
5078
+ own_capabilities: follow.target_feed.own_capabilities,
5079
+ own_follows: follow.target_feed.own_follows,
5080
+ own_followings: follow.target_feed.own_followings
5081
+ } : {}
5082
+ };
5083
+ if (source.created_by.id === connectedUserId && !hasOwnFields) {
5049
5084
  newState.own_follows = currentState.own_follows ? currentState.own_follows.concat(follow) : [follow];
5050
5085
  }
5051
5086
  if (currentState.followers !== void 0) {
@@ -5054,7 +5089,7 @@ const updateStateFollowCreated = (follow, currentState, currentFeedId, connected
5054
5089
  }
5055
5090
  return { changed: true, data: newState };
5056
5091
  };
5057
- function handleFollowCreated(eventOrResponse, fromWs) {
5092
+ function handleFollowCreated(eventOrResponse, fromWs, hasOwnFields = false) {
5058
5093
  const follow = eventOrResponse.follow;
5059
5094
  if (!shouldUpdateState({
5060
5095
  stateUpdateQueueId: getStateUpdateQueueId(follow, "follow-created"),
@@ -5070,7 +5105,8 @@ function handleFollowCreated(eventOrResponse, fromWs) {
5070
5105
  follow,
5071
5106
  this.currentState,
5072
5107
  this.feed,
5073
- connectedUser?.id
5108
+ connectedUser?.id,
5109
+ hasOwnFields
5074
5110
  );
5075
5111
  if (result.changed) {
5076
5112
  this.state.next(result.data);
@@ -5294,14 +5330,14 @@ function handleCommentUpdated(payload, fromWs) {
5294
5330
  const { comment } = payload;
5295
5331
  const entityId = comment.parent_id ?? comment.object_id;
5296
5332
  if (!shouldUpdateState({
5297
- stateUpdateQueueId: getStateUpdateQueueId(
5298
- payload,
5299
- "comment-updated"
5300
- ),
5333
+ stateUpdateQueueId: getStateUpdateQueueId(payload, "comment-updated"),
5301
5334
  stateUpdateQueue: this.stateUpdateQueue,
5302
5335
  watch: this.currentState.watch,
5303
5336
  fromWs,
5304
- isTriggeredByConnectedUser: eventTriggeredByConnectedUser.call(this, payload)
5337
+ isTriggeredByConnectedUser: eventTriggeredByConnectedUser.call(
5338
+ this,
5339
+ payload
5340
+ )
5305
5341
  })) {
5306
5342
  return;
5307
5343
  }
@@ -5311,7 +5347,10 @@ function handleCommentUpdated(payload, fromWs) {
5311
5347
  const index = this.getCommentIndex(comment, currentState);
5312
5348
  if (index === -1) return currentState;
5313
5349
  const newComments = [...entityState.comments];
5314
- newComments[index] = comment;
5350
+ newComments[index] = {
5351
+ ...comment,
5352
+ own_reactions: entityState.comments[index].own_reactions
5353
+ };
5315
5354
  return {
5316
5355
  ...currentState,
5317
5356
  comments_by_entity_id: {
@@ -5740,7 +5779,13 @@ function handleBookmarkUpdated(event) {
5740
5779
  });
5741
5780
  }
5742
5781
  }
5743
- function addActivitiesToState(newActivities, activities, position, { fromWebSocket } = { fromWebSocket: false }) {
5782
+ function addActivitiesToState(newActivities, activities, position, {
5783
+ hasOwnFields,
5784
+ backfillOwnFields
5785
+ } = {
5786
+ hasOwnFields: true,
5787
+ backfillOwnFields: true
5788
+ }) {
5744
5789
  if (activities === void 0) {
5745
5790
  return {
5746
5791
  changed: false,
@@ -5763,23 +5808,31 @@ function addActivitiesToState(newActivities, activities, position, { fromWebSock
5763
5808
  ...activities,
5764
5809
  ...position === "end" ? newActivitiesDeduplicated : []
5765
5810
  ];
5766
- this.newActivitiesAdded(newActivitiesDeduplicated, { fromWebSocket });
5811
+ this.activitiesAddedOrUpdated(newActivitiesDeduplicated, {
5812
+ hasOwnFields,
5813
+ backfillOwnFields
5814
+ });
5767
5815
  result = { changed: true, activities: updatedActivities };
5768
5816
  }
5769
5817
  return result;
5770
5818
  }
5771
5819
  function handleActivityAdded(event) {
5772
- if (this.activityAddedEventFilter) {
5773
- if (!this.activityAddedEventFilter(event)) {
5774
- return;
5775
- }
5820
+ const currentUser = this.client.state.getLatestValue().connected_user;
5821
+ const decision = this.resolveNewActivityDecision(
5822
+ event.activity,
5823
+ currentUser,
5824
+ false
5825
+ );
5826
+ if (decision === "ignore") {
5827
+ return;
5776
5828
  }
5829
+ const position = decision === "add-to-end" ? "end" : "start";
5777
5830
  const currentActivities = this.currentState.activities;
5778
5831
  const result = addActivitiesToState.bind(this)(
5779
5832
  [event.activity],
5780
5833
  currentActivities,
5781
- this.currentState.addNewActivitiesTo,
5782
- { fromWebSocket: true }
5834
+ position,
5835
+ { hasOwnFields: false, backfillOwnFields: true }
5783
5836
  );
5784
5837
  if (result.changed) {
5785
5838
  const activity = event.activity;
@@ -5896,7 +5949,10 @@ function handleActivityUpdated(payload, fromWs) {
5896
5949
  updatePinnedActivityInState(payload, currentPinnedActivities)
5897
5950
  ];
5898
5951
  if (result1?.changed || result2.changed) {
5899
- this.client.hydratePollCache([payload.activity]);
5952
+ this.activitiesAddedOrUpdated([payload.activity], {
5953
+ hasOwnFields: payload.activity.current_feed?.own_capabilities !== void 0,
5954
+ backfillOwnFields: false
5955
+ });
5900
5956
  this.state.partialNext({
5901
5957
  activities: result1?.changed ? result1.entities : currentActivities,
5902
5958
  pinned_activities: result2.entities
@@ -6408,6 +6464,30 @@ function handleWatchStarted() {
6408
6464
  function handleWatchStopped() {
6409
6465
  this.state.partialNext({ watch: false });
6410
6466
  }
6467
+ const activityResolvers = [
6468
+ {
6469
+ matchesField: (field) => field === "activity_type",
6470
+ resolve: (activity) => activity.type
6471
+ },
6472
+ {
6473
+ matchesField: (field) => field === "within_bounds",
6474
+ resolve: (activity) => activity.location
6475
+ },
6476
+ {
6477
+ matchesField: () => true,
6478
+ resolve: (item, path) => resolveDotPathValue(item, path)
6479
+ }
6480
+ ];
6481
+ function activityFilter(activity, requestConfig) {
6482
+ const filter = requestConfig?.filter;
6483
+ if (!filter || typeof filter !== "object") {
6484
+ return true;
6485
+ }
6486
+ return itemMatchesFilter(activity, filter, {
6487
+ resolvers: [...activityResolvers],
6488
+ arrayEqMode: "contains"
6489
+ });
6490
+ }
6411
6491
  const DEFAULT_MAX_RETRIES = 3;
6412
6492
  function isRetryableError(error) {
6413
6493
  if (error instanceof StreamApiError) {
@@ -6599,9 +6679,9 @@ function clearQueuedFeeds() {
6599
6679
  queuedFeeds.clear();
6600
6680
  }
6601
6681
  const _Feed = class _Feed extends FeedApi {
6602
- constructor(client, groupId, id, data, watch = false, addNewActivitiesTo = "start", activityAddedEventFilter) {
6682
+ constructor(client, groupId, id, data, watch = false, onNewActivity) {
6603
6683
  super(client, groupId, id);
6604
- this.activityAddedEventFilter = activityAddedEventFilter;
6684
+ this.onNewActivity = onNewActivity;
6605
6685
  this.indexedActivityIds = /* @__PURE__ */ new Set();
6606
6686
  this.stateUpdateQueue = /* @__PURE__ */ new Set();
6607
6687
  this.eventHandlers = {
@@ -6671,8 +6751,7 @@ const _Feed = class _Feed extends FeedApi {
6671
6751
  is_loading: false,
6672
6752
  is_loading_activities: false,
6673
6753
  comments_by_entity_id: {},
6674
- watch,
6675
- addNewActivitiesTo
6754
+ watch
6676
6755
  });
6677
6756
  this.client = client;
6678
6757
  this.state.subscribeWithSelector(
@@ -6693,9 +6772,6 @@ const _Feed = class _Feed extends FeedApi {
6693
6772
  get currentState() {
6694
6773
  return this.state.getLatestValue();
6695
6774
  }
6696
- set addNewActivitiesTo(value) {
6697
- this.state.partialNext({ addNewActivitiesTo: value });
6698
- }
6699
6775
  hasActivity(activityId) {
6700
6776
  return this.indexedActivityIds.has(activityId);
6701
6777
  }
@@ -6704,6 +6780,24 @@ const _Feed = class _Feed extends FeedApi {
6704
6780
  (pinnedActivity) => pinnedActivity.activity.id === activityId
6705
6781
  );
6706
6782
  }
6783
+ /**
6784
+ * Resolves how to handle a new activity (WS or HTTP): ignore, add-to-start, or add-to-end.
6785
+ * Uses onNewActivity if set; else default (current user + filter match) adds to start.
6786
+ */
6787
+ resolveNewActivityDecision(activity, currentUser, _fromHttp) {
6788
+ if (this.onNewActivity) {
6789
+ return this.onNewActivity({ activity, currentUser });
6790
+ }
6791
+ if (!currentUser) return "ignore";
6792
+ if (activity.user?.id !== currentUser.id) return "ignore";
6793
+ if (!activityFilter(
6794
+ activity,
6795
+ this.currentState.last_get_or_create_request_config
6796
+ )) {
6797
+ return "ignore";
6798
+ }
6799
+ return "add-to-start";
6800
+ }
6707
6801
  async synchronize() {
6708
6802
  const { last_get_or_create_request_config } = this.state.getLatestValue();
6709
6803
  if (last_get_or_create_request_config?.watch) {
@@ -6741,7 +6835,8 @@ const _Feed = class _Feed extends FeedApi {
6741
6835
  const result = addActivitiesToState.bind(this)(
6742
6836
  response.activities,
6743
6837
  currentActivities,
6744
- "end"
6838
+ "end",
6839
+ { hasOwnFields: true, backfillOwnFields: false }
6745
6840
  );
6746
6841
  const aggregatedActivitiesResult = addAggregatedActivitiesToState(
6747
6842
  response.aggregated_activities,
@@ -6790,7 +6885,7 @@ const _Feed = class _Feed extends FeedApi {
6790
6885
  return nextState;
6791
6886
  });
6792
6887
  }
6793
- this.newActivitiesAdded(response.activities);
6888
+ this.activitiesAddedOrUpdated(response.activities);
6794
6889
  return response;
6795
6890
  } finally {
6796
6891
  this.state.partialNext({
@@ -7131,11 +7226,12 @@ const _Feed = class _Feed extends FeedApi {
7131
7226
  });
7132
7227
  return response;
7133
7228
  }
7134
- async unfollow(feedOrFid, options) {
7229
+ async unfollow(feedOrFid, options, enrichOwnFields) {
7135
7230
  const fid = typeof feedOrFid === "string" ? feedOrFid : feedOrFid.feed;
7136
7231
  const response = await this.client.unfollow({
7137
7232
  source: this.feed,
7138
7233
  target: fid,
7234
+ enrich_own_fields: enrichOwnFields,
7139
7235
  ...options
7140
7236
  });
7141
7237
  return response;
@@ -7164,11 +7260,41 @@ const _Feed = class _Feed extends FeedApi {
7164
7260
  next: currentState.next
7165
7261
  });
7166
7262
  }
7263
+ /**
7264
+ * Applies a new activity to this feed's state (decision + add to activities).
7265
+ * Used when the activity was added via this feed's addActivity or via client.addActivity.
7266
+ */
7267
+ addActivityFromHTTPResponse(activity) {
7268
+ const currentUser = this.client.state.getLatestValue().connected_user;
7269
+ const decision = this.resolveNewActivityDecision(
7270
+ activity,
7271
+ currentUser,
7272
+ true
7273
+ );
7274
+ if (decision !== "ignore") {
7275
+ const position = decision === "add-to-end" ? "end" : "start";
7276
+ const currentActivities = this.currentState.activities;
7277
+ const result = addActivitiesToState.bind(this)(
7278
+ [activity],
7279
+ currentActivities,
7280
+ position,
7281
+ {
7282
+ hasOwnFields: activity.current_feed?.own_capabilities !== void 0,
7283
+ backfillOwnFields: false
7284
+ }
7285
+ );
7286
+ if (result.changed) {
7287
+ this.client.hydratePollCache([activity]);
7288
+ this.state.partialNext({ activities: result.activities });
7289
+ }
7290
+ }
7291
+ }
7167
7292
  async addActivity(request) {
7168
7293
  const response = await this.client.addActivity({
7169
7294
  ...request,
7170
7295
  feeds: [this.feed]
7171
7296
  });
7297
+ this.addActivityFromHTTPResponse(response.activity);
7172
7298
  return response;
7173
7299
  }
7174
7300
  handleWSEvent(event) {
@@ -7189,7 +7315,7 @@ const _Feed = class _Feed extends FeedApi {
7189
7315
  }
7190
7316
  this.eventDispatcher.dispatch(event);
7191
7317
  }
7192
- newActivitiesAdded(activities, options = { fromWebSocket: false }) {
7318
+ activitiesAddedOrUpdated(activities, options = { hasOwnFields: true, backfillOwnFields: true }) {
7193
7319
  this.client.hydratePollCache(activities);
7194
7320
  this.getOrCreateFeeds(activities, options);
7195
7321
  }
@@ -7207,7 +7333,7 @@ const _Feed = class _Feed extends FeedApi {
7207
7333
  });
7208
7334
  const newFeeds = Array.from(feedsToGetOrCreate.values());
7209
7335
  const fieldsToUpdate = [];
7210
- if (!options.fromWebSocket) {
7336
+ if (options.hasOwnFields) {
7211
7337
  fieldsToUpdate.push("own_membership");
7212
7338
  if (!enrichmentOptions?.skip_own_capabilities) {
7213
7339
  fieldsToUpdate.push("own_capabilities");
@@ -7227,7 +7353,7 @@ const _Feed = class _Feed extends FeedApi {
7227
7353
  fieldsToUpdate
7228
7354
  });
7229
7355
  });
7230
- if (options.fromWebSocket) {
7356
+ if (!options.hasOwnFields && options.backfillOwnFields) {
7231
7357
  const uninitializedFeeds = newFeeds.filter((feedResponse) => {
7232
7358
  const feed = this.client.feed(feedResponse.group_id, feedResponse.id);
7233
7359
  return feed.currentState.own_capabilities === void 0;
@@ -7250,6 +7376,9 @@ const _Feed = class _Feed extends FeedApi {
7250
7376
  _Feed.noop = () => {
7251
7377
  };
7252
7378
  let Feed = _Feed;
7379
+ function applyNewActivityToActiveFeeds(activity) {
7380
+ return this.addActivityFromHTTPResponse(activity);
7381
+ }
7253
7382
  function handleUserUpdated(event) {
7254
7383
  this.state.next((currentState) => {
7255
7384
  let newState;
@@ -7329,7 +7458,9 @@ function disconnectActivityFromFeed(activity) {
7329
7458
  }
7330
7459
  }
7331
7460
  class ActivityWithStateUpdates {
7332
- constructor(id, feedsClient, { fromResponse } = { fromResponse: void 0 }) {
7461
+ constructor(id, feedsClient, { fromResponse } = {
7462
+ fromResponse: void 0
7463
+ }) {
7333
7464
  this.id = id;
7334
7465
  this.feedsClient = feedsClient;
7335
7466
  this.state = new StateStore({
@@ -7380,7 +7511,7 @@ class ActivityWithStateUpdates {
7380
7511
  initialState: activityResponse
7381
7512
  });
7382
7513
  if (this.feed) {
7383
- this.feed.activityAddedEventFilter = () => false;
7514
+ this.feed.onNewActivity = () => "ignore";
7384
7515
  }
7385
7516
  if (comments) {
7386
7517
  await this.loadNextPageActivityComments(comments);
@@ -7433,7 +7564,11 @@ class ActivityWithStateUpdates {
7433
7564
  const { activities } = addActivitiesToState.bind(this.feed)(
7434
7565
  [initialState],
7435
7566
  [],
7436
- "start"
7567
+ "start",
7568
+ {
7569
+ hasOwnFields: initialState.current_feed?.own_capabilities !== void 0,
7570
+ backfillOwnFields: false
7571
+ }
7437
7572
  );
7438
7573
  this.feed?.state.partialNext({
7439
7574
  activities
@@ -7864,18 +7999,12 @@ class FeedsClient extends FeedsApi {
7864
7999
  id,
7865
8000
  data,
7866
8001
  watch,
7867
- options2?.addNewActivitiesTo,
7868
- options2?.activityAddedEventFilter
8002
+ options2?.onNewActivity
7869
8003
  );
7870
8004
  }
7871
8005
  const feed = this.activeFeeds[fid];
7872
- if (!isCreated && options2) {
7873
- if (options2?.addNewActivitiesTo) {
7874
- feed.addNewActivitiesTo = options2.addNewActivitiesTo;
7875
- }
7876
- if (options2?.activityAddedEventFilter) {
7877
- feed.activityAddedEventFilter = options2.activityAddedEventFilter;
7878
- }
8006
+ if (!isCreated && options2?.onNewActivity !== void 0) {
8007
+ feed.onNewActivity = options2.onNewActivity;
7879
8008
  }
7880
8009
  if (!feed.currentState.watch) {
7881
8010
  if (!isCreated && data) {
@@ -8055,6 +8184,16 @@ class FeedsClient extends FeedsApi {
8055
8184
  });
8056
8185
  }
8057
8186
  }
8187
+ async addActivity(request) {
8188
+ const response = await super.addActivity(request);
8189
+ request.feeds.forEach((fid) => {
8190
+ const feed = this.activeFeeds[fid];
8191
+ if (feed) {
8192
+ applyNewActivityToActiveFeeds.call(feed, response.activity);
8193
+ }
8194
+ });
8195
+ return response;
8196
+ }
8058
8197
  async queryFeeds(request) {
8059
8198
  const response = await this._queryFeeds(request);
8060
8199
  const feedResponses = response.feeds;
@@ -8064,12 +8203,12 @@ class FeedsClient extends FeedsApi {
8064
8203
  id: feedResponse.id,
8065
8204
  data: feedResponse,
8066
8205
  watch: request?.watch,
8067
- fieldsToUpdate: [
8206
+ fieldsToUpdate: request?.enrich_own_fields ? [
8068
8207
  "own_capabilities",
8069
8208
  "own_follows",
8070
8209
  "own_membership",
8071
8210
  "own_followings"
8072
- ]
8211
+ ] : []
8073
8212
  })
8074
8213
  );
8075
8214
  return {
@@ -8104,7 +8243,7 @@ class FeedsClient extends FeedsApi {
8104
8243
  // For follow API endpoints we update the state after HTTP response to allow queryFeeds with watch: false
8105
8244
  async follow(request) {
8106
8245
  const response = await super.follow(request);
8107
- this.updateStateFromFollows([response.follow]);
8246
+ this.updateStateFromFollows([response.follow], !!request.enrich_own_fields);
8108
8247
  return response;
8109
8248
  }
8110
8249
  /**
@@ -8114,12 +8253,12 @@ class FeedsClient extends FeedsApi {
8114
8253
  */
8115
8254
  async followBatch(request) {
8116
8255
  const response = await super.followBatch(request);
8117
- this.updateStateFromFollows(response.follows);
8256
+ this.updateStateFromFollows(response.follows, !!request.enrich_own_fields);
8118
8257
  return response;
8119
8258
  }
8120
8259
  async getOrCreateFollows(request) {
8121
8260
  const response = await super.getOrCreateFollows(request);
8122
- this.updateStateFromFollows(response.created);
8261
+ this.updateStateFromFollows(response.created, !!request.enrich_own_fields);
8123
8262
  return response;
8124
8263
  }
8125
8264
  async unfollow(request) {
@@ -8210,13 +8349,15 @@ class FeedsClient extends FeedsApi {
8210
8349
  }).map((a) => getFeed.call(a))
8211
8350
  ];
8212
8351
  }
8213
- updateStateFromFollows(follows) {
8352
+ updateStateFromFollows(follows, hasOwnFields) {
8214
8353
  follows.forEach((follow) => {
8215
8354
  const feeds = [
8216
8355
  ...this.findAllActiveFeedsByFid(follow.source_feed.feed),
8217
8356
  ...this.findAllActiveFeedsByFid(follow.target_feed.feed)
8218
8357
  ];
8219
- feeds.forEach((f) => handleFollowCreated.bind(f)({ follow }, false));
8358
+ feeds.forEach(
8359
+ (f) => handleFollowCreated.bind(f)({ follow }, false, hasOwnFields)
8360
+ );
8220
8361
  });
8221
8362
  }
8222
8363
  updateStateFromUnfollows(follows) {
@@ -8246,22 +8387,23 @@ export {
8246
8387
  Constants as C,
8247
8388
  FeedsClient as F,
8248
8389
  StreamApiError as S,
8249
- Feed as a,
8250
- StreamPoll as b,
8251
- checkHasAnotherPage as c,
8390
+ activityFilter as a,
8391
+ Feed as b,
8392
+ StreamPoll as c,
8252
8393
  debounce as d,
8253
- isFollowResponse as e,
8254
- isReactionResponse as f,
8255
- isCommentResponse as g,
8256
- isImageFile as h,
8394
+ checkHasAnotherPage as e,
8395
+ isFollowResponse as f,
8396
+ isReactionResponse as g,
8397
+ isCommentResponse as h,
8257
8398
  isVoteAnswer as i,
8258
- isVideoFile as j,
8259
- getStateUpdateQueueId as k,
8260
- updateEntityInArray as l,
8261
- feedsLoggerSystem as m,
8262
- ensureExhausted as n,
8399
+ isImageFile as j,
8400
+ isVideoFile as k,
8401
+ getStateUpdateQueueId as l,
8402
+ updateEntityInArray as m,
8403
+ feedsLoggerSystem as n,
8404
+ ensureExhausted as o,
8263
8405
  replaceUniqueArrayMerge as r,
8264
8406
  shouldUpdateState as s,
8265
8407
  uniqueArrayMerge as u
8266
8408
  };
8267
- //# sourceMappingURL=feeds-client-BHpmg4_E.mjs.map
8409
+ //# sourceMappingURL=feeds-client-B03y08Kq.mjs.map