@nolag/iot 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,16 +24,23 @@ npm install @nolag/js-sdk @nolag/iot
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 (iot, chat, dash, ...) can share the same connection as long as
29
+ each uses its own app.
30
+
27
31
  ```typescript
32
+ import { NoLag } from "@nolag/js-sdk";
28
33
  import { NoLagIoT } from "@nolag/iot";
29
34
 
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
+
30
39
  // --- Device: sends telemetry, receives commands ---
31
- const device = new NoLagIoT("DEVICE_TOKEN", {
32
- deviceName: "Sensor #7",
33
- role: "device",
34
- });
40
+ const device = new NoLagIoT({ client, deviceName: "Sensor #7", role: "device" });
35
41
 
36
- await device.connect();
42
+ await client.connect(); // the app owns the connection
43
+ await device.ready(); // wrapper setup done (identity, presence, groups)
37
44
 
38
45
  const group = device.joinGroup("warehouse-a");
39
46
 
@@ -49,31 +56,47 @@ group.on("command", (cmd) => {
49
56
  group.ackCommand(cmd.id, "completed", { success: true });
50
57
  });
51
58
 
52
- // --- Controller: monitors telemetry, sends commands ---
53
- const controller = new NoLagIoT("CONTROLLER_TOKEN", {
54
- deviceName: "Dashboard",
55
- role: "controller",
56
- });
59
+ // Teardown: the wrapper releases its handlers and topics (and cancels any
60
+ // pending command timeouts); the app closes the socket.
61
+ device.detach();
62
+ client.disconnect();
63
+ ```
57
64
 
58
- await controller.connect();
65
+ A controller shares the same pattern — construct with `{ client, role: "controller" }`,
66
+ `await controller.ready()`, then monitor telemetry and dispatch commands:
59
67
 
68
+ ```typescript
60
69
  const controlGroup = controller.joinGroup("warehouse-a");
61
70
 
62
- // Monitor telemetry
63
71
  controlGroup.on("telemetry", (reading) => {
64
72
  console.log(`${reading.deviceId}/${reading.sensorId}: ${reading.value}${reading.unit}`);
65
73
  });
66
74
 
67
- // Send a command to a device
68
- const cmd = await controlGroup.sendCommand("sensor-7", "calibrate", {
69
- offset: 0.5,
70
- });
71
-
72
- controlGroup.on("commandAck", (ack) => {
73
- console.log(`Command ${ack.id}: ${ack.status}`);
74
- });
75
+ // Resolves when the target device acks; rejects on failure or timeout
76
+ const cmd = await controlGroup.sendCommand("sensor-7", "calibrate", { offset: 0.5 });
77
+ console.log(`Command ${cmd.id}: ${cmd.status}`);
75
78
  ```
76
79
 
80
+ ## Lifecycle
81
+
82
+ - **Construction = attach.** The wrapper wires its handlers onto the injected
83
+ client immediately. If the client is already connected, setup runs on the
84
+ next microtask; otherwise it runs when the client's `connect` event fires.
85
+ - **`ready()`** resolves once the first setup completed (identity, online
86
+ lobby, configured groups). Auth failures surface via your own
87
+ `await client.connect()`, not via `ready()`.
88
+ - **Reconnects are automatic.** The wrapper re-applies device presence to every
89
+ joined group (persistent presence) and reconciles the online-device list,
90
+ emitting only real deltas.
91
+ - **`detach()`** removes exactly this wrapper's handlers and topics, cancels any
92
+ pending command-timeout timers, and never touches the socket. It is terminal:
93
+ construct a new instance to re-attach. Detach while the client is still
94
+ connected so server-side unsubscribes go through. In frameworks, call it from
95
+ your dispose hook (`onUnmounted`, HMR dispose).
96
+ - **One wrapper per (client, app).** Sharing a client across wrappers of
97
+ DIFFERENT apps is the intended pattern; two wrappers on the same app would
98
+ collide on topics and presence (the SDK warns if you do this).
99
+
77
100
  ## API Reference
78
101
 
79
102
  ### `NoLagIoT`
@@ -81,41 +104,51 @@ controlGroup.on("commandAck", (ack) => {
81
104
  #### Constructor
82
105
 
83
106
  ```typescript
84
- const iot = new NoLagIoT(token: string, options?: NoLagIoTOptions);
107
+ const iot = new NoLagIoT(options: NoLagIoTOptions);
85
108
  ```
86
109
 
87
110
  **Options:**
88
111
 
89
112
  | Option | Type | Default | Description |
90
113
  |--------|------|---------|-------------|
114
+ | `client` | `NoLagSocket` | *required* | The injected core NoLag client |
91
115
  | `deviceId` | `string` | auto-generated | Unique device ID |
92
116
  | `deviceName` | `string` | — | Display name |
93
117
  | `role` | `DeviceRole` | `'device'` | `'device'` or `'controller'` |
94
118
  | `metadata` | `Record<string, unknown>` | — | Custom device data |
119
+ | `appName` | `string` | `'iot'` | NoLag app for topic prefixes |
95
120
  | `groups` | `string[]` | — | Auto-join these groups on connect |
96
121
  | `maxTelemetryPoints` | `number` | `1000` | Max telemetry points in memory |
97
122
  | `commandTimeout` | `number` | `30000` | Command ack timeout (ms) |
98
123
  | `debug` | `boolean` | `false` | Enable debug logging |
99
- | `reconnect` | `boolean` | `true` | Auto-reconnect on disconnect |
100
124
 
101
125
  #### Methods
102
126
 
103
127
  | Method | Returns | Description |
104
128
  |--------|---------|-------------|
105
- | `connect()` | `Promise<void>` | Connect to NoLag |
106
- | `disconnect()` | `void` | Disconnect |
129
+ | `ready()` | `Promise<void>` | Resolves when wrapper setup completed |
130
+ | `detach()` | `void` | Release handlers, topics, and command timers (terminal; never closes the socket) |
107
131
  | `joinGroup(name)` | `DeviceGroup` | Join a device group |
108
132
  | `leaveGroup(name)` | `void` | Leave a group |
109
133
  | `getGroups()` | `DeviceGroup[]` | Get all joined groups |
110
134
  | `getOnlineDevices()` | `Device[]` | Get online devices |
111
135
 
136
+ #### Properties
137
+
138
+ | Property | Type | Description |
139
+ |----------|------|-------------|
140
+ | `connected` | `boolean` | Whether currently connected |
141
+ | `localDevice` | `Device \| null` | The local device |
142
+ | `groups` | `Map<string, DeviceGroup>` | All joined groups |
143
+
112
144
  #### Events
113
145
 
114
146
  | Event | Payload | Description |
115
147
  |-------|---------|-------------|
116
- | `connected` | — | Connected |
117
- | `disconnected` | | Disconnected |
118
- | `reconnected` | — | Reconnected |
148
+ | `connected` | — | First setup completed |
149
+ | `disconnected` | `reason` | Disconnected |
150
+ | `reconnecting` | — | The client is re-establishing the connection |
151
+ | `reconnected` | — | Setup restored after a reconnect |
119
152
  | `error` | `Error` | Error |
120
153
  | `deviceOnline` | `Device` | Device came online |
121
154
  | `deviceOffline` | `Device` | Device went offline |
@@ -17,8 +17,12 @@ export declare class DeviceGroup extends EventEmitter<DeviceGroupEvents> {
17
17
  private _commandManager;
18
18
  private _receivedCommands;
19
19
  private _log;
20
+ private _isConnected;
21
+ private _onTelemetryRef;
22
+ private _onCommandsRef;
23
+ private _onCmdAckRef;
20
24
  /** @internal */
21
- constructor(name: string, roomContext: RoomContext, localDevice: Device, options: ResolvedIoTOptions, log: (...args: unknown[]) => void);
25
+ constructor(name: string, roomContext: RoomContext, localDevice: Device, options: ResolvedIoTOptions, log: (...args: unknown[]) => void, isConnected: () => boolean);
22
26
  /** All remote devices currently in this group */
23
27
  get devices(): Map<string, Device>;
24
28
  /**
@@ -1,3 +1,4 @@
1
+ import type { NoLagSocket } from '@nolag/js-sdk';
1
2
  import { EventEmitter } from './EventEmitter';
2
3
  import { DeviceGroup } from './DeviceGroup';
3
4
  import type { NoLagIoTOptions, IoTClientEvents, Device } from './types';
@@ -7,31 +8,36 @@ import type { NoLagIoTOptions, IoTClientEvents, Device } from './types';
7
8
  * Provides device presence, real-time telemetry streaming, and command dispatch
8
9
  * with ack tracking — all framework-agnostic via events.
9
10
  *
11
+ * The wrapper NEVER manages the connection. The app owns one core NoLag
12
+ * client (shared by any number of wrappers on distinct apps) and the
13
+ * wrapper attaches to it at construction and releases it via `detach()`.
14
+ *
10
15
  * @example
11
16
  * ```typescript
17
+ * import { NoLag } from '@nolag/js-sdk';
12
18
  * import { NoLagIoT } from '@nolag/iot';
13
19
  *
14
- * const iot = new NoLagIoT(token, { deviceId: 'sensor-01', role: 'device', debug: true });
20
+ * const client = NoLag(async () => (await (await fetch('/api/nolag-token')).json()).token);
21
+ * const iot = new NoLagIoT({ client, deviceId: 'sensor-01', role: 'device' });
15
22
  *
16
23
  * iot.on('connected', () => console.log('Connected!'));
17
- * await iot.connect();
24
+ *
25
+ * await client.connect(); // the app owns the connection
26
+ * await iot.ready(); // wrapper setup done (identity, lobby, groups)
18
27
  *
19
28
  * const group = iot.joinGroup('factory-floor');
20
29
  * group.on('command', (cmd) => {
21
- * console.log('Received command:', cmd.command);
22
30
  * group.ackCommand(cmd.id, 'completed', { ok: true });
23
31
  * });
32
+ * group.sendTelemetry('temperature', 22.5, { unit: '°C' });
24
33
  *
25
- * // Send telemetry every second
26
- * setInterval(() => {
27
- * group.sendTelemetry('temperature', 22.5, { unit: '°C' });
28
- * }, 1000);
34
+ * iot.detach(); // wrapper releases its handlers and topics
35
+ * client.disconnect(); // the app closes the socket
29
36
  * ```
30
37
  */
31
38
  export declare class NoLagIoT extends EventEmitter<IoTClientEvents> {
32
- private _token;
33
- private _options;
34
39
  private _client;
40
+ private _options;
35
41
  private _localDevice;
36
42
  private _groups;
37
43
  private _lobby;
@@ -39,21 +45,55 @@ export declare class NoLagIoT extends EventEmitter<IoTClientEvents> {
39
45
  private _actorToDeviceId;
40
46
  private _deviceId;
41
47
  private _log;
42
- constructor(token: string, options?: NoLagIoTOptions);
43
- /** Whether the underlying connection is established */
48
+ private _epoch;
49
+ private _detached;
50
+ private _isReady;
51
+ private _readyResolve;
52
+ private _readyReject;
53
+ private _readyPromise;
54
+ private _lobbyRefreshTimer;
55
+ private _onConnectRef;
56
+ private _onDisconnectRef;
57
+ private _onReconnectRef;
58
+ private _onErrorRef;
59
+ private _onPresenceJoinRef;
60
+ private _onPresenceLeaveRef;
61
+ private _onPresenceUpdateRef;
62
+ private _onLobbyJoinRef;
63
+ private _onLobbyLeaveRef;
64
+ private _onLobbyUpdateRef;
65
+ constructor(options: NoLagIoTOptions);
66
+ /** Whether the underlying connection is established (connected ≠ ready) */
44
67
  get connected(): boolean;
45
- /** The local device info (available after connect) */
68
+ /** The injected core client (owned by the app, not the wrapper) */
69
+ get client(): NoLagSocket;
70
+ /** The local device info (available after ready) */
46
71
  get localDevice(): Device | null;
47
72
  /** All currently joined groups */
48
73
  get groups(): Map<string, DeviceGroup>;
49
74
  /**
50
- * Connect to NoLag and set up global presence.
75
+ * Resolves once the wrapper's first setup completed (identity, lobby and
76
+ * configured groups ready — equivalently, once 'connected' has fired).
77
+ * Rejects only if detach() is called before that. Client auth failures
78
+ * surface via the app's own `await client.connect()`, not here.
79
+ */
80
+ ready(): Promise<void>;
81
+ /**
82
+ * Detach from the client: remove every handler this wrapper added,
83
+ * unsubscribe its topics and lobby (when connected), clear state. Also
84
+ * clears any pending command-timeout timers on every group. Terminal and
85
+ * idempotent; never touches the socket. To use IoT again, construct a new
86
+ * instance.
51
87
  */
52
- connect(): Promise<void>;
88
+ detach(): void;
89
+ private _onConnect;
53
90
  /**
54
- * Disconnect from NoLag and clean up all groups.
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.
55
94
  */
56
- disconnect(): void;
95
+ private _runSetup;
96
+ private _scheduleLobbyRefresh;
57
97
  /**
58
98
  * Join a device group. Creates, subscribes, and activates it.
59
99
  * Returns an existing group if already joined.
@@ -71,16 +111,27 @@ export declare class NoLagIoT extends EventEmitter<IoTClientEvents> {
71
111
  * Get all devices currently online across all groups.
72
112
  */
73
113
  getOnlineDevices(): Device[];
114
+ private _assertUsable;
74
115
  private _subscribeGroup;
116
+ /**
117
+ * On a shared client, presence events from other apps' wrappers arrive on
118
+ * the same connection-level events. Wrappers stamp their presence with a
119
+ * `__scope` (their appName); a mismatched tag means another app's data.
120
+ * Untagged presence is accepted (older peers in this same app).
121
+ */
122
+ private _foreignScope;
75
123
  private _handleRoomPresenceJoin;
76
124
  private _handleRoomPresenceLeave;
77
125
  private _handleRoomPresenceUpdate;
78
- private _setupLobby;
79
126
  private _handleLobbyJoin;
80
127
  private _handleLobbyLeave;
81
128
  private _handleLobbyUpdate;
82
- private _hydrateOnlineDevices;
129
+ /**
130
+ * Reconcile the online-device map against a fresh lobby snapshot, emitting
131
+ * only the deltas (deviceOffline for vanished, deviceOnline for new). One
132
+ * path for initial hydration, reconnect restore, and the deferred refetch.
133
+ */
134
+ private _diffHydrateOnlineDevices;
83
135
  private _presenceToDevice;
84
136
  private _findDeviceIdByActorId;
85
- private _restoreGroups;
86
137
  }
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 i=this._handlers.get(e);if(i)for(const s of i)try{s(...t)}catch(t){console.error(`Error in ${String(e)} handler:`,t)}}listenerCount(e){return this._handlers.get(e)?.size??0}}class i{constructor(e){this._devices=new Map,this._actorToDeviceId=new Map,this._localActorId=e}addFromPresence(e,t,i){if(e===this._localActorId)return null;const s=this._actorToDeviceId.get(e),o=t.deviceId||s||e,n={deviceId:o,actorTokenId:e,deviceName:t.deviceName,role:t.role,metadata:t.metadata,joinedAt:i??Date.now(),isLocal:!1};return this._devices.set(o,n),this._actorToDeviceId.set(e,o),n}removeByActorId(e){if(e===this._localActorId)return null;const t=this._actorToDeviceId.get(e);if(!t)return null;const i=this._devices.get(t)??null;return this._devices.delete(t),this._actorToDeviceId.delete(e),i}getDevice(e){return this._devices.get(e)}getDeviceByActorId(e){const t=this._actorToDeviceId.get(e);return t?this._devices.get(t):void 0}getAll(){return Array.from(this._devices.values())}get devices(){return this._devices}clear(){this._devices.clear(),this._actorToDeviceId.clear()}}class s{constructor(e){this._store=new Map,this._ids=new Set,this._maxPoints=e}add(e){if(this._ids.has(e.id))return!1;const t=this._key(e.deviceId,e.sensorId);this._store.has(t)||this._store.set(t,[]);const i=this._store.get(t);return i.push(e),i.length>this._maxPoints&&i.splice(0,i.length-this._maxPoints),this._ids.add(e.id),!0}getAll(e,t){if(void 0!==e&&void 0!==t)return[...this._store.get(this._key(e,t))??[]];const i=[];for(const[t,s]of this._store.entries())(void 0===e||t.startsWith(`${e}:`))&&i.push(...s);return i}getLatest(e,t){const i=this._store.get(this._key(e,t));if(i&&0!==i.length)return i[i.length-1]}has(e){return this._ids.has(e)}get size(){let e=0;for(const t of this._store.values())e+=t.length;return e}clear(){this._store.clear(),this._ids.clear()}_key(e,t){return`${e}:${t}`}}function o(){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 n(e,t){return t?(...t)=>{console.log(`[${e}]`,...t)}:(...e)=>{}}class c{constructor(e){this._pending=new Map,this._commands=new Map,this._defaultTimeout=e}send(e,t,i,s,n){const c=o(),r=Date.now(),a={id:c,targetDeviceId:e,command:t,params:i,status:"pending",sentBy:s,sentAt:r};this._commands.set(c,a);const d=new Promise((e,i)=>{const s=n??this._defaultTimeout,o=setTimeout(()=>{const e=this._pending.get(c);e&&(e.command.status="timeout",this._commands.set(c,e.command),this._pending.delete(c),i(new Error(`Command "${t}" (${c}) timed out after ${s}ms`)))},s);this._pending.set(c,{command:a,resolve:e,reject:i,timer:o})});return d.catch(()=>{}),d}ack(e,t,i){const s=this._pending.get(e);if(!s)return null;clearTimeout(s.timer),this._pending.delete(e);const o=Date.now(),n=s.command;return n.status=t,"acked"===t?n.ackedAt=o:"completed"===t?(n.ackedAt=n.ackedAt??o,n.completedAt=o,n.result=i):"failed"===t&&(n.ackedAt=n.ackedAt??o,n.error="string"==typeof i?i:"Command failed"),this._commands.set(e,n),"acked"===t||"completed"===t?s.resolve(n):s.reject(new Error(n.error??"Command failed")),n}get(e){return this._commands.get(e)}getPending(){return Array.from(this._pending.values()).map(e=>e.command)}dispose(){for(const[e,t]of this._pending.entries())clearTimeout(t.timer),t.command.status="timeout",this._commands.set(e,t.command),t.reject(new Error(`Command "${t.command.command}" (${e}) was disposed`));this._pending.clear()}}const r="telemetry",a="commands",d="_cmd_ack";class h extends t{constructor(e,t,o,n,r){super(),this._receivedCommands=new Map,this.name=e,this._roomContext=t,this._localDevice=o,this._options=n,this._log=r,this._presenceManager=new i(o.actorTokenId),this._telemetryStore=new s(n.maxTelemetryPoints),this._commandManager=new c(n.commandTimeout)}get devices(){return this._presenceManager.devices}sendTelemetry(e,t,i={}){const s={id:o(),deviceId:this._localDevice.deviceId,sensorId:e,value:t,unit:i.unit,tags:i.tags,timestamp:Date.now(),isReplay:!1};return this._log("Sending telemetry:",e,"=",t),this._roomContext.emit(r,s,{echo:!1}),this._telemetryStore.add(s),s}getTelemetry(e,t){return this._telemetryStore.getAll(e,t)}sendCommand(e,t,i){this._log("Sending command:",t,"→",e);const s=this._commandManager.send(e,t,i,this._localDevice.deviceId,this._options.commandTimeout),o=this._commandManager.getPending(),n=o[o.length-1];return n&&this._roomContext.emit(a,n,{echo:!1,filter:e}),s}ackCommand(e,t,i){this._log("Acking command:",e,t);const s={commandId:e,status:t,result:i,ackedBy:this._localDevice.deviceId,ackedAt:Date.now()},o=this._receivedCommands.get(e)||this._commandManager.get(e),n=o?.sentBy;this._receivedCommands.delete(e),this._roomContext.emit(d,s,{echo:!1,...n?{filter:n}:{}}),this._commandManager.ack(e,t,i)}getDevices(){return this._presenceManager.getAll()}getDevice(e){return this._presenceManager.getDevice(e)}_subscribe(){this._log("Group subscribe:",this.name),this._roomContext.subscribe(r),"device"===this._options.role?this._roomContext.subscribe(a,{filters:[this._localDevice.deviceId]}):this._roomContext.subscribe(a),"controller"===this._options.role?this._roomContext.subscribe(d,{filters:[this._localDevice.deviceId]}):this._roomContext.subscribe(d),this._roomContext.on(r,e=>{this._handleIncomingTelemetry(e)}),this._roomContext.on(a,e=>{this._handleIncomingCommand(e)}),this._roomContext.on(d,e=>{this._handleIncomingCmdAck(e)})}_activate(){this._log("Group activate:",this.name),this._setPresence(),this._roomContext.fetchPresence().then(e=>{this._log("Group presence fetched:",this.name,e.length,"actors");for(const t of e)if(t.presence){const e=this._presenceManager.addFromPresence(t.actorTokenId,t.presence,t.joinedAt);e&&this.emit("deviceJoined",e)}}).catch(e=>{this._log("Failed to fetch group presence:",e)})}_updateLocalPresence(){this._setPresence()}_handlePresenceJoin(e,t){const i=this._presenceManager.addFromPresence(e,t);i&&(this._log("Device joined group:",this.name,i.deviceId),this.emit("deviceJoined",i))}_handlePresenceLeave(e){const t=this._presenceManager.removeByActorId(e);t&&(this._log("Device left group:",this.name,t.deviceId),this.emit("deviceLeft",t))}_handlePresenceUpdate(e,t){this._presenceManager.addFromPresence(e,t)}_cleanup(){this._log("Group cleanup:",this.name),this._roomContext.unsubscribe(r),this._roomContext.unsubscribe(a),this._roomContext.unsubscribe(d),this._roomContext.off(r),this._roomContext.off(a),this._roomContext.off(d),this._commandManager.dispose(),this._receivedCommands.clear(),this._presenceManager.clear(),this.removeAllListeners()}_handleIncomingTelemetry(e){const t=e;this._log("Received telemetry:",t.sensorId,"=",t.value,"from",t.deviceId);this._telemetryStore.add(t)&&this.emit("telemetry",t)}_handleIncomingCommand(e){const t=e;"controller"!==this._options.role&&(this._log("Received command:",t.command,"from",t.sentBy),this._receivedCommands.set(t.id,t),this.emit("command",t))}_handleIncomingCmdAck(e){const t=e;this._log("Received command ack:",t.commandId,t.status);const i=this._commandManager.ack(t.commandId,t.status,t.result);i&&this.emit("commandAck",i)}_setPresence(){const e={deviceId:this._localDevice.deviceId,deviceName:this._localDevice.deviceName,role:this._localDevice.role,metadata:this._localDevice.metadata};this._roomContext.setPresence(e)}}class l extends t{constructor(e,t={}){super(),this._client=null,this._localDevice=null,this._groups=new Map,this._lobby=null,this._onlineDevices=new Map,this._actorToDeviceId=new Map,this._token=e,this._deviceId=t.deviceId??o(),this._options={deviceId:this._deviceId,deviceName:t.deviceName,role:t.role??"device",metadata:t.metadata,appName:t.appName??"iot",url:t.url,maxTelemetryPoints:t.maxTelemetryPoints??1e3,commandTimeout:t.commandTimeout??3e4,debug:t.debug??!1,reconnect:t.reconnect??!0,groups:t.groups??[]},this._log=n("NoLagIoT",this._options.debug)}get connected(){return this._client?.connected??!1}get localDevice(){return this._localDevice}get groups(){return this._groups}async connect(){this._log("Connecting...");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._log("Connected"),this._groups.size>0&&(this._log("Reconnected — restoring groups..."),this._restoreGroups(),this.emit("reconnected"))}),this._client.on("disconnect",e=>{this._log("Disconnected:",e),this.emit("disconnected",e)}),this._client.on("reconnect",()=>{this._log("Reconnecting...")}),this._client.on("error",e=>{this._log("Error:",e),this.emit("error",e)}),await this._client.connect(),this._client.on("presence:join",e=>{this._handleRoomPresenceJoin(e)}),this._client.on("presence:leave",e=>{this._handleRoomPresenceLeave(e)}),this._client.on("presence:update",e=>{this._handleRoomPresenceUpdate(e)}),this._localDevice={deviceId:this._deviceId,actorTokenId:this._client.actorId,deviceName:this._options.deviceName,role:this._options.role,metadata:this._options.metadata,joinedAt:Date.now(),isLocal:!0},this._log("Local device:",this._localDevice.deviceId,"→",this._localDevice.actorTokenId),await this._setupLobby(),this.emit("connected");for(const e of this._options.groups)this.joinGroup(e);setTimeout(()=>{this._lobby&&this._client?.connected&&this._lobby.fetchPresence().then(e=>{this._hydrateOnlineDevices(e)}).catch(()=>{})},2e3)}disconnect(){this._log("Disconnecting...");for(const e of[...this._groups.keys()])this.leaveGroup(e);this._lobby?.unsubscribe(),this._lobby=null,this._client?.disconnect(),this._client=null,this._onlineDevices.clear(),this._actorToDeviceId.clear(),this._localDevice=null}joinGroup(e){if(!this._client||!this._localDevice)throw new Error("Not connected — call connect() first");let t=this._groups.get(e);return t||(t=this._subscribeGroup(e),t._activate()),t}leaveGroup(e){const t=this._groups.get(e);t&&(this._log("Leaving group:",e),t._cleanup(),this._groups.delete(e))}getGroups(){return Array.from(this._groups.values())}getOnlineDevices(){return Array.from(this._onlineDevices.values())}_subscribeGroup(e){if(!this._client||!this._localDevice)throw new Error("Not connected — call connect() first");this._log("Subscribing group:",e);const t=this._client.setApp(this._options.appName).setRoom(e),i=new h(e,t,this._localDevice,this._options,n(`DeviceGroup:${e}`,this._options.debug));return this._groups.set(e,i),i._subscribe(),i}_handleRoomPresenceJoin(e){if(e.actorTokenId===this._localDevice?.actorTokenId)return;const t=e.presence;if(!t?.deviceId)return;const i=this._presenceToDevice(e.actorTokenId,t);this._actorToDeviceId.set(e.actorTokenId,i.deviceId),this._onlineDevices.has(i.deviceId)||(this._onlineDevices.set(i.deviceId,i),this.emit("deviceOnline",i));for(const i of this._groups.values())i._handlePresenceJoin(e.actorTokenId,t)}_handleRoomPresenceLeave(e){if(e.actorTokenId!==this._localDevice?.actorTokenId)for(const t of this._groups.values())t._handlePresenceLeave(e.actorTokenId)}_handleRoomPresenceUpdate(e){if(e.actorTokenId===this._localDevice?.actorTokenId)return;const t=e.presence;if(t?.deviceId){if(this._onlineDevices.has(t.deviceId)){const i=this._presenceToDevice(e.actorTokenId,t);this._onlineDevices.set(i.deviceId,i)}for(const i of this._groups.values())i._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 i=t;"join"===e?this._handleLobbyJoin(i):"leave"===e?this._handleLobbyLeave(i):this._handleLobbyUpdate(i)};this._client.on("lobbyPresence:join",e("join")),this._client.on("lobbyPresence:leave",e("leave")),this._client.on("lobbyPresence:update",e("update"));try{const e=await this._lobby.subscribe();this._hydrateOnlineDevices(e),this._log("Lobby subscribed, online devices:",this._onlineDevices.size)}catch(e){this._log("Lobby subscription failed:",e)}}_handleLobbyJoin(e){const{actorId:t,data:i}=e;if(t===this._localDevice?.actorTokenId)return;const s=i;if(!s.deviceId)return;const o=this._presenceToDevice(t,s);this._actorToDeviceId.set(t,o.deviceId),this._onlineDevices.has(o.deviceId)||(this._onlineDevices.set(o.deviceId,o),this.emit("deviceOnline",o))}_handleLobbyLeave(e){const{actorId:t,data:i}=e;if(t===this._localDevice?.actorTokenId)return;const s=i,o=s?.deviceId||this._actorToDeviceId.get(t)||this._findDeviceIdByActorId(t);if(o){const e=this._onlineDevices.get(o);e&&(this._onlineDevices.delete(o),this._actorToDeviceId.delete(t),this.emit("deviceOffline",e))}}_handleLobbyUpdate(e){const{actorId:t,data:i}=e;if(t===this._localDevice?.actorTokenId)return;const s=i;if(!s.deviceId)return;const o=this._presenceToDevice(t,s);this._onlineDevices.set(o.deviceId,o)}_hydrateOnlineDevices(e){for(const t of Object.keys(e)){const i=e[t];for(const e of Object.keys(i)){if(e===this._localDevice?.actorTokenId)continue;const t=i[e],s=t?.presence??t;if(s?.deviceId){const t=this._presenceToDevice(e,s);this._actorToDeviceId.set(e,t.deviceId),this._onlineDevices.has(t.deviceId)||(this._onlineDevices.set(t.deviceId,t),this.emit("deviceOnline",t))}}}}_presenceToDevice(e,t){return{deviceId:t.deviceId,actorTokenId:e,deviceName:t.deviceName,role:t.role,metadata:t.metadata,joinedAt:Date.now(),isLocal:!1}}_findDeviceIdByActorId(e){for(const t of this._onlineDevices.values())if(t.actorTokenId===e)return t.deviceId}_restoreGroups(){for(const e of this._groups.values())e._updateLocalPresence();this._lobby?.fetchPresence().then(e=>{this._onlineDevices.clear(),this._actorToDeviceId.clear(),this._hydrateOnlineDevices(e)}).catch(e=>{this._log("Failed to re-fetch lobby presence:",e)})}}export{c as CommandManager,h as DeviceGroup,t as EventEmitter,l as NoLagIoT,i as PresenceManager,s as TelemetryStore};
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 i=this._handlers.get(e);if(i)for(const s of i)try{s(...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._devices=new Map,this._actorToDeviceId=new Map,this._localActorId=e}addFromPresence(e,t,i){if(e===this._localActorId)return null;const s=this._actorToDeviceId.get(e),o=t.deviceId||s||e,n={deviceId:o,actorTokenId:e,deviceName:t.deviceName,role:t.role,metadata:t.metadata,joinedAt:i??Date.now(),isLocal:!1};return this._devices.set(o,n),this._actorToDeviceId.set(e,o),n}removeByActorId(e){if(e===this._localActorId)return null;const t=this._actorToDeviceId.get(e);if(!t)return null;const i=this._devices.get(t)??null;return this._devices.delete(t),this._actorToDeviceId.delete(e),i}getDevice(e){return this._devices.get(e)}getDeviceByActorId(e){const t=this._actorToDeviceId.get(e);return t?this._devices.get(t):void 0}getAll(){return Array.from(this._devices.values())}get devices(){return this._devices}clear(){this._devices.clear(),this._actorToDeviceId.clear()}}class i{constructor(e){this._store=new Map,this._ids=new Set,this._maxPoints=e}add(e){if(this._ids.has(e.id))return!1;const t=this._key(e.deviceId,e.sensorId);this._store.has(t)||this._store.set(t,[]);const i=this._store.get(t);return i.push(e),i.length>this._maxPoints&&i.splice(0,i.length-this._maxPoints),this._ids.add(e.id),!0}getAll(e,t){if(void 0!==e&&void 0!==t)return[...this._store.get(this._key(e,t))??[]];const i=[];for(const[t,s]of this._store.entries())(void 0===e||t.startsWith(`${e}:`))&&i.push(...s);return i}getLatest(e,t){const i=this._store.get(this._key(e,t));if(i&&0!==i.length)return i[i.length-1]}has(e){return this._ids.has(e)}get size(){let e=0;for(const t of this._store.values())e+=t.length;return e}clear(){this._store.clear(),this._ids.clear()}_key(e,t){return`${e}:${t}`}}function s(){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 n=new WeakMap;class c{constructor(e){this._pending=new Map,this._commands=new Map,this._defaultTimeout=e}send(e,t,i,o,n){const c=s(),r=Date.now(),a={id:c,targetDeviceId:e,command:t,params:i,status:"pending",sentBy:o,sentAt:r};this._commands.set(c,a);const h=new Promise((e,i)=>{const s=n??this._defaultTimeout,o=setTimeout(()=>{const e=this._pending.get(c);e&&(e.command.status="timeout",this._commands.set(c,e.command),this._pending.delete(c),i(new Error(`Command "${t}" (${c}) timed out after ${s}ms`)))},s);this._pending.set(c,{command:a,resolve:e,reject:i,timer:o})});return h.catch(()=>{}),h}ack(e,t,i){const s=this._pending.get(e);if(!s)return null;clearTimeout(s.timer),this._pending.delete(e);const o=Date.now(),n=s.command;return n.status=t,"acked"===t?n.ackedAt=o:"completed"===t?(n.ackedAt=n.ackedAt??o,n.completedAt=o,n.result=i):"failed"===t&&(n.ackedAt=n.ackedAt??o,n.error="string"==typeof i?i:"Command failed"),this._commands.set(e,n),"acked"===t||"completed"===t?s.resolve(n):s.reject(new Error(n.error??"Command failed")),n}get(e){return this._commands.get(e)}getPending(){return Array.from(this._pending.values()).map(e=>e.command)}dispose(){for(const[e,t]of this._pending.entries())clearTimeout(t.timer),t.command.status="timeout",this._commands.set(e,t.command),t.reject(new Error(`Command "${t.command.command}" (${e}) was disposed`));this._pending.clear()}}const r="telemetry",a="commands",h="_cmd_ack";class d extends e{constructor(e,s,o,n,r,a){super(),this._receivedCommands=new Map,this._onTelemetryRef=null,this._onCommandsRef=null,this._onCmdAckRef=null,this.name=e,this._roomContext=s,this._localDevice=o,this._options=n,this._log=r,this._isConnected=a,this._presenceManager=new t(o.actorTokenId),this._telemetryStore=new i(n.maxTelemetryPoints),this._commandManager=new c(n.commandTimeout)}get devices(){return this._presenceManager.devices}sendTelemetry(e,t,i={}){const o={id:s(),deviceId:this._localDevice.deviceId,sensorId:e,value:t,unit:i.unit,tags:i.tags,timestamp:Date.now(),isReplay:!1};return this._log("Sending telemetry:",e,"=",t),this._roomContext.emit(r,o,{echo:!1}),this._telemetryStore.add(o),o}getTelemetry(e,t){return this._telemetryStore.getAll(e,t)}sendCommand(e,t,i){this._log("Sending command:",t,"→",e);const s=this._commandManager.send(e,t,i,this._localDevice.deviceId,this._options.commandTimeout),o=this._commandManager.getPending(),n=o[o.length-1];return n&&this._roomContext.emit(a,n,{echo:!1,filter:e}),s}ackCommand(e,t,i){this._log("Acking command:",e,t);const s={commandId:e,status:t,result:i,ackedBy:this._localDevice.deviceId,ackedAt:Date.now()},o=this._receivedCommands.get(e)||this._commandManager.get(e),n=o?.sentBy;this._receivedCommands.delete(e),this._roomContext.emit(h,s,{echo:!1,...n?{filter:n}:{}}),this._commandManager.ack(e,t,i)}getDevices(){return this._presenceManager.getAll()}getDevice(e){return this._presenceManager.getDevice(e)}_subscribe(){this._log("Group subscribe:",this.name),this._roomContext.subscribe(r),"device"===this._options.role?this._roomContext.subscribe(a,{filters:[this._localDevice.deviceId]}):this._roomContext.subscribe(a),"controller"===this._options.role?this._roomContext.subscribe(h,{filters:[this._localDevice.deviceId]}):this._roomContext.subscribe(h),this._onTelemetryRef=e=>{this._handleIncomingTelemetry(e)},this._roomContext.on(r,this._onTelemetryRef),this._onCommandsRef=e=>{this._handleIncomingCommand(e)},this._roomContext.on(a,this._onCommandsRef),this._onCmdAckRef=e=>{this._handleIncomingCmdAck(e)},this._roomContext.on(h,this._onCmdAckRef)}_activate(){this._log("Group activate:",this.name),this._setPresence(),this._roomContext.fetchPresence().then(e=>{this._log("Group presence fetched:",this.name,e.length,"actors");for(const t of e)if(t.presence){const e=this._presenceManager.addFromPresence(t.actorTokenId,t.presence,t.joinedAt);e&&this.emit("deviceJoined",e)}}).catch(e=>{this._log("Failed to fetch group presence:",e)})}_updateLocalPresence(){this._setPresence()}_handlePresenceJoin(e,t){const i=this._presenceManager.addFromPresence(e,t);i&&(this._log("Device joined group:",this.name,i.deviceId),this.emit("deviceJoined",i))}_handlePresenceLeave(e){const t=this._presenceManager.removeByActorId(e);t&&(this._log("Device left group:",this.name,t.deviceId),this.emit("deviceLeft",t))}_handlePresenceUpdate(e,t){this._presenceManager.addFromPresence(e,t)}_cleanup(){this._log("Group cleanup:",this.name),this._isConnected()&&(this._roomContext.unsubscribe(r),this._roomContext.unsubscribe(a),this._roomContext.unsubscribe(h)),this._onTelemetryRef&&this._roomContext.off(r,this._onTelemetryRef),this._onCommandsRef&&this._roomContext.off(a,this._onCommandsRef),this._onCmdAckRef&&this._roomContext.off(h,this._onCmdAckRef),this._onTelemetryRef=null,this._onCommandsRef=null,this._onCmdAckRef=null,this._commandManager.dispose(),this._receivedCommands.clear(),this._presenceManager.clear(),this.removeAllListeners()}_handleIncomingTelemetry(e){const t=e;this._log("Received telemetry:",t.sensorId,"=",t.value,"from",t.deviceId);this._telemetryStore.add(t)&&this.emit("telemetry",t)}_handleIncomingCommand(e){const t=e;"controller"!==this._options.role&&(this._log("Received command:",t.command,"from",t.sentBy),this._receivedCommands.set(t.id,t),this.emit("command",t))}_handleIncomingCmdAck(e){const t=e;this._log("Received command ack:",t.commandId,t.status);const i=this._commandManager.ack(t.commandId,t.status,t.result);i&&this.emit("commandAck",i)}_setPresence(){const e={deviceId:this._localDevice.deviceId,deviceName:this._localDevice.deviceName,role:this._localDevice.role,metadata:this._localDevice.metadata,__scope:this._options.appName};this._roomContext.setPresence(e)}}class _ extends e{constructor(e){if(super(),this._localDevice=null,this._groups=new Map,this._lobby=null,this._onlineDevices=new Map,this._actorToDeviceId=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._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("NoLagIoT requires an injected NoLag client: new NoLagIoT({ client, deviceId, ... })");this._client=e.client,this._deviceId=e.deviceId??s(),this._options={deviceId:this._deviceId,deviceName:e.deviceName,role:e.role??"device",metadata:e.metadata,appName:e.appName??"iot",maxTelemetryPoints:e.maxTelemetryPoints??1e3,commandTimeout:e.commandTimeout??3e4,debug:e.debug??!1,groups:e.groups??[]},this._log=o("NoLagIoT",this._options.debug),this._readyPromise=new Promise((e,t)=>{this._readyResolve=e,this._readyReject=t}),this._readyPromise.catch(()=>{}),function(e,t,i){let s=n.get(e);s||(s=new Map,n.set(e,s));const o=s.get(t);o&&console.warn(`[${i}] Another wrapper (${o}) is already attached to this client for app "${t}". Use one wrapper per (client, app) — detach the other instance first.`),s.set(t,i)}(this._client,this._options.appName,"NoLagIoT"),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("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 localDevice(){return this._localDevice}get groups(){return this._groups}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("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._groups.keys()])this._groups.get(e)._cleanup(),this._groups.delete(e);if(this._lobby&&this._client.connected)try{this._lobby.unsubscribe()}catch{}var e,t;this._lobby=null,this._onlineDevices.clear(),this._actorToDeviceId.clear(),this._localDevice=null,e=this._client,t=this._options.appName,n.get(e)?.delete(t),this._isReady||this._readyReject(new Error("NoLagIoT 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._localDevice?this._localDevice.actorTokenId=this._client.actorId:(this._localDevice={deviceId:this._deviceId,actorTokenId:this._client.actorId,deviceName:this._options.deviceName,role:this._options.role,metadata:this._options.metadata,joinedAt:Date.now(),isLocal:!0},this._log("Local device:",this._localDevice.deviceId,"→",this._localDevice.actorTokenId)),this._lobby||(this._lobby=this._client.setApp(this._options.appName).setLobby("online"));try{const e=await this._lobby.subscribe();if(t())return;this._diffHydrateOnlineDevices(e),this._log("Lobby subscribed, online devices:",this._onlineDevices.size)}catch(e){if(t())return;this._log("Lobby subscription failed:",e)}if(this._isReady)for(const e of this._groups.values())e._updateLocalPresence();else for(const e of this._options.groups){this._subscribeGroup(e)._activate()}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._diffHydrateOnlineDevices(t)}).catch(()=>{})},2e3)}joinGroup(e){this._assertUsable();let t=this._groups.get(e);return t||(t=this._subscribeGroup(e),t._activate()),t}leaveGroup(e){const t=this._groups.get(e);t&&(this._log("Leaving group:",e),t._cleanup(),this._groups.delete(e))}getGroups(){return Array.from(this._groups.values())}getOnlineDevices(){return Array.from(this._onlineDevices.values())}_assertUsable(){if(this._detached)throw new Error("NoLagIoT has been detached — construct a new instance");if(!this._isReady||!this._localDevice)throw new Error('NoLagIoT not ready — await ready() or the "connected" event')}_subscribeGroup(e){this._log("Subscribing group:",e);const t=this._client.setApp(this._options.appName).setRoom(e),i=new d(e,t,this._localDevice,this._options,o(`DeviceGroup:${e}`,this._options.debug),()=>this._client.connected);return this._groups.set(e,i),i._subscribe(),i}_foreignScope(e){const t=e?.__scope;return"string"==typeof t&&t!==this._options.appName}_handleRoomPresenceJoin(e){if(e.actorTokenId===this._localDevice?.actorTokenId)return;const t=e.presence;if(!t?.deviceId||this._foreignScope(t))return;const i=this._presenceToDevice(e.actorTokenId,t);this._actorToDeviceId.set(e.actorTokenId,i.deviceId),this._onlineDevices.has(i.deviceId)||(this._onlineDevices.set(i.deviceId,i),this.emit("deviceOnline",i));for(const i of this._groups.values())i._handlePresenceJoin(e.actorTokenId,t)}_handleRoomPresenceLeave(e){if(e.actorTokenId!==this._localDevice?.actorTokenId)for(const t of this._groups.values())t._handlePresenceLeave(e.actorTokenId)}_handleRoomPresenceUpdate(e){if(e.actorTokenId===this._localDevice?.actorTokenId)return;const t=e.presence;if(t?.deviceId&&!this._foreignScope(t)){if(this._onlineDevices.has(t.deviceId)){const i=this._presenceToDevice(e.actorTokenId,t);this._onlineDevices.set(i.deviceId,i)}for(const i of this._groups.values())i._handlePresenceUpdate(e.actorTokenId,t)}}_handleLobbyJoin(e){const{actorId:t,data:i}=e;if(t===this._localDevice?.actorTokenId)return;const s=i;if(!s?.deviceId||this._foreignScope(s))return;const o=this._presenceToDevice(t,s);this._actorToDeviceId.set(t,o.deviceId),this._onlineDevices.has(o.deviceId)||(this._onlineDevices.set(o.deviceId,o),this.emit("deviceOnline",o))}_handleLobbyLeave(e){const{actorId:t,data:i}=e;if(t===this._localDevice?.actorTokenId)return;const s=i;if(this._foreignScope(s))return;const o=s?.deviceId||this._actorToDeviceId.get(t)||this._findDeviceIdByActorId(t);if(o){const e=this._onlineDevices.get(o);e&&(this._onlineDevices.delete(o),this._actorToDeviceId.delete(t),this.emit("deviceOffline",e))}}_handleLobbyUpdate(e){const{actorId:t,data:i}=e;if(t===this._localDevice?.actorTokenId)return;const s=i;if(!s?.deviceId||this._foreignScope(s))return;const o=this._presenceToDevice(t,s);this._onlineDevices.set(o.deviceId,o)}_diffHydrateOnlineDevices(e){const t=new Map,i=new Map;for(const s of Object.keys(e)){const o=e[s];for(const e of Object.keys(o)){if(e===this._localDevice?.actorTokenId)continue;const s=o[e],n=s?.presence??s;n?.deviceId&&!this._foreignScope(n)&&(t.has(n.deviceId)||t.set(n.deviceId,this._presenceToDevice(e,n)),i.set(e,n.deviceId))}}for(const[e,i]of[...this._onlineDevices])if(!t.has(e)){this._onlineDevices.delete(e);for(const[t,i]of[...this._actorToDeviceId])i===e&&this._actorToDeviceId.delete(t);this.emit("deviceOffline",i)}for(const[e,i]of t)this._onlineDevices.has(e)||(this._onlineDevices.set(e,i),this.emit("deviceOnline",i));for(const[e,t]of i)this._actorToDeviceId.set(e,t)}_presenceToDevice(e,t){return{deviceId:t.deviceId,actorTokenId:e,deviceName:t.deviceName,role:t.role,metadata:t.metadata,joinedAt:Date.now(),isLocal:!1}}_findDeviceIdByActorId(e){for(const t of this._onlineDevices.values())if(t.actorTokenId===e)return t.deviceId}}export{c as CommandManager,d as DeviceGroup,e as EventEmitter,_ as NoLagIoT,t as PresenceManager,i as TelemetryStore};
2
2
  //# sourceMappingURL=browser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sources":["../src/EventEmitter.ts","../src/PresenceManager.ts","../src/TelemetryStore.ts","../src/utils.ts","../src/CommandManager.ts","../src/constants.ts","../src/DeviceGroup.ts","../src/NoLagIoT.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","PresenceManager","localActorId","_devices","_actorToDeviceId","_localActorId","addFromPresence","actorTokenId","presence","joinedAt","existing","deviceId","device","deviceName","role","metadata","Date","now","isLocal","removeByActorId","getDevice","getDeviceByActorId","undefined","getAll","Array","from","values","devices","TelemetryStore","maxPoints","_store","_ids","_maxPoints","reading","id","key","_key","sensorId","bucket","push","length","splice","results","entries","startsWith","getLatest","total","generateId","crypto","randomUUID","replace","Math","floor","random","toString","createLogger","prefix","enabled","log","_args","CommandManager","defaultTimeout","_pending","_commands","_defaultTimeout","send","targetDeviceId","command","params","sentBy","timeout","cmd","status","sentAt","promise","Promise","resolve","reject","ms","timer","setTimeout","entry","Error","catch","ack","commandId","result","clearTimeout","ackedAt","completedAt","getPending","map","dispose","TOPIC_TELEMETRY","TOPIC_COMMANDS","TOPIC_CMD_ACK","DeviceGroup","name","roomContext","localDevice","options","super","_receivedCommands","_roomContext","_localDevice","_options","_log","_presenceManager","_telemetryStore","maxTelemetryPoints","_commandManager","commandTimeout","sendTelemetry","value","opts","unit","tags","timestamp","isReplay","echo","getTelemetry","sendCommand","pending","filter","ackCommand","ackedBy","ackFilter","getDevices","_subscribe","subscribe","filters","data","_handleIncomingTelemetry","_handleIncomingCommand","_handleIncomingCmdAck","_activate","_setPresence","fetchPresence","then","actors","actor","err","_updateLocalPresence","_handlePresenceJoin","presenceData","_handlePresenceLeave","_handlePresenceUpdate","_cleanup","unsubscribe","setPresence","NoLagIoT","token","_client","_groups","_lobby","_onlineDevices","_token","_deviceId","appName","url","debug","reconnect","groups","connected","connect","clientOptions","NoLag","_restoreGroups","reason","_handleRoomPresenceJoin","_handleRoomPresenceLeave","_handleRoomPresenceUpdate","actorId","_setupLobby","groupName","joinGroup","state","_hydrateOnlineDevices","disconnect","keys","leaveGroup","group","_subscribeGroup","getGroups","getOnlineDevices","setApp","setRoom","_presenceToDevice","setLobby","lobbyHandler","type","_handleLobbyJoin","_handleLobbyLeave","_handleLobbyUpdate","initialState","_findDeviceIdByActorId","roomId","Object","roomPresence","raw"],"mappings":"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"}
1
+ {"version":3,"file":"browser.js","sources":["../src/EventEmitter.ts","../src/PresenceManager.ts","../src/TelemetryStore.ts","../src/utils.ts","../src/CommandManager.ts","../src/constants.ts","../src/DeviceGroup.ts","../src/NoLagIoT.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","PresenceManager","localActorId","_devices","_actorToDeviceId","_localActorId","addFromPresence","actorTokenId","presence","joinedAt","existing","deviceId","device","deviceName","role","metadata","Date","now","isLocal","removeByActorId","getDevice","getDeviceByActorId","undefined","getAll","Array","from","values","devices","TelemetryStore","maxPoints","_store","_ids","_maxPoints","reading","id","key","_key","sensorId","bucket","push","length","splice","results","entries","startsWith","getLatest","total","generateId","crypto","randomUUID","replace","Math","floor","random","toString","createLogger","prefix","enabled","log","_args","wrapperRegistry","WeakMap","CommandManager","defaultTimeout","_pending","_commands","_defaultTimeout","send","targetDeviceId","command","params","sentBy","timeout","cmd","status","sentAt","promise","Promise","resolve","reject","ms","timer","setTimeout","entry","Error","catch","ack","commandId","result","clearTimeout","ackedAt","completedAt","getPending","map","dispose","TOPIC_TELEMETRY","TOPIC_COMMANDS","TOPIC_CMD_ACK","DeviceGroup","name","roomContext","localDevice","options","isConnected","super","_receivedCommands","_onTelemetryRef","_onCommandsRef","_onCmdAckRef","_roomContext","_localDevice","_options","_log","_isConnected","_presenceManager","_telemetryStore","maxTelemetryPoints","_commandManager","commandTimeout","sendTelemetry","value","opts","unit","tags","timestamp","isReplay","echo","getTelemetry","sendCommand","pending","filter","ackCommand","ackedBy","ackFilter","getDevices","_subscribe","subscribe","filters","data","_handleIncomingTelemetry","_handleIncomingCommand","_handleIncomingCmdAck","_activate","_setPresence","fetchPresence","then","actors","actor","err","_updateLocalPresence","_handlePresenceJoin","presenceData","_handlePresenceLeave","_handlePresenceUpdate","_cleanup","unsubscribe","__scope","appName","setPresence","NoLagIoT","_groups","_lobby","_onlineDevices","_epoch","_detached","_isReady","_lobbyRefreshTimer","_onConnectRef","_onConnect","_onDisconnectRef","reason","_onReconnectRef","_onErrorRef","_onPresenceJoinRef","_handleRoomPresenceJoin","_onPresenceLeaveRef","_handleRoomPresenceLeave","_onPresenceUpdateRef","_handleRoomPresenceUpdate","_onLobbyJoinRef","_handleLobbyJoin","_onLobbyLeaveRef","_handleLobbyLeave","_onLobbyUpdateRef","_handleLobbyUpdate","client","TypeError","_client","_deviceId","debug","groups","_readyPromise","_readyResolve","_readyReject","wrapperName","apps","warn","registerWrapper","queueMicrotask","connected","ready","detach","keys","_runSetup","epoch","stale","actorId","setApp","setLobby","state","_diffHydrateOnlineDevices","group","groupName","_subscribeGroup","_scheduleLobbyRefresh","joinGroup","_assertUsable","leaveGroup","getGroups","getOnlineDevices","setRoom","_foreignScope","scope","_presenceToDevice","_findDeviceIdByActorId","fresh","freshActors","roomId","Object","roomPresence","raw","mappedDeviceId"],"mappings":"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"}
@@ -12,3 +12,5 @@ export declare const TOPIC_COMMANDS = "commands";
12
12
  export declare const TOPIC_CMD_ACK = "_cmd_ack";
13
13
  /** Lobby ID for global online presence */
14
14
  export declare const LOBBY_ID = "online";
15
+ /** Delay before the post-setup lobby presence refetch (catches simultaneous joiners) */
16
+ export declare const LOBBY_REFRESH_DELAY_MS = 2000;