@nolag/dash 0.1.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,12 +24,21 @@ npm install @nolag/js-sdk @nolag/dash
24
24
 
25
25
  ## Quick Start
26
26
 
27
+ The app owns one core NoLag client; wrappers attach to it. Any number of
28
+ wrapper SDKs (dash, chat, notify, ...) can share the same connection as
29
+ long as each uses its own app.
30
+
27
31
  ```typescript
32
+ import { NoLag } from "@nolag/js-sdk";
28
33
  import { NoLagDash } from "@nolag/dash";
29
34
 
30
- const dash = new NoLagDash("YOUR_ACTOR_TOKEN");
35
+ // One client for the whole app. In a browser, use a token provider so the
36
+ // SDK can mint fresh short-lived client tokens from your backend.
37
+ const client = NoLag(async () => (await (await fetch("/api/nolag-token")).json()).token);
38
+ const dash = new NoLagDash({ client, username: "Alice" });
31
39
 
32
- await dash.connect();
40
+ await client.connect(); // the app owns the connection
41
+ await dash.ready(); // wrapper setup done (identity, presence, panels)
33
42
 
34
43
  const panel = dash.joinPanel("server-metrics");
35
44
 
@@ -53,8 +62,37 @@ panel.on("widgetUpdate", (widget) => {
53
62
  // Aggregations
54
63
  const agg = panel.getAggregation("cpu", 60_000); // last 60s
55
64
  console.log(`CPU avg: ${agg.avg}%, max: ${agg.max}%`);
65
+
66
+ // See who's watching
67
+ dash.on("viewerOnline", (viewer) => {
68
+ console.log(`${viewer.username} is watching`);
69
+ });
70
+
71
+ // Teardown: the wrapper releases its handlers and topics; the app closes
72
+ // the socket (never the other way around).
73
+ dash.detach();
74
+ client.disconnect();
56
75
  ```
57
76
 
77
+ ## Lifecycle
78
+
79
+ - **Construction = attach.** The wrapper wires its handlers onto the injected
80
+ client immediately. If the client is already connected, setup runs on the
81
+ next microtask; otherwise it runs when the client's `connect` event fires.
82
+ - **`ready()`** resolves once the first setup completed (identity, online
83
+ lobby, configured panels). Auth failures surface via your own
84
+ `await client.connect()`, not via `ready()`.
85
+ - **Reconnects are automatic.** The wrapper restores presence and reconciles
86
+ the online-viewer list, emitting only real deltas.
87
+ - **`detach()`** removes exactly this wrapper's handlers and topics and never
88
+ touches the socket. It is terminal: construct a new instance to re-attach.
89
+ Detach while the client is still connected so server-side unsubscribes go
90
+ through. In frameworks, call it from your dispose hook (`onUnmounted`,
91
+ HMR dispose).
92
+ - **One wrapper per (client, app).** Sharing a client across wrappers of
93
+ DIFFERENT apps is the intended pattern; two wrappers on the same app would
94
+ collide on topics and presence (the SDK warns if you do this).
95
+
58
96
  ## API Reference
59
97
 
60
98
  ### `NoLagDash`
@@ -62,38 +100,50 @@ console.log(`CPU avg: ${agg.avg}%, max: ${agg.max}%`);
62
100
  #### Constructor
63
101
 
64
102
  ```typescript
65
- const dash = new NoLagDash(token: string, options?: NoLagDashOptions);
103
+ const dash = new NoLagDash(options: NoLagDashOptions);
66
104
  ```
67
105
 
68
106
  **Options:**
69
107
 
70
108
  | Option | Type | Default | Description |
71
109
  |--------|------|---------|-------------|
72
- | `username` | `string` | | Display name |
73
- | `metadata` | `Record<string, unknown>` | — | Custom data |
110
+ | `client` | `NoLagSocket` | *required* | The injected core NoLag client |
111
+ | `username` | `string` | — | Display name for this viewer |
112
+ | `metadata` | `Record<string, unknown>` | — | Custom viewer data |
113
+ | `appName` | `string` | `'dash'` | NoLag app for topic prefixes |
74
114
  | `panels` | `string[]` | — | Auto-join these panels on connect |
75
- | `maxMetricPoints` | `number` | | Max metric points kept in memory |
76
- | `aggregationWindow` | `number` | | Default aggregation window (ms) |
77
- | `debug` | `boolean` | `false` | Enable debug logging |
78
- | `reconnect` | `boolean` | `true` | Auto-reconnect on disconnect |
115
+ | `maxMetricPoints` | `number` | `1000` | Max metric points kept in memory per stream |
116
+ | `aggregationWindow` | `number` | `60000` | Default aggregation window (ms) |
117
+ | `debug` | `boolean` | `false` | Enable wrapper debug logging |
79
118
 
80
119
  #### Methods
81
120
 
82
121
  | Method | Returns | Description |
83
122
  |--------|---------|-------------|
84
- | `connect()` | `Promise<void>` | Connect to NoLag |
85
- | `disconnect()` | `void` | Disconnect |
86
- | `joinPanel(name)` | `DashboardPanel` | Join a dashboard panel |
123
+ | `ready()` | `Promise<void>` | Resolves when wrapper setup completed |
124
+ | `detach()` | `void` | Release handlers and topics (terminal; never closes the socket) |
125
+ | `joinPanel(name, opts?)` | `DashboardPanel` | Join a dashboard panel |
87
126
  | `leavePanel(name)` | `void` | Leave a panel |
127
+ | `getPanels()` | `DashboardPanel[]` | Get all joined panels |
128
+ | `getOnlineViewers()` | `DashboardViewer[]` | Get all online viewers |
129
+
130
+ #### Properties
131
+
132
+ | Property | Type | Description |
133
+ |----------|------|-------------|
134
+ | `connected` | `boolean` | Whether currently connected |
135
+ | `localViewer` | `DashboardViewer \| null` | The current viewer |
136
+ | `panels` | `Map<string, DashboardPanel>` | All joined panels |
88
137
 
89
138
  #### Events
90
139
 
91
140
  | Event | Payload | Description |
92
141
  |-------|---------|-------------|
93
- | `connected` | — | Connected |
94
- | `disconnected` | | Disconnected |
95
- | `reconnected` | — | Reconnected |
96
- | `error` | `Error` | Error |
142
+ | `connected` | — | Connected to NoLag |
143
+ | `disconnected` | `string` | Disconnected (reason) |
144
+ | `reconnecting` | — | Reconnect attempt started |
145
+ | `reconnected` | | Reconnected after disconnect |
146
+ | `error` | `Error` | Connection or protocol error |
97
147
  | `viewerOnline` | `DashboardViewer` | Viewer came online |
98
148
  | `viewerOffline` | `DashboardViewer` | Viewer went offline |
99
149
 
@@ -10,7 +10,11 @@ export declare class DashboardPanel extends EventEmitter<DashPanelEvents> {
10
10
  private _widgetManager;
11
11
  private _log;
12
12
  private _localViewerId;
13
- constructor(name: string, roomContext: RoomContext, localViewerId: string, localActorId: string, options: ResolvedDashOptions, log: (...args: unknown[]) => void);
13
+ private _isConnected;
14
+ private _onMetricsRef;
15
+ private _onWidgetsRef;
16
+ /** @internal */
17
+ constructor(name: string, roomContext: RoomContext, localViewerId: string, localActorId: string, options: ResolvedDashOptions, log: (...args: unknown[]) => void, isConnected: () => boolean);
14
18
  publishMetric(streamId: string, value: number, opts?: {
15
19
  unit?: string;
16
20
  tags?: Record<string, string>;
@@ -1,31 +1,139 @@
1
+ import type { NoLagSocket } from '@nolag/js-sdk';
1
2
  import { EventEmitter } from './EventEmitter';
2
3
  import { DashboardPanel } from './DashboardPanel';
3
- import type { NoLagDashOptions, DashClientEvents } from './types';
4
+ import type { NoLagDashOptions, DashClientEvents, DashboardViewer } from './types';
5
+ /**
6
+ * NoLagDash — high-level live dashboard SDK built on @nolag/js-sdk.
7
+ *
8
+ * Provides multi-panel dashboards, real-time metric streams with
9
+ * aggregation, widget updates, viewer presence, and replay — all
10
+ * framework-agnostic via events.
11
+ *
12
+ * The wrapper NEVER manages the connection. The app owns one core NoLag
13
+ * client (shared by any number of wrappers on distinct apps) and the
14
+ * wrapper attaches to it at construction and releases it via `detach()`.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { NoLag } from '@nolag/js-sdk';
19
+ * import { NoLagDash } from '@nolag/dash';
20
+ *
21
+ * const client = NoLag(async () => (await (await fetch('/api/nolag-token')).json()).token);
22
+ * const dash = new NoLagDash({ client, appName: 'my-dash', username: 'Alice' });
23
+ *
24
+ * dash.on('viewerOnline', (v) => console.log(v.username, 'is watching'));
25
+ *
26
+ * await client.connect(); // the app owns the connection
27
+ * await dash.ready(); // wrapper setup done (identity, lobby, panels)
28
+ *
29
+ * const panel = dash.joinPanel('overview');
30
+ * panel.on('metric', (m) => console.log(m.streamId, m.value));
31
+ * panel.publishMetric('cpu', 75);
32
+ *
33
+ * dash.detach(); // wrapper releases its handlers and topics
34
+ * client.disconnect(); // the app closes the socket
35
+ * ```
36
+ */
4
37
  export declare class NoLagDash extends EventEmitter<DashClientEvents> {
5
- private _token;
6
- private _options;
7
38
  private _client;
39
+ private _options;
40
+ private _localViewer;
8
41
  private _panels;
9
42
  private _lobby;
10
43
  private _onlineViewers;
11
44
  private _actorToViewerId;
12
45
  private _viewerId;
13
46
  private _log;
14
- constructor(token: string, options?: NoLagDashOptions);
47
+ private _epoch;
48
+ private _detached;
49
+ private _isReady;
50
+ private _readyResolve;
51
+ private _readyReject;
52
+ private _readyPromise;
53
+ private _lobbyRefreshTimer;
54
+ private _onConnectRef;
55
+ private _onDisconnectRef;
56
+ private _onReconnectRef;
57
+ private _onErrorRef;
58
+ private _onReplayStartRef;
59
+ private _onReplayEndRef;
60
+ private _onPresenceJoinRef;
61
+ private _onPresenceLeaveRef;
62
+ private _onPresenceUpdateRef;
63
+ private _onLobbyJoinRef;
64
+ private _onLobbyLeaveRef;
65
+ private _onLobbyUpdateRef;
66
+ constructor(options: NoLagDashOptions);
67
+ /** Whether the underlying connection is established (connected ≠ ready) */
15
68
  get connected(): boolean;
69
+ /** The injected core client (owned by the app, not the wrapper) */
70
+ get client(): NoLagSocket;
71
+ /** The local viewer's info (available after ready) */
72
+ get localViewer(): DashboardViewer | null;
73
+ /** All currently joined panels */
16
74
  get panels(): Map<string, DashboardPanel>;
17
- connect(): Promise<void>;
18
- disconnect(): void;
75
+ /**
76
+ * Resolves once the wrapper's first setup completed (identity, lobby and
77
+ * configured panels ready — equivalently, once 'connected' has fired).
78
+ * Rejects only if detach() is called before that. Client auth failures
79
+ * surface via the app's own `await client.connect()`, not here.
80
+ */
81
+ ready(): Promise<void>;
82
+ /**
83
+ * Detach from the client: remove every handler this wrapper added,
84
+ * unsubscribe its topics and lobby (when connected), clear state.
85
+ * Terminal and idempotent; never touches the socket. To use dash again,
86
+ * construct a new instance.
87
+ */
88
+ detach(): void;
89
+ private _onConnect;
90
+ /**
91
+ * One setup pass per connection epoch. Serves both initial setup (epoch 1)
92
+ * and reconnect restore (epoch > 1). Aborts silently whenever a newer
93
+ * epoch started or the wrapper detached — checked after every await.
94
+ */
95
+ private _runSetup;
96
+ private _scheduleLobbyRefresh;
97
+ /**
98
+ * Join a dashboard panel. If the panel was pre-subscribed via the `panels`
99
+ * option, activates it. Otherwise creates, subscribes, and activates it.
100
+ */
19
101
  joinPanel(name: string, opts?: {
20
102
  metricFilters?: string[];
21
103
  }): DashboardPanel;
104
+ /**
105
+ * Leave a dashboard panel. Fully unsubscribes and removes it.
106
+ */
22
107
  leavePanel(name: string): void;
23
- private _subscribePanel;
108
+ /**
109
+ * Get all joined panels.
110
+ */
111
+ getPanels(): DashboardPanel[];
112
+ /**
113
+ * Get all viewers currently online across all panels.
114
+ */
115
+ getOnlineViewers(): DashboardViewer[];
116
+ private _assertUsable;
117
+ private _subscribePanelInternal;
118
+ /**
119
+ * On a shared client, presence events from other apps' wrappers arrive on
120
+ * the same connection-level events. Wrappers stamp their presence with a
121
+ * `__scope` (their appName); a mismatched tag means another app's data.
122
+ * Untagged presence is accepted (older peers in this same app).
123
+ */
124
+ private _foreignScope;
24
125
  private _handlePresenceJoin;
25
126
  private _handlePresenceLeave;
26
127
  private _handlePresenceUpdate;
27
- private _setupLobby;
28
- private _hydrateViewers;
128
+ private _handleLobbyJoin;
129
+ private _handleLobbyLeave;
130
+ private _handleLobbyUpdate;
131
+ /**
132
+ * Reconcile the online-viewer map against a fresh lobby snapshot, emitting
133
+ * only the deltas (viewerOffline for vanished, viewerOnline for new). One
134
+ * path for initial hydration, reconnect restore, and the deferred refetch.
135
+ */
136
+ private _diffHydrateOnlineViewers;
29
137
  private _toViewer;
30
- private _restorePanels;
138
+ private _findViewerIdByActorId;
31
139
  }
package/dist/browser.js CHANGED
@@ -1,2 +1,2 @@
1
- import{NoLag as e}from"@nolag/js-sdk";class t{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 i of s)try{i(...t)}catch(t){console.error(`Error in ${String(e)} handler:`,t)}}listenerCount(e){return this._handlers.get(e)?.size??0}}class s{constructor(e){this._streams=new Map,this._ids=new Set,this._maxPerStream=e}add(e){if(this._ids.has(e.id))return!1;this._ids.add(e.id),this._streams.has(e.streamId)||this._streams.set(e.streamId,[]);const t=this._streams.get(e.streamId);for(t.push(e),t.length>1&&e.timestamp<t[t.length-2].timestamp&&t.sort((e,t)=>e.timestamp-t.timestamp);t.length>this._maxPerStream;){const e=t.shift();this._ids.delete(e.id)}return!0}getAll(e){if(e)return[...this._streams.get(e)??[]];const t=[];for(const e of this._streams.values())t.push(...e);return t.sort((e,t)=>e.timestamp-t.timestamp)}getAggregation(e,t){const s=this._streams.get(e)??[],i=Date.now(),r=t??6e4,n=s.filter(e=>e.timestamp>=i-r);if(0===n.length)return{streamId:e,min:0,max:0,avg:0,sum:0,count:0,last:0,windowMs:r};let o=1/0,a=-1/0,c=0;for(const e of n)e.value<o&&(o=e.value),e.value>a&&(a=e.value),c+=e.value;return{streamId:e,min:o,max:a,avg:c/n.length,sum:c,count:n.length,last:n[n.length-1].value,windowMs:r}}has(e){return this._ids.has(e)}get size(){return this._ids.size}clear(){this._streams.clear(),this._ids.clear()}}class i{constructor(){this._widgets=new Map}update(e){this._widgets.set(e.widgetId,e)}get(e){return this._widgets.get(e)}getAll(){return Array.from(this._widgets.values())}clear(){this._widgets.clear()}}class r{constructor(e){this._users=new Map,this._actorToViewerId=new Map,this._localActorId=e}addFromPresence(e,t,s){if(e===this._localActorId)return null;const i=t.viewerId||this._actorToViewerId.get(e)||e,r={viewerId:i,actorTokenId:e,username:t.username,metadata:t.metadata,joinedAt:s||Date.now(),isLocal:!1};return this._users.set(i,r),this._actorToViewerId.set(e,i),r}removeByActorId(e){if(e===this._localActorId)return null;const t=this._actorToViewerId.get(e);if(!t)return null;const s=this._users.get(t)||null;return this._users.delete(t),this._actorToViewerId.delete(e),s}getAll(){return Array.from(this._users.values())}get users(){return this._users}clear(){this._users.clear(),this._actorToViewerId.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 o(e,t){return t?(...t)=>{console.log(`[${e}]`,...t)}:(...e)=>{}}const a="metrics",c="widgets";class h extends t{constructor(e,t,n,o,a,c){super(),this.name=e,this._roomContext=t,this._localViewerId=n,this._options=a,this._log=c,this._presenceManager=new r(o),this._metricStore=new s(a.maxMetricPoints),this._widgetManager=new i}publishMetric(e,t,s){const i={id:n(),streamId:e,value:t,unit:s?.unit,tags:s?.tags,timestamp:Date.now(),isReplay:!1};this._metricStore.add(i);const r={echo:!1};return s?.filter&&(r.filter=s.filter),this._roomContext.emit(a,{id:i.id,streamId:e,value:t,unit:i.unit,tags:i.tags,timestamp:i.timestamp},r),i}setMetricFilters(e){this._roomContext.setFilters(a,e)}addMetricFilters(e){this._roomContext.addFilters(a,e)}removeMetricFilters(e){this._roomContext.removeFilters(a,e)}publishWidget(e,t,s,i){const r={id:n(),widgetId:e,type:t,data:s,label:i,timestamp:Date.now(),isReplay:!1};return this._widgetManager.update(r),this._roomContext.emit(c,{id:r.id,widgetId:e,type:t,data:s,label:i,timestamp:r.timestamp},{echo:!1}),r}getMetrics(e){return this._metricStore.getAll(e)}getAggregation(e,t){return this._metricStore.getAggregation(e,t)}getWidget(e){return this._widgetManager.get(e)}getWidgets(){return this._widgetManager.getAll()}getViewers(){return this._presenceManager.getAll()}_subscribe(e){if(void 0!==e){const t=e.length>0?e:["__none__"];this._roomContext.subscribe(a,{filters:t})}else this._roomContext.subscribe(a);this._roomContext.subscribe(c),this._roomContext.on(a,(e,t)=>{const s=e,i={id:s.id,streamId:s.streamId,value:s.value,unit:s.unit,tags:s.tags,timestamp:s.timestamp,isReplay:t.isReplay??!1};this._metricStore.add(i)&&this.emit("metric",i)}),this._roomContext.on(c,(e,t)=>{const s=e,i={id:s.id,widgetId:s.widgetId,type:s.type,data:s.data,label:s.label,timestamp:s.timestamp,isReplay:t.isReplay??!1};this._widgetManager.update(i),this.emit("widgetUpdate",i)})}_activate(){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("viewerJoined",e)}}).catch(()=>{})}_deactivate(){this._presenceManager.clear()}_handlePresenceJoin(e,t){const s=this._presenceManager.addFromPresence(e,t);s&&this.emit("viewerJoined",s)}_handlePresenceLeave(e){const t=this._presenceManager.removeByActorId(e);t&&this.emit("viewerLeft",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._roomContext.unsubscribe(a),this._roomContext.unsubscribe(c),this._roomContext.off(a),this._roomContext.off(c),this._metricStore.clear(),this._widgetManager.clear(),this._presenceManager.clear(),this.removeAllListeners()}_setPresence(){this._roomContext.setPresence({viewerId:this._localViewerId,username:this._options.username,metadata:this._options.metadata})}}class l extends t{constructor(e,t={}){super(),this._client=null,this._panels=new Map,this._lobby=null,this._onlineViewers=new Map,this._actorToViewerId=new Map,this._token=e,this._viewerId=n(),this._options={username:t.username,metadata:t.metadata,appName:t.appName??"dash",url:t.url,maxMetricPoints:t.maxMetricPoints??1e3,aggregationWindow:t.aggregationWindow??6e4,debug:t.debug??!1,reconnect:t.reconnect??!0,panels:t.panels??[]},this._log=o("NoLagDash",this._options.debug)}get connected(){return this._client?.connected??!1}get panels(){return this._panels}async connect(){const t={debug:this._options.debug,reconnect:this._options.reconnect};this._options.url&&(t.url=this._options.url),this._client=e(this._token,t),this._client.on("connect",()=>{this._panels.size>0&&(this._restorePanels(),this.emit("reconnected"))}),this._client.on("disconnect",e=>this.emit("disconnected",e)),this._client.on("error",e=>this.emit("error",e)),this._client.on("replay:start",e=>{for(const t of this._panels.values())t._handleReplayStart(e.count)}),this._client.on("replay:end",e=>{for(const t of this._panels.values())t._handleReplayEnd(e.replayed)}),await this._client.connect(),this._client.on("presence:join",e=>this._handlePresenceJoin(e)),this._client.on("presence:leave",e=>this._handlePresenceLeave(e)),this._client.on("presence:update",e=>this._handlePresenceUpdate(e)),await this._setupLobby();for(const e of this._options.panels)this._subscribePanel(e);this.emit("connected"),setTimeout(()=>{this._lobby&&this._client?.connected&&this._lobby.fetchPresence().then(e=>this._hydrateViewers(e)).catch(()=>{})},2e3)}disconnect(){for(const e of[...this._panels.keys()])this.leavePanel(e);this._lobby?.unsubscribe(),this._lobby=null,this._client?.disconnect(),this._client=null,this._onlineViewers.clear(),this._actorToViewerId.clear()}joinPanel(e,t){if(!this._client)throw new Error("Not connected — call connect() first");let s=this._panels.get(e);return s||(s=this._subscribePanel(e,t?.metricFilters)),s._activate(),s}leavePanel(e){const t=this._panels.get(e);t&&(t._cleanup(),this._panels.delete(e))}_subscribePanel(e,t){if(!this._client)throw new Error("Not connected");const s=this._client.setApp(this._options.appName).setRoom(e),i=new h(e,s,this._viewerId,this._client.actorId,this._options,o(`DashPanel:${e}`,this._options.debug));return this._panels.set(e,i),i._subscribe(t),i}_handlePresenceJoin(e){if(e.actorTokenId===this._client?.actorId)return;const t=e.presence;if(!t?.viewerId)return;const s=this._toViewer(e.actorTokenId,t);this._actorToViewerId.set(e.actorTokenId,s.viewerId),this._onlineViewers.has(s.viewerId)||(this._onlineViewers.set(s.viewerId,s),this.emit("viewerOnline",s));for(const s of this._panels.values())s._handlePresenceJoin(e.actorTokenId,t)}_handlePresenceLeave(e){if(e.actorTokenId!==this._client?.actorId)for(const t of this._panels.values())t._handlePresenceLeave(e.actorTokenId)}_handlePresenceUpdate(e){if(e.actorTokenId===this._client?.actorId)return;const t=e.presence;if(t?.viewerId)for(const s of this._panels.values())s._handlePresenceUpdate(e.actorTokenId,t)}async _setupLobby(){if(!this._client)return;this._lobby=this._client.setApp(this._options.appName).setLobby("online");const e=e=>t=>{const s=t;if("join"===e){const e=s.data;if(s.actorId!==this._client?.actorId&&e?.viewerId){const t=this._toViewer(s.actorId,e);this._actorToViewerId.set(s.actorId,t.viewerId),this._onlineViewers.has(t.viewerId)||(this._onlineViewers.set(t.viewerId,t),this.emit("viewerOnline",t))}}else if(s.actorId!==this._client?.actorId){const e=this._actorToViewerId.get(s.actorId);if(e){const t=this._onlineViewers.get(e);t&&(this._onlineViewers.delete(e),this._actorToViewerId.delete(s.actorId),this.emit("viewerOffline",t))}}};this._client.on("lobbyPresence:join",e("join")),this._client.on("lobbyPresence:leave",e("leave")),this._client.on("lobbyPresence:update",e("join"));try{const e=await this._lobby.subscribe();this._hydrateViewers(e)}catch{}}_hydrateViewers(e){for(const t of Object.keys(e))for(const s of Object.keys(e[t])){if(s===this._client?.actorId)continue;const i=e[t][s],r=i?.presence??i;if(r?.viewerId){const e=this._toViewer(s,r);this._actorToViewerId.set(s,e.viewerId),this._onlineViewers.has(e.viewerId)||(this._onlineViewers.set(e.viewerId,e),this.emit("viewerOnline",e))}}}_toViewer(e,t){return{viewerId:t.viewerId,actorTokenId:e,username:t.username,metadata:t.metadata,joinedAt:Date.now(),isLocal:!1}}_restorePanels(){for(const e of this._panels.values())e._updateLocalPresence();this._lobby?.fetchPresence().then(e=>{this._onlineViewers.clear(),this._actorToViewerId.clear(),this._hydrateViewers(e)}).catch(()=>{})}}export{h as DashboardPanel,t as EventEmitter,l as NoLagDash};
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 i of s)try{i(...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._streams=new Map,this._ids=new Set,this._maxPerStream=e}add(e){if(this._ids.has(e.id))return!1;this._ids.add(e.id),this._streams.has(e.streamId)||this._streams.set(e.streamId,[]);const t=this._streams.get(e.streamId);for(t.push(e),t.length>1&&e.timestamp<t[t.length-2].timestamp&&t.sort((e,t)=>e.timestamp-t.timestamp);t.length>this._maxPerStream;){const e=t.shift();this._ids.delete(e.id)}return!0}getAll(e){if(e)return[...this._streams.get(e)??[]];const t=[];for(const e of this._streams.values())t.push(...e);return t.sort((e,t)=>e.timestamp-t.timestamp)}getAggregation(e,t){const s=this._streams.get(e)??[],i=Date.now(),n=t??6e4,r=s.filter(e=>e.timestamp>=i-n);if(0===r.length)return{streamId:e,min:0,max:0,avg:0,sum:0,count:0,last:0,windowMs:n};let o=1/0,a=-1/0,h=0;for(const e of r)e.value<o&&(o=e.value),e.value>a&&(a=e.value),h+=e.value;return{streamId:e,min:o,max:a,avg:h/r.length,sum:h,count:r.length,last:r[r.length-1].value,windowMs:n}}has(e){return this._ids.has(e)}get size(){return this._ids.size}clear(){this._streams.clear(),this._ids.clear()}}class s{constructor(){this._widgets=new Map}update(e){this._widgets.set(e.widgetId,e)}get(e){return this._widgets.get(e)}getAll(){return Array.from(this._widgets.values())}clear(){this._widgets.clear()}}class i{constructor(e){this._users=new Map,this._actorToViewerId=new Map,this._localActorId=e}addFromPresence(e,t,s){if(e===this._localActorId)return null;const i=t.viewerId||this._actorToViewerId.get(e)||e,n={viewerId:i,actorTokenId:e,username:t.username,metadata:t.metadata,joinedAt:s||Date.now(),isLocal:!1};return this._users.set(i,n),this._actorToViewerId.set(e,i),n}removeByActorId(e){if(e===this._localActorId)return null;const t=this._actorToViewerId.get(e);if(!t)return null;const s=this._users.get(t)||null;return this._users.delete(t),this._actorToViewerId.delete(e),s}getAll(){return Array.from(this._users.values())}get users(){return this._users}clear(){this._users.clear(),this._actorToViewerId.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 r(e,t){return t?(...t)=>{console.log(`[${e}]`,...t)}:(...e)=>{}}const o=new WeakMap;const a="metrics",h="widgets";class c extends e{constructor(e,n,r,o,a,h,c){super(),this._onMetricsRef=null,this._onWidgetsRef=null,this.name=e,this._roomContext=n,this._localViewerId=r,this._options=a,this._log=h,this._isConnected=c,this._presenceManager=new i(o),this._metricStore=new t(a.maxMetricPoints),this._widgetManager=new s}publishMetric(e,t,s){const i={id:n(),streamId:e,value:t,unit:s?.unit,tags:s?.tags,timestamp:Date.now(),isReplay:!1};this._metricStore.add(i);const r={echo:!1};return s?.filter&&(r.filter=s.filter),this._roomContext.emit(a,{id:i.id,streamId:e,value:t,unit:i.unit,tags:i.tags,timestamp:i.timestamp},r),i}setMetricFilters(e){this._roomContext.setFilters(a,e)}addMetricFilters(e){this._roomContext.addFilters(a,e)}removeMetricFilters(e){this._roomContext.removeFilters(a,e)}publishWidget(e,t,s,i){const r={id:n(),widgetId:e,type:t,data:s,label:i,timestamp:Date.now(),isReplay:!1};return this._widgetManager.update(r),this._roomContext.emit(h,{id:r.id,widgetId:e,type:t,data:s,label:i,timestamp:r.timestamp},{echo:!1}),r}getMetrics(e){return this._metricStore.getAll(e)}getAggregation(e,t){return this._metricStore.getAggregation(e,t)}getWidget(e){return this._widgetManager.get(e)}getWidgets(){return this._widgetManager.getAll()}getViewers(){return this._presenceManager.getAll()}_subscribe(e){if(void 0!==e){const t=e.length>0?e:["__none__"];this._roomContext.subscribe(a,{filters:t})}else this._roomContext.subscribe(a);this._roomContext.subscribe(h),this._onMetricsRef=(e,t)=>{const s=e,i={id:s.id,streamId:s.streamId,value:s.value,unit:s.unit,tags:s.tags,timestamp:s.timestamp,isReplay:t.isReplay??!1};this._metricStore.add(i)&&this.emit("metric",i)},this._roomContext.on(a,this._onMetricsRef),this._onWidgetsRef=(e,t)=>{const s=e,i={id:s.id,widgetId:s.widgetId,type:s.type,data:s.data,label:s.label,timestamp:s.timestamp,isReplay:t.isReplay??!1};this._widgetManager.update(i),this.emit("widgetUpdate",i)},this._roomContext.on(h,this._onWidgetsRef)}_activate(){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("viewerJoined",e)}}).catch(()=>{})}_deactivate(){this._presenceManager.clear()}_handlePresenceJoin(e,t){const s=this._presenceManager.addFromPresence(e,t);s&&this.emit("viewerJoined",s)}_handlePresenceLeave(e){const t=this._presenceManager.removeByActorId(e);t&&this.emit("viewerLeft",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("Panel cleanup:",this.name),this._isConnected()&&(this._roomContext.unsubscribe(a),this._roomContext.unsubscribe(h)),this._onMetricsRef&&this._roomContext.off(a,this._onMetricsRef),this._onWidgetsRef&&this._roomContext.off(h,this._onWidgetsRef),this._onMetricsRef=null,this._onWidgetsRef=null,this._metricStore.clear(),this._widgetManager.clear(),this._presenceManager.clear(),this.removeAllListeners()}_setPresence(){this._roomContext.setPresence({viewerId:this._localViewerId,username:this._options.username,metadata:this._options.metadata,__scope:this._options.appName})}}class l extends e{constructor(e){if(super(),this._localViewer=null,this._panels=new Map,this._lobby=null,this._onlineViewers=new Map,this._actorToViewerId=new Map,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._panels.values())e._handleReplayStart(t.count)},this._onReplayEndRef=e=>{const t=e;for(const e of this._panels.values())e._handleReplayEnd(t.replayed)},this._onPresenceJoinRef=e=>this._handlePresenceJoin(e),this._onPresenceLeaveRef=e=>this._handlePresenceLeave(e),this._onPresenceUpdateRef=e=>this._handlePresenceUpdate(e),this._onLobbyJoinRef=e=>this._handleLobbyJoin(e),this._onLobbyLeaveRef=e=>this._handleLobbyLeave(e),this._onLobbyUpdateRef=e=>this._handleLobbyUpdate(e),!e?.client)throw new TypeError("NoLagDash requires an injected NoLag client: new NoLagDash({ client, appName, ... })");this._client=e.client,this._viewerId=n(),this._options={username:e.username,metadata:e.metadata,appName:e.appName??"dash",maxMetricPoints:e.maxMetricPoints??1e3,aggregationWindow:e.aggregationWindow??6e4,debug:e.debug??!1,panels:e.panels??[]},this._log=r("NoLagDash",this._options.debug),this._readyPromise=new Promise((e,t)=>{this._readyResolve=e,this._readyReject=t}),this._readyPromise.catch(()=>{}),function(e,t,s){let i=o.get(e);i||(i=new Map,o.set(e,i));const n=i.get(t);n&&console.warn(`[${s}] Another wrapper (${n}) is already attached to this client for app "${t}". Use one wrapper per (client, app) — detach the other instance first.`),i.set(t,s)}(this._client,this._options.appName,"NoLagDash"),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 localViewer(){return this._localViewer}get panels(){return this._panels}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._panels.keys()])this._panels.get(e)._cleanup(),this._panels.delete(e);if(this._lobby&&this._client.connected)try{this._lobby.unsubscribe()}catch{}var e,t;this._lobby=null,this._onlineViewers.clear(),this._actorToViewerId.clear(),this._localViewer=null,e=this._client,t=this._options.appName,o.get(e)?.delete(t),this._isReady||this._readyReject(new Error("NoLagDash 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._localViewer?this._localViewer.actorTokenId=this._client.actorId:(this._localViewer={viewerId:this._viewerId,actorTokenId:this._client.actorId,username:this._options.username,metadata:this._options.metadata,joinedAt:Date.now(),isLocal:!0},this._log("Local viewer:",this._localViewer.viewerId,"→",this._localViewer.actorTokenId)),this._lobby||(this._lobby=this._client.setApp(this._options.appName).setLobby("online"));try{const e=await this._lobby.subscribe();if(t())return;this._diffHydrateOnlineViewers(e),this._log("Lobby subscribed, online viewers:",this._onlineViewers.size)}catch(e){if(t())return;this._log("Lobby subscription failed:",e)}if(this._isReady)for(const e of this._panels.values())e._updateLocalPresence();else for(const e of this._options.panels)this._subscribePanelInternal(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._diffHydrateOnlineViewers(t)}).catch(()=>{})},2e3)}joinPanel(e,t){this._assertUsable();let s=this._panels.get(e);return s||(s=this._subscribePanelInternal(e,t?.metricFilters)),s._activate(),s}leavePanel(e){const t=this._panels.get(e);t&&(this._log("Leaving panel:",e),t._cleanup(),this._panels.delete(e))}getPanels(){return Array.from(this._panels.values())}getOnlineViewers(){return Array.from(this._onlineViewers.values())}_assertUsable(){if(this._detached)throw new Error("NoLagDash has been detached — construct a new instance");if(!this._isReady||!this._localViewer)throw new Error('NoLagDash not ready — await ready() or the "connected" event')}_subscribePanelInternal(e,t){this._log("Subscribing panel:",e);const s=this._client.setApp(this._options.appName).setRoom(e),i=new c(e,s,this._viewerId,this._client.actorId,this._options,r(`DashPanel:${e}`,this._options.debug),()=>this._client.connected);return this._panels.set(e,i),i._subscribe(t),i}_foreignScope(e){const t=e?.__scope;return"string"==typeof t&&t!==this._options.appName}_handlePresenceJoin(e){if(e.actorTokenId===this._localViewer?.actorTokenId)return;const t=e.presence;if(!t?.viewerId||this._foreignScope(t))return;const s=this._toViewer(e.actorTokenId,t);this._actorToViewerId.set(e.actorTokenId,s.viewerId),this._onlineViewers.has(s.viewerId)||(this._onlineViewers.set(s.viewerId,s),this.emit("viewerOnline",s));for(const s of this._panels.values())s._handlePresenceJoin(e.actorTokenId,t)}_handlePresenceLeave(e){if(e.actorTokenId!==this._localViewer?.actorTokenId)for(const t of this._panels.values())t._handlePresenceLeave(e.actorTokenId)}_handlePresenceUpdate(e){if(e.actorTokenId===this._localViewer?.actorTokenId)return;const t=e.presence;if(t?.viewerId&&!this._foreignScope(t))for(const s of this._panels.values())s._handlePresenceUpdate(e.actorTokenId,t)}_handleLobbyJoin(e){const{actorId:t,data:s}=e;if(t===this._localViewer?.actorTokenId)return;const i=s;if(!i?.viewerId||this._foreignScope(i))return;const n=this._toViewer(t,i);this._actorToViewerId.set(t,n.viewerId),this._onlineViewers.has(n.viewerId)||(this._onlineViewers.set(n.viewerId,n),this.emit("viewerOnline",n))}_handleLobbyLeave(e){const{actorId:t,data:s}=e;if(t===this._localViewer?.actorTokenId)return;const i=s;if(this._foreignScope(i))return;const n=i?.viewerId||this._actorToViewerId.get(t)||this._findViewerIdByActorId(t);if(n){const e=this._onlineViewers.get(n);e&&(this._onlineViewers.delete(n),this._actorToViewerId.delete(t),this.emit("viewerOffline",e))}}_handleLobbyUpdate(e){const{actorId:t,data:s}=e;if(t===this._localViewer?.actorTokenId)return;const i=s;if(!i?.viewerId||this._foreignScope(i))return;const n=this._toViewer(t,i);this._onlineViewers.set(n.viewerId,n)}_diffHydrateOnlineViewers(e){const t=new Map,s=new Map;for(const i of Object.keys(e)){const n=e[i];for(const e of Object.keys(n)){if(e===this._localViewer?.actorTokenId)continue;const i=n[e],r=i?.presence??i;r?.viewerId&&!this._foreignScope(r)&&(t.has(r.viewerId)||t.set(r.viewerId,this._toViewer(e,r)),s.set(e,r.viewerId))}}for(const[e,s]of[...this._onlineViewers])if(!t.has(e)){this._onlineViewers.delete(e);for(const[t,s]of[...this._actorToViewerId])s===e&&this._actorToViewerId.delete(t);this.emit("viewerOffline",s)}for(const[e,s]of t)this._onlineViewers.has(e)||(this._onlineViewers.set(e,s),this.emit("viewerOnline",s));for(const[e,t]of s)this._actorToViewerId.set(e,t)}_toViewer(e,t){return{viewerId:t.viewerId,actorTokenId:e,username:t.username,metadata:t.metadata,joinedAt:Date.now(),isLocal:!1}}_findViewerIdByActorId(e){for(const t of this._onlineViewers.values())if(t.actorTokenId===e)return t.viewerId}}export{c as DashboardPanel,e as EventEmitter,l as NoLagDash};
2
2
  //# sourceMappingURL=browser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sources":["../src/EventEmitter.ts","../src/MetricStore.ts","../src/WidgetManager.ts","../src/PresenceManager.ts","../src/utils.ts","../src/constants.ts","../src/DashboardPanel.ts","../src/NoLagDash.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","MetricStore","maxPerStream","_streams","_ids","_maxPerStream","point","id","streamId","points","push","length","timestamp","sort","a","b","removed","shift","getAll","all","values","getAggregation","windowMs","now","Date","window","filtered","filter","p","min","max","avg","sum","count","last","Infinity","value","WidgetManager","_widgets","update","widget","widgetId","Array","from","PresenceManager","localActorId","_users","_actorToViewerId","_localActorId","addFromPresence","actorTokenId","presence","joinedAt","viewerId","viewer","username","metadata","isLocal","removeByActorId","users","generateId","crypto","randomUUID","replace","Math","floor","random","toString","createLogger","prefix","enabled","log","_args","TOPIC_METRICS","TOPIC_WIDGETS","DashboardPanel","name","roomContext","localViewerId","options","super","_roomContext","_localViewerId","_options","_log","_presenceManager","_metricStore","maxMetricPoints","_widgetManager","publishMetric","opts","unit","tags","isReplay","emitOpts","echo","setMetricFilters","filters","setFilters","addMetricFilters","addFilters","removeMetricFilters","removeFilters","publishWidget","type","data","label","getMetrics","getWidget","getWidgets","getViewers","_subscribe","metricFilters","undefined","subscribe","meta","raw","_activate","_setPresence","fetchPresence","then","actors","actor","v","catch","_deactivate","_handlePresenceJoin","pd","_handlePresenceLeave","_handlePresenceUpdate","_handleReplayStart","_handleReplayEnd","replayed","_updateLocalPresence","_cleanup","unsubscribe","setPresence","NoLagDash","token","_client","_panels","_lobby","_onlineViewers","_token","_viewerId","appName","url","aggregationWindow","debug","reconnect","panels","connected","connect","clientOptions","NoLag","_restorePanels","reason","_setupLobby","_subscribePanel","setTimeout","s","_hydrateViewers","disconnect","keys","leavePanel","joinPanel","Error","panel","setApp","setRoom","actorId","_toViewer","setLobby","lh","vid","state","rid","Object","aid"],"mappings":"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"}
1
+ {"version":3,"file":"browser.js","sources":["../src/EventEmitter.ts","../src/MetricStore.ts","../src/WidgetManager.ts","../src/PresenceManager.ts","../src/utils.ts","../src/constants.ts","../src/DashboardPanel.ts","../src/NoLagDash.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","MetricStore","maxPerStream","_streams","_ids","_maxPerStream","point","id","streamId","points","push","length","timestamp","sort","a","b","removed","shift","getAll","all","values","getAggregation","windowMs","now","Date","window","filtered","filter","p","min","max","avg","sum","count","last","Infinity","value","WidgetManager","_widgets","update","widget","widgetId","Array","from","PresenceManager","localActorId","_users","_actorToViewerId","_localActorId","addFromPresence","actorTokenId","presence","joinedAt","viewerId","viewer","username","metadata","isLocal","removeByActorId","users","generateId","crypto","randomUUID","replace","Math","floor","random","toString","createLogger","prefix","enabled","log","_args","wrapperRegistry","WeakMap","TOPIC_METRICS","TOPIC_WIDGETS","DashboardPanel","name","roomContext","localViewerId","options","isConnected","super","_onMetricsRef","_onWidgetsRef","_roomContext","_localViewerId","_options","_log","_isConnected","_presenceManager","_metricStore","maxMetricPoints","_widgetManager","publishMetric","opts","unit","tags","isReplay","emitOpts","echo","setMetricFilters","filters","setFilters","addMetricFilters","addFilters","removeMetricFilters","removeFilters","publishWidget","type","data","label","getMetrics","getWidget","getWidgets","getViewers","_subscribe","metricFilters","undefined","subscribe","meta","raw","_activate","_setPresence","fetchPresence","then","actors","actor","v","catch","_deactivate","_handlePresenceJoin","pd","_handlePresenceLeave","_handlePresenceUpdate","_handleReplayStart","_handleReplayEnd","replayed","_updateLocalPresence","_cleanup","unsubscribe","setPresence","__scope","appName","NoLagDash","_localViewer","_panels","_lobby","_onlineViewers","_epoch","_detached","_isReady","_lobbyRefreshTimer","_onConnectRef","_onConnect","_onDisconnectRef","reason","_onReconnectRef","_onErrorRef","_onReplayStartRef","panel","_onReplayEndRef","_onPresenceJoinRef","_onPresenceLeaveRef","_onPresenceUpdateRef","_onLobbyJoinRef","_handleLobbyJoin","_onLobbyLeaveRef","_handleLobbyLeave","_onLobbyUpdateRef","_handleLobbyUpdate","client","TypeError","_client","_viewerId","aggregationWindow","debug","panels","_readyPromise","Promise","resolve","reject","_readyResolve","_readyReject","wrapperName","apps","existing","warn","registerWrapper","queueMicrotask","connected","localViewer","ready","detach","clearTimeout","keys","Error","_runSetup","epoch","stale","actorId","setApp","setLobby","state","_diffHydrateOnlineViewers","err","panelName","_subscribePanelInternal","_scheduleLobbyRefresh","setTimeout","joinPanel","_assertUsable","leavePanel","getPanels","getOnlineViewers","setRoom","_foreignScope","scope","_toViewer","_findViewerIdByActorId","fresh","freshActors","roomId","Object","roomPresence","mappedViewerId"],"mappings":"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"}
@@ -4,3 +4,5 @@ export declare const DEFAULT_AGGREGATION_WINDOW = 60000;
4
4
  export declare const TOPIC_METRICS = "metrics";
5
5
  export declare const TOPIC_WIDGETS = "widgets";
6
6
  export declare const LOBBY_ID = "online";
7
+ /** Delay before the post-setup lobby presence refetch (catches simultaneous joiners) */
8
+ export declare const LOBBY_REFRESH_DELAY_MS = 2000;