@nolag/feed 1.1.0 → 1.2.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.
@@ -1,6 +1,6 @@
1
1
  import type { RoomContext } from '@nolag/js-sdk';
2
2
  import { EventEmitter } from './EventEmitter';
3
- import type { FeedChannelEvents, FeedPost, FeedComment, FeedUser, FeedPresenceData, ResolvedFeedOptions, CreatePostOptions } from './types';
3
+ import type { FeedChannelEvents, FeedPost, FeedComment, FeedUser, FeedPresenceData, ResolvedFeedOptions, CreatePostOptions, FilterValue, FeedFilterOptions, FeedFilterTopic } from './types';
4
4
  /**
5
5
  * FeedChannel — a single feed channel with posts, comments, reactions, and
6
6
  * presence.
@@ -20,6 +20,8 @@ export declare class FeedChannel extends EventEmitter<FeedChannelEvents> {
20
20
  private _isConnected;
21
21
  private _unreadCount;
22
22
  private _active;
23
+ /** Filter values applied per content topic. */
24
+ private _filters;
23
25
  private _onPostsRef;
24
26
  private _onReactionsRef;
25
27
  private _onCommentsRef;
@@ -33,11 +35,44 @@ export declare class FeedChannel extends EventEmitter<FeedChannelEvents> {
33
35
  likePost(postId: string): void;
34
36
  unlikePost(postId: string): void;
35
37
  addComment(postId: string, text: string): FeedComment;
38
+ /** The filter values currently applied to this channel, by topic. */
39
+ get filters(): Record<FeedFilterTopic, FilterValue[]>;
40
+ /**
41
+ * Replace this channel's filters — only posts published with one of these
42
+ * values are delivered. Reactions and comments get the same set unless you
43
+ * scope the call with `{ topic }`, so you never receive a like for a post
44
+ * you cannot see.
45
+ *
46
+ * Passing an empty array clears filtering and restores the wildcard
47
+ * subscription, which receives everything.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * channel.setFilters(['sports', 'news']); // sports OR news
52
+ * channel.setFilters([['sports', 'live']]); // sports AND live
53
+ * channel.setFilters([]); // everything
54
+ * ```
55
+ */
56
+ setFilters(values: FilterValue[], opts?: FeedFilterOptions): void;
57
+ /** Add filter values to the existing set. Existing AND groups are kept. */
58
+ addFilters(values: string[], opts?: FeedFilterOptions): void;
59
+ /**
60
+ * Remove filter values from the existing set. Removing the last value
61
+ * restores the wildcard subscription.
62
+ */
63
+ removeFilters(values: string[], opts?: FeedFilterOptions): void;
64
+ private _targetTopics;
65
+ /**
66
+ * The publish options that put a reaction or comment in front of the same
67
+ * audience as the post it belongs to. An unknown post (never seen, or
68
+ * evicted from the cache) falls back to unfiltered.
69
+ */
70
+ private _postFilter;
36
71
  getComments(postId: string): FeedComment[];
37
72
  markRead(): void;
38
73
  getUsers(): FeedUser[];
39
74
  /** @internal Subscribe to post/reaction/comment topics and attach listeners (all channels) */
40
- _subscribe(): void;
75
+ _subscribe(filters?: FilterValue[]): void;
41
76
  _activate(): void;
42
77
  _deactivate(): void;
43
78
  _handlePresenceJoin(actorTokenId: string, presenceData: FeedPresenceData): void;
@@ -1,7 +1,7 @@
1
1
  import type { NoLagSocket } from '@nolag/js-sdk';
2
2
  import { EventEmitter } from './EventEmitter';
3
3
  import { FeedChannel } from './FeedChannel';
4
- import type { NoLagFeedOptions, FeedClientEvents, FeedUser } from './types';
4
+ import type { NoLagFeedOptions, FeedClientEvents, FeedUser, JoinChannelOptions } from './types';
5
5
  /**
6
6
  * NoLagFeed — high-level activity-feed SDK built on @nolag/js-sdk.
7
7
  *
@@ -99,7 +99,7 @@ export declare class NoLagFeed extends EventEmitter<FeedClientEvents> {
99
99
  * If the channel was pre-subscribed via the `channels` option, activates it.
100
100
  * Otherwise creates, subscribes, and activates it.
101
101
  */
102
- joinChannel(name: string): FeedChannel;
102
+ joinChannel(name: string, opts?: JoinChannelOptions): FeedChannel;
103
103
  /**
104
104
  * Leave a feed channel. Fully unsubscribes and removes it.
105
105
  */
package/dist/browser.js CHANGED
@@ -1,2 +1,2 @@
1
- class e{constructor(){this._handlers=new Map}on(e,t){return this._handlers.has(e)||this._handlers.set(e,new Set),this._handlers.get(e).add(t),this}off(e,t){return t?this._handlers.get(e)?.delete(t):this._handlers.delete(e),this}removeAllListeners(){return this._handlers.clear(),this}emit(e,...t){const s=this._handlers.get(e);if(s)for(const n of s)try{n(...t)}catch(t){console.error(`Error in ${String(e)} handler:`,t)}}listenerCount(e){return this._handlers.get(e)?.size??0}}class t{constructor(e){this._posts=[],this._ids=new Set,this._maxSize=e}add(e){if(this._ids.has(e.id))return!1;for(this._ids.add(e.id),this._posts.push(e),this._posts.length>1&&e.timestamp<this._posts[this._posts.length-2].timestamp&&this._posts.sort((e,t)=>e.timestamp-t.timestamp);this._posts.length>this._maxSize;){const e=this._posts.shift();this._ids.delete(e.id)}return!0}get(e){return this._posts.find(t=>t.id===e)}getAll(){return[...this._posts]}updateLikeCount(e,t,s){const n=this._posts.find(t=>t.id===e);n&&(n.likeCount=t,n.likedByMe=s)}incrementCommentCount(e){const t=this._posts.find(t=>t.id===e);t&&t.commentCount++}has(e){return this._ids.has(e)}get size(){return this._posts.length}clear(){this._posts=[],this._ids.clear()}}class s{constructor(){this._likes=new Map}like(e,t){this._likes.has(e)||this._likes.set(e,new Set);const s=this._likes.get(e),n=!s.has(t);return s.add(t),{postId:e,likeCount:s.size,isNew:n}}unlike(e,t){const s=this._likes.get(e);if(!s)return{postId:e,likeCount:0,wasLiked:!1};const n=s.has(t);return s.delete(t),{postId:e,likeCount:s.size,wasLiked:n}}isLikedBy(e,t){return this._likes.get(e)?.has(t)??!1}getLikeCount(e){return this._likes.get(e)?.size??0}clear(){this._likes.clear()}}class n{constructor(e){this._users=new Map,this._actorToUserId=new Map,this._localActorId=e}addFromPresence(e,t,s){if(e===this._localActorId)return null;const n=this._actorToUserId.get(e),i=t.userId||n||e,o={userId:i,actorTokenId:e,username:t.username,avatar:t.avatar,metadata:t.metadata,joinedAt:s||Date.now(),isLocal:!1};return this._users.set(i,o),this._actorToUserId.set(e,i),o}removeByActorId(e){if(e===this._localActorId)return null;const t=this._actorToUserId.get(e);if(!t)return null;const s=this._users.get(t)||null;return this._users.delete(t),this._actorToUserId.delete(e),s}getUser(e){return this._users.get(e)}getUserByActorId(e){const t=this._actorToUserId.get(e);return t?this._users.get(t):void 0}getAll(){return Array.from(this._users.values())}get users(){return this._users}clear(){this._users.clear(),this._actorToUserId.clear()}}function i(){return"undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID?crypto.randomUUID():"xxxx-xxxx-xxxx-xxxx".replace(/x/g,()=>Math.floor(16*Math.random()).toString(16))}function o(e,t){return t?(...t)=>{console.log(`[${e}]`,...t)}:(...e)=>{}}const r=new WeakMap;const a="posts",h="reactions",c="comments";class l extends e{constructor(e,i,o,r,a,h){super(),this._comments=new Map,this._unreadCount=0,this._active=!1,this._onPostsRef=null,this._onReactionsRef=null,this._onCommentsRef=null,this.name=e,this._roomContext=i,this._localUser=o,this._options=r,this._log=a,this._isConnected=h,this._presenceManager=new n(o.actorTokenId),this._postStore=new t(r.maxPostCache),this._reactionManager=new s}get posts(){return this._postStore.getAll()}get unreadCount(){return this._unreadCount}get active(){return this._active}createPost(e){const t={id:i(),userId:this._localUser.userId,username:this._localUser.username,avatar:this._localUser.avatar,content:e.content,media:e.media,data:e.data,likeCount:0,commentCount:0,likedByMe:!1,timestamp:Date.now(),status:"sending",isReplay:!1};return this._postStore.add(t),this.emit("postSent",t),this._roomContext.emit(a,{id:t.id,userId:t.userId,username:t.username,avatar:t.avatar,content:t.content,media:t.media,data:t.data,timestamp:t.timestamp},{echo:!1}),t.status="sent",t}getPosts(){return this._postStore.getAll()}likePost(e){const{likeCount:t,isNew:s}=this._reactionManager.like(e,this._localUser.userId);s&&(this._postStore.updateLikeCount(e,t,!0),this._roomContext.emit(h,{postId:e,userId:this._localUser.userId,type:"like",timestamp:Date.now()},{echo:!1}),this.emit("postLiked",{postId:e,userId:this._localUser.userId,likeCount:t}))}unlikePost(e){const{likeCount:t,wasLiked:s}=this._reactionManager.unlike(e,this._localUser.userId);s&&(this._postStore.updateLikeCount(e,t,!1),this._roomContext.emit(h,{postId:e,userId:this._localUser.userId,type:"unlike",timestamp:Date.now()},{echo:!1}),this.emit("postUnliked",{postId:e,userId:this._localUser.userId,likeCount:t}))}addComment(e,t){const s={id:i(),postId:e,userId:this._localUser.userId,username:this._localUser.username,avatar:this._localUser.avatar,text:t,timestamp:Date.now(),isReplay:!1};return this._comments.has(e)||this._comments.set(e,[]),this._comments.get(e).push(s),this._postStore.incrementCommentCount(e),this.emit("commentSent",s),this._roomContext.emit(c,{id:s.id,postId:e,userId:s.userId,username:s.username,avatar:s.avatar,text:s.text,timestamp:s.timestamp},{echo:!1}),s}getComments(e){return this._comments.get(e)??[]}markRead(){0!==this._unreadCount&&(this._unreadCount=0,this.emit("unreadChanged",{channel:this.name,count:0}))}getUsers(){return this._presenceManager.getAll()}_subscribe(){this._log("Channel subscribe:",this.name),this._roomContext.subscribe(a),this._roomContext.subscribe(h),this._roomContext.subscribe(c),this._onPostsRef=(e,t)=>{this._handleIncomingPost(e,t)},this._roomContext.on(a,this._onPostsRef),this._onReactionsRef=e=>{this._handleIncomingReaction(e)},this._roomContext.on(h,this._onReactionsRef),this._onCommentsRef=(e,t)=>{this._handleIncomingComment(e,t)},this._roomContext.on(c,this._onCommentsRef)}_activate(){this._active=!0,this._markRead(),this._setPresence(),this._roomContext.fetchPresence().then(e=>{for(const t of e)if(t.presence){const e=this._presenceManager.addFromPresence(t.actorTokenId,t.presence,t.joinedAt);e&&this.emit("subscriberJoined",e)}}).catch(()=>{})}_deactivate(){this._active=!1,this._presenceManager.clear()}_handlePresenceJoin(e,t){const s=this._presenceManager.addFromPresence(e,t);s&&this.emit("subscriberJoined",s)}_handlePresenceLeave(e){const t=this._presenceManager.removeByActorId(e);t&&this.emit("subscriberLeft",t)}_handlePresenceUpdate(e,t){this._presenceManager.addFromPresence(e,t)}_handleReplayStart(e){this.emit("replayStart",{count:e})}_handleReplayEnd(e){this.emit("replayEnd",{replayed:e})}_updateLocalPresence(){this._setPresence()}_cleanup(){this._log("Channel cleanup:",this.name),this._isConnected()&&(this._roomContext.unsubscribe(a),this._roomContext.unsubscribe(h),this._roomContext.unsubscribe(c)),this._onPostsRef&&this._roomContext.off(a,this._onPostsRef),this._onReactionsRef&&this._roomContext.off(h,this._onReactionsRef),this._onCommentsRef&&this._roomContext.off(c,this._onCommentsRef),this._onPostsRef=null,this._onReactionsRef=null,this._onCommentsRef=null,this._postStore.clear(),this._reactionManager.clear(),this._comments.clear(),this._presenceManager.clear(),this.removeAllListeners()}_handleIncomingPost(e,t){const s=e,n={id:s.id,userId:s.userId,username:s.username,avatar:s.avatar,content:s.content,media:s.media,data:s.data,likeCount:0,commentCount:0,likedByMe:!1,timestamp:s.timestamp,status:"delivered",isReplay:t.isReplay??!1};this._postStore.add(n)&&(this.emit("postCreated",n),this._active||n.isReplay||(this._unreadCount++,this.emit("unreadChanged",{channel:this.name,count:this._unreadCount})))}_handleIncomingReaction(e){const t=e;if("like"===t.type){const{likeCount:e}=this._reactionManager.like(t.postId,t.userId),s=this._reactionManager.isLikedBy(t.postId,this._localUser.userId);this._postStore.updateLikeCount(t.postId,e,s),this.emit("postLiked",{postId:t.postId,userId:t.userId,likeCount:e})}else if("unlike"===t.type){const{likeCount:e}=this._reactionManager.unlike(t.postId,t.userId),s=this._reactionManager.isLikedBy(t.postId,this._localUser.userId);this._postStore.updateLikeCount(t.postId,e,s),this.emit("postUnliked",{postId:t.postId,userId:t.userId,likeCount:e})}}_handleIncomingComment(e,t){const s=e,n={id:s.id,postId:s.postId,userId:s.userId,username:s.username,avatar:s.avatar,text:s.text,timestamp:s.timestamp,isReplay:t.isReplay??!1};this._comments.has(n.postId)||this._comments.set(n.postId,[]),this._comments.get(n.postId).push(n),this._postStore.incrementCommentCount(n.postId),this.emit("commentAdded",n)}_markRead(){0!==this._unreadCount&&(this._unreadCount=0,this.emit("unreadChanged",{channel:this.name,count:0}))}_setPresence(){this._roomContext.setPresence({userId:this._localUser.userId,username:this._localUser.username,avatar:this._localUser.avatar,metadata:this._localUser.metadata,__scope:this._options.appName})}}class _ extends e{constructor(e){if(super(),this._localUser=null,this._channels=new Map,this._lobby=null,this._onlineUsers=new Map,this._actorToUserId=new Map,this._activeChannel=null,this._epoch=0,this._detached=!1,this._isReady=!1,this._lobbyRefreshTimer=null,this._onConnectRef=()=>this._onConnect(),this._onDisconnectRef=e=>{this._log("Disconnected:",e),this.emit("disconnected",e)},this._onReconnectRef=()=>{this._log("Reconnecting..."),this.emit("reconnecting")},this._onErrorRef=e=>{this._log("Error:",e),this.emit("error",e)},this._onReplayStartRef=e=>{const t=e;for(const e of this._channels.values())e._handleReplayStart(t.count)},this._onReplayEndRef=e=>{const t=e;for(const e of this._channels.values())e._handleReplayEnd(t.replayed)},this._onPresenceJoinRef=e=>this._handleRoomPresenceJoin(e),this._onPresenceLeaveRef=e=>this._handleRoomPresenceLeave(e),this._onPresenceUpdateRef=e=>this._handleRoomPresenceUpdate(e),this._onLobbyJoinRef=e=>this._handleLobbyJoin(e),this._onLobbyLeaveRef=e=>this._handleLobbyLeave(e),this._onLobbyUpdateRef=e=>this._handleLobbyUpdate(e),!e?.client)throw new TypeError("NoLagFeed requires an injected NoLag client: new NoLagFeed({ client, username, ... })");this._client=e.client,this._userId=i(),this._options={username:e.username,avatar:e.avatar,metadata:e.metadata,appName:e.appName??"feed",maxPostCache:e.maxPostCache??200,maxCommentCache:e.maxCommentCache??100,debug:e.debug??!1,channels:e.channels??[]},this._log=o("NoLagFeed",this._options.debug),this._readyPromise=new Promise((e,t)=>{this._readyResolve=e,this._readyReject=t}),this._readyPromise.catch(()=>{}),function(e,t,s){let n=r.get(e);n||(n=new Map,r.set(e,n));const i=n.get(t);i&&console.warn(`[${s}] Another wrapper (${i}) is already attached to this client for app "${t}". Use one wrapper per (client, app) — detach the other instance first.`),n.set(t,s)}(this._client,this._options.appName,"NoLagFeed"),this._client.on("connect",this._onConnectRef),this._client.on("disconnect",this._onDisconnectRef),this._client.on("reconnect",this._onReconnectRef),this._client.on("error",this._onErrorRef),this._client.on("replay:start",this._onReplayStartRef),this._client.on("replay:end",this._onReplayEndRef),this._client.on("presence:join",this._onPresenceJoinRef),this._client.on("presence:leave",this._onPresenceLeaveRef),this._client.on("presence:update",this._onPresenceUpdateRef),this._client.on("lobbyPresence:join",this._onLobbyJoinRef),this._client.on("lobbyPresence:leave",this._onLobbyLeaveRef),this._client.on("lobbyPresence:update",this._onLobbyUpdateRef),queueMicrotask(()=>{0===this._epoch&&!this._detached&&this._client.connected&&this._onConnect()})}get connected(){return!this._detached&&this._client.connected}get client(){return this._client}get localUser(){return this._localUser}get channels(){return this._channels}ready(){return this._readyPromise}detach(){if(!this._detached){this._log("Detaching..."),this._detached=!0,this._epoch++,this._lobbyRefreshTimer&&(clearTimeout(this._lobbyRefreshTimer),this._lobbyRefreshTimer=null),this._client.off("connect",this._onConnectRef),this._client.off("disconnect",this._onDisconnectRef),this._client.off("reconnect",this._onReconnectRef),this._client.off("error",this._onErrorRef),this._client.off("replay:start",this._onReplayStartRef),this._client.off("replay:end",this._onReplayEndRef),this._client.off("presence:join",this._onPresenceJoinRef),this._client.off("presence:leave",this._onPresenceLeaveRef),this._client.off("presence:update",this._onPresenceUpdateRef),this._client.off("lobbyPresence:join",this._onLobbyJoinRef),this._client.off("lobbyPresence:leave",this._onLobbyLeaveRef),this._client.off("lobbyPresence:update",this._onLobbyUpdateRef);for(const e of[...this._channels.keys()])this._channels.get(e)._cleanup(),this._channels.delete(e);if(this._activeChannel=null,this._lobby&&this._client.connected)try{this._lobby.unsubscribe()}catch{}var e,t;this._lobby=null,this._onlineUsers.clear(),this._actorToUserId.clear(),this._localUser=null,e=this._client,t=this._options.appName,r.get(e)?.delete(t),this._isReady||this._readyReject(new Error("NoLagFeed detached before ready"))}}_onConnect(){this._epoch++,this._runSetup(this._epoch)}async _runSetup(e){const t=()=>e!==this._epoch||this._detached;this._log(this._isReady?"Restoring after reconnect...":"Setting up..."),this._localUser?this._localUser.actorTokenId=this._client.actorId:(this._localUser={userId:this._userId,actorTokenId:this._client.actorId,username:this._options.username,avatar:this._options.avatar,metadata:this._options.metadata,joinedAt:Date.now(),isLocal:!0},this._log("Local user:",this._localUser.userId,"→",this._localUser.actorTokenId)),this._lobby||(this._lobby=this._client.setApp(this._options.appName).setLobby("online"));try{const e=await this._lobby.subscribe();if(t())return;this._diffHydrateOnlineUsers(e),this._log("Lobby subscribed, online users:",this._onlineUsers.size)}catch(e){if(t())return;this._log("Lobby subscription failed:",e)}if(this._isReady)this._activeChannel&&this._channels.get(this._activeChannel)?._updateLocalPresence();else for(const e of this._options.channels)this._subscribeChannelInternal(e);t()||(this._isReady?this.emit("reconnected"):(this._isReady=!0,this._readyResolve(),this.emit("connected")),this._scheduleLobbyRefresh(e))}_scheduleLobbyRefresh(e){this._lobbyRefreshTimer&&clearTimeout(this._lobbyRefreshTimer),this._lobbyRefreshTimer=setTimeout(()=>{this._lobbyRefreshTimer=null,e===this._epoch&&!this._detached&&this._client.connected&&this._lobby&&this._lobby.fetchPresence().then(t=>{e!==this._epoch||this._detached||this._diffHydrateOnlineUsers(t)}).catch(()=>{})},2e3)}joinChannel(e){if(this._assertUsable(),this._activeChannel&&this._activeChannel!==e){const e=this._channels.get(this._activeChannel);e&&e._deactivate()}let t=this._channels.get(e);return t||(t=this._subscribeChannelInternal(e)),this._activeChannel=e,t._activate(),t}leaveChannel(e){const t=this._channels.get(e);t&&(this._log("Leaving channel:",e),t._cleanup(),this._channels.delete(e),this._activeChannel===e&&(this._activeChannel=null))}getChannels(){return Array.from(this._channels.values())}getOnlineUsers(){return Array.from(this._onlineUsers.values())}updateProfile(e){if(this._localUser&&(void 0!==e.username&&(this._localUser.username=e.username,this._options.username=e.username),void 0!==e.avatar&&(this._localUser.avatar=e.avatar,this._options.avatar=e.avatar),void 0!==e.metadata&&(this._localUser.metadata={...this._localUser.metadata,...e.metadata},this._options.metadata=this._localUser.metadata),this._activeChannel)){const e=this._channels.get(this._activeChannel);e&&e._updateLocalPresence()}}_assertUsable(){if(this._detached)throw new Error("NoLagFeed has been detached — construct a new instance");if(!this._isReady||!this._localUser)throw new Error('NoLagFeed not ready — await ready() or the "connected" event')}_subscribeChannelInternal(e){this._log("Subscribing channel:",e);const t=this._client.setApp(this._options.appName).setRoom(e),s=new l(e,t,this._localUser,this._options,o(`FeedChannel:${e}`,this._options.debug),()=>this._client.connected);return this._channels.set(e,s),s._subscribe(),s}_foreignScope(e){const t=e?.__scope;return"string"==typeof t&&t!==this._options.appName}_handleRoomPresenceJoin(e){if(e.actorTokenId===this._localUser?.actorTokenId)return;const t=e.presence;if(!t?.userId||this._foreignScope(t))return;const s=this._presenceToUser(e.actorTokenId,t);this._actorToUserId.set(e.actorTokenId,s.userId),this._onlineUsers.has(s.userId)||(this._onlineUsers.set(s.userId,s),this.emit("userOnline",s));const n=this._activeChannel?this._channels.get(this._activeChannel):void 0;n&&n._handlePresenceJoin(e.actorTokenId,t)}_handleRoomPresenceLeave(e){if(e.actorTokenId===this._localUser?.actorTokenId)return;const t=this._activeChannel?this._channels.get(this._activeChannel):void 0;t&&t._handlePresenceLeave(e.actorTokenId)}_handleRoomPresenceUpdate(e){if(e.actorTokenId===this._localUser?.actorTokenId)return;const t=e.presence;if(!t?.userId||this._foreignScope(t))return;if(this._onlineUsers.has(t.userId)){const s=this._presenceToUser(e.actorTokenId,t);this._onlineUsers.set(s.userId,s)}const s=this._activeChannel?this._channels.get(this._activeChannel):void 0;s&&s._handlePresenceUpdate(e.actorTokenId,t)}_handleLobbyJoin(e){const{actorId:t,data:s}=e;if(t===this._localUser?.actorTokenId)return;const n=s;if(!n.userId||this._foreignScope(n))return;const i=this._presenceToUser(t,n);this._actorToUserId.set(t,i.userId),this._onlineUsers.has(i.userId)||(this._onlineUsers.set(i.userId,i),this.emit("userOnline",i))}_handleLobbyLeave(e){const{actorId:t,data:s}=e;if(t===this._localUser?.actorTokenId)return;const n=s;if(this._foreignScope(n))return;const i=n?.userId||this._actorToUserId.get(t)||this._findUserIdByActorId(t);if(i){const e=this._onlineUsers.get(i);e&&(this._onlineUsers.delete(i),this._actorToUserId.delete(t),this.emit("userOffline",e))}}_handleLobbyUpdate(e){const{actorId:t,data:s}=e;if(t===this._localUser?.actorTokenId)return;const n=s;if(!n.userId||this._foreignScope(n))return;const i=this._presenceToUser(t,n);this._onlineUsers.set(i.userId,i)}_diffHydrateOnlineUsers(e){const t=new Map,s=new Map;for(const n of Object.keys(e)){const i=e[n];for(const e of Object.keys(i)){if(e===this._localUser?.actorTokenId)continue;const n=i[e],o=n?.presence??n;o?.userId&&!this._foreignScope(o)&&(t.has(o.userId)||t.set(o.userId,this._presenceToUser(e,o)),s.set(e,o.userId))}}for(const[e,s]of[...this._onlineUsers])if(!t.has(e)){this._onlineUsers.delete(e);for(const[t,s]of[...this._actorToUserId])s===e&&this._actorToUserId.delete(t);this.emit("userOffline",s)}for(const[e,s]of t)this._onlineUsers.has(e)||(this._onlineUsers.set(e,s),this.emit("userOnline",s));for(const[e,t]of s)this._actorToUserId.set(e,t)}_presenceToUser(e,t){return{userId:t.userId,actorTokenId:e,username:t.username,avatar:t.avatar,metadata:t.metadata,joinedAt:Date.now(),isLocal:!1}}_findUserIdByActorId(e){for(const t of this._onlineUsers.values())if(t.actorTokenId===e)return t.userId}}export{e as EventEmitter,l as FeedChannel,_ as NoLagFeed};
1
+ class e{constructor(){this._handlers=new Map}on(e,t){return this._handlers.has(e)||this._handlers.set(e,new Set),this._handlers.get(e).add(t),this}off(e,t){return t?this._handlers.get(e)?.delete(t):this._handlers.delete(e),this}removeAllListeners(){return this._handlers.clear(),this}emit(e,...t){const s=this._handlers.get(e);if(s)for(const n of s)try{n(...t)}catch(t){console.error(`Error in ${String(e)} handler:`,t)}}listenerCount(e){return this._handlers.get(e)?.size??0}}class t{constructor(e){this._posts=[],this._ids=new Set,this._maxSize=e}add(e){if(this._ids.has(e.id))return!1;for(this._ids.add(e.id),this._posts.push(e),this._posts.length>1&&e.timestamp<this._posts[this._posts.length-2].timestamp&&this._posts.sort((e,t)=>e.timestamp-t.timestamp);this._posts.length>this._maxSize;){const e=this._posts.shift();this._ids.delete(e.id)}return!0}get(e){return this._posts.find(t=>t.id===e)}getAll(){return[...this._posts]}updateLikeCount(e,t,s){const n=this._posts.find(t=>t.id===e);n&&(n.likeCount=t,n.likedByMe=s)}incrementCommentCount(e){const t=this._posts.find(t=>t.id===e);t&&t.commentCount++}has(e){return this._ids.has(e)}get size(){return this._posts.length}clear(){this._posts=[],this._ids.clear()}}class s{constructor(){this._likes=new Map}like(e,t){this._likes.has(e)||this._likes.set(e,new Set);const s=this._likes.get(e),n=!s.has(t);return s.add(t),{postId:e,likeCount:s.size,isNew:n}}unlike(e,t){const s=this._likes.get(e);if(!s)return{postId:e,likeCount:0,wasLiked:!1};const n=s.has(t);return s.delete(t),{postId:e,likeCount:s.size,wasLiked:n}}isLikedBy(e,t){return this._likes.get(e)?.has(t)??!1}getLikeCount(e){return this._likes.get(e)?.size??0}clear(){this._likes.clear()}}class n{constructor(e){this._users=new Map,this._actorToUserId=new Map,this._localActorId=e}addFromPresence(e,t,s){if(e===this._localActorId)return null;const n=this._actorToUserId.get(e),i=t.userId||n||e,o={userId:i,actorTokenId:e,username:t.username,avatar:t.avatar,metadata:t.metadata,joinedAt:s||Date.now(),isLocal:!1};return this._users.set(i,o),this._actorToUserId.set(e,i),o}removeByActorId(e){if(e===this._localActorId)return null;const t=this._actorToUserId.get(e);if(!t)return null;const s=this._users.get(t)||null;return this._users.delete(t),this._actorToUserId.delete(e),s}getUser(e){return this._users.get(e)}getUserByActorId(e){const t=this._actorToUserId.get(e);return t?this._users.get(t):void 0}getAll(){return Array.from(this._users.values())}get users(){return this._users}clear(){this._users.clear(),this._actorToUserId.clear()}}function i(){return"undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID?crypto.randomUUID():"xxxx-xxxx-xxxx-xxxx".replace(/x/g,()=>Math.floor(16*Math.random()).toString(16))}function o(e,t){return t?(...t)=>{console.log(`[${e}]`,...t)}:(...e)=>{}}function r(e){return e?.filter?{filter:e.filter}:e?.filters&&e.filters.length>0?{filters:e.filters}:{}}function a(e,t){const s=new Set,n=[];for(const t of e)"string"==typeof t?s.add(t):n.push(t);for(const e of t)s.add(e);return[...s,...n]}function h(e,t){const s=new Set(t);return e.filter(e=>"string"!=typeof e||!s.has(e))}function c(e){return e?.filter?e.filter:e?.filters&&e.filters.length>0?(t=e.filters,[...t].map(e=>e.toLowerCase()).sort().join("|")):void 0;var t}const l=new WeakMap;const _="posts",d="reactions",u="comments",p=[_,d,u],m={posts:_,reactions:d,comments:u};class f extends e{constructor(e,i,o,r,a,h){super(),this._comments=new Map,this._unreadCount=0,this._active=!1,this._filters={posts:[],reactions:[],comments:[]},this._onPostsRef=null,this._onReactionsRef=null,this._onCommentsRef=null,this.name=e,this._roomContext=i,this._localUser=o,this._options=r,this._log=a,this._isConnected=h,this._presenceManager=new n(o.actorTokenId),this._postStore=new t(r.maxPostCache),this._reactionManager=new s}get posts(){return this._postStore.getAll()}get unreadCount(){return this._unreadCount}get active(){return this._active}createPost(e){const t={id:i(),userId:this._localUser.userId,username:this._localUser.username,avatar:this._localUser.avatar,content:e.content,media:e.media,data:e.data,likeCount:0,commentCount:0,likedByMe:!1,timestamp:Date.now(),filter:c(e),status:"sending",isReplay:!1};return this._postStore.add(t),this.emit("postSent",t),this._roomContext.emit(_,{id:t.id,userId:t.userId,username:t.username,avatar:t.avatar,content:t.content,media:t.media,data:t.data,timestamp:t.timestamp},{echo:!1,...r(e)}),t.status="sent",t}getPosts(){return this._postStore.getAll()}likePost(e){const{likeCount:t,isNew:s}=this._reactionManager.like(e,this._localUser.userId);s&&(this._postStore.updateLikeCount(e,t,!0),this._roomContext.emit(d,{postId:e,userId:this._localUser.userId,type:"like",timestamp:Date.now()},{echo:!1,...this._postFilter(e)}),this.emit("postLiked",{postId:e,userId:this._localUser.userId,likeCount:t}))}unlikePost(e){const{likeCount:t,wasLiked:s}=this._reactionManager.unlike(e,this._localUser.userId);s&&(this._postStore.updateLikeCount(e,t,!1),this._roomContext.emit(d,{postId:e,userId:this._localUser.userId,type:"unlike",timestamp:Date.now()},{echo:!1,...this._postFilter(e)}),this.emit("postUnliked",{postId:e,userId:this._localUser.userId,likeCount:t}))}addComment(e,t){const s={id:i(),postId:e,userId:this._localUser.userId,username:this._localUser.username,avatar:this._localUser.avatar,text:t,timestamp:Date.now(),isReplay:!1};return this._comments.has(e)||this._comments.set(e,[]),this._comments.get(e).push(s),this._postStore.incrementCommentCount(e),this.emit("commentSent",s),this._roomContext.emit(u,{id:s.id,postId:e,userId:s.userId,username:s.username,avatar:s.avatar,text:s.text,timestamp:s.timestamp},{echo:!1,...this._postFilter(e)}),s}get filters(){return{posts:[...this._filters.posts],reactions:[...this._filters.reactions],comments:[...this._filters.comments]}}setFilters(e,t){for(const s of this._targetTopics(t))this._filters[s]=[...e],this._roomContext.setFilters(m[s],e)}addFilters(e,t){for(const s of this._targetTopics(t))this.setFilters(a(this._filters[s],e),{topic:s})}removeFilters(e,t){for(const s of this._targetTopics(t))this.setFilters(h(this._filters[s],e),{topic:s})}_targetTopics(e){return e?.topic?[e.topic]:["posts","reactions","comments"]}_postFilter(e){return t=this._postStore.get(e)?.filter,t?t.includes("|")?{filters:t.split("|")}:{filter:t}:{};var t}getComments(e){return this._comments.get(e)??[]}markRead(){0!==this._unreadCount&&(this._unreadCount=0,this.emit("unreadChanged",{channel:this.name,count:0}))}getUsers(){return this._presenceManager.getAll()}_subscribe(e){this._log("Channel subscribe:",this.name);const t=e?[...e]:[];if(this._filters={posts:[...t],reactions:[...t],comments:[...t]},t.length>0){const e={filters:t};for(const t of p)this._roomContext.subscribe(t,e)}else for(const e of p)this._roomContext.subscribe(e);this._onPostsRef=(e,t)=>{this._handleIncomingPost(e,t)},this._roomContext.on(_,this._onPostsRef),this._onReactionsRef=e=>{this._handleIncomingReaction(e)},this._roomContext.on(d,this._onReactionsRef),this._onCommentsRef=(e,t)=>{this._handleIncomingComment(e,t)},this._roomContext.on(u,this._onCommentsRef)}_activate(){this._active=!0,this._markRead(),this._setPresence(),this._roomContext.fetchPresence().then(e=>{for(const t of e)if(t.presence){const e=this._presenceManager.addFromPresence(t.actorTokenId,t.presence,t.joinedAt);e&&this.emit("subscriberJoined",e)}}).catch(()=>{})}_deactivate(){this._active=!1,this._presenceManager.clear()}_handlePresenceJoin(e,t){const s=this._presenceManager.addFromPresence(e,t);s&&this.emit("subscriberJoined",s)}_handlePresenceLeave(e){const t=this._presenceManager.removeByActorId(e);t&&this.emit("subscriberLeft",t)}_handlePresenceUpdate(e,t){this._presenceManager.addFromPresence(e,t)}_handleReplayStart(e){this.emit("replayStart",{count:e})}_handleReplayEnd(e){this.emit("replayEnd",{replayed:e})}_updateLocalPresence(){this._setPresence()}_cleanup(){this._log("Channel cleanup:",this.name),this._isConnected()&&(this._roomContext.unsubscribe(_),this._roomContext.unsubscribe(d),this._roomContext.unsubscribe(u)),this._onPostsRef&&this._roomContext.off(_,this._onPostsRef),this._onReactionsRef&&this._roomContext.off(d,this._onReactionsRef),this._onCommentsRef&&this._roomContext.off(u,this._onCommentsRef),this._onPostsRef=null,this._onReactionsRef=null,this._onCommentsRef=null,this._postStore.clear(),this._reactionManager.clear(),this._comments.clear(),this._presenceManager.clear(),this.removeAllListeners()}_handleIncomingPost(e,t){const s=e,n={id:s.id,userId:s.userId,username:s.username,avatar:s.avatar,content:s.content,media:s.media,data:s.data,likeCount:0,commentCount:0,likedByMe:!1,timestamp:s.timestamp,filter:t.filter,status:"delivered",isReplay:t.isReplay??!1};this._postStore.add(n)&&(this.emit("postCreated",n),this._active||n.isReplay||(this._unreadCount++,this.emit("unreadChanged",{channel:this.name,count:this._unreadCount})))}_handleIncomingReaction(e){const t=e;if("like"===t.type){const{likeCount:e}=this._reactionManager.like(t.postId,t.userId),s=this._reactionManager.isLikedBy(t.postId,this._localUser.userId);this._postStore.updateLikeCount(t.postId,e,s),this.emit("postLiked",{postId:t.postId,userId:t.userId,likeCount:e})}else if("unlike"===t.type){const{likeCount:e}=this._reactionManager.unlike(t.postId,t.userId),s=this._reactionManager.isLikedBy(t.postId,this._localUser.userId);this._postStore.updateLikeCount(t.postId,e,s),this.emit("postUnliked",{postId:t.postId,userId:t.userId,likeCount:e})}}_handleIncomingComment(e,t){const s=e,n={id:s.id,postId:s.postId,userId:s.userId,username:s.username,avatar:s.avatar,text:s.text,timestamp:s.timestamp,isReplay:t.isReplay??!1};this._comments.has(n.postId)||this._comments.set(n.postId,[]),this._comments.get(n.postId).push(n),this._postStore.incrementCommentCount(n.postId),this.emit("commentAdded",n)}_markRead(){0!==this._unreadCount&&(this._unreadCount=0,this.emit("unreadChanged",{channel:this.name,count:0}))}_setPresence(){this._roomContext.setPresence({userId:this._localUser.userId,username:this._localUser.username,avatar:this._localUser.avatar,metadata:this._localUser.metadata,__scope:this._options.appName})}}class I extends e{constructor(e){if(super(),this._localUser=null,this._channels=new Map,this._lobby=null,this._onlineUsers=new Map,this._actorToUserId=new Map,this._activeChannel=null,this._epoch=0,this._detached=!1,this._isReady=!1,this._lobbyRefreshTimer=null,this._onConnectRef=()=>this._onConnect(),this._onDisconnectRef=e=>{this._log("Disconnected:",e),this.emit("disconnected",e)},this._onReconnectRef=()=>{this._log("Reconnecting..."),this.emit("reconnecting")},this._onErrorRef=e=>{this._log("Error:",e),this.emit("error",e)},this._onReplayStartRef=e=>{const t=e;for(const e of this._channels.values())e._handleReplayStart(t.count)},this._onReplayEndRef=e=>{const t=e;for(const e of this._channels.values())e._handleReplayEnd(t.replayed)},this._onPresenceJoinRef=e=>this._handleRoomPresenceJoin(e),this._onPresenceLeaveRef=e=>this._handleRoomPresenceLeave(e),this._onPresenceUpdateRef=e=>this._handleRoomPresenceUpdate(e),this._onLobbyJoinRef=e=>this._handleLobbyJoin(e),this._onLobbyLeaveRef=e=>this._handleLobbyLeave(e),this._onLobbyUpdateRef=e=>this._handleLobbyUpdate(e),!e?.client)throw new TypeError("NoLagFeed requires an injected NoLag client: new NoLagFeed({ client, username, ... })");this._client=e.client,this._userId=i(),this._options={username:e.username,avatar:e.avatar,metadata:e.metadata,appName:e.appName??"feed",maxPostCache:e.maxPostCache??200,maxCommentCache:e.maxCommentCache??100,debug:e.debug??!1,channels:e.channels??[]},this._log=o("NoLagFeed",this._options.debug),this._readyPromise=new Promise((e,t)=>{this._readyResolve=e,this._readyReject=t}),this._readyPromise.catch(()=>{}),function(e,t,s){let n=l.get(e);n||(n=new Map,l.set(e,n));const i=n.get(t);i&&console.warn(`[${s}] Another wrapper (${i}) is already attached to this client for app "${t}". Use one wrapper per (client, app) — detach the other instance first.`),n.set(t,s)}(this._client,this._options.appName,"NoLagFeed"),this._client.on("connect",this._onConnectRef),this._client.on("disconnect",this._onDisconnectRef),this._client.on("reconnect",this._onReconnectRef),this._client.on("error",this._onErrorRef),this._client.on("replay:start",this._onReplayStartRef),this._client.on("replay:end",this._onReplayEndRef),this._client.on("presence:join",this._onPresenceJoinRef),this._client.on("presence:leave",this._onPresenceLeaveRef),this._client.on("presence:update",this._onPresenceUpdateRef),this._client.on("lobbyPresence:join",this._onLobbyJoinRef),this._client.on("lobbyPresence:leave",this._onLobbyLeaveRef),this._client.on("lobbyPresence:update",this._onLobbyUpdateRef),queueMicrotask(()=>{0===this._epoch&&!this._detached&&this._client.connected&&this._onConnect()})}get connected(){return!this._detached&&this._client.connected}get client(){return this._client}get localUser(){return this._localUser}get channels(){return this._channels}ready(){return this._readyPromise}detach(){if(!this._detached){this._log("Detaching..."),this._detached=!0,this._epoch++,this._lobbyRefreshTimer&&(clearTimeout(this._lobbyRefreshTimer),this._lobbyRefreshTimer=null),this._client.off("connect",this._onConnectRef),this._client.off("disconnect",this._onDisconnectRef),this._client.off("reconnect",this._onReconnectRef),this._client.off("error",this._onErrorRef),this._client.off("replay:start",this._onReplayStartRef),this._client.off("replay:end",this._onReplayEndRef),this._client.off("presence:join",this._onPresenceJoinRef),this._client.off("presence:leave",this._onPresenceLeaveRef),this._client.off("presence:update",this._onPresenceUpdateRef),this._client.off("lobbyPresence:join",this._onLobbyJoinRef),this._client.off("lobbyPresence:leave",this._onLobbyLeaveRef),this._client.off("lobbyPresence:update",this._onLobbyUpdateRef);for(const e of[...this._channels.keys()])this._channels.get(e)._cleanup(),this._channels.delete(e);if(this._activeChannel=null,this._lobby&&this._client.connected)try{this._lobby.unsubscribe()}catch{}var e,t;this._lobby=null,this._onlineUsers.clear(),this._actorToUserId.clear(),this._localUser=null,e=this._client,t=this._options.appName,l.get(e)?.delete(t),this._isReady||this._readyReject(new Error("NoLagFeed detached before ready"))}}_onConnect(){this._epoch++,this._runSetup(this._epoch)}async _runSetup(e){const t=()=>e!==this._epoch||this._detached;this._log(this._isReady?"Restoring after reconnect...":"Setting up..."),this._localUser?this._localUser.actorTokenId=this._client.actorId:(this._localUser={userId:this._userId,actorTokenId:this._client.actorId,username:this._options.username,avatar:this._options.avatar,metadata:this._options.metadata,joinedAt:Date.now(),isLocal:!0},this._log("Local user:",this._localUser.userId,"→",this._localUser.actorTokenId)),this._lobby||(this._lobby=this._client.setApp(this._options.appName).setLobby("online"));try{const e=await this._lobby.subscribe();if(t())return;this._diffHydrateOnlineUsers(e),this._log("Lobby subscribed, online users:",this._onlineUsers.size)}catch(e){if(t())return;this._log("Lobby subscription failed:",e)}if(this._isReady)this._activeChannel&&this._channels.get(this._activeChannel)?._updateLocalPresence();else for(const e of this._options.channels)this._subscribeChannelInternal(e);t()||(this._isReady?this.emit("reconnected"):(this._isReady=!0,this._readyResolve(),this.emit("connected")),this._scheduleLobbyRefresh(e))}_scheduleLobbyRefresh(e){this._lobbyRefreshTimer&&clearTimeout(this._lobbyRefreshTimer),this._lobbyRefreshTimer=setTimeout(()=>{this._lobbyRefreshTimer=null,e===this._epoch&&!this._detached&&this._client.connected&&this._lobby&&this._lobby.fetchPresence().then(t=>{e!==this._epoch||this._detached||this._diffHydrateOnlineUsers(t)}).catch(()=>{})},2e3)}joinChannel(e,t){if(this._assertUsable(),this._activeChannel&&this._activeChannel!==e){const e=this._channels.get(this._activeChannel);e&&e._deactivate()}let s=this._channels.get(e);return s?t?.filters&&s.setFilters(t.filters):s=this._subscribeChannelInternal(e,t?.filters),this._activeChannel=e,s._activate(),s}leaveChannel(e){const t=this._channels.get(e);t&&(this._log("Leaving channel:",e),t._cleanup(),this._channels.delete(e),this._activeChannel===e&&(this._activeChannel=null))}getChannels(){return Array.from(this._channels.values())}getOnlineUsers(){return Array.from(this._onlineUsers.values())}updateProfile(e){if(this._localUser&&(void 0!==e.username&&(this._localUser.username=e.username,this._options.username=e.username),void 0!==e.avatar&&(this._localUser.avatar=e.avatar,this._options.avatar=e.avatar),void 0!==e.metadata&&(this._localUser.metadata={...this._localUser.metadata,...e.metadata},this._options.metadata=this._localUser.metadata),this._activeChannel)){const e=this._channels.get(this._activeChannel);e&&e._updateLocalPresence()}}_assertUsable(){if(this._detached)throw new Error("NoLagFeed has been detached — construct a new instance");if(!this._isReady||!this._localUser)throw new Error('NoLagFeed not ready — await ready() or the "connected" event')}_subscribeChannelInternal(e,t){this._log("Subscribing channel:",e);const s=this._client.setApp(this._options.appName).setRoom(e),n=new f(e,s,this._localUser,this._options,o(`FeedChannel:${e}`,this._options.debug),()=>this._client.connected);return this._channels.set(e,n),n._subscribe(t),n}_foreignScope(e){const t=e?.__scope;return"string"==typeof t&&t!==this._options.appName}_handleRoomPresenceJoin(e){if(e.actorTokenId===this._localUser?.actorTokenId)return;const t=e.presence;if(!t?.userId||this._foreignScope(t))return;const s=this._presenceToUser(e.actorTokenId,t);this._actorToUserId.set(e.actorTokenId,s.userId),this._onlineUsers.has(s.userId)||(this._onlineUsers.set(s.userId,s),this.emit("userOnline",s));const n=this._activeChannel?this._channels.get(this._activeChannel):void 0;n&&n._handlePresenceJoin(e.actorTokenId,t)}_handleRoomPresenceLeave(e){if(e.actorTokenId===this._localUser?.actorTokenId)return;const t=this._activeChannel?this._channels.get(this._activeChannel):void 0;t&&t._handlePresenceLeave(e.actorTokenId)}_handleRoomPresenceUpdate(e){if(e.actorTokenId===this._localUser?.actorTokenId)return;const t=e.presence;if(!t?.userId||this._foreignScope(t))return;if(this._onlineUsers.has(t.userId)){const s=this._presenceToUser(e.actorTokenId,t);this._onlineUsers.set(s.userId,s)}const s=this._activeChannel?this._channels.get(this._activeChannel):void 0;s&&s._handlePresenceUpdate(e.actorTokenId,t)}_handleLobbyJoin(e){const{actorId:t,data:s}=e;if(t===this._localUser?.actorTokenId)return;const n=s;if(!n.userId||this._foreignScope(n))return;const i=this._presenceToUser(t,n);this._actorToUserId.set(t,i.userId),this._onlineUsers.has(i.userId)||(this._onlineUsers.set(i.userId,i),this.emit("userOnline",i))}_handleLobbyLeave(e){const{actorId:t,data:s}=e;if(t===this._localUser?.actorTokenId)return;const n=s;if(this._foreignScope(n))return;const i=n?.userId||this._actorToUserId.get(t)||this._findUserIdByActorId(t);if(i){const e=this._onlineUsers.get(i);e&&(this._onlineUsers.delete(i),this._actorToUserId.delete(t),this.emit("userOffline",e))}}_handleLobbyUpdate(e){const{actorId:t,data:s}=e;if(t===this._localUser?.actorTokenId)return;const n=s;if(!n.userId||this._foreignScope(n))return;const i=this._presenceToUser(t,n);this._onlineUsers.set(i.userId,i)}_diffHydrateOnlineUsers(e){const t=new Map,s=new Map;for(const n of Object.keys(e)){const i=e[n];for(const e of Object.keys(i)){if(e===this._localUser?.actorTokenId)continue;const n=i[e],o=n?.presence??n;o?.userId&&!this._foreignScope(o)&&(t.has(o.userId)||t.set(o.userId,this._presenceToUser(e,o)),s.set(e,o.userId))}}for(const[e,s]of[...this._onlineUsers])if(!t.has(e)){this._onlineUsers.delete(e);for(const[t,s]of[...this._actorToUserId])s===e&&this._actorToUserId.delete(t);this.emit("userOffline",s)}for(const[e,s]of t)this._onlineUsers.has(e)||(this._onlineUsers.set(e,s),this.emit("userOnline",s));for(const[e,t]of s)this._actorToUserId.set(e,t)}_presenceToUser(e,t){return{userId:t.userId,actorTokenId:e,username:t.username,avatar:t.avatar,metadata:t.metadata,joinedAt:Date.now(),isLocal:!1}}_findUserIdByActorId(e){for(const t of this._onlineUsers.values())if(t.actorTokenId===e)return t.userId}}export{e as EventEmitter,f as FeedChannel,I as NoLagFeed};
2
2
  //# sourceMappingURL=browser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sources":["../src/EventEmitter.ts","../src/PostStore.ts","../src/ReactionManager.ts","../src/PresenceManager.ts","../src/utils.ts","../src/constants.ts","../src/FeedChannel.ts","../src/NoLagFeed.ts"],"sourcesContent":[null,null,null,null,null,null,null,null],"names":["EventEmitter","constructor","this","_handlers","Map","on","event","handler","has","set","Set","get","add","off","delete","removeAllListeners","clear","emit","args","handlers","e","console","error","String","listenerCount","size","PostStore","maxSize","_posts","_ids","_maxSize","post","id","push","length","timestamp","sort","a","b","removed","shift","find","p","getAll","updateLikeCount","postId","count","likedByMe","likeCount","incrementCommentCount","commentCount","ReactionManager","_likes","like","userId","likers","isNew","unlike","wasLiked","isLikedBy","getLikeCount","PresenceManager","localActorId","_users","_actorToUserId","_localActorId","addFromPresence","actorTokenId","presence","joinedAt","existing","user","username","avatar","metadata","Date","now","isLocal","removeByActorId","getUser","getUserByActorId","undefined","Array","from","values","users","generateId","crypto","randomUUID","replace","Math","floor","random","toString","createLogger","prefix","enabled","log","_args","wrapperRegistry","WeakMap","TOPIC_POSTS","TOPIC_REACTIONS","TOPIC_COMMENTS","FeedChannel","name","roomContext","localUser","options","isConnected","super","_comments","_unreadCount","_active","_onPostsRef","_onReactionsRef","_onCommentsRef","_roomContext","_localUser","_options","_log","_isConnected","_presenceManager","_postStore","maxPostCache","_reactionManager","posts","unreadCount","active","createPost","opts","content","media","data","status","isReplay","echo","getPosts","likePost","type","unlikePost","addComment","text","comment","getComments","markRead","channel","getUsers","_subscribe","subscribe","meta","_handleIncomingPost","_handleIncomingReaction","_handleIncomingComment","_activate","_markRead","_setPresence","fetchPresence","then","actors","actor","catch","_deactivate","_handlePresenceJoin","presenceData","_handlePresenceLeave","_handlePresenceUpdate","_handleReplayStart","_handleReplayEnd","replayed","_updateLocalPresence","_cleanup","unsubscribe","raw","setPresence","__scope","appName","NoLagFeed","_channels","_lobby","_onlineUsers","_activeChannel","_epoch","_detached","_isReady","_lobbyRefreshTimer","_onConnectRef","_onConnect","_onDisconnectRef","reason","_onReconnectRef","_onErrorRef","_onReplayStartRef","_onReplayEndRef","_onPresenceJoinRef","_handleRoomPresenceJoin","_onPresenceLeaveRef","_handleRoomPresenceLeave","_onPresenceUpdateRef","_handleRoomPresenceUpdate","_onLobbyJoinRef","_handleLobbyJoin","_onLobbyLeaveRef","_handleLobbyLeave","_onLobbyUpdateRef","_handleLobbyUpdate","client","TypeError","_client","_userId","maxCommentCache","debug","channels","_readyPromise","Promise","resolve","reject","_readyResolve","_readyReject","wrapperName","apps","warn","registerWrapper","queueMicrotask","connected","ready","detach","clearTimeout","keys","Error","_runSetup","epoch","stale","actorId","setApp","setLobby","state","_diffHydrateOnlineUsers","err","channelName","_subscribeChannelInternal","_scheduleLobbyRefresh","setTimeout","joinChannel","_assertUsable","prev","leaveChannel","getChannels","getOnlineUsers","updateProfile","updates","activeChannel","setRoom","_foreignScope","scope","_presenceToUser","_findUserIdByActorId","fresh","freshActors","roomId","Object","roomPresence","mappedUserId"],"mappings":"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"}
1
+ {"version":3,"file":"browser.js","sources":["../src/EventEmitter.ts","../src/PostStore.ts","../src/ReactionManager.ts","../src/PresenceManager.ts","../src/utils.ts","../src/constants.ts","../src/FeedChannel.ts","../src/NoLagFeed.ts"],"sourcesContent":[null,null,null,null,null,null,null,null],"names":["EventEmitter","constructor","this","_handlers","Map","on","event","handler","has","set","Set","get","add","off","delete","removeAllListeners","clear","emit","args","handlers","e","console","error","String","listenerCount","size","PostStore","maxSize","_posts","_ids","_maxSize","post","id","push","length","timestamp","sort","a","b","removed","shift","find","p","getAll","updateLikeCount","postId","count","likedByMe","likeCount","incrementCommentCount","commentCount","ReactionManager","_likes","like","userId","likers","isNew","unlike","wasLiked","isLikedBy","getLikeCount","PresenceManager","localActorId","_users","_actorToUserId","_localActorId","addFromPresence","actorTokenId","presence","joinedAt","existing","user","username","avatar","metadata","Date","now","isLocal","removeByActorId","getUser","getUserByActorId","undefined","Array","from","values","users","generateId","crypto","randomUUID","replace","Math","floor","random","toString","createLogger","prefix","enabled","log","_args","filterEmitOptions","opts","filter","filters","mergeFilters","simple","groups","f","v","withoutFilters","remove","drop","recordedFilter","map","toLowerCase","join","wrapperRegistry","WeakMap","TOPIC_POSTS","TOPIC_REACTIONS","TOPIC_COMMENTS","FILTERED_TOPICS","FILTER_TOPICS","posts","reactions","comments","FeedChannel","name","roomContext","localUser","options","isConnected","super","_comments","_unreadCount","_active","_filters","_onPostsRef","_onReactionsRef","_onCommentsRef","_roomContext","_localUser","_options","_log","_isConnected","_presenceManager","_postStore","maxPostCache","_reactionManager","unreadCount","active","createPost","content","media","data","status","isReplay","echo","getPosts","likePost","type","_postFilter","unlikePost","addComment","text","comment","setFilters","topic","_targetTopics","addFilters","removeFilters","includes","split","getComments","markRead","channel","getUsers","_subscribe","initial","subscribe","meta","_handleIncomingPost","_handleIncomingReaction","_handleIncomingComment","_activate","_markRead","_setPresence","fetchPresence","then","actors","actor","catch","_deactivate","_handlePresenceJoin","presenceData","_handlePresenceLeave","_handlePresenceUpdate","_handleReplayStart","_handleReplayEnd","replayed","_updateLocalPresence","_cleanup","unsubscribe","raw","setPresence","__scope","appName","NoLagFeed","_channels","_lobby","_onlineUsers","_activeChannel","_epoch","_detached","_isReady","_lobbyRefreshTimer","_onConnectRef","_onConnect","_onDisconnectRef","reason","_onReconnectRef","_onErrorRef","_onReplayStartRef","_onReplayEndRef","_onPresenceJoinRef","_handleRoomPresenceJoin","_onPresenceLeaveRef","_handleRoomPresenceLeave","_onPresenceUpdateRef","_handleRoomPresenceUpdate","_onLobbyJoinRef","_handleLobbyJoin","_onLobbyLeaveRef","_handleLobbyLeave","_onLobbyUpdateRef","_handleLobbyUpdate","client","TypeError","_client","_userId","maxCommentCache","debug","channels","_readyPromise","Promise","resolve","reject","_readyResolve","_readyReject","wrapperName","apps","warn","registerWrapper","queueMicrotask","connected","ready","detach","clearTimeout","keys","Error","_runSetup","epoch","stale","actorId","setApp","setLobby","state","_diffHydrateOnlineUsers","err","channelName","_subscribeChannelInternal","_scheduleLobbyRefresh","setTimeout","joinChannel","_assertUsable","prev","leaveChannel","getChannels","getOnlineUsers","updateProfile","updates","activeChannel","setRoom","_foreignScope","scope","_presenceToUser","_findUserIdByActorId","fresh","freshActors","roomId","Object","roomPresence","mappedUserId"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -273,6 +273,78 @@ function createLogger(prefix, enabled) {
273
273
  }
274
274
  return (...args) => { console.log(`[${prefix}]`, ...args); };
275
275
  }
276
+ // ============ Filters ============
277
+ /**
278
+ * Build the filter fragment of an emit options object.
279
+ *
280
+ * `filter` wins over `filters`: a publish is routed to exactly one topic, so
281
+ * honouring both would silently drop one of them.
282
+ */
283
+ function filterEmitOptions(opts) {
284
+ if (opts?.filter)
285
+ return { filter: opts.filter };
286
+ if (opts?.filters && opts.filters.length > 0)
287
+ return { filters: opts.filters };
288
+ return {};
289
+ }
290
+ /**
291
+ * Rebuild publish options from the filter a message arrived with, so a reply
292
+ * to it reaches the same audience the original did.
293
+ *
294
+ * The server joins AND groups into one composite value with '|', which is not
295
+ * a legal character in a plain filter, so split those back apart.
296
+ */
297
+ function inheritFilter(filter) {
298
+ if (!filter)
299
+ return {};
300
+ if (filter.includes('|'))
301
+ return { filters: filter.split('|') };
302
+ return { filter };
303
+ }
304
+ /**
305
+ * Merge OR terms into an existing filter set. AND groups (nested arrays) are
306
+ * preserved as-is — only plain string terms are deduplicated.
307
+ */
308
+ function mergeFilters(existing, add) {
309
+ const simple = new Set();
310
+ const groups = [];
311
+ for (const f of existing) {
312
+ if (typeof f === 'string')
313
+ simple.add(f);
314
+ else
315
+ groups.push(f);
316
+ }
317
+ for (const v of add)
318
+ simple.add(v);
319
+ return [...simple, ...groups];
320
+ }
321
+ /**
322
+ * Drop OR terms from a filter set. AND groups are left untouched — remove
323
+ * those by calling `setFilters` with the set you want.
324
+ */
325
+ function withoutFilters(existing, remove) {
326
+ const drop = new Set(remove);
327
+ return existing.filter((f) => typeof f !== 'string' || !drop.has(f));
328
+ }
329
+ /**
330
+ * The composite key the server derives from an AND filter group: values are
331
+ * lowercased, sorted, and joined with '|'. Mirrored here so an item created
332
+ * locally carries the same filter string as one arriving off the wire.
333
+ */
334
+ function compositeFilterKey(values) {
335
+ return [...values].map((v) => v.toLowerCase()).sort().join('|');
336
+ }
337
+ /**
338
+ * The single string form of whatever filter a publish used, for recording on
339
+ * the local copy of an item. Round-trips through `inheritFilter`.
340
+ */
341
+ function recordedFilter(opts) {
342
+ if (opts?.filter)
343
+ return opts.filter;
344
+ if (opts?.filters && opts.filters.length > 0)
345
+ return compositeFilterKey(opts.filters);
346
+ return undefined;
347
+ }
276
348
  // ============ Wrapper registry ============
277
349
  // One wrapper instance per (client, appName): two wrappers sharing an app on
278
350
  // one connection would collide on topics, presence and the online lobby.
@@ -307,6 +379,14 @@ const LOBBY_ID = 'online';
307
379
  /** Delay before the post-setup lobby presence refetch (catches simultaneous joiners) */
308
380
  const LOBBY_REFRESH_DELAY_MS = 2000;
309
381
 
382
+ /** The content topics a channel filter applies to, kept in step deliberately. */
383
+ const FILTERED_TOPICS = [TOPIC_POSTS, TOPIC_REACTIONS, TOPIC_COMMENTS];
384
+ /** Maps the public topic names onto the wire topics. */
385
+ const FILTER_TOPICS = {
386
+ posts: TOPIC_POSTS,
387
+ reactions: TOPIC_REACTIONS,
388
+ comments: TOPIC_COMMENTS,
389
+ };
310
390
  /**
311
391
  * FeedChannel — a single feed channel with posts, comments, reactions, and
312
392
  * presence.
@@ -320,6 +400,10 @@ class FeedChannel extends EventEmitter {
320
400
  this._comments = new Map();
321
401
  this._unreadCount = 0;
322
402
  this._active = false;
403
+ /** Filter values applied per content topic. */
404
+ this._filters = {
405
+ posts: [], reactions: [], comments: [],
406
+ };
323
407
  // Stored topic handler refs — cleanup removes exactly these, never all
324
408
  // handlers for a topic (the client may be shared with other consumers).
325
409
  this._onPostsRef = null;
@@ -342,14 +426,15 @@ class FeedChannel extends EventEmitter {
342
426
  const post = {
343
427
  id: generateId(), userId: this._localUser.userId, username: this._localUser.username,
344
428
  avatar: this._localUser.avatar, content: opts.content, media: opts.media, data: opts.data,
345
- likeCount: 0, commentCount: 0, likedByMe: false, timestamp: Date.now(), status: 'sending', isReplay: false,
429
+ likeCount: 0, commentCount: 0, likedByMe: false, timestamp: Date.now(),
430
+ filter: recordedFilter(opts), status: 'sending', isReplay: false,
346
431
  };
347
432
  this._postStore.add(post);
348
433
  this.emit('postSent', post);
349
434
  this._roomContext.emit(TOPIC_POSTS, {
350
435
  id: post.id, userId: post.userId, username: post.username, avatar: post.avatar,
351
436
  content: post.content, media: post.media, data: post.data, timestamp: post.timestamp,
352
- }, { echo: false });
437
+ }, { echo: false, ...filterEmitOptions(opts) });
353
438
  post.status = 'sent';
354
439
  return post;
355
440
  }
@@ -358,7 +443,7 @@ class FeedChannel extends EventEmitter {
358
443
  const { likeCount, isNew } = this._reactionManager.like(postId, this._localUser.userId);
359
444
  if (isNew) {
360
445
  this._postStore.updateLikeCount(postId, likeCount, true);
361
- this._roomContext.emit(TOPIC_REACTIONS, { postId, userId: this._localUser.userId, type: 'like', timestamp: Date.now() }, { echo: false });
446
+ this._roomContext.emit(TOPIC_REACTIONS, { postId, userId: this._localUser.userId, type: 'like', timestamp: Date.now() }, { echo: false, ...this._postFilter(postId) });
362
447
  this.emit('postLiked', { postId, userId: this._localUser.userId, likeCount });
363
448
  }
364
449
  }
@@ -366,7 +451,7 @@ class FeedChannel extends EventEmitter {
366
451
  const { likeCount, wasLiked } = this._reactionManager.unlike(postId, this._localUser.userId);
367
452
  if (wasLiked) {
368
453
  this._postStore.updateLikeCount(postId, likeCount, false);
369
- this._roomContext.emit(TOPIC_REACTIONS, { postId, userId: this._localUser.userId, type: 'unlike', timestamp: Date.now() }, { echo: false });
454
+ this._roomContext.emit(TOPIC_REACTIONS, { postId, userId: this._localUser.userId, type: 'unlike', timestamp: Date.now() }, { echo: false, ...this._postFilter(postId) });
370
455
  this.emit('postUnliked', { postId, userId: this._localUser.userId, likeCount });
371
456
  }
372
457
  }
@@ -383,9 +468,68 @@ class FeedChannel extends EventEmitter {
383
468
  this._roomContext.emit(TOPIC_COMMENTS, {
384
469
  id: comment.id, postId, userId: comment.userId, username: comment.username,
385
470
  avatar: comment.avatar, text: comment.text, timestamp: comment.timestamp,
386
- }, { echo: false });
471
+ }, { echo: false, ...this._postFilter(postId) });
387
472
  return comment;
388
473
  }
474
+ // ============ Filters ============
475
+ /** The filter values currently applied to this channel, by topic. */
476
+ get filters() {
477
+ return {
478
+ posts: [...this._filters.posts],
479
+ reactions: [...this._filters.reactions],
480
+ comments: [...this._filters.comments],
481
+ };
482
+ }
483
+ /**
484
+ * Replace this channel's filters — only posts published with one of these
485
+ * values are delivered. Reactions and comments get the same set unless you
486
+ * scope the call with `{ topic }`, so you never receive a like for a post
487
+ * you cannot see.
488
+ *
489
+ * Passing an empty array clears filtering and restores the wildcard
490
+ * subscription, which receives everything.
491
+ *
492
+ * @example
493
+ * ```ts
494
+ * channel.setFilters(['sports', 'news']); // sports OR news
495
+ * channel.setFilters([['sports', 'live']]); // sports AND live
496
+ * channel.setFilters([]); // everything
497
+ * ```
498
+ */
499
+ setFilters(values, opts) {
500
+ for (const topic of this._targetTopics(opts)) {
501
+ this._filters[topic] = [...values];
502
+ // The core types filters as `string[]`, but both its implementation and
503
+ // the wire protocol accept AND groups (nested arrays).
504
+ this._roomContext.setFilters(FILTER_TOPICS[topic], values);
505
+ }
506
+ }
507
+ /** Add filter values to the existing set. Existing AND groups are kept. */
508
+ addFilters(values, opts) {
509
+ for (const topic of this._targetTopics(opts)) {
510
+ this.setFilters(mergeFilters(this._filters[topic], values), { topic });
511
+ }
512
+ }
513
+ /**
514
+ * Remove filter values from the existing set. Removing the last value
515
+ * restores the wildcard subscription.
516
+ */
517
+ removeFilters(values, opts) {
518
+ for (const topic of this._targetTopics(opts)) {
519
+ this.setFilters(withoutFilters(this._filters[topic], values), { topic });
520
+ }
521
+ }
522
+ _targetTopics(opts) {
523
+ return opts?.topic ? [opts.topic] : ['posts', 'reactions', 'comments'];
524
+ }
525
+ /**
526
+ * The publish options that put a reaction or comment in front of the same
527
+ * audience as the post it belongs to. An unknown post (never seen, or
528
+ * evicted from the cache) falls back to unfiltered.
529
+ */
530
+ _postFilter(postId) {
531
+ return inheritFilter(this._postStore.get(postId)?.filter);
532
+ }
389
533
  getComments(postId) {
390
534
  return this._comments.get(postId) ?? [];
391
535
  }
@@ -397,11 +541,19 @@ class FeedChannel extends EventEmitter {
397
541
  }
398
542
  getUsers() { return this._presenceManager.getAll(); }
399
543
  /** @internal Subscribe to post/reaction/comment topics and attach listeners (all channels) */
400
- _subscribe() {
544
+ _subscribe(filters) {
401
545
  this._log('Channel subscribe:', this.name);
402
- this._roomContext.subscribe(TOPIC_POSTS);
403
- this._roomContext.subscribe(TOPIC_REACTIONS);
404
- this._roomContext.subscribe(TOPIC_COMMENTS);
546
+ const initial = filters ? [...filters] : [];
547
+ this._filters = { posts: [...initial], reactions: [...initial], comments: [...initial] };
548
+ if (initial.length > 0) {
549
+ const opts = { filters: initial };
550
+ for (const topic of FILTERED_TOPICS)
551
+ this._roomContext.subscribe(topic, opts);
552
+ }
553
+ else {
554
+ for (const topic of FILTERED_TOPICS)
555
+ this._roomContext.subscribe(topic);
556
+ }
405
557
  // Listen for posts (refs stored for handler-specific removal)
406
558
  this._onPostsRef = (data, meta) => {
407
559
  this._handleIncomingPost(data, meta);
@@ -483,7 +635,8 @@ class FeedChannel extends EventEmitter {
483
635
  avatar: raw.avatar, content: raw.content,
484
636
  media: raw.media, data: raw.data,
485
637
  likeCount: 0, commentCount: 0, likedByMe: false,
486
- timestamp: raw.timestamp, status: 'delivered', isReplay: meta.isReplay ?? false,
638
+ timestamp: raw.timestamp, filter: meta.filter,
639
+ status: 'delivered', isReplay: meta.isReplay ?? false,
487
640
  };
488
641
  if (this._postStore.add(post)) {
489
642
  this.emit('postCreated', post);
@@ -842,7 +995,7 @@ class NoLagFeed extends EventEmitter {
842
995
  * If the channel was pre-subscribed via the `channels` option, activates it.
843
996
  * Otherwise creates, subscribes, and activates it.
844
997
  */
845
- joinChannel(name) {
998
+ joinChannel(name, opts) {
846
999
  this._assertUsable();
847
1000
  // Deactivate the current active channel
848
1001
  if (this._activeChannel && this._activeChannel !== name) {
@@ -853,7 +1006,12 @@ class NoLagFeed extends EventEmitter {
853
1006
  // Get or create the channel
854
1007
  let channel = this._channels.get(name);
855
1008
  if (!channel) {
856
- channel = this._subscribeChannelInternal(name);
1009
+ channel = this._subscribeChannelInternal(name, opts?.filters);
1010
+ }
1011
+ else if (opts?.filters) {
1012
+ // Already subscribed (pre-subscribed via the `channels` option, or an
1013
+ // earlier join). Re-point its filters rather than ignoring them.
1014
+ channel.setFilters(opts.filters);
857
1015
  }
858
1016
  this._activeChannel = name;
859
1017
  channel._activate();
@@ -922,12 +1080,12 @@ class NoLagFeed extends EventEmitter {
922
1080
  }
923
1081
  }
924
1082
  // ============ Private: Channel Setup ============
925
- _subscribeChannelInternal(name) {
1083
+ _subscribeChannelInternal(name, filters) {
926
1084
  this._log('Subscribing channel:', name);
927
1085
  const roomContext = this._client.setApp(this._options.appName).setRoom(name);
928
1086
  const channel = new FeedChannel(name, roomContext, this._localUser, this._options, createLogger(`FeedChannel:${name}`, this._options.debug), () => this._client.connected);
929
1087
  this._channels.set(name, channel);
930
- channel._subscribe();
1088
+ channel._subscribe(filters);
931
1089
  return channel;
932
1090
  }
933
1091
  // ============ Private: Scope Filtering ============