@stream-io/feeds-client 0.2.6 → 0.2.8
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 +21 -0
- package/dist/cjs/index.js +408 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/react-bindings.js +1368 -0
- package/dist/cjs/react-bindings.js.map +1 -0
- package/dist/es/index.mjs +398 -0
- package/dist/es/index.mjs.map +1 -0
- package/dist/es/react-bindings.mjs +1368 -0
- package/dist/es/react-bindings.mjs.map +1 -0
- package/dist/index-Cfbt0DFY.js +6492 -0
- package/dist/index-Cfbt0DFY.js.map +1 -0
- package/dist/index-DLC5hiNd.mjs +6476 -0
- package/dist/index-DLC5hiNd.mjs.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/bindings/index.d.ts +2 -0
- package/dist/types/bindings/index.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/contexts/StreamFeedContext.d.ts +2 -1
- package/dist/types/bindings/react/contexts/StreamFeedContext.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/contexts/StreamFeedsContext.d.ts +2 -1
- package/dist/types/bindings/react/contexts/StreamFeedsContext.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/contexts/StreamSearchContext.d.ts +2 -1
- package/dist/types/bindings/react/contexts/StreamSearchContext.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/contexts/StreamSearchResultsContext.d.ts +2 -1
- package/dist/types/bindings/react/contexts/StreamSearchResultsContext.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/client-state-hooks/index.d.ts +1 -0
- package/dist/types/bindings/react/hooks/client-state-hooks/index.d.ts.map +1 -0
- package/dist/types/bindings/react/hooks/client-state-hooks/useClientConnectedUser.d.ts +5 -0
- package/dist/types/bindings/react/hooks/client-state-hooks/useClientConnectedUser.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/client-state-hooks/useWsConnectionState.d.ts +1 -0
- package/dist/types/bindings/react/hooks/client-state-hooks/useWsConnectionState.d.ts.map +1 -0
- package/dist/{@react-bindings → 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 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useAggregatedActivities.d.ts +3 -2
- package/dist/types/bindings/react/hooks/feed-state-hooks/useAggregatedActivities.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useComments.d.ts +2 -3
- package/dist/types/bindings/react/hooks/feed-state-hooks/useComments.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useFeedActivities.d.ts +3 -2
- package/dist/types/bindings/react/hooks/feed-state-hooks/useFeedActivities.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useFeedMetadata.d.ts +3 -2
- package/dist/types/bindings/react/hooks/feed-state-hooks/useFeedMetadata.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useFollowers.d.ts +5 -4
- package/dist/types/bindings/react/hooks/feed-state-hooks/useFollowers.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useFollowing.d.ts +5 -4
- package/dist/types/bindings/react/hooks/feed-state-hooks/useFollowing.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useIsAggregatedActivityRead.d.ts +2 -2
- package/dist/types/bindings/react/hooks/feed-state-hooks/useIsAggregatedActivityRead.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useIsAggregatedActivitySeen.d.ts +2 -2
- package/dist/types/bindings/react/hooks/feed-state-hooks/useIsAggregatedActivitySeen.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useNotificationStatus.d.ts +2 -1
- package/dist/types/bindings/react/hooks/feed-state-hooks/useNotificationStatus.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useOwnCapabilities.d.ts +2 -1
- package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/feed-state-hooks/useOwnFollows.d.ts +3 -2
- package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnFollows.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/internal/index.d.ts +1 -0
- package/dist/types/bindings/react/hooks/internal/index.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/internal/useStableCallback.d.ts +1 -0
- package/dist/types/bindings/react/hooks/internal/useStableCallback.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/search-state-hooks/index.d.ts +1 -0
- package/dist/types/bindings/react/hooks/search-state-hooks/index.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/search-state-hooks/useSearchQuery.d.ts +2 -1
- package/dist/types/bindings/react/hooks/search-state-hooks/useSearchQuery.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/search-state-hooks/useSearchResult.d.ts +2 -1
- package/dist/types/bindings/react/hooks/search-state-hooks/useSearchResult.d.ts.map +1 -0
- package/dist/types/bindings/react/hooks/search-state-hooks/useSearchSources.d.ts +5 -0
- package/dist/types/bindings/react/hooks/search-state-hooks/useSearchSources.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/useCreateFeedsClient.d.ts +2 -4
- package/dist/types/bindings/react/hooks/useCreateFeedsClient.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/util/index.d.ts +1 -0
- package/dist/types/bindings/react/hooks/util/index.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/util/useBookmarkActions.d.ts +2 -1
- package/dist/types/bindings/react/hooks/util/useBookmarkActions.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/hooks/util/useReactionActions.d.ts +2 -1
- package/dist/types/bindings/react/hooks/util/useReactionActions.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/index.d.ts +2 -1
- package/dist/types/bindings/react/index.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/wrappers/StreamFeed.d.ts +2 -1
- package/dist/types/bindings/react/wrappers/StreamFeed.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/wrappers/StreamFeeds.d.ts +1 -0
- package/dist/types/bindings/react/wrappers/StreamFeeds.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/wrappers/StreamSearch.d.ts +2 -1
- package/dist/types/bindings/react/wrappers/StreamSearch.d.ts.map +1 -0
- package/dist/{@react-bindings → types/bindings/react}/wrappers/StreamSearchResults.d.ts +2 -1
- package/dist/types/bindings/react/wrappers/StreamSearchResults.d.ts.map +1 -0
- package/dist/{src → types}/common/ApiClient.d.ts +18 -0
- package/dist/types/common/ApiClient.d.ts.map +1 -0
- package/dist/{src → types}/common/ConnectionIdManager.d.ts +1 -0
- package/dist/types/common/ConnectionIdManager.d.ts.map +1 -0
- package/dist/{src → types}/common/EventDispatcher.d.ts +1 -0
- package/dist/types/common/EventDispatcher.d.ts.map +1 -0
- package/dist/{src → types}/common/Poll.d.ts +2 -1
- package/dist/types/common/Poll.d.ts.map +1 -0
- package/dist/{src → types}/common/TokenManager.d.ts +2 -0
- package/dist/types/common/TokenManager.d.ts.map +1 -0
- package/dist/{src → types}/common/gen-imports.d.ts +1 -0
- package/dist/types/common/gen-imports.d.ts.map +1 -0
- package/dist/{src → types}/common/rate-limit.d.ts +1 -0
- package/dist/types/common/rate-limit.d.ts.map +1 -0
- package/dist/{src → types}/common/real-time/StableWSConnection.d.ts +4 -4
- package/dist/types/common/real-time/StableWSConnection.d.ts.map +1 -0
- package/dist/{src → types}/common/real-time/event-models.d.ts +1 -0
- package/dist/types/common/real-time/event-models.d.ts.map +1 -0
- package/dist/{src → types}/common/search/ActivitySearchSource.d.ts +1 -0
- package/dist/types/common/search/ActivitySearchSource.d.ts.map +1 -0
- package/dist/{src → types}/common/search/BaseSearchSource.d.ts +2 -1
- package/dist/types/common/search/BaseSearchSource.d.ts.map +1 -0
- package/dist/{src → types}/common/search/FeedSearchSource.d.ts +1 -0
- package/dist/types/common/search/FeedSearchSource.d.ts.map +1 -0
- package/dist/{src → types}/common/search/SearchController.d.ts +2 -1
- package/dist/types/common/search/SearchController.d.ts.map +1 -0
- package/dist/{src → types}/common/search/UserSearchSource.d.ts +2 -1
- package/dist/types/common/search/UserSearchSource.d.ts.map +1 -0
- package/dist/{src → types}/common/search/index.d.ts +1 -0
- package/dist/types/common/search/index.d.ts.map +1 -0
- package/dist/{src → types}/common/search/types.d.ts +1 -0
- package/dist/types/common/search/types.d.ts.map +1 -0
- package/dist/{src → types}/common/types.d.ts +3 -1
- package/dist/types/common/types.d.ts.map +1 -0
- package/dist/{src → types}/common/utils.d.ts +1 -0
- package/dist/types/common/utils.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/activity/handle-activity-added.d.ts +3 -2
- package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/activity/handle-activity-deleted.d.ts +3 -2
- package/dist/types/feed/event-handlers/activity/handle-activity-deleted.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/activity/handle-activity-marked.d.ts +1 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-marked.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/activity/handle-activity-pinned.d.ts +1 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-pinned.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-reaction-added.d.ts +15 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-reaction-added.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-reaction-deleted.d.ts +15 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-reaction-deleted.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/activity/handle-activity-removed-from-feed.d.ts +1 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-removed-from-feed.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/activity/handle-activity-unpinned.d.ts +1 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-unpinned.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/activity/handle-activity-updated.d.ts +1 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/activity/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/activity/index.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/bookmark/handle-bookmark-added.d.ts +1 -0
- package/dist/types/feed/event-handlers/bookmark/handle-bookmark-added.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/bookmark/handle-bookmark-deleted.d.ts +1 -0
- package/dist/types/feed/event-handlers/bookmark/handle-bookmark-deleted.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/bookmark/handle-bookmark-updated.d.ts +1 -0
- package/dist/types/feed/event-handlers/bookmark/handle-bookmark-updated.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/bookmark/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/bookmark/index.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/comment/handle-comment-added.d.ts +1 -0
- package/dist/types/feed/event-handlers/comment/handle-comment-added.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/comment/handle-comment-deleted.d.ts +1 -0
- package/dist/types/feed/event-handlers/comment/handle-comment-deleted.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/comment/handle-comment-reaction.d.ts +1 -0
- package/dist/types/feed/event-handlers/comment/handle-comment-reaction.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/comment/handle-comment-updated.d.ts +1 -0
- package/dist/types/feed/event-handlers/comment/handle-comment-updated.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/comment/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/comment/index.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/feed/handle-feed-updated.d.ts +1 -0
- package/dist/types/feed/event-handlers/feed/handle-feed-updated.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/feed/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/feed/index.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/feed-member/handle-feed-member-added.d.ts +1 -0
- package/dist/types/feed/event-handlers/feed-member/handle-feed-member-added.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/feed-member/handle-feed-member-removed.d.ts +1 -0
- package/dist/types/feed/event-handlers/feed-member/handle-feed-member-removed.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/feed-member/handle-feed-member-updated.d.ts +1 -0
- package/dist/types/feed/event-handlers/feed-member/handle-feed-member-updated.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/feed-member/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/feed-member/index.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/follow/handle-follow-created.d.ts +3 -2
- package/dist/types/feed/event-handlers/follow/handle-follow-created.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/follow/handle-follow-deleted.d.ts +2 -1
- package/dist/types/feed/event-handlers/follow/handle-follow-deleted.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/follow/handle-follow-updated.d.ts +3 -2
- package/dist/types/feed/event-handlers/follow/handle-follow-updated.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/follow/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/follow/index.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/index.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts +1 -0
- package/dist/types/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/notification-feed/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/notification-feed/index.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/watch/handle-watch-started.d.ts +1 -0
- package/dist/types/feed/event-handlers/watch/handle-watch-started.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/watch/handle-watch-stopped.d.ts +1 -0
- package/dist/types/feed/event-handlers/watch/handle-watch-stopped.d.ts.map +1 -0
- package/dist/{src → types}/feed/event-handlers/watch/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/watch/index.d.ts.map +1 -0
- package/dist/{src → types}/feed/feed.d.ts +9 -6
- package/dist/types/feed/feed.d.ts.map +1 -0
- package/dist/{src → types}/feed/index.d.ts +1 -0
- package/dist/types/feed/index.d.ts.map +1 -0
- package/dist/{src → types}/feeds-client/event-handlers/index.d.ts +1 -0
- package/dist/types/feeds-client/event-handlers/index.d.ts.map +1 -0
- package/dist/{src → types}/feeds-client/event-handlers/user/handle-user-updated.d.ts +1 -0
- package/dist/types/feeds-client/event-handlers/user/handle-user-updated.d.ts.map +1 -0
- package/dist/{src → types}/feeds-client/feeds-client.d.ts +18 -10
- package/dist/types/feeds-client/feeds-client.d.ts.map +1 -0
- package/dist/{src → types}/feeds-client/index.d.ts +1 -0
- package/dist/types/feeds-client/index.d.ts.map +1 -0
- package/dist/{src → types}/gen/feeds/FeedApi.d.ts +1 -0
- package/dist/types/gen/feeds/FeedApi.d.ts.map +1 -0
- package/dist/{src → types}/gen/feeds/FeedsApi.d.ts +1 -0
- package/dist/types/gen/feeds/FeedsApi.d.ts.map +1 -0
- package/dist/{src → types}/gen/model-decoders/decoders.d.ts +1 -0
- package/dist/types/gen/model-decoders/decoders.d.ts.map +1 -0
- package/dist/{src → types}/gen/model-decoders/event-decoder-mapping.d.ts +1 -0
- package/dist/types/gen/model-decoders/event-decoder-mapping.d.ts.map +1 -0
- package/dist/{src → types}/gen/models/index.d.ts +43 -1
- package/dist/types/gen/models/index.d.ts.map +1 -0
- package/dist/{src → types}/gen/moderation/ModerationApi.d.ts +1 -0
- package/dist/types/gen/moderation/ModerationApi.d.ts.map +1 -0
- package/dist/{src → types}/gen-imports.d.ts +1 -0
- package/dist/types/gen-imports.d.ts.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/{src → types}/moderation-client.d.ts +1 -0
- package/dist/types/moderation-client.d.ts.map +1 -0
- package/dist/{src → types}/types-internal.d.ts +4 -0
- package/dist/types/types-internal.d.ts.map +1 -0
- package/dist/{src → types}/types.d.ts +1 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/{src → types}/utils/check-has-another-page.d.ts +1 -0
- package/dist/types/utils/check-has-another-page.d.ts.map +1 -0
- package/dist/{src → types}/utils/constants.d.ts +1 -0
- package/dist/types/utils/constants.d.ts.map +1 -0
- package/dist/{src → types}/utils/index.d.ts +2 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/is-react-native.d.ts +5 -0
- package/dist/types/utils/is-react-native.d.ts.map +1 -0
- package/dist/types/utils/logger.d.ts +61 -0
- package/dist/types/utils/logger.d.ts.map +1 -0
- package/dist/types/utils/state-update-queue.d.ts +83 -0
- package/dist/types/utils/state-update-queue.d.ts.map +1 -0
- package/dist/types/utils/type-assertions.d.ts +12 -0
- package/dist/types/utils/type-assertions.d.ts.map +1 -0
- package/dist/{src → types}/utils/unique-array-merge.d.ts +1 -0
- package/dist/types/utils/unique-array-merge.d.ts.map +1 -0
- package/dist/{src → types}/utils/update-entity-in-array.d.ts +1 -0
- package/dist/types/utils/update-entity-in-array.d.ts.map +1 -0
- package/package.json +21 -33
- package/src/bindings/index.ts +1 -0
- package/src/bindings/react/contexts/StreamFeedContext.tsx +18 -0
- package/src/bindings/react/contexts/StreamFeedsContext.tsx +21 -0
- package/src/bindings/react/contexts/StreamSearchContext.tsx +18 -0
- package/src/bindings/react/contexts/StreamSearchResultsContext.tsx +20 -0
- package/src/bindings/react/hooks/client-state-hooks/useClientConnectedUser.ts +18 -0
- package/src/bindings/react/hooks/client-state-hooks/useWsConnectionState.ts +18 -0
- package/src/bindings/react/hooks/feed-state-hooks/useAggregatedActivities.ts +25 -0
- package/src/bindings/react/hooks/feed-state-hooks/useComments.ts +91 -0
- package/src/bindings/react/hooks/feed-state-hooks/useFeedActivities.ts +36 -0
- package/src/bindings/react/hooks/feed-state-hooks/useFeedMetadata.ts +28 -0
- package/src/bindings/react/hooks/feed-state-hooks/useFollowers.ts +54 -0
- package/src/bindings/react/hooks/feed-state-hooks/useFollowing.ts +54 -0
- package/src/bindings/react/hooks/feed-state-hooks/useIsAggregatedActivityRead.ts +29 -0
- package/src/bindings/react/hooks/feed-state-hooks/useIsAggregatedActivitySeen.ts +28 -0
- package/src/bindings/react/hooks/feed-state-hooks/useNotificationStatus.ts +28 -0
- package/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts +70 -0
- package/src/bindings/react/hooks/feed-state-hooks/useOwnFollows.ts +18 -0
- package/src/bindings/react/hooks/internal/useStableCallback.ts +37 -0
- package/src/bindings/react/hooks/search-state-hooks/useSearchQuery.ts +14 -0
- package/src/bindings/react/hooks/search-state-hooks/useSearchResult.ts +36 -0
- package/src/bindings/react/hooks/search-state-hooks/useSearchSources.ts +17 -0
- package/src/bindings/react/hooks/useCreateFeedsClient.ts +73 -0
- package/src/bindings/react/hooks/util/useBookmarkActions.ts +40 -0
- package/src/bindings/react/hooks/util/useReactionActions.ts +56 -0
- package/{@react-bindings → src/bindings/react}/index.ts +1 -1
- package/src/bindings/react/wrappers/StreamFeed.tsx +23 -0
- package/src/bindings/react/wrappers/StreamFeeds.tsx +13 -0
- package/src/bindings/react/wrappers/StreamSearch.tsx +23 -0
- package/src/bindings/react/wrappers/StreamSearchResults.tsx +23 -0
- package/src/common/ApiClient.ts +86 -33
- package/src/common/EventDispatcher.ts +3 -6
- package/src/common/Poll.ts +1 -1
- package/src/common/TokenManager.ts +4 -0
- package/src/common/real-time/StableWSConnection.ts +64 -60
- package/src/common/search/BaseSearchSource.ts +11 -4
- package/src/common/search/SearchController.ts +4 -2
- package/src/common/types.ts +3 -2
- package/src/feed/event-handlers/activity/activity-utils.test.ts +40 -9
- package/src/feed/event-handlers/activity/handle-activity-added.test.ts +1 -1
- package/src/feed/event-handlers/activity/handle-activity-added.ts +7 -7
- package/src/feed/event-handlers/activity/handle-activity-deleted.ts +15 -12
- package/src/feed/event-handlers/activity/handle-activity-reaction-added.test.ts +101 -1
- package/src/feed/event-handlers/activity/handle-activity-reaction-added.ts +55 -29
- package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.test.ts +118 -1
- package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.ts +59 -32
- package/src/feed/event-handlers/activity/handle-activity-removed-from-feed.ts +1 -1
- package/src/feed/event-handlers/follow/follow-state-update-queue.test.ts +219 -0
- package/src/feed/event-handlers/follow/handle-follow-created.ts +7 -2
- package/src/feed/event-handlers/follow/handle-follow-deleted.ts +5 -0
- package/src/feed/event-handlers/follow/handle-follow-updated.test.ts +0 -43
- package/src/feed/event-handlers/follow/handle-follow-updated.ts +7 -2
- package/src/feed/feed.test.ts +90 -0
- package/src/feed/feed.ts +25 -4
- package/src/feeds-client/feeds-client.ts +35 -4
- package/src/gen/feeds/FeedsApi.ts +2 -0
- package/src/gen/model-decoders/decoders.ts +22 -0
- package/src/gen/models/index.ts +71 -1
- package/src/index.ts +9 -0
- package/src/test-utils/response-generators.ts +12 -3
- package/src/types-internal.ts +4 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/is-react-native.ts +7 -0
- package/src/utils/logger.ts +18 -0
- package/src/utils/state-update-queue.test.ts +85 -9
- package/src/utils/state-update-queue.ts +104 -11
- package/src/utils/type-assertions.ts +22 -1
- package/dist/@react-bindings/hooks/client-state-hooks/useClientConnectedUser.d.ts +0 -4
- package/dist/@react-bindings/hooks/search-state-hooks/useSearchSources.d.ts +0 -4
- package/dist/@react-bindings/hooks/useStateStore.d.ts +0 -3
- package/dist/index-react-bindings.browser.cjs +0 -6607
- package/dist/index-react-bindings.browser.cjs.map +0 -1
- package/dist/index-react-bindings.browser.js +0 -6574
- package/dist/index-react-bindings.browser.js.map +0 -1
- package/dist/index-react-bindings.node.cjs +0 -6607
- package/dist/index-react-bindings.node.cjs.map +0 -1
- package/dist/index-react-bindings.node.js +0 -6574
- package/dist/index-react-bindings.node.js.map +0 -1
- package/dist/index.browser.cjs +0 -6578
- package/dist/index.browser.cjs.map +0 -1
- package/dist/index.browser.js +0 -6551
- package/dist/index.browser.js.map +0 -1
- package/dist/index.d.ts +0 -9
- package/dist/index.node.cjs +0 -6578
- package/dist/index.node.cjs.map +0 -1
- package/dist/index.node.js +0 -6551
- package/dist/index.node.js.map +0 -1
- package/dist/src/common/StateStore.d.ts +0 -125
- package/dist/src/feed/event-handlers/activity/handle-activity-reaction-added.d.ts +0 -12
- package/dist/src/feed/event-handlers/activity/handle-activity-reaction-deleted.d.ts +0 -12
- package/dist/src/utils/state-update-queue.d.ts +0 -6
- package/dist/src/utils/type-assertions.d.ts +0 -7
- package/index.ts +0 -9
- package/src/common/StateStore.ts +0 -332
- /package/{@react-bindings → src/bindings/react}/hooks/client-state-hooks/index.ts +0 -0
- /package/{@react-bindings → src/bindings/react}/hooks/feed-state-hooks/index.ts +0 -0
- /package/{@react-bindings → src/bindings/react}/hooks/internal/index.ts +0 -0
- /package/{@react-bindings → src/bindings/react}/hooks/search-state-hooks/index.ts +0 -0
- /package/{@react-bindings → src/bindings/react}/hooks/util/index.ts +0 -0
package/src/gen/models/index.ts
CHANGED
|
@@ -473,7 +473,7 @@ export interface ActivityResponse {
|
|
|
473
473
|
|
|
474
474
|
moderation?: ModerationV2Response;
|
|
475
475
|
|
|
476
|
-
notification_context?:
|
|
476
|
+
notification_context?: NotificationContext;
|
|
477
477
|
|
|
478
478
|
parent?: ActivityResponse;
|
|
479
479
|
|
|
@@ -587,6 +587,8 @@ export interface AddCommentReactionRequest {
|
|
|
587
587
|
|
|
588
588
|
create_notification_activity?: boolean;
|
|
589
589
|
|
|
590
|
+
enforce_unique?: boolean;
|
|
591
|
+
|
|
590
592
|
skip_push?: boolean;
|
|
591
593
|
|
|
592
594
|
custom?: Record<string, any>;
|
|
@@ -647,6 +649,8 @@ export interface AddReactionRequest {
|
|
|
647
649
|
|
|
648
650
|
create_notification_activity?: boolean;
|
|
649
651
|
|
|
652
|
+
enforce_unique?: boolean;
|
|
653
|
+
|
|
650
654
|
skip_push?: boolean;
|
|
651
655
|
|
|
652
656
|
custom?: Record<string, any>;
|
|
@@ -1223,6 +1227,8 @@ export interface CallIngressResponse {
|
|
|
1223
1227
|
rtmp: RTMPIngress;
|
|
1224
1228
|
|
|
1225
1229
|
srt: SRTIngress;
|
|
1230
|
+
|
|
1231
|
+
whip: WHIPIngress;
|
|
1226
1232
|
}
|
|
1227
1233
|
|
|
1228
1234
|
export interface CallMember {
|
|
@@ -1312,6 +1318,8 @@ export interface CallResponse {
|
|
|
1312
1318
|
|
|
1313
1319
|
transcribing: boolean;
|
|
1314
1320
|
|
|
1321
|
+
translating: boolean;
|
|
1322
|
+
|
|
1315
1323
|
type: string;
|
|
1316
1324
|
|
|
1317
1325
|
updated_at: Date;
|
|
@@ -1544,6 +1552,8 @@ export interface Channel {
|
|
|
1544
1552
|
|
|
1545
1553
|
created_by?: User;
|
|
1546
1554
|
|
|
1555
|
+
members_lookup?: Record<string, ChannelMemberLookup>;
|
|
1556
|
+
|
|
1547
1557
|
truncated_by?: User;
|
|
1548
1558
|
}
|
|
1549
1559
|
|
|
@@ -1727,6 +1737,22 @@ export interface ChannelMember {
|
|
|
1727
1737
|
user?: UserResponse;
|
|
1728
1738
|
}
|
|
1729
1739
|
|
|
1740
|
+
export interface ChannelMemberLookup {
|
|
1741
|
+
archived: boolean;
|
|
1742
|
+
|
|
1743
|
+
banned: boolean;
|
|
1744
|
+
|
|
1745
|
+
hidden: boolean;
|
|
1746
|
+
|
|
1747
|
+
pinned: boolean;
|
|
1748
|
+
|
|
1749
|
+
archived_at?: Date;
|
|
1750
|
+
|
|
1751
|
+
ban_expires?: Date;
|
|
1752
|
+
|
|
1753
|
+
pinned_at?: Date;
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1730
1756
|
export interface ChannelMemberResponse {
|
|
1731
1757
|
channel_role: string;
|
|
1732
1758
|
}
|
|
@@ -2269,6 +2295,10 @@ export interface DeleteCommentReactionResponse {
|
|
|
2269
2295
|
|
|
2270
2296
|
export interface DeleteCommentResponse {
|
|
2271
2297
|
duration: string;
|
|
2298
|
+
|
|
2299
|
+
activity: ActivityResponse;
|
|
2300
|
+
|
|
2301
|
+
comment: CommentResponse;
|
|
2272
2302
|
}
|
|
2273
2303
|
|
|
2274
2304
|
export interface DeleteFeedResponse {
|
|
@@ -4050,6 +4080,12 @@ export interface NotificationConfig {
|
|
|
4050
4080
|
track_seen?: boolean;
|
|
4051
4081
|
}
|
|
4052
4082
|
|
|
4083
|
+
export interface NotificationContext {
|
|
4084
|
+
target?: NotificationTarget;
|
|
4085
|
+
|
|
4086
|
+
trigger?: NotificationTrigger;
|
|
4087
|
+
}
|
|
4088
|
+
|
|
4053
4089
|
export interface NotificationFeedUpdatedEvent {
|
|
4054
4090
|
created_at: Date;
|
|
4055
4091
|
|
|
@@ -4098,6 +4134,26 @@ export interface NotificationStatusResponse {
|
|
|
4098
4134
|
seen_activities?: string[];
|
|
4099
4135
|
}
|
|
4100
4136
|
|
|
4137
|
+
export interface NotificationTarget {
|
|
4138
|
+
id: string;
|
|
4139
|
+
|
|
4140
|
+
name?: string;
|
|
4141
|
+
|
|
4142
|
+
text?: string;
|
|
4143
|
+
|
|
4144
|
+
type?: string;
|
|
4145
|
+
|
|
4146
|
+
user_id?: string;
|
|
4147
|
+
|
|
4148
|
+
attachments?: Attachment[];
|
|
4149
|
+
}
|
|
4150
|
+
|
|
4151
|
+
export interface NotificationTrigger {
|
|
4152
|
+
text: string;
|
|
4153
|
+
|
|
4154
|
+
type: string;
|
|
4155
|
+
}
|
|
4156
|
+
|
|
4101
4157
|
export interface NullTime {}
|
|
4102
4158
|
|
|
4103
4159
|
export interface OCRRule {
|
|
@@ -5699,6 +5755,8 @@ export interface TranscriptionSettings {
|
|
|
5699
5755
|
mode: 'available' | 'disabled' | 'auto-on';
|
|
5700
5756
|
|
|
5701
5757
|
speech_segment_config?: SpeechSegmentConfig;
|
|
5758
|
+
|
|
5759
|
+
translation?: TranslationSettings;
|
|
5702
5760
|
}
|
|
5703
5761
|
|
|
5704
5762
|
export interface TranscriptionSettingsResponse {
|
|
@@ -5746,6 +5804,14 @@ export interface TranscriptionSettingsResponse {
|
|
|
5746
5804
|
mode: 'available' | 'disabled' | 'auto-on';
|
|
5747
5805
|
|
|
5748
5806
|
speech_segment_config?: SpeechSegmentConfig;
|
|
5807
|
+
|
|
5808
|
+
translation?: TranslationSettings;
|
|
5809
|
+
}
|
|
5810
|
+
|
|
5811
|
+
export interface TranslationSettings {
|
|
5812
|
+
enabled: boolean;
|
|
5813
|
+
|
|
5814
|
+
languages: string[];
|
|
5749
5815
|
}
|
|
5750
5816
|
|
|
5751
5817
|
export interface TypingIndicators {
|
|
@@ -6449,6 +6515,10 @@ export interface VoteData {
|
|
|
6449
6515
|
option_id?: string;
|
|
6450
6516
|
}
|
|
6451
6517
|
|
|
6518
|
+
export interface WHIPIngress {
|
|
6519
|
+
address: string;
|
|
6520
|
+
}
|
|
6521
|
+
|
|
6452
6522
|
export interface WSAuthMessage {
|
|
6453
6523
|
token: string;
|
|
6454
6524
|
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from '@stream-io/state-store';
|
|
2
|
+
export * from './feeds-client/feeds-client';
|
|
3
|
+
export * from './feed/feed';
|
|
4
|
+
export * from './gen/models';
|
|
5
|
+
export * from './types';
|
|
6
|
+
export * from './common/types';
|
|
7
|
+
export * from './common/search';
|
|
8
|
+
export * from './common/Poll';
|
|
9
|
+
export * from './utils';
|
|
@@ -414,10 +414,14 @@ export function generateBookmarkUpdatedEvent(
|
|
|
414
414
|
export function generateCommentAddedEvent(
|
|
415
415
|
overrides: Omit<
|
|
416
416
|
Partial<EventPayload<'feeds.comment.added'>>,
|
|
417
|
-
'comment' | 'type'
|
|
418
|
-
> & {
|
|
417
|
+
'comment' | 'activity' | 'type'
|
|
418
|
+
> & {
|
|
419
|
+
comment?: Parameters<typeof generateCommentResponse>[0];
|
|
420
|
+
activity?: Parameters<typeof generateActivityResponse>[0];
|
|
421
|
+
} = {},
|
|
419
422
|
): EventPayload<'feeds.comment.added'> {
|
|
420
423
|
const comment = generateCommentResponse(overrides.comment);
|
|
424
|
+
const activity = generateActivityResponse(overrides.activity);
|
|
421
425
|
return {
|
|
422
426
|
type: 'feeds.comment.added',
|
|
423
427
|
created_at: new Date(),
|
|
@@ -425,6 +429,7 @@ export function generateCommentAddedEvent(
|
|
|
425
429
|
custom: {},
|
|
426
430
|
...overrides,
|
|
427
431
|
comment,
|
|
432
|
+
activity,
|
|
428
433
|
};
|
|
429
434
|
}
|
|
430
435
|
|
|
@@ -465,14 +470,17 @@ export function generateCommentUpdatedEvent(
|
|
|
465
470
|
export function generateCommentReactionAddedEvent(
|
|
466
471
|
overrides: Omit<
|
|
467
472
|
Partial<EventPayload<'feeds.comment.reaction.added'>>,
|
|
468
|
-
'comment' | 'reaction' | 'type'
|
|
473
|
+
'comment' | 'reaction' | 'activity' | 'type'
|
|
469
474
|
> & {
|
|
470
475
|
comment?: Parameters<typeof generateCommentResponse>[0];
|
|
471
476
|
reaction?: Parameters<typeof generateFeedReactionResponse>[0];
|
|
477
|
+
activity?: Parameters<typeof generateActivityResponse>[0];
|
|
472
478
|
} = {},
|
|
473
479
|
): EventPayload<'feeds.comment.reaction.added'> {
|
|
474
480
|
const comment = generateCommentResponse(overrides.comment);
|
|
475
481
|
const reaction = generateFeedReactionResponse(overrides.reaction);
|
|
482
|
+
const activity = generateActivityResponse(overrides.activity);
|
|
483
|
+
|
|
476
484
|
return {
|
|
477
485
|
type: 'feeds.comment.reaction.added',
|
|
478
486
|
created_at: new Date(),
|
|
@@ -481,6 +489,7 @@ export function generateCommentReactionAddedEvent(
|
|
|
481
489
|
...overrides,
|
|
482
490
|
comment,
|
|
483
491
|
reaction,
|
|
492
|
+
activity,
|
|
484
493
|
};
|
|
485
494
|
}
|
|
486
495
|
|
package/src/types-internal.ts
CHANGED
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as loggerInternal from '@stream-io/logger';
|
|
2
|
+
|
|
3
|
+
type AvailableScopes =
|
|
4
|
+
| 'api-client'
|
|
5
|
+
| 'event-dispatcher'
|
|
6
|
+
| 'token-manager'
|
|
7
|
+
| 'stable-ws-connection';
|
|
8
|
+
|
|
9
|
+
export type ConfigureLoggersOptions =
|
|
10
|
+
loggerInternal.ConfigureLoggersOptions<AvailableScopes>;
|
|
11
|
+
export type Logger = loggerInternal.Logger<AvailableScopes>;
|
|
12
|
+
|
|
13
|
+
export const configureLoggers =
|
|
14
|
+
loggerInternal.configureLoggers<AvailableScopes>;
|
|
15
|
+
export const getLogger = loggerInternal.getLogger<AvailableScopes>;
|
|
16
|
+
|
|
17
|
+
export type { LogLevel, Sink } from '@stream-io/logger';
|
|
18
|
+
export { LogLevelEnum, restoreDefaults } from '@stream-io/logger';
|
|
@@ -4,50 +4,126 @@ import { shouldUpdateState } from './state-update-queue';
|
|
|
4
4
|
|
|
5
5
|
describe('state-update-queue', () => {
|
|
6
6
|
describe('shouldUpdateState', () => {
|
|
7
|
-
it('should return true when watch is false', () => {
|
|
7
|
+
it('should return true when only watch is false', () => {
|
|
8
8
|
const result = shouldUpdateState({
|
|
9
9
|
stateUpdateQueueId: 'test-id',
|
|
10
|
-
stateUpdateQueue: new Set(['other-id']),
|
|
10
|
+
stateUpdateQueue: new Set(['ws-other-id']),
|
|
11
11
|
watch: false,
|
|
12
|
+
isTriggeredByConnectedUser: true,
|
|
12
13
|
});
|
|
13
14
|
|
|
14
15
|
expect(result).toBe(true);
|
|
15
16
|
});
|
|
16
17
|
|
|
17
|
-
it('should return true when
|
|
18
|
-
const
|
|
18
|
+
it('should return true when only isTriggeredByConnectedUser is false', () => {
|
|
19
|
+
const result = shouldUpdateState({
|
|
20
|
+
stateUpdateQueueId: 'test-id',
|
|
21
|
+
stateUpdateQueue: new Set(['ws-other-id']),
|
|
22
|
+
watch: true,
|
|
23
|
+
isTriggeredByConnectedUser: false,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
expect(result).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should return true when watch is true and it is triggered by the connected_user, but queueId is not in queue', () => {
|
|
30
|
+
const stateUpdateQueue = new Set(['ws-other-id-1', 'ws-other-id-2']);
|
|
19
31
|
|
|
20
32
|
const result = shouldUpdateState({
|
|
21
33
|
stateUpdateQueueId: 'test-id',
|
|
22
34
|
stateUpdateQueue: stateUpdateQueue,
|
|
23
35
|
watch: true,
|
|
36
|
+
isTriggeredByConnectedUser: true,
|
|
24
37
|
});
|
|
25
38
|
|
|
26
|
-
expect(stateUpdateQueue).toContain('test-id');
|
|
39
|
+
expect(stateUpdateQueue).toContain('ws-test-id');
|
|
27
40
|
expect(result).toBe(true);
|
|
28
41
|
});
|
|
29
42
|
|
|
30
|
-
it('should return false and remove queueId from queue when watch is true and queueId is in queue', () => {
|
|
31
|
-
const stateUpdateQueue = new Set(['test-id', 'other-id']);
|
|
43
|
+
it('should return false and remove queueId from queue when watch is true and WS initiated queueId is in queue', () => {
|
|
44
|
+
const stateUpdateQueue = new Set(['ws-test-id', 'ws-other-id']);
|
|
32
45
|
|
|
33
46
|
const result = shouldUpdateState({
|
|
34
47
|
stateUpdateQueueId: 'test-id',
|
|
35
48
|
stateUpdateQueue,
|
|
36
49
|
watch: true,
|
|
50
|
+
fromWs: false,
|
|
51
|
+
isTriggeredByConnectedUser: true,
|
|
37
52
|
});
|
|
38
53
|
|
|
39
54
|
expect(result).toBe(false);
|
|
40
|
-
expect(stateUpdateQueue).toEqual(new Set(['other-id']));
|
|
55
|
+
expect(stateUpdateQueue).toEqual(new Set(['ws-other-id']));
|
|
41
56
|
});
|
|
42
57
|
|
|
43
|
-
it('should
|
|
58
|
+
it('should return false and remove queueId from queue when watch is true and HTTP initiated queueId is in queue', () => {
|
|
59
|
+
const stateUpdateQueue = new Set(['http-test-id', 'http-other-id']);
|
|
60
|
+
|
|
61
|
+
const result = shouldUpdateState({
|
|
62
|
+
stateUpdateQueueId: 'test-id',
|
|
63
|
+
stateUpdateQueue,
|
|
64
|
+
watch: true,
|
|
65
|
+
isTriggeredByConnectedUser: true,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
expect(result).toBe(false);
|
|
69
|
+
expect(stateUpdateQueue).toEqual(new Set(['http-other-id']));
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should handle empty queue when conditions are met', () => {
|
|
44
73
|
const result = shouldUpdateState({
|
|
45
74
|
stateUpdateQueueId: 'test-id',
|
|
46
75
|
stateUpdateQueue: new Set(),
|
|
47
76
|
watch: true,
|
|
77
|
+
isTriggeredByConnectedUser: true,
|
|
48
78
|
});
|
|
49
79
|
|
|
50
80
|
expect(result).toBe(true);
|
|
51
81
|
});
|
|
82
|
+
|
|
83
|
+
it('should not clear the queue state if 2 equal HTTP response updates arrive', () => {
|
|
84
|
+
const stateUpdateQueue = new Set<string>();
|
|
85
|
+
|
|
86
|
+
const result1 = shouldUpdateState({
|
|
87
|
+
stateUpdateQueueId: 'test-id',
|
|
88
|
+
stateUpdateQueue,
|
|
89
|
+
watch: true,
|
|
90
|
+
fromWs: false,
|
|
91
|
+
isTriggeredByConnectedUser: true,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const result2 = shouldUpdateState({
|
|
95
|
+
stateUpdateQueueId: 'test-id',
|
|
96
|
+
stateUpdateQueue,
|
|
97
|
+
watch: true,
|
|
98
|
+
fromWs: false,
|
|
99
|
+
isTriggeredByConnectedUser: true,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
expect(result1).toBe(true);
|
|
103
|
+
expect(result2).toBe(true);
|
|
104
|
+
expect(stateUpdateQueue).toEqual(new Set(['http-test-id']))
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('should not clear the queue state if 2 equal WS event updates arrive', () => {
|
|
108
|
+
const stateUpdateQueue = new Set<string>();
|
|
109
|
+
|
|
110
|
+
const result1 = shouldUpdateState({
|
|
111
|
+
stateUpdateQueueId: 'test-id',
|
|
112
|
+
stateUpdateQueue,
|
|
113
|
+
watch: true,
|
|
114
|
+
isTriggeredByConnectedUser: true,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const result2 = shouldUpdateState({
|
|
118
|
+
stateUpdateQueueId: 'test-id',
|
|
119
|
+
stateUpdateQueue,
|
|
120
|
+
watch: true,
|
|
121
|
+
isTriggeredByConnectedUser: true,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
expect(result1).toBe(true);
|
|
125
|
+
expect(result2).toBe(true);
|
|
126
|
+
expect(stateUpdateQueue).toEqual(new Set(['ws-test-id']))
|
|
127
|
+
})
|
|
52
128
|
});
|
|
53
129
|
});
|
|
@@ -1,24 +1,110 @@
|
|
|
1
|
-
import { isFollowResponse } from './type-assertions';
|
|
1
|
+
import { isFollowResponse, isReactionResponse } from './type-assertions';
|
|
2
|
+
import { AddCommentReactionResponse, AddReactionResponse } from '../gen/models';
|
|
2
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Decide whether to apply a state update that may arrive twice (HTTP + WS)
|
|
6
|
+
* for the same logical change initiated by the connected user.
|
|
7
|
+
*
|
|
8
|
+
* ###### Why
|
|
9
|
+
* When `watch` is enabled and the connected user triggers a change, you often get:
|
|
10
|
+
* - an immediate local/HTTP-driven update (e.g., optimistic UI, REST response)
|
|
11
|
+
* - a subsequent server broadcast over WebSocket for the same change
|
|
12
|
+
*
|
|
13
|
+
* This helper suppresses the duplicate so you apply the update exactly once.
|
|
14
|
+
*
|
|
15
|
+
* ###### How it works
|
|
16
|
+
* - Builds a prefixed key from `stateUpdateQueueId` and the transport:
|
|
17
|
+
* - HTTP → `http-${id}`
|
|
18
|
+
* - WS → `ws-${id}`
|
|
19
|
+
* - If the *paired* key already exists (e.g., WS sees `http-${id}` or HTTP sees `ws-${id}`),
|
|
20
|
+
* it removes that key and returns `false` (skip as duplicate).
|
|
21
|
+
* - Otherwise it enqueues the current prefixed key and returns `true` (apply update).
|
|
22
|
+
*
|
|
23
|
+
* ###### When it returns `true`
|
|
24
|
+
* - `watch` is `false` -> no deduping needed
|
|
25
|
+
* - `isTriggeredByConnectedUser` is `false` -> dedupe only targets that echo the initiator's
|
|
26
|
+
* - First arrival for a given `id` and transport pair
|
|
27
|
+
*
|
|
28
|
+
* ###### When it returns `false`
|
|
29
|
+
* The *second* arrival for the same logical `{id}` from the *other* transport is detected
|
|
30
|
+
* (e.g., you already saw `http-${id}`, now a `ws-${id}` arrives).
|
|
31
|
+
*
|
|
32
|
+
* ###### Example
|
|
33
|
+
* ```ts
|
|
34
|
+
* const queue = new Set<string>();
|
|
35
|
+
*
|
|
36
|
+
* 1) User follows someone → HTTP path resolves first
|
|
37
|
+
* if (shouldUpdateState({
|
|
38
|
+
* stateUpdateQueueId: 'follow:targetUserId',
|
|
39
|
+
* stateUpdateQueue: queue,
|
|
40
|
+
* watch: true,
|
|
41
|
+
* fromWs: false,
|
|
42
|
+
* isTriggeredByConnectedUser: true,
|
|
43
|
+
* })) {
|
|
44
|
+
* applyFollowLocally();
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* 2) A moment later WS echoes the same follow
|
|
48
|
+
* if (shouldUpdateState({
|
|
49
|
+
* stateUpdateQueueId: 'follow:targetUserId',
|
|
50
|
+
* stateUpdateQueue: queue,
|
|
51
|
+
* watch: true,
|
|
52
|
+
* fromWs: true,
|
|
53
|
+
* isTriggeredByConnectedUser: true,
|
|
54
|
+
* })) {
|
|
55
|
+
* // This will return false → skip duplicate
|
|
56
|
+
* applyFollowLocally();
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* ###### Reverse order also works
|
|
61
|
+
* If WS lands first and HTTP lands second, the second one will be skipped.
|
|
62
|
+
*
|
|
63
|
+
* ###### Choosing good IDs
|
|
64
|
+
* Use a stable, collision-free `stateUpdateQueueId` for the same logical change.
|
|
65
|
+
* Examples:
|
|
66
|
+
* - `follow-created-${sourceFeed.id}-${targetFeed.id}`
|
|
67
|
+
* - `activity-reaction-added-${activity.id}-${reaction.type}`
|
|
68
|
+
*
|
|
69
|
+
* @param config
|
|
70
|
+
* @param config.stateUpdateQueueId - Stable identifier for the logical change
|
|
71
|
+
* @param config.stateUpdateQueue - A shared Set used as a small dedupe cache
|
|
72
|
+
* @param config.watch - Whether watch/broadcast mode is enabled
|
|
73
|
+
* @param config.fromWs - `true` if this event came from WebSocket; `false` for HTTP (default: true)
|
|
74
|
+
* @param config.isTriggeredByConnectedUser - Only dedupe echoes of our own actions
|
|
75
|
+
*
|
|
76
|
+
* @returns {boolean} Whether or not the state update should be applied.
|
|
77
|
+
*/
|
|
3
78
|
export const shouldUpdateState = ({
|
|
4
79
|
stateUpdateQueueId,
|
|
5
80
|
stateUpdateQueue,
|
|
6
81
|
watch,
|
|
82
|
+
fromWs = true,
|
|
83
|
+
isTriggeredByConnectedUser = false,
|
|
7
84
|
}: {
|
|
8
85
|
stateUpdateQueueId: string;
|
|
9
86
|
stateUpdateQueue: Set<string>;
|
|
10
87
|
watch: boolean;
|
|
11
|
-
|
|
12
|
-
|
|
88
|
+
fromWs?: boolean;
|
|
89
|
+
isTriggeredByConnectedUser: boolean;
|
|
90
|
+
}): boolean => {
|
|
91
|
+
if (!watch || !isTriggeredByConnectedUser) {
|
|
13
92
|
return true;
|
|
14
93
|
}
|
|
15
94
|
|
|
16
|
-
|
|
17
|
-
|
|
95
|
+
const prefixedStateUpdateQueueId = fromWs
|
|
96
|
+
? `ws-${stateUpdateQueueId}`
|
|
97
|
+
: `http-${stateUpdateQueueId}`;
|
|
98
|
+
const pairedStateUpdateQueueId = fromWs
|
|
99
|
+
? `http-${stateUpdateQueueId}`
|
|
100
|
+
: `ws-${stateUpdateQueueId}`;
|
|
101
|
+
|
|
102
|
+
if (watch && stateUpdateQueue.has(pairedStateUpdateQueueId)) {
|
|
103
|
+
stateUpdateQueue.delete(pairedStateUpdateQueueId);
|
|
18
104
|
return false;
|
|
19
105
|
}
|
|
20
106
|
|
|
21
|
-
stateUpdateQueue.add(
|
|
107
|
+
stateUpdateQueue.add(prefixedStateUpdateQueueId);
|
|
22
108
|
return true;
|
|
23
109
|
};
|
|
24
110
|
|
|
@@ -26,12 +112,19 @@ export function getStateUpdateQueueId(
|
|
|
26
112
|
data: object,
|
|
27
113
|
prefix?: 'deleted' | 'updated' | 'created' | (string & {}),
|
|
28
114
|
) {
|
|
115
|
+
const toJoin = prefix ? [prefix] : [];
|
|
29
116
|
if (isFollowResponse(data)) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return toJoin
|
|
117
|
+
return toJoin
|
|
118
|
+
.concat([data.source_feed.feed, data.target_feed.feed])
|
|
119
|
+
.join('-');
|
|
120
|
+
} else if (isReactionResponse(data)) {
|
|
121
|
+
return toJoin
|
|
122
|
+
.concat([
|
|
123
|
+
(data as AddReactionResponse).activity.id ??
|
|
124
|
+
(data as AddCommentReactionResponse).comment.id,
|
|
125
|
+
data.reaction.type,
|
|
126
|
+
])
|
|
127
|
+
.join('-');
|
|
35
128
|
}
|
|
36
129
|
// else if (isMemberResponse(data)) {
|
|
37
130
|
// }
|
|
@@ -1,11 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AddCommentReactionResponse,
|
|
3
|
+
AddReactionResponse,
|
|
4
|
+
CommentResponse,
|
|
5
|
+
DeleteCommentReactionResponse,
|
|
6
|
+
FollowResponse,
|
|
7
|
+
} from '../gen/models';
|
|
2
8
|
import { StreamFile } from '../types';
|
|
3
9
|
import { CommentParent } from '../types';
|
|
10
|
+
import { DeleteReactionResponse } from '@stream-io/node-sdk';
|
|
4
11
|
|
|
5
12
|
export const isFollowResponse = (data: object): data is FollowResponse => {
|
|
6
13
|
return 'source_feed' in data && 'target_feed' in data;
|
|
7
14
|
};
|
|
8
15
|
|
|
16
|
+
export const isReactionResponse = (
|
|
17
|
+
data: object,
|
|
18
|
+
): data is (
|
|
19
|
+
| AddReactionResponse
|
|
20
|
+
| AddCommentReactionResponse
|
|
21
|
+
| DeleteReactionResponse
|
|
22
|
+
| DeleteCommentReactionResponse
|
|
23
|
+
) & { fid: string } => {
|
|
24
|
+
return (
|
|
25
|
+
'reaction' in data &&
|
|
26
|
+
('activity' in data || 'comment' in data)
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
9
30
|
export const isCommentResponse = (
|
|
10
31
|
entity: CommentParent,
|
|
11
32
|
): entity is CommentResponse => {
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { StateStore } from '../../src/common/StateStore';
|
|
2
|
-
export declare function useStateStore<T extends Record<string, unknown>, O extends Readonly<Record<string, unknown> | readonly unknown[]>>(store: StateStore<T>, selector: (v: T) => O): O;
|
|
3
|
-
export declare function useStateStore<T extends Record<string, unknown>, O extends Readonly<Record<string, unknown> | readonly unknown[]>>(store: StateStore<T> | undefined, selector: (v: T) => O): O | undefined;
|