@stream-io/feeds-client 0.3.17 → 0.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +27 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/react-bindings.js +1 -1
- package/dist/es/index.mjs +2 -2
- package/dist/es/react-bindings.mjs +1 -1
- package/dist/{feeds-client-Bq_SWnZW.mjs → feeds-client-BseA5k3b.mjs} +69 -35
- package/dist/feeds-client-BseA5k3b.mjs.map +1 -0
- package/dist/{feeds-client-BGF3utPy.js → feeds-client-BwOGqhU9.js} +69 -35
- package/dist/feeds-client-BwOGqhU9.js.map +1 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/activity-updater.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/bookmark/handle-bookmark-added.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/bookmark/handle-bookmark-deleted.d.ts.map +1 -1
- package/dist/types/feed/feed.d.ts +1 -0
- package/dist/types/feed/feed.d.ts.map +1 -1
- package/dist/types/feeds-client/feeds-client.d.ts +6 -2
- package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
- package/dist/types/feeds-client/get-or-create-active-feed.d.ts +4 -0
- package/dist/types/feeds-client/get-or-create-active-feed.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/feed/event-handlers/activity/handle-activity-added.ts +2 -2
- package/src/feed/event-handlers/activity/handle-activity-updated.ts +0 -11
- package/src/feed/event-handlers/activity-updater.ts +0 -8
- package/src/feed/event-handlers/bookmark/handle-bookmark-added.ts +2 -10
- package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.ts +2 -10
- package/src/feed/event-handlers/bookmark/handle-bookmark-updated.ts +2 -2
- package/src/feed/event-handlers/follow/handle-follow-deleted.ts +7 -7
- package/src/feed/feed.ts +44 -1
- package/src/feeds-client/feeds-client.ts +37 -7
- package/src/feeds-client/get-or-create-active-feed.ts +12 -0
- package/dist/feeds-client-BGF3utPy.js.map +0 -1
- package/dist/feeds-client-Bq_SWnZW.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [0.3.19](https://github.com/GetStream/stream-feeds-js/compare/@stream-io/feeds-client-0.3.18...@stream-io/feeds-client-0.3.19) (2025-12-11)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* reactive state updates for follow/unfollow ([#188](https://github.com/GetStream/stream-feeds-js/issues/188)) ([841d436](https://github.com/GetStream/stream-feeds-js/commit/841d43605a5f47cc929b3865f6c13ad26dbbf4c0))
|
|
11
|
+
|
|
12
|
+
## [0.3.18](https://github.com/GetStream/stream-feeds-js/compare/@stream-io/feeds-client-0.3.17...@stream-io/feeds-client-0.3.18) (2025-12-10)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* backfill current feed ([#187](https://github.com/GetStream/stream-feeds-js/issues/187)) ([e215250](https://github.com/GetStream/stream-feeds-js/commit/e215250141aae281464fcec6267934c9a1aecb11))
|
|
18
|
+
|
|
5
19
|
## [0.3.17](https://github.com/GetStream/stream-feeds-js/compare/@stream-io/feeds-client-0.3.16...@stream-io/feeds-client-0.3.17) (2025-12-08)
|
|
6
20
|
|
|
7
21
|
|
package/README.md
CHANGED
|
@@ -1,9 +1,36 @@
|
|
|
1
|
+
# Official plain JS SDK and low-level client for Stream Feeds
|
|
1
2
|
|
|
3
|
+
Bring users together through personalized feeds, threaded discussions, and real-time updates that make every interaction feel meaningful.
|
|
2
4
|
|
|
5
|
+
## **Quick Links**
|
|
3
6
|
|
|
7
|
+
- [Register](https://getstream.io/chat/trial/) to get an API key for Stream Feeds
|
|
8
|
+
- [React Sample apps](../../#react-sample-apps)
|
|
9
|
+
- [Docs](https://getstream.io/activity-feeds/docs/)
|
|
4
10
|
|
|
11
|
+
## What is Stream?
|
|
5
12
|
|
|
13
|
+
Stream allows developers to rapidly deploy scalable feeds, chat messaging and video with an industry leading 99.999% uptime SLA guarantee.
|
|
6
14
|
|
|
15
|
+
Stream's Activity Feed V3 SDK enables teams of all sizes to build scalable activity feeds. The best place to get started is to follow the tutorial:
|
|
7
16
|
|
|
17
|
+
TODO
|
|
8
18
|
|
|
19
|
+
## 👩💻 Free for Makers 👨💻
|
|
9
20
|
|
|
21
|
+
Stream is free for most side and hobby projects. To qualify, your project/company needs to have < 5 team members and < $10k in monthly revenue. Makers get $100 in monthly credit for feeds for free.
|
|
22
|
+
|
|
23
|
+
## 💡 Supported Features 💡
|
|
24
|
+
|
|
25
|
+
Here are some of the features we support:
|
|
26
|
+
|
|
27
|
+
- **For-You feed**: Most modern apps combine a “For You” feed with a regular “Following” feed. With activity selectors you can:
|
|
28
|
+
- surface popular activities
|
|
29
|
+
- show activities near the user
|
|
30
|
+
- match activities to a user’s interests
|
|
31
|
+
- mix-and-match these selectors to build an engaging personalized feed.
|
|
32
|
+
- **Comments**: Voting, threading, images, URL previews, @mentions & notifications. Basically all the features of Reddit style commenting systems.
|
|
33
|
+
- **Advanced feed features**: Activity expiration • visibility controls • feed visibility levels • feed members • bookmarking • follow-approval flow • stories support.
|
|
34
|
+
- **Activity filtering**: Filter activity feeds with almost no hit to performance
|
|
35
|
+
- **Search & queries**: Activity search, **query activities**, and **query feeds** endpoints.
|
|
36
|
+
- **Modern essentials**: Permissions • OpenAPI spec • GDPR endpoints • realtime WebSocket events • push notifications • “own capabilities” API.
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const stateStore = require("@stream-io/state-store");
|
|
4
|
-
const feedsClient = require("../feeds-client-
|
|
4
|
+
const feedsClient = require("../feeds-client-BwOGqhU9.js");
|
|
5
5
|
const loggerInternal = require("@stream-io/logger");
|
|
6
6
|
const ChannelOwnCapability = {
|
|
7
7
|
BAN_CHANNEL_MEMBERS: "ban-channel-members",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const require$$0 = require("react");
|
|
4
4
|
require("@stream-io/state-store");
|
|
5
|
-
const feedsClient = require("../feeds-client-
|
|
5
|
+
const feedsClient = require("../feeds-client-BwOGqhU9.js");
|
|
6
6
|
require("axios");
|
|
7
7
|
var shim = { exports: {} };
|
|
8
8
|
var useSyncExternalStoreShim_production = {};
|
package/dist/es/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { StateStore } from "@stream-io/state-store";
|
|
2
2
|
export * from "@stream-io/state-store";
|
|
3
|
-
import { d as debounce } from "../feeds-client-
|
|
4
|
-
import { A, C, a, F, S, b, c, n, m, k, g, e, h, f, j, i, r, s, u, l } from "../feeds-client-
|
|
3
|
+
import { d as debounce } from "../feeds-client-BseA5k3b.mjs";
|
|
4
|
+
import { A, C, a, F, S, b, c, n, m, k, g, e, h, f, j, i, r, s, u, l } from "../feeds-client-BseA5k3b.mjs";
|
|
5
5
|
import { LogLevelEnum } from "@stream-io/logger";
|
|
6
6
|
const ChannelOwnCapability = {
|
|
7
7
|
BAN_CHANNEL_MEMBERS: "ban-channel-members",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import require$$0, { useCallback, useMemo, useState, useEffect, createContext, useContext, useRef } from "react";
|
|
2
2
|
import "@stream-io/state-store";
|
|
3
|
-
import { F as FeedsClient, g as isCommentResponse, c as checkHasAnotherPage } from "../feeds-client-
|
|
3
|
+
import { F as FeedsClient, g as isCommentResponse, c as checkHasAnotherPage } from "../feeds-client-BseA5k3b.mjs";
|
|
4
4
|
import "axios";
|
|
5
5
|
var shim = { exports: {} };
|
|
6
6
|
var useSyncExternalStoreShim_production = {};
|
|
@@ -3914,7 +3914,7 @@ const getRateLimitFromResponseHeader = (response_headers) => {
|
|
|
3914
3914
|
};
|
|
3915
3915
|
return result;
|
|
3916
3916
|
};
|
|
3917
|
-
const version = "0.3.
|
|
3917
|
+
const version = "0.3.19";
|
|
3918
3918
|
class ApiClient {
|
|
3919
3919
|
constructor(apiKey, tokenManager, connectionIdManager, options) {
|
|
3920
3920
|
this.apiKey = apiKey;
|
|
@@ -4857,10 +4857,10 @@ const updateStateFollowDeleted = (follow, currentState, currentFeedId, connected
|
|
|
4857
4857
|
// Update FeedResponse fields, that has the new follower/following count
|
|
4858
4858
|
...follow.target_feed
|
|
4859
4859
|
};
|
|
4860
|
-
if (source.created_by.id === connectedUserId
|
|
4861
|
-
newState.own_follows = currentState.own_follows.filter(
|
|
4860
|
+
if (source.created_by.id === connectedUserId) {
|
|
4861
|
+
newState.own_follows = currentState.own_follows ? currentState.own_follows.filter(
|
|
4862
4862
|
(followItem) => followItem.source_feed.feed !== follow.source_feed.feed
|
|
4863
|
-
);
|
|
4863
|
+
) : [];
|
|
4864
4864
|
}
|
|
4865
4865
|
if (currentState.followers !== void 0) {
|
|
4866
4866
|
newState.followers = currentState.followers.filter(
|
|
@@ -5279,13 +5279,10 @@ const sharedUpdateActivity$6 = ({
|
|
|
5279
5279
|
if (eventBelongsToCurrentUser) {
|
|
5280
5280
|
newOwnBookmarks = [...newOwnBookmarks, event.bookmark];
|
|
5281
5281
|
}
|
|
5282
|
-
if (!event.bookmark.activity.current_feed && event.bookmark.activity.feeds.length === 1 && currentActivity.current_feed) {
|
|
5283
|
-
event.bookmark.activity.current_feed = currentActivity.current_feed;
|
|
5284
|
-
}
|
|
5285
5282
|
return {
|
|
5286
|
-
...
|
|
5287
|
-
|
|
5288
|
-
|
|
5283
|
+
...currentActivity,
|
|
5284
|
+
bookmark_count: event.bookmark.activity.bookmark_count,
|
|
5285
|
+
own_bookmarks: newOwnBookmarks
|
|
5289
5286
|
};
|
|
5290
5287
|
};
|
|
5291
5288
|
const addBookmarkToActivities = (event, activities, eventBelongsToCurrentUser) => updateEntityInArray({
|
|
@@ -5355,13 +5352,10 @@ const sharedUpdateActivity$5 = ({
|
|
|
5355
5352
|
(bookmark) => !isSameBookmark(bookmark, event.bookmark)
|
|
5356
5353
|
);
|
|
5357
5354
|
}
|
|
5358
|
-
if (!event.bookmark.activity.current_feed && event.bookmark.activity.feeds.length === 1 && currentActivity.current_feed) {
|
|
5359
|
-
event.bookmark.activity.current_feed = currentActivity.current_feed;
|
|
5360
|
-
}
|
|
5361
5355
|
return {
|
|
5362
|
-
...
|
|
5363
|
-
|
|
5364
|
-
|
|
5356
|
+
...currentActivity,
|
|
5357
|
+
bookmark_count: event.bookmark.activity.bookmark_count,
|
|
5358
|
+
own_bookmarks: newOwnBookmarks
|
|
5365
5359
|
};
|
|
5366
5360
|
};
|
|
5367
5361
|
const removeBookmarkFromActivities = (event, activities, eventBelongsToCurrentUser) => updateEntityInArray({
|
|
@@ -5433,9 +5427,9 @@ const sharedUpdateActivity$4 = ({
|
|
|
5433
5427
|
}
|
|
5434
5428
|
}
|
|
5435
5429
|
return {
|
|
5436
|
-
...
|
|
5437
|
-
|
|
5438
|
-
|
|
5430
|
+
...currentActivity,
|
|
5431
|
+
bookmark_count: event.bookmark.activity.bookmark_count,
|
|
5432
|
+
own_bookmarks: newOwnBookmarks
|
|
5439
5433
|
};
|
|
5440
5434
|
};
|
|
5441
5435
|
const updateBookmarkInActivities = (event, activities, eventBelongsToCurrentUser) => updateEntityInArray({
|
|
@@ -5514,6 +5508,7 @@ function addActivitiesToState(newActivities, activities, position) {
|
|
|
5514
5508
|
...activities,
|
|
5515
5509
|
...position === "end" ? newActivitiesDeduplicated : []
|
|
5516
5510
|
];
|
|
5511
|
+
this.newActivitiesAdded(newActivitiesDeduplicated);
|
|
5517
5512
|
result = { changed: true, activities: updatedActivities };
|
|
5518
5513
|
}
|
|
5519
5514
|
return result;
|
|
@@ -5593,9 +5588,6 @@ const updateActivity = ({
|
|
|
5593
5588
|
currentActivity,
|
|
5594
5589
|
newActivtiy
|
|
5595
5590
|
}) => {
|
|
5596
|
-
if (!newActivtiy.current_feed && newActivtiy.feeds.length === 1 && currentActivity.current_feed) {
|
|
5597
|
-
newActivtiy.current_feed = currentActivity.current_feed;
|
|
5598
|
-
}
|
|
5599
5591
|
return {
|
|
5600
5592
|
...newActivtiy,
|
|
5601
5593
|
own_reactions: currentActivity.own_reactions,
|
|
@@ -5645,12 +5637,6 @@ function handleActivityUpdated(payload, fromWs) {
|
|
|
5645
5637
|
activities: currentActivities,
|
|
5646
5638
|
pinned_activities: currentPinnedActivities
|
|
5647
5639
|
} = this.currentState;
|
|
5648
|
-
const currentActivity = currentActivities?.find(
|
|
5649
|
-
(a) => a.id === payload.activity.id
|
|
5650
|
-
);
|
|
5651
|
-
if (!payload.activity.current_feed && payload.activity.feeds.length === 1 && currentActivity?.current_feed) {
|
|
5652
|
-
payload.activity.current_feed = currentActivity.current_feed;
|
|
5653
|
-
}
|
|
5654
5640
|
const [result1, result2] = [
|
|
5655
5641
|
this.hasActivity(payload.activity.id) ? updateActivityInState(payload, currentActivities) : void 0,
|
|
5656
5642
|
updatePinnedActivityInState(payload, currentPinnedActivities)
|
|
@@ -6241,6 +6227,9 @@ const deepEqual = (x, y) => {
|
|
|
6241
6227
|
return false;
|
|
6242
6228
|
}
|
|
6243
6229
|
};
|
|
6230
|
+
function getOrCreateActiveFeed(group, id, data, watch) {
|
|
6231
|
+
return this.getOrCreateActiveFeed(group, id, data, watch);
|
|
6232
|
+
}
|
|
6244
6233
|
const _Feed = class _Feed extends FeedApi {
|
|
6245
6234
|
constructor(client, groupId, id, data, watch = false, addNewActivitiesTo = "start", activityAddedEventFilter) {
|
|
6246
6235
|
super(client, groupId, id);
|
|
@@ -6433,7 +6422,7 @@ const _Feed = class _Feed extends FeedApi {
|
|
|
6433
6422
|
return nextState;
|
|
6434
6423
|
});
|
|
6435
6424
|
}
|
|
6436
|
-
this.
|
|
6425
|
+
this.newActivitiesAdded(response.activities);
|
|
6437
6426
|
return response;
|
|
6438
6427
|
} finally {
|
|
6439
6428
|
this.state.partialNext({
|
|
@@ -6814,6 +6803,19 @@ const _Feed = class _Feed extends FeedApi {
|
|
|
6814
6803
|
handleWSEvent(event) {
|
|
6815
6804
|
const eventHandler = this.eventHandlers[event.type];
|
|
6816
6805
|
if (eventHandler !== _Feed.noop) {
|
|
6806
|
+
if ("activity" in event && this.hasActivity(event.activity.id)) {
|
|
6807
|
+
const currentActivity = this.currentState.activities?.find(
|
|
6808
|
+
(a) => a.id === event.activity.id
|
|
6809
|
+
);
|
|
6810
|
+
if (event.activity.feeds.length > 1 && !event.activity.current_feed && currentActivity?.current_feed) {
|
|
6811
|
+
event.activity.current_feed = currentActivity.current_feed;
|
|
6812
|
+
}
|
|
6813
|
+
if (event.activity.feeds.length === 1 && event.activity.current_feed && currentActivity?.current_feed) {
|
|
6814
|
+
event.activity.current_feed.own_capabilities = currentActivity.current_feed.own_capabilities;
|
|
6815
|
+
event.activity.current_feed.own_follows = currentActivity.current_feed.own_follows;
|
|
6816
|
+
event.activity.current_feed.own_membership = currentActivity.current_feed.own_membership;
|
|
6817
|
+
}
|
|
6818
|
+
}
|
|
6817
6819
|
eventHandler?.(event);
|
|
6818
6820
|
}
|
|
6819
6821
|
if (typeof eventHandler === "undefined") {
|
|
@@ -6821,6 +6823,18 @@ const _Feed = class _Feed extends FeedApi {
|
|
|
6821
6823
|
}
|
|
6822
6824
|
this.eventDispatcher.dispatch(event);
|
|
6823
6825
|
}
|
|
6826
|
+
newActivitiesAdded(activities) {
|
|
6827
|
+
this.client.hydratePollCache(activities);
|
|
6828
|
+
activities.forEach((activity) => {
|
|
6829
|
+
if (activity.current_feed) {
|
|
6830
|
+
getOrCreateActiveFeed.bind(this.client)(
|
|
6831
|
+
activity.current_feed.group_id,
|
|
6832
|
+
activity.current_feed.id,
|
|
6833
|
+
activity.current_feed
|
|
6834
|
+
);
|
|
6835
|
+
}
|
|
6836
|
+
});
|
|
6837
|
+
}
|
|
6824
6838
|
};
|
|
6825
6839
|
_Feed.noop = () => {
|
|
6826
6840
|
};
|
|
@@ -7365,8 +7379,7 @@ class FeedsClient extends FeedsApi {
|
|
|
7365
7379
|
id,
|
|
7366
7380
|
void 0,
|
|
7367
7381
|
void 0,
|
|
7368
|
-
options2
|
|
7369
|
-
options2?.activityAddedEventFilter
|
|
7382
|
+
options2
|
|
7370
7383
|
);
|
|
7371
7384
|
};
|
|
7372
7385
|
this.activityWithStateUpdates = (id) => {
|
|
@@ -7384,20 +7397,30 @@ class FeedsClient extends FeedsApi {
|
|
|
7384
7397
|
};
|
|
7385
7398
|
this.eventDispatcher.dispatch(networkEvent);
|
|
7386
7399
|
};
|
|
7387
|
-
this.getOrCreateActiveFeed = (group, id, data, watch,
|
|
7400
|
+
this.getOrCreateActiveFeed = (group, id, data, watch, options2) => {
|
|
7388
7401
|
const fid = `${group}:${id}`;
|
|
7402
|
+
let isCreated = false;
|
|
7389
7403
|
if (!this.activeFeeds[fid]) {
|
|
7404
|
+
isCreated = true;
|
|
7390
7405
|
this.activeFeeds[fid] = new Feed(
|
|
7391
7406
|
this,
|
|
7392
7407
|
group,
|
|
7393
7408
|
id,
|
|
7394
7409
|
data,
|
|
7395
7410
|
watch,
|
|
7396
|
-
addNewActivitiesTo,
|
|
7397
|
-
activityAddedEventFilter
|
|
7411
|
+
options2?.addNewActivitiesTo,
|
|
7412
|
+
options2?.activityAddedEventFilter
|
|
7398
7413
|
);
|
|
7399
7414
|
}
|
|
7400
7415
|
const feed = this.activeFeeds[fid];
|
|
7416
|
+
if (!isCreated && options2) {
|
|
7417
|
+
if (options2?.addNewActivitiesTo) {
|
|
7418
|
+
feed.addNewActivitiesTo = options2.addNewActivitiesTo;
|
|
7419
|
+
}
|
|
7420
|
+
if (options2?.activityAddedEventFilter) {
|
|
7421
|
+
feed.activityAddedEventFilter = options2.activityAddedEventFilter;
|
|
7422
|
+
}
|
|
7423
|
+
}
|
|
7401
7424
|
if (!feed.currentState.watch) {
|
|
7402
7425
|
if (data) handleFeedUpdated.call(feed, { feed: data });
|
|
7403
7426
|
if (watch) handleWatchStarted.call(feed);
|
|
@@ -7669,6 +7692,17 @@ class FeedsClient extends FeedsApi {
|
|
|
7669
7692
|
}
|
|
7670
7693
|
return response;
|
|
7671
7694
|
}
|
|
7695
|
+
async getFollowSuggestions(...params) {
|
|
7696
|
+
const response = await super.getFollowSuggestions(...params);
|
|
7697
|
+
response.suggestions.forEach((suggestion) => {
|
|
7698
|
+
this.getOrCreateActiveFeed(
|
|
7699
|
+
suggestion.group_id,
|
|
7700
|
+
suggestion.id,
|
|
7701
|
+
suggestion
|
|
7702
|
+
);
|
|
7703
|
+
});
|
|
7704
|
+
return response;
|
|
7705
|
+
}
|
|
7672
7706
|
findAllActiveFeedsByActivityId(activityId) {
|
|
7673
7707
|
return [
|
|
7674
7708
|
...Object.values(this.activeFeeds),
|
|
@@ -7750,4 +7784,4 @@ export {
|
|
|
7750
7784
|
shouldUpdateState as s,
|
|
7751
7785
|
uniqueArrayMerge as u
|
|
7752
7786
|
};
|
|
7753
|
-
//# sourceMappingURL=feeds-client-
|
|
7787
|
+
//# sourceMappingURL=feeds-client-BseA5k3b.mjs.map
|