@nolag/notify 0.1.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.
package/README.md ADDED
@@ -0,0 +1,166 @@
1
+ # @nolag/notify
2
+
3
+ Real-time notifications SDK for [NoLag](https://nolag.app) — channels, read/unread tracking, and badge counts.
4
+
5
+ ## How It Works with NoLag
6
+
7
+ NoLag is a real-time messaging platform that handles WebSocket connections, message routing, persistence, and scaling. This SDK wraps the low-level [@nolag/js-sdk](https://www.npmjs.com/package/@nolag/js-sdk) and gives you a purpose-built notification API — channels, read tracking, badge counts, and replay — without managing topics or subscriptions yourself.
8
+
9
+ ### Getting Your Token
10
+
11
+ 1. Sign up at [nolag.app](https://nolag.app)
12
+ 2. Create a new **project** in the portal
13
+ 3. Choose the **Notify** blueprint when creating an app — this pre-configures the topics (`notifications`, `_read`) and settings your notification system needs
14
+ 4. Go to the app's **Tokens** page and generate an **actor token**
15
+ 5. Use that token when connecting with this SDK
16
+
17
+ Each token identifies a unique user (actor) in NoLag. The blueprint handles all the infrastructure setup — you just build your notification UI.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ npm install @nolag/js-sdk @nolag/notify
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```typescript
28
+ import { NoLagNotify } from "@nolag/notify";
29
+
30
+ const notify = new NoLagNotify("YOUR_ACTOR_TOKEN", {
31
+ channels: ["alerts", "updates"],
32
+ });
33
+
34
+ await notify.connect();
35
+
36
+ // Listen for notifications
37
+ notify.on("notification", (n) => {
38
+ console.log(`[${n.channel}] ${n.title}: ${n.body}`);
39
+ });
40
+
41
+ // Subscribe to a channel
42
+ const channel = notify.subscribe("alerts");
43
+
44
+ channel.on("notification", (n) => {
45
+ showToast(n.title, n.body);
46
+ });
47
+
48
+ // Send a notification
49
+ channel.send("Deploy complete", {
50
+ body: "v2.1.0 deployed to production",
51
+ icon: "rocket",
52
+ data: { version: "2.1.0" },
53
+ });
54
+
55
+ // Badge counts
56
+ const badges = notify.getBadgeCounts();
57
+ console.log(`Total unread: ${badges.total}`);
58
+
59
+ // Mark as read
60
+ channel.markRead(notificationId);
61
+ channel.markAllRead();
62
+ ```
63
+
64
+ ## API Reference
65
+
66
+ ### `NoLagNotify`
67
+
68
+ #### Constructor
69
+
70
+ ```typescript
71
+ const notify = new NoLagNotify(token: string, options?: NoLagNotifyOptions);
72
+ ```
73
+
74
+ **Options:**
75
+
76
+ | Option | Type | Default | Description |
77
+ |--------|------|---------|-------------|
78
+ | `channels` | `string[]` | — | Auto-subscribe to these channels on connect |
79
+ | `metadata` | `Record<string, unknown>` | — | Custom metadata |
80
+ | `maxNotificationCache` | `number` | `500` | Max notifications kept in memory per channel |
81
+ | `debug` | `boolean` | `false` | Enable debug logging |
82
+ | `reconnect` | `boolean` | `true` | Auto-reconnect on disconnect |
83
+
84
+ #### Methods
85
+
86
+ | Method | Returns | Description |
87
+ |--------|---------|-------------|
88
+ | `connect()` | `Promise<void>` | Connect to NoLag |
89
+ | `disconnect()` | `void` | Disconnect |
90
+ | `subscribe(channelName)` | `NotifyChannel` | Subscribe to a notification channel |
91
+ | `unsubscribe(channelName)` | `void` | Unsubscribe from a channel |
92
+ | `getBadgeCounts()` | `BadgeCounts` | Get unread counts (total + per channel) |
93
+ | `markAllRead()` | `void` | Mark all notifications as read |
94
+
95
+ #### Events
96
+
97
+ | Event | Payload | Description |
98
+ |-------|---------|-------------|
99
+ | `connected` | — | Connected to NoLag |
100
+ | `disconnected` | — | Disconnected |
101
+ | `reconnected` | — | Reconnected after disconnect |
102
+ | `error` | `Error` | Connection or protocol error |
103
+ | `notification` | `Notification` | Notification received on any channel |
104
+ | `badgeUpdated` | `BadgeCounts` | Badge counts changed |
105
+
106
+ ### `NotifyChannel`
107
+
108
+ #### Methods
109
+
110
+ | Method | Returns | Description |
111
+ |--------|---------|-------------|
112
+ | `send(title, options?)` | `void` | Send a notification |
113
+ | `markRead(id)` | `void` | Mark a notification as read |
114
+ | `markAllRead()` | `void` | Mark all in this channel as read |
115
+ | `getNotifications()` | `Notification[]` | Get all cached notifications |
116
+ | `getUnread()` | `Notification[]` | Get unread notifications |
117
+
118
+ #### Properties
119
+
120
+ | Property | Type | Description |
121
+ |----------|------|-------------|
122
+ | `name` | `string` | Channel name |
123
+ | `notifications` | `Notification[]` | Cached notifications |
124
+ | `unreadCount` | `number` | Unread count |
125
+ | `active` | `boolean` | Whether currently subscribed |
126
+
127
+ #### Events
128
+
129
+ | Event | Payload | Description |
130
+ |-------|---------|-------------|
131
+ | `notification` | `Notification` | Notification received |
132
+ | `read` | `string` | Notification marked as read (id) |
133
+ | `readAll` | — | All marked as read |
134
+ | `replayStart` | — | Replay started |
135
+ | `replayEnd` | — | Replay finished |
136
+
137
+ ## Types
138
+
139
+ ```typescript
140
+ interface Notification {
141
+ id: string;
142
+ channel: string;
143
+ title: string;
144
+ body?: string;
145
+ icon?: string;
146
+ data?: Record<string, unknown>;
147
+ timestamp: number;
148
+ read: boolean;
149
+ isReplay: boolean;
150
+ }
151
+
152
+ interface BadgeCounts {
153
+ total: number;
154
+ byChannel: Record<string, number>;
155
+ }
156
+
157
+ interface SendNotificationOptions {
158
+ body?: string;
159
+ icon?: string;
160
+ data?: Record<string, unknown>;
161
+ }
162
+ ```
163
+
164
+ ## License
165
+
166
+ MIT
@@ -0,0 +1,23 @@
1
+ import type { BadgeCounts } from './types';
2
+ /**
3
+ * Aggregates unread notification counts across channels.
4
+ */
5
+ export declare class BadgeManager {
6
+ private _counts;
7
+ /**
8
+ * Update the unread count for a channel.
9
+ */
10
+ update(channel: string, unreadCount: number): void;
11
+ /**
12
+ * Get the unread count for a specific channel.
13
+ */
14
+ get(channel: string): number;
15
+ /**
16
+ * Get all badge counts — total and per-channel breakdown.
17
+ */
18
+ getAll(): BadgeCounts;
19
+ /**
20
+ * Clear all counts.
21
+ */
22
+ clear(): void;
23
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Tiny typed event emitter — framework-agnostic base for NoLag SDKs.
3
+ */
4
+ export declare class EventEmitter<EventMap extends {
5
+ [K in keyof EventMap]: unknown[];
6
+ }> {
7
+ private _handlers;
8
+ on<K extends keyof EventMap>(event: K, handler: (...args: EventMap[K]) => void): this;
9
+ off<K extends keyof EventMap>(event: K, handler?: (...args: EventMap[K]) => void): this;
10
+ removeAllListeners(): this;
11
+ protected emit<K extends keyof EventMap>(event: K, ...args: EventMap[K]): void;
12
+ listenerCount<K extends keyof EventMap>(event: K): number;
13
+ }
@@ -0,0 +1,77 @@
1
+ import { EventEmitter } from './EventEmitter';
2
+ import { NotifyChannel } from './NotifyChannel';
3
+ import type { NoLagNotifyOptions, NotifyClientEvents, BadgeCounts } from './types';
4
+ /**
5
+ * NoLagNotify — high-level notifications SDK built on @nolag/js-sdk.
6
+ *
7
+ * Provides multi-channel notifications, read/unread tracking, badge counts,
8
+ * message replay, and global presence — all framework-agnostic via events.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { NoLagNotify } from '@nolag/notify';
13
+ *
14
+ * const notify = new NoLagNotify(token);
15
+ *
16
+ * notify.on('connected', () => console.log('Connected!'));
17
+ * notify.on('notification', (n) => console.log('New notification:', n.title));
18
+ *
19
+ * await notify.connect();
20
+ *
21
+ * const alerts = notify.subscribe('alerts');
22
+ * alerts.on('notification', (n) => console.log(n.title));
23
+ * ```
24
+ */
25
+ export declare class NoLagNotify extends EventEmitter<NotifyClientEvents> {
26
+ private _token;
27
+ private _options;
28
+ private _client;
29
+ private _channels;
30
+ private _lobby;
31
+ private _badgeManager;
32
+ private _presenceManager;
33
+ private _actorToUserId;
34
+ private _userId;
35
+ private _log;
36
+ constructor(token: string, options?: NoLagNotifyOptions);
37
+ /** Whether the underlying connection is established */
38
+ get connected(): boolean;
39
+ /** All currently subscribed channels */
40
+ get channels(): Map<string, NotifyChannel>;
41
+ /**
42
+ * Connect to NoLag and set up global presence.
43
+ */
44
+ connect(): Promise<void>;
45
+ /**
46
+ * Disconnect from NoLag and clean up all channels.
47
+ */
48
+ disconnect(): void;
49
+ /**
50
+ * Subscribe to a notification channel (idempotent).
51
+ * Returns the NotifyChannel instance.
52
+ */
53
+ subscribe(channelName: string): NotifyChannel;
54
+ /**
55
+ * Unsubscribe from a notification channel.
56
+ */
57
+ unsubscribe(channelName: string): void;
58
+ /**
59
+ * Get the current badge counts across all channels.
60
+ */
61
+ getBadgeCounts(): BadgeCounts;
62
+ /**
63
+ * Mark all notifications as read across all channels.
64
+ */
65
+ markAllRead(): void;
66
+ private _subscribeChannel;
67
+ private _emitBadgeUpdated;
68
+ private _handleRoomPresenceJoin;
69
+ private _handleRoomPresenceLeave;
70
+ private _handleRoomPresenceUpdate;
71
+ private _setupLobby;
72
+ private _handleLobbyJoin;
73
+ private _handleLobbyLeave;
74
+ private _handleLobbyUpdate;
75
+ private _hydratePresence;
76
+ private _restoreChannels;
77
+ }
@@ -0,0 +1,48 @@
1
+ import type { Notification } from './types';
2
+ /**
3
+ * Bounded, deduplicated notification cache ordered by timestamp,
4
+ * with read/unread tracking.
5
+ */
6
+ export declare class NotificationStore {
7
+ private _notifications;
8
+ private _ids;
9
+ private _maxSize;
10
+ constructor(maxSize: number);
11
+ /**
12
+ * Add a notification. Returns true if the notification was new (not a duplicate).
13
+ */
14
+ add(notification: Notification): boolean;
15
+ /**
16
+ * Mark a notification as read by id.
17
+ * Returns true if the notification was found.
18
+ */
19
+ markRead(id: string): boolean;
20
+ /**
21
+ * Mark all notifications as read.
22
+ */
23
+ markAllRead(): void;
24
+ /**
25
+ * Get all notifications in timestamp order.
26
+ */
27
+ getAll(): Notification[];
28
+ /**
29
+ * Get all unread notifications.
30
+ */
31
+ getUnread(): Notification[];
32
+ /**
33
+ * Get the number of unread notifications.
34
+ */
35
+ get unreadCount(): number;
36
+ /**
37
+ * Get notification count.
38
+ */
39
+ get size(): number;
40
+ /**
41
+ * Check if a notification ID exists.
42
+ */
43
+ has(id: string): boolean;
44
+ /**
45
+ * Clear all notifications.
46
+ */
47
+ clear(): void;
48
+ }
@@ -0,0 +1,60 @@
1
+ import type { RoomContext } from '@nolag/js-sdk';
2
+ import { EventEmitter } from './EventEmitter';
3
+ import type { NotifyChannelEvents, Notification, ResolvedNotifyOptions, SendNotificationOptions } from './types';
4
+ /**
5
+ * NotifyChannel — a single notification channel with read/unread tracking.
6
+ *
7
+ * Created via `NoLagNotify.subscribe(name)`. Do not instantiate directly.
8
+ */
9
+ export declare class NotifyChannel extends EventEmitter<NotifyChannelEvents> {
10
+ /** Channel name */
11
+ readonly name: string;
12
+ private _roomContext;
13
+ private _options;
14
+ private _store;
15
+ private _log;
16
+ private _active;
17
+ /** @internal */
18
+ constructor(name: string, roomContext: RoomContext, options: ResolvedNotifyOptions, log: (...args: unknown[]) => void);
19
+ /** All notifications in this channel (timestamp order) */
20
+ get notifications(): Notification[];
21
+ /** Number of unread notifications */
22
+ get unreadCount(): number;
23
+ /** Whether this channel is currently active */
24
+ get active(): boolean;
25
+ /**
26
+ * Send a notification to this channel.
27
+ */
28
+ send(title: string, opts?: SendNotificationOptions): void;
29
+ /**
30
+ * Mark a single notification as read by id.
31
+ * Emits the read receipt to the _read topic for cross-tab sync.
32
+ */
33
+ markRead(id: string): void;
34
+ /**
35
+ * Mark all notifications in this channel as read.
36
+ */
37
+ markAllRead(): void;
38
+ /**
39
+ * Get all notifications (alias for the notifications getter).
40
+ */
41
+ getNotifications(): Notification[];
42
+ /**
43
+ * Get all unread notifications.
44
+ */
45
+ getUnread(): Notification[];
46
+ /** @internal Subscribe to notifications and _read topics */
47
+ _subscribe(): void;
48
+ /** @internal Activate this channel (mark as visible/active) */
49
+ _activate(): void;
50
+ /** @internal Deactivate this channel */
51
+ _deactivate(): void;
52
+ /** @internal Handle replay start event */
53
+ _handleReplayStart(count: number): void;
54
+ /** @internal Handle replay end event */
55
+ _handleReplayEnd(replayed: number): void;
56
+ /** @internal Unsubscribe and clean up */
57
+ _cleanup(): void;
58
+ private _handleIncomingNotification;
59
+ private _handleIncomingRead;
60
+ }
@@ -0,0 +1,40 @@
1
+ import type { NotifyPresenceData } from './types';
2
+ export interface NotifyUser {
3
+ userId: string;
4
+ actorTokenId: string;
5
+ metadata?: Record<string, unknown>;
6
+ joinedAt: number;
7
+ }
8
+ /**
9
+ * Maps actorTokenId to NotifyUser for global presence tracking.
10
+ */
11
+ export declare class PresenceManager {
12
+ private _users;
13
+ private _actorToUserId;
14
+ /**
15
+ * Add or update a user from presence data.
16
+ * Returns the NotifyUser, or null if presence data is invalid.
17
+ */
18
+ addFromPresence(actorTokenId: string, presenceData: NotifyPresenceData, joinedAt?: number): NotifyUser | null;
19
+ /**
20
+ * Remove a user by actorTokenId.
21
+ * Returns the removed user, or null if not found.
22
+ */
23
+ removeByActorId(actorTokenId: string): NotifyUser | null;
24
+ /**
25
+ * Get a user by userId.
26
+ */
27
+ getUser(userId: string): NotifyUser | undefined;
28
+ /**
29
+ * Get a user by actorTokenId.
30
+ */
31
+ getUserByActorId(actorTokenId: string): NotifyUser | undefined;
32
+ /**
33
+ * Get all tracked users.
34
+ */
35
+ getAll(): NotifyUser[];
36
+ /**
37
+ * Clear all tracked users.
38
+ */
39
+ clear(): void;
40
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @nolag/notify
3
+ * Real-time notifications SDK for Browser and React Native
4
+ */
5
+ export { NoLagNotify } from './NoLagNotify';
6
+ export { NotifyChannel } from './NotifyChannel';
7
+ export { EventEmitter } from './EventEmitter';
8
+ export type { NoLagNotifyOptions, Notification, SendNotificationOptions, BadgeCounts, NotifyClientEvents, NotifyChannelEvents, NotifyPresenceData, } from './types';
@@ -0,0 +1,2 @@
1
+ import{NoLag as t}from"@nolag/js-sdk";class e{constructor(){this._handlers=new Map}on(t,e){return this._handlers.has(t)||this._handlers.set(t,new Set),this._handlers.get(t).add(e),this}off(t,e){return e?this._handlers.get(t)?.delete(e):this._handlers.delete(t),this}removeAllListeners(){return this._handlers.clear(),this}emit(t,...e){const s=this._handlers.get(t);if(s)for(const n of s)try{n(...e)}catch(e){console.error(`Error in ${String(t)} handler:`,e)}}listenerCount(t){return this._handlers.get(t)?.size??0}}class s{constructor(t){this._notifications=[],this._ids=new Set,this._maxSize=t}add(t){if(this._ids.has(t.id))return!1;for(this._ids.add(t.id),this._notifications.push(t),this._notifications.length>1&&t.timestamp<this._notifications[this._notifications.length-2].timestamp&&this._notifications.sort((t,e)=>t.timestamp-e.timestamp);this._notifications.length>this._maxSize;){const t=this._notifications.shift();this._ids.delete(t.id)}return!0}markRead(t){const e=this._notifications.find(e=>e.id===t);return!!e&&(e.read=!0,!0)}markAllRead(){for(const t of this._notifications)t.read=!0}getAll(){return[...this._notifications]}getUnread(){return this._notifications.filter(t=>!t.read)}get unreadCount(){return this._notifications.filter(t=>!t.read).length}get size(){return this._notifications.length}has(t){return this._ids.has(t)}clear(){this._notifications=[],this._ids.clear()}}function n(){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 i(t,e){return e?(...e)=>{console.log(`[${t}]`,...e)}:(...t)=>{}}const o="notifications",r="_read";class a extends e{constructor(t,e,n,i){super(),this._active=!1,this.name=t,this._roomContext=e,this._options=n,this._store=new s(n.maxNotificationCache),this._log=i}get notifications(){return this._store.getAll()}get unreadCount(){return this._store.unreadCount}get active(){return this._active}send(t,e){const s={id:n(),channel:this.name,title:t,body:e?.body,icon:e?.icon,data:e?.data,timestamp:Date.now()};this._roomContext.emit(o,{id:s.id,channel:s.channel,title:s.title,body:s.body,icon:s.icon,data:s.data,timestamp:s.timestamp})}markRead(t){this._store.markRead(t)&&(this._log("Mark read:",t),this._roomContext.emit(r,{id:t,channel:this.name}),this.emit("read",t))}markAllRead(){this._store.markAllRead(),this._log("Mark all read:",this.name),this._roomContext.emit(r,{all:!0,channel:this.name}),this.emit("readAll")}getNotifications(){return this._store.getAll()}getUnread(){return this._store.getUnread()}_subscribe(){this._log("Channel subscribe:",this.name),this._roomContext.subscribe(o),this._roomContext.subscribe(r),this._roomContext.on(o,(t,e)=>{this._handleIncomingNotification(t,e)}),this._roomContext.on(r,t=>{this._handleIncomingRead(t)})}_activate(){this._log("Channel activate:",this.name),this._active=!0}_deactivate(){this._log("Channel deactivate:",this.name),this._active=!1}_handleReplayStart(t){this.emit("replayStart",{count:t})}_handleReplayEnd(t){this.emit("replayEnd",{replayed:t})}_cleanup(){this._log("Channel cleanup:",this.name),this._roomContext.unsubscribe(o),this._roomContext.unsubscribe(r),this._roomContext.off(o),this._roomContext.off(r),this._store.clear(),this.removeAllListeners()}_handleIncomingNotification(t,e){const s=t,i={id:s.id||n(),channel:this.name,title:s.title,body:s.body,icon:s.icon,data:s.data,timestamp:s.timestamp||Date.now(),read:!1,isReplay:e.isReplay??!1};this._store.add(i)&&(this._log("Notification received:",i.id,i.title),this.emit("notification",i))}_handleIncomingRead(t){const e=t;!0===e.all?(this._store.markAllRead(),this.emit("readAll")):"string"==typeof e.id&&this._store.markRead(e.id)&&this.emit("read",e.id)}}class c{constructor(){this._counts=new Map}update(t,e){this._counts.set(t,e)}get(t){return this._counts.get(t)??0}getAll(){const t={};let e=0;for(const[s,n]of this._counts)t[s]=n,e+=n;return{total:e,byChannel:t}}clear(){this._counts.clear()}}class h{constructor(){this._users=new Map,this._actorToUserId=new Map}addFromPresence(t,e,s){if(!e?.userId)return null;const n=this._actorToUserId.get(t),i=e.userId||n||t,o={userId:i,actorTokenId:t,metadata:e.metadata,joinedAt:s||Date.now()};return this._users.set(i,o),this._actorToUserId.set(t,i),o}removeByActorId(t){const e=this._actorToUserId.get(t);if(!e)return null;const s=this._users.get(e)||null;return this._users.delete(e),this._actorToUserId.delete(t),s}getUser(t){return this._users.get(t)}getUserByActorId(t){const e=this._actorToUserId.get(t);return e?this._users.get(e):void 0}getAll(){return Array.from(this._users.values())}clear(){this._users.clear(),this._actorToUserId.clear()}}class d extends e{constructor(t,e={}){super(),this._client=null,this._channels=new Map,this._lobby=null,this._badgeManager=new c,this._presenceManager=new h,this._actorToUserId=new Map,this._token=t,this._userId=n(),this._options={metadata:e.metadata,appName:e.appName??"notify",url:e.url,maxNotificationCache:e.maxNotificationCache??500,debug:e.debug??!1,reconnect:e.reconnect??!0,channels:e.channels??[]},this._log=i("NoLagNotify",this._options.debug)}get connected(){return this._client?.connected??!1}get channels(){return this._channels}async connect(){this._log("Connecting...");const e={debug:this._options.debug,reconnect:this._options.reconnect};this._options.url&&(e.url=this._options.url),this._client=t(this._token,e),this._client.on("connect",()=>{this._log("Connected"),this._channels.size>0&&(this._log("Reconnected — restoring channels..."),this._restoreChannels(),this.emit("reconnected"))}),this._client.on("disconnect",t=>{this._log("Disconnected:",t),this.emit("disconnected",t)}),this._client.on("reconnect",()=>{this._log("Reconnecting...")}),this._client.on("error",t=>{this._log("Error:",t),this.emit("error",t)}),this._client.on("replay:start",t=>{const e=t;for(const t of this._channels.values())t._handleReplayStart(e.count)}),this._client.on("replay:end",t=>{const e=t;for(const t of this._channels.values())t._handleReplayEnd(e.replayed)}),await this._client.connect(),this._client.on("presence:join",t=>{this._handleRoomPresenceJoin(t)}),this._client.on("presence:leave",t=>{this._handleRoomPresenceLeave(t)}),this._client.on("presence:update",t=>{this._handleRoomPresenceUpdate(t)}),this._log("Local userId:",this._userId,"→ actorId:",this._client.actorId),await this._setupLobby();for(const t of this._options.channels)this._subscribeChannel(t);this.emit("connected"),setTimeout(()=>{this._lobby&&this._client?.connected&&this._lobby.fetchPresence().then(t=>{this._hydratePresence(t)}).catch(()=>{})},2e3)}disconnect(){this._log("Disconnecting...");for(const t of[...this._channels.keys()])this.unsubscribe(t);this._lobby?.unsubscribe(),this._lobby=null,this._client?.disconnect(),this._client=null,this._badgeManager.clear(),this._presenceManager.clear(),this._actorToUserId.clear()}subscribe(t){if(!this._client)throw new Error("Not connected — call connect() first");const e=this._channels.get(t);if(e)return e;const s=this._subscribeChannel(t);return s._activate(),s}unsubscribe(t){const e=this._channels.get(t);e&&(this._log("Unsubscribing channel:",t),e._cleanup(),this._channels.delete(t),this._badgeManager.update(t,0),this._emitBadgeUpdated())}getBadgeCounts(){return this._badgeManager.getAll()}markAllRead(){for(const t of this._channels.values())t.markAllRead()}_subscribeChannel(t){if(!this._client)throw new Error("Not connected — call connect() first");this._log("Subscribing channel:",t);const e=this._client.setApp(this._options.appName).setRoom(t),s=new a(t,e,this._options,i(`NotifyChannel:${t}`,this._options.debug));return this._channels.set(t,s),s._subscribe(),s.on("notification",e=>{this._badgeManager.update(t,s.unreadCount),this._emitBadgeUpdated(),this.emit("notification",e)}),s.on("read",()=>{this._badgeManager.update(t,s.unreadCount),this._emitBadgeUpdated()}),s.on("readAll",()=>{this._badgeManager.update(t,0),this._emitBadgeUpdated()}),s}_emitBadgeUpdated(){this.emit("badgeUpdated",this._badgeManager.getAll())}_handleRoomPresenceJoin(t){if(t.actorTokenId===this._client?.actorId)return;const e=t.presence;if(!e?.userId)return;const s=this._presenceManager.addFromPresence(t.actorTokenId,e);s&&this._actorToUserId.set(t.actorTokenId,s.userId)}_handleRoomPresenceLeave(t){t.actorTokenId!==this._client?.actorId&&this._presenceManager.removeByActorId(t.actorTokenId)}_handleRoomPresenceUpdate(t){if(t.actorTokenId===this._client?.actorId)return;const e=t.presence;e?.userId&&this._presenceManager.addFromPresence(t.actorTokenId,e)}async _setupLobby(){if(!this._client)return;this._lobby=this._client.setApp(this._options.appName).setLobby("online");const t={userId:this._userId,metadata:this._options.metadata};this._lobby.setPresence?.(t);const e=t=>e=>{const s=e;"join"===t?this._handleLobbyJoin(s):"leave"===t?this._handleLobbyLeave(s):this._handleLobbyUpdate(s)};this._client.on("lobbyPresence:join",e("join")),this._client.on("lobbyPresence:leave",e("leave")),this._client.on("lobbyPresence:update",e("update"));try{const t=await this._lobby.subscribe();this._hydratePresence(t),this._log("Lobby subscribed")}catch(t){this._log("Lobby subscription failed:",t)}}_handleLobbyJoin(t){const{actorId:e,data:s}=t;if(e===this._client?.actorId)return;const n=s;if(!n?.userId)return;const i=this._presenceManager.addFromPresence(e,n);i&&this._actorToUserId.set(e,i.userId)}_handleLobbyLeave(t){const{actorId:e}=t;e!==this._client?.actorId&&(this._presenceManager.removeByActorId(e),this._actorToUserId.delete(e))}_handleLobbyUpdate(t){const{actorId:e,data:s}=t;if(e===this._client?.actorId)return;const n=s;n?.userId&&this._presenceManager.addFromPresence(e,n)}_hydratePresence(t){for(const e of Object.keys(t)){const s=t[e];for(const t of Object.keys(s)){if(t===this._client?.actorId)continue;const e=s[t],n=e?.presence??e;if(n?.userId){const e=this._presenceManager.addFromPresence(t,n);e&&this._actorToUserId.set(t,e.userId)}}}}_restoreChannels(){this._lobby?.fetchPresence().then(t=>{this._presenceManager.clear(),this._actorToUserId.clear(),this._hydratePresence(t)}).catch(t=>{this._log("Failed to re-fetch lobby presence:",t)})}}export{e as EventEmitter,d as NoLagNotify,a as NotifyChannel};
2
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sources":["../src/EventEmitter.ts","../src/NotificationStore.ts","../src/utils.ts","../src/constants.ts","../src/NotifyChannel.ts","../src/BadgeManager.ts","../src/PresenceManager.ts","../src/NoLagNotify.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","NotificationStore","maxSize","_notifications","_ids","_maxSize","notification","id","push","length","timestamp","sort","a","b","removed","shift","markRead","find","n","read","markAllRead","getAll","getUnread","filter","unreadCount","generateId","crypto","randomUUID","replace","Math","floor","random","toString","createLogger","prefix","enabled","log","_args","TOPIC_NOTIFICATIONS","TOPIC_READ","NotifyChannel","name","roomContext","options","super","_active","_roomContext","_options","_store","maxNotificationCache","_log","notifications","active","send","title","opts","channel","body","icon","data","Date","now","all","getNotifications","_subscribe","subscribe","meta","_handleIncomingNotification","_handleIncomingRead","_activate","_deactivate","_handleReplayStart","count","_handleReplayEnd","replayed","_cleanup","unsubscribe","raw","isReplay","BadgeManager","_counts","update","byChannel","total","PresenceManager","_users","_actorToUserId","addFromPresence","actorTokenId","presenceData","joinedAt","userId","existing","user","metadata","removeByActorId","getUser","getUserByActorId","undefined","Array","from","values","NoLagNotify","token","_client","_channels","_lobby","_badgeManager","_presenceManager","_token","_userId","appName","url","debug","reconnect","channels","connected","connect","clientOptions","NoLag","_restoreChannels","reason","_handleRoomPresenceJoin","_handleRoomPresenceLeave","_handleRoomPresenceUpdate","actorId","_setupLobby","channelName","_subscribeChannel","setTimeout","fetchPresence","then","state","_hydratePresence","catch","disconnect","keys","Error","_emitBadgeUpdated","getBadgeCounts","setApp","setRoom","presence","setLobby","setPresence","lobbyHandler","type","_handleLobbyJoin","_handleLobbyLeave","_handleLobbyUpdate","initialState","err","roomId","Object","roomPresence"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /** Default app name for channel topic prefixes */
2
+ export declare const DEFAULT_APP_NAME = "notify";
3
+ /** Default max notifications kept per channel */
4
+ export declare const DEFAULT_MAX_NOTIFICATION_CACHE = 500;
5
+ /** Topic name for notifications within a channel */
6
+ export declare const TOPIC_NOTIFICATIONS = "notifications";
7
+ /** Topic name for read receipts within a channel */
8
+ export declare const TOPIC_READ = "_read";
9
+ /** Lobby ID for global online presence */
10
+ export declare const LOBBY_ID = "online";