openrtc 3.0.0 → 3.0.2

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.
Files changed (66) hide show
  1. package/README.md +42 -0
  2. package/dist/{Connection-BZ6piJsh.d.ts → Connection-BGVBMbWg.d.ts} +5 -0
  3. package/dist/{DelegatingRuntimeAdapter-s3QvVuTj.d.ts → DelegatingRuntimeAdapter-JmhmwKTC.d.ts} +2 -2
  4. package/dist/{IpcRuntimeAdapter-CghYNfcc.d.ts → IpcRuntimeAdapter-DMQoN2XL.d.ts} +2 -2
  5. package/dist/{WasmBridge-FSGSSPWK.js → WasmBridge-L76OAD5U.js} +1 -1
  6. package/dist/{assembly-BEMgeExQ.d.ts → assembly-DGrOqsLW.d.ts} +2 -2
  7. package/dist/{capabilities-fJ11v3xA.d.ts → capabilities-DsKud7Sw.d.ts} +1 -1
  8. package/dist/chunk-4TOWICSH.js +1 -0
  9. package/dist/{chunk-5CWZ6GGD.js → chunk-7MAQEBMM.js} +1 -1
  10. package/dist/{chunk-IVH7EHAZ.js → chunk-A2TFNNXG.js} +1 -1
  11. package/dist/chunk-EI6PDMHI.js +2 -0
  12. package/dist/{chunk-3CV7SSY3.js → chunk-HL3TV2QA.js} +1 -1
  13. package/dist/chunk-IUU6JCLK.js +1 -0
  14. package/dist/chunk-NC375DSH.js +1 -0
  15. package/dist/{chunk-W45XAU3I.js → chunk-TFOFTLTV.js} +1 -1
  16. package/dist/chunk-UCNK7KB6.js +2 -0
  17. package/dist/coreClient-ByXs38IP.d.ts +309 -0
  18. package/dist/coreClient.d.ts +4 -250
  19. package/dist/coreClient.js +1 -1
  20. package/dist/deviceHandle-Y3SYSCJ6.js +1 -0
  21. package/dist/{dist-XO466BRG.js → dist-FIVA6EPA.js} +0 -18
  22. package/dist/external-broadcast.d.ts +5 -5
  23. package/dist/external-broadcast.js +1 -1
  24. package/dist/index.d.ts +7 -7
  25. package/dist/index.js +1 -1
  26. package/dist/ipcFactory-OJMZCIIQ.js +1 -0
  27. package/dist/native.d.ts +6 -6
  28. package/dist/native.js +1 -1
  29. package/dist/node.d.ts +7 -7
  30. package/dist/node.js +2 -2
  31. package/dist/openrtc-2VLRZHQ3.js +2 -0
  32. package/dist/openrtc_bg.wasm +0 -0
  33. package/dist/room-QHKIFLR7.js +1 -0
  34. package/dist/runtime/WasmRuntimeAdapter.d.ts +3 -3
  35. package/dist/runtime/WasmRuntimeAdapter.js +1 -1
  36. package/dist/runtime/device-status.d.ts +1 -1
  37. package/dist/runtime/factories.d.ts +5 -5
  38. package/dist/runtime/factories.js +1 -1
  39. package/dist/runtime/index.d.ts +19 -12
  40. package/dist/runtime/index.js +1 -1
  41. package/dist/server-browser.d.ts +5 -5
  42. package/dist/server.d.ts +5 -5
  43. package/dist/server.js +1 -1
  44. package/dist/service-node.d.ts +5 -5
  45. package/dist/service-node.js +1 -1
  46. package/dist/testing/native.d.ts +5 -5
  47. package/dist/testing/native.js +1 -1
  48. package/dist/testing.d.ts +5 -5
  49. package/dist/testing.js +1 -1
  50. package/dist/transport/index.d.ts +2 -2
  51. package/dist/{types-DiFR_L_m.d.ts → types-YGlXXpQA.d.ts} +21 -5
  52. package/native/darwin-arm64/openrtc-node-host +0 -0
  53. package/native/darwin-arm64/openrtc-node-host.manifest.json +4 -4
  54. package/native/darwin-x64/openrtc-node-host +0 -0
  55. package/native/darwin-x64/openrtc-node-host.manifest.json +4 -4
  56. package/native/linux-x64/openrtc-node-host +0 -0
  57. package/native/linux-x64/openrtc-node-host.manifest.json +4 -4
  58. package/package.json +1 -1
  59. package/dist/chunk-CAUMGKP4.js +0 -2
  60. package/dist/chunk-NIUTTTJS.js +0 -2
  61. package/dist/chunk-O7Z6WLGA.js +0 -1
  62. package/dist/chunk-WZ2VUWTQ.js +0 -1
  63. package/dist/deviceHandle-KTPNRJSS.js +0 -1
  64. package/dist/ipcFactory-RUGRMNGB.js +0 -1
  65. package/dist/openrtc-MG4DOSLP.js +0 -2
  66. package/dist/room-FFDNIK6N.js +0 -1
package/README.md CHANGED
@@ -260,6 +260,17 @@ the explicitly enabled, content-blind managed path. `advancedFanout: true` is a
260
260
  one-release alias for fixed sparse latest-state delivery. `state()` remains
261
261
  unavailable in sparse rooms; use a named channel with application revisions.
262
262
 
263
+ ### Debugging
264
+
265
+ For an opt-in, bounded support timeline, use
266
+ `const capture = ticket.diagnostics.capture({ maxEvents: 256 })`, reproduce the
267
+ problem, then call `capture.stop()` and save `capture.snapshot()`. Constructor
268
+ `diagnostics: { logger }` records activation outcomes even before a handle
269
+ exists. Rust hosts use `client.diagnostic_snapshot().await` and the standard
270
+ `tracing` subscriber owned by their app. Credentials and payloads are excluded
271
+ from these new support records; legacy verbose logs remain private.
272
+ See the [debugging guide](../../apps/docs/content/openrtc/debugging.mdx) for setup and interpretation.
273
+
263
274
  ### Passive connection metrics
264
275
 
265
276
  ```ts
@@ -280,3 +291,34 @@ or path (`webrtc`, `moq`, `iroh-quic`, `iroh-lan`, `iroh-relay`, or `ble`).
280
291
  A missing, unadmitted, replaced, or retired path has null measurements. Samples
281
292
  carry the existing transport stable ID, transport/route generations, and
282
293
  `metricsSampledAtMs`. These read-only diagnostics do not determine readiness.
294
+
295
+ ## Third-party notices
296
+
297
+ ### Adapted OpenMLS RustCrypto provider
298
+
299
+ The native and WASM runtimes include an adaptation of the MIT-licensed
300
+ `openmls_rust_crypto` 0.6.0 provider by the OpenMLS Authors, with the upstream
301
+ HPKE 0.8 dependency transition. This notice applies to that component;
302
+ OpenRTC’s project license remains unchanged.
303
+
304
+ ```text
305
+ Copyright (c) 2020 OpenMLS Authors
306
+
307
+ Permission is hereby granted, free of charge, to any person obtaining a copy
308
+ of this software and associated documentation files (the "Software"), to deal
309
+ in the Software without restriction, including without limitation the rights
310
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
311
+ copies of the Software, and to permit persons to whom the Software is
312
+ furnished to do so, subject to the following conditions:
313
+
314
+ The above copyright notice and this permission notice shall be included in all
315
+ copies or substantial portions of the Software.
316
+
317
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
318
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
319
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
320
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
321
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
322
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
323
+ SOFTWARE.
324
+ ```
@@ -205,6 +205,10 @@ interface ScopedChannelOptions {
205
205
  */
206
206
  existingRouteOnly?: boolean;
207
207
  framing?: ChannelFraming;
208
+ /** u32be payload bound, at most 16 MiB; defaults to 16 MiB. Raw streams are unaffected. */
209
+ maxFrameBytes?: number;
210
+ /** Absolute lifetime of an incomplete u32be frame, 1..60000 ms; defaults to 10000. */
211
+ frameTimeoutMs?: number;
208
212
  }
209
213
  interface ScopedLogicalChannel {
210
214
  channelId: string;
@@ -971,6 +975,7 @@ interface NativeManagedSessionStartResult {
971
975
  localDevice?: LocalDeviceInfo | null;
972
976
  }
973
977
  interface RoomMember {
978
+ deviceId?: string;
974
979
  nodeId: string;
975
980
  userId: string;
976
981
  ticket: string;
@@ -1,5 +1,5 @@
1
- import { U as DiscoveryMode, V as AuthMode, W as SignalingMode, X as ClientOptions, Y as ExplicitFileDataSendParams, Z as ISignalingBackend, _ as RuntimeIdentity, O as AuthContext, $ as RoomMember, a0 as Device, a1 as DeviceStatusSnapshot, n as PeerSessionSnapshot, q as ResolvedPeerIdentity, a2 as ManagedConnectionRecord, a3 as SignalingEnvelope, a4 as DeviceEvent, d as TransferPeerDemandRequest, f as TransferPeerDemandStatus, a5 as DesiredPeerProjection, a6 as SignalingSession, a7 as SessionEvent, a8 as LocalDeviceInfo, a9 as NativeManagedSessionStartResult, j as ProtocolName, N as GrantScope, aa as TicketMeshPeerReadiness, ab as BackendPeerBiStream, ac as BackendPeerUniStream, ad as PortableMediaPublish, ae as PortableMediaPublicationStart, af as PortableMediaSample, ag as PortableMediaChunk, ah as PortableMediaControl, ai as NativeConnectParams, aj as NativeConnectResult, ak as BackendConnectionState, al as NativePeerDataEvent } from './Connection-BZ6piJsh.js';
2
- import { R as RuntimeCapabilities } from './capabilities-fJ11v3xA.js';
1
+ import { U as DiscoveryMode, V as AuthMode, W as SignalingMode, X as ClientOptions, Y as ExplicitFileDataSendParams, Z as ISignalingBackend, _ as RuntimeIdentity, O as AuthContext, $ as RoomMember, a0 as Device, a1 as DeviceStatusSnapshot, n as PeerSessionSnapshot, q as ResolvedPeerIdentity, a2 as ManagedConnectionRecord, a3 as SignalingEnvelope, a4 as DeviceEvent, d as TransferPeerDemandRequest, f as TransferPeerDemandStatus, a5 as DesiredPeerProjection, a6 as SignalingSession, a7 as SessionEvent, a8 as LocalDeviceInfo, a9 as NativeManagedSessionStartResult, j as ProtocolName, N as GrantScope, aa as TicketMeshPeerReadiness, ab as BackendPeerBiStream, ac as BackendPeerUniStream, ad as PortableMediaPublish, ae as PortableMediaPublicationStart, af as PortableMediaSample, ag as PortableMediaChunk, ah as PortableMediaControl, ai as NativeConnectParams, aj as NativeConnectResult, ak as BackendConnectionState, al as NativePeerDataEvent } from './Connection-BGVBMbWg.js';
2
+ import { R as RuntimeCapabilities } from './capabilities-DsKud7Sw.js';
3
3
 
4
4
  /** Host-neutral configuration shared by browser/WASM and native/IPC adapters. */
5
5
  interface RuntimeBridgeOptions {
@@ -1,6 +1,6 @@
1
- import { R as RuntimeBridgeOptions, D as DelegatingRuntimeAdapter } from './DelegatingRuntimeAdapter-s3QvVuTj.js';
1
+ import { R as RuntimeBridgeOptions, D as DelegatingRuntimeAdapter } from './DelegatingRuntimeAdapter-JmhmwKTC.js';
2
2
  import { P as PlutoIpcBridge } from './ipc-DgzKqHH3.js';
3
- import { S as ServiceErrorObservation, ak as BackendConnectionState, al as NativePeerDataEvent, a0 as Device } from './Connection-BZ6piJsh.js';
3
+ import { S as ServiceErrorObservation, ak as BackendConnectionState, al as NativePeerDataEvent, a0 as Device } from './Connection-BGVBMbWg.js';
4
4
 
5
5
  /**
6
6
  * Root-client owner for the one native WebView projection.
@@ -1 +1 @@
1
- export{b as WasmBridge,a as loadBrowserWasmRuntimeModule}from'./chunk-3CV7SSY3.js';import'./chunk-AYHD4X2R.js';import'./chunk-CAUMGKP4.js';import'./chunk-L4HWDDXL.js';import'./chunk-OT7IPLZE.js';import'./chunk-OWKAJPOI.js';import'./chunk-TPF643LU.js';import'./chunk-L2ZZXECX.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';
1
+ export{b as WasmBridge,a as loadBrowserWasmRuntimeModule}from'./chunk-HL3TV2QA.js';import'./chunk-AYHD4X2R.js';import'./chunk-UCNK7KB6.js';import'./chunk-L4HWDDXL.js';import'./chunk-OT7IPLZE.js';import'./chunk-OWKAJPOI.js';import'./chunk-TPF643LU.js';import'./chunk-L2ZZXECX.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';
@@ -1,5 +1,5 @@
1
- import { k as RuntimePeerState, v as ConnectionState, o as PeerReadiness, l as PeerConnectOptions, m as Connection, I as IncomingStream, N as GrantScope, Q as RuntimeClientOptions, Z as ISignalingBackend, aD as RuntimeAuthIdentity, O as AuthContext, j as ProtocolName, L as LocalDeviceInfo, G as DeviceProfile, aq as BrowserProtocolStore, ar as NamespaceDescriptor, as as IrohMutationReceipt, at as IrohDocEntry, aj as NativeConnectResult, t as RuntimeDevice, M as ManagedOptions, y as ManagedSession, D as DeviceStatus, B as ConnectDeviceHooks, F as ConnectDeviceOptions, A as ConnectDeviceResult, z as DeviceConnectOptions, a2 as ManagedConnectionRecord, n as PeerSessionSnapshot, q as ResolvedPeerIdentity, aE as RuntimeSession, aF as AppLimits, J as JoinRoomOptions, K as RuntimeRoomMember, aG as ConnectionTarget, s as ScopedChannelOptions, u as ScopedLogicalChannel, r as PeerStreamOptions, ai as NativeConnectParams, H as RawConnection, C as ChannelDescriptor, Y as ExplicitFileDataSendParams, aH as PresenceLoopOptions, d as TransferPeerDemandRequest, f as TransferPeerDemandStatus, b as RoomArchitectureSnapshot, c as RoomAuthorityAssignment, p as RuntimePeerHealth, w as ReadinessOptions, x as ConnectionEvent } from './Connection-BZ6piJsh.js';
2
- import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-fJ11v3xA.js';
1
+ import { k as RuntimePeerState, v as ConnectionState, o as PeerReadiness, l as PeerConnectOptions, m as Connection, I as IncomingStream, N as GrantScope, Q as RuntimeClientOptions, Z as ISignalingBackend, aD as RuntimeAuthIdentity, O as AuthContext, j as ProtocolName, L as LocalDeviceInfo, G as DeviceProfile, aq as BrowserProtocolStore, ar as NamespaceDescriptor, as as IrohMutationReceipt, at as IrohDocEntry, aj as NativeConnectResult, t as RuntimeDevice, M as ManagedOptions, y as ManagedSession, D as DeviceStatus, B as ConnectDeviceHooks, F as ConnectDeviceOptions, A as ConnectDeviceResult, z as DeviceConnectOptions, a2 as ManagedConnectionRecord, n as PeerSessionSnapshot, q as ResolvedPeerIdentity, aE as RuntimeSession, aF as AppLimits, J as JoinRoomOptions, K as RuntimeRoomMember, aG as ConnectionTarget, s as ScopedChannelOptions, u as ScopedLogicalChannel, r as PeerStreamOptions, ai as NativeConnectParams, H as RawConnection, C as ChannelDescriptor, Y as ExplicitFileDataSendParams, aH as PresenceLoopOptions, d as TransferPeerDemandRequest, f as TransferPeerDemandStatus, b as RoomArchitectureSnapshot, c as RoomAuthorityAssignment, p as RuntimePeerHealth, w as ReadinessOptions, x as ConnectionEvent } from './Connection-BGVBMbWg.js';
2
+ import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-DsKud7Sw.js';
3
3
 
4
4
  /**
5
5
  * Coalesced peer reconciliation scheduler and full reconcile orchestration.
@@ -1,4 +1,4 @@
1
- import { j as ProtocolName, i as RouteOptimization } from './Connection-BZ6piJsh.js';
1
+ import { j as ProtocolName, i as RouteOptimization } from './Connection-BGVBMbWg.js';
2
2
 
3
3
  type RuntimeAdapterKind = 'browser-wasm' | 'native-ipc' | 'tauri-ipc' | 'unknown';
4
4
  type CapabilityMaturity = 'stable' | 'preview' | 'support-only' | 'unavailable';
@@ -0,0 +1 @@
1
+ import {b as b$3}from'./chunk-FKAQDDUM.js';import {b as b$1,a as a$2}from'./chunk-ZA44REGI.js';import {b as b$6,a as a$4,c}from'./chunk-NC375DSH.js';import {a as a$1,b as b$4}from'./chunk-IUU6JCLK.js';import {b as b$2,a as a$3}from'./chunk-CCCYE3XN.js';import {d,a,e}from'./chunk-L7N4T2PX.js';import {d as d$1,b as b$5}from'./chunk-2GX6GB6L.js';function I(a,e,t,i){let n=JSON.stringify({__openrtc:2,capability:i,kind:a,name:e,value:t});if(n===void 0||!n.includes('"value":'))throw new Error("[OpenRTC] Messages must be JSON-serializable values.");return new TextEncoder().encode(n)}function B(a){let e;try{e=a instanceof Uint8Array?JSON.parse(new TextDecoder().decode(a)):a&&typeof a=="object"?a:{};}catch{return null}return e!=null&&e.__openrtc===2&&typeof e.capability=="string"&&e.capability.length>0&&e.capability.length<=192&&/^(?:devices|space|room|ticket):[A-Za-z0-9_.:@-]+$/.test(e.capability)&&(e.kind==="raw"||e.kind==="channel"||e.kind==="state")&&typeof e.name=="string"&&e.name.length>0&&e.name.length<=80&&/^[A-Za-z0-9_.:@-]+$/.test(e.name)&&Object.prototype.hasOwnProperty.call(e,"value")?e:null}var b="openrtc-peer-stream/1",de=32,ee=16,L=4294967295,he=/^[A-Za-z0-9][A-Za-z0-9._/+:-]{0,127}$/,ue=/^([0-9a-f]{64})-([0-9a-f]{64})$/i;function R(a){let e=a?.trim()??"";if(!he.test(e))throw new Error("[OpenRTC] stream protocol must be 1-128 safe ASCII characters.");return e}function x(a){let e=a?.trim()??"",t=ue.exec(e);return t?[t[1].toLowerCase(),t[2].toLowerCase()].sort().join("-"):e}function te(a){if(a===null||a===0)return null;if(!Number.isFinite(a)||a<0)throw new RangeError("[OpenRTC] datagram maximum age must be a non-negative finite number or null.");return Math.min(L,Math.ceil(a))}function ie(a){if(!Number.isSafeInteger(a)||a<1||a>L)throw new RangeError(`[OpenRTC] datagram buffer limits must be integers from 1 to ${L}.`);return a}var _=class{constructor(e,t){this.runtime=e;this.peerId=t;this.incomingAge=null;this.outgoingAge=null;this.incomingLimit=ee;this.outgoingLimit=ee;this.policyInstance=null;this.incomingWaiters=new Set;this.outgoingWaiters=new Set;this.outgoingAvailable=new Set;this.incomingError=null;this.receiveLoopStarted=false;this.sendLoop=null;this.closed=false;this.incomingClosed=false;this.outgoingClosed=false;this.maxDatagramSize=e.peerDatagramMaxSize?.()??1024,this.readable=new ReadableStream({pull:i=>this.pullIncoming(i),cancel:()=>this.closeIncoming()},{highWaterMark:0}),this.writable=new WritableStream({write:i=>this.enqueueOutgoing(i),close:async()=>{this.outgoingClosed=true,await this.sendLoop;},abort:()=>{this.outgoingClosed=true,this.policyInstance?.closeOutgoing(),this.wake(this.outgoingWaiters),this.wake(this.outgoingAvailable);}},{highWaterMark:1});}get incomingMaxAge(){return this.incomingAge}set incomingMaxAge(e){this.incomingAge=te(e),this.policy.setIncomingMaxAge(this.incomingAge??void 0,Date.now()),this.wake(this.incomingWaiters);}get outgoingMaxAge(){return this.outgoingAge}set outgoingMaxAge(e){this.outgoingAge=te(e),this.policy.setOutgoingMaxAge(this.outgoingAge??void 0);}get incomingMaxBufferedDatagrams(){return this.incomingLimit}set incomingMaxBufferedDatagrams(e){this.incomingLimit=ie(e),this.policy.setIncomingMaxBufferedDatagrams(this.incomingLimit);}get outgoingMaxBufferedDatagrams(){return this.outgoingLimit}set outgoingMaxBufferedDatagrams(e){this.outgoingLimit=ie(e),this.policy.setOutgoingMaxBufferedDatagrams(this.outgoingLimit),this.wake(this.outgoingWaiters);}getStats(){return this.policy.getStats(Date.now())}get policy(){if(!this.policyInstance){let e=this.runtime.createPeerDatagramPolicy;if(!e)throw new Error("[OpenRTC] Shared protected-datagram policy is unavailable in this runtime.");this.policyInstance=e();}return this.policyInstance}close(){this.closed||(this.closed=true,this.closeIncoming(),this.outgoingClosed=true,this.policyInstance?.closeOutgoing(),this.wake(this.outgoingWaiters),this.wake(this.outgoingAvailable));}async pullIncoming(e){for(this.receiveLoopStarted||(this.receiveLoopStarted=true,this.pumpIncoming());;){let t=this.policy.popIncoming(Date.now());if(t){e.enqueue(new Uint8Array(t));return}if(this.incomingError){e.error(this.incomingError);return}if(this.incomingClosed){e.close();return}await new Promise(i=>this.incomingWaiters.add(i));}}async pumpIncoming(){let e=this.runtime.receivePeerDatagram;if(!e){this.incomingError=new Error("[OpenRTC] Protected peer datagrams are unavailable in this runtime."),this.wake(this.incomingWaiters);return}try{for(;!this.incomingClosed;){let t=new Uint8Array(await e(this.peerId));if(this.incomingClosed)return;this.policy.pushIncoming(t,Date.now()),this.wake(this.incomingWaiters);}}catch(t){this.incomingClosed||(this.incomingError=t,this.wake(this.incomingWaiters));}}async enqueueOutgoing(e){if(this.closed||this.outgoingClosed)throw new Error("[OpenRTC] peer datagram stream is closed.");if(!(e instanceof Uint8Array)||e.byteLength>this.maxDatagramSize)throw new Error(`[OpenRTC] peer datagrams must be Uint8Array values up to ${this.maxDatagramSize} bytes.`);for(;!this.policy.pushOutgoing(e,Date.now())&&!this.closed;)await new Promise(t=>this.outgoingWaiters.add(t));if(this.closed||this.outgoingClosed)throw new Error("[OpenRTC] peer datagram stream is closed.");this.startSendLoop(),this.wake(this.outgoingAvailable);}startSendLoop(){this.sendLoop||this.closed||(this.sendLoop=this.pumpOutgoing());}async pumpOutgoing(){let e=this.runtime.sendPeerDatagram;if(!e){this.policy.closeOutgoing();return}for(;!this.closed;){let t=this.policy.popOutgoing(Date.now());if(!t){if(this.wake(this.outgoingWaiters),this.outgoingClosed)return;await new Promise(n=>this.outgoingAvailable.add(n));continue}this.wake(this.outgoingWaiters);let i=new Uint8Array(t.payload);try{await e(this.peerId,i,t.remainingMaxAgeMs??void 0)===!1?this.policy.recordExpiredOutgoing():this.policy.recordSent(i.byteLength);}catch{this.policy.recordSendFailure();}this.wake(this.outgoingWaiters);}}closeIncoming(){this.incomingClosed||(this.incomingClosed=true,this.policyInstance?.closeIncoming(),this.wake(this.incomingWaiters));}wake(e){for(let t of e)t();e.clear();}},S=class{constructor(){this.controller=null;this.closed=false;this.readable=new ReadableStream({start:e=>{this.controller=e;},cancel:()=>{this.closed=true,this.controller=null;}},{highWaterMark:de});}enqueue(e){return this.closed||!this.controller||(this.controller.desiredSize??0)<=0?false:(this.controller.enqueue(e),true)}close(){this.closed||(this.closed=true,this.controller?.close(),this.controller=null);}},F=class{constructor(e,t,i,n){this.client=e;this.peerId=t;this.capabilityKey=n;this.incomingBi=new S;this.incomingUni=new S;this.incomingBidirectionalStreams=this.incomingBi.readable;this.incomingUnidirectionalStreams=this.incomingUni.readable;this.closed=false;this.protocolHandlers=new Map;this.datagrams=new _(i,this.peerId);}async createBidirectionalStream(e){let t=R(e.protocol),i=await this.client.channels.openBi(this.peerId,b,{timeoutMs:e.timeoutMs,channelMetadata:{protocol:t,[a$3]:this.capabilityKey}});return {protocol:t,readable:i.readable,writable:i.writable}}async createUnidirectionalStream(e){let t=R(e.protocol);return (await this.client.channels.openUni(this.peerId,b,{timeoutMs:e.timeoutMs,channelMetadata:{protocol:t,[a$3]:this.capabilityKey}})).writable}accept(e,t){if(e.type==="bi"){let n=e.stream;if(!n.recv||!n.send)return false;let s={peerId:this.peerId,protocol:t,readable:n.recv,writable:n.send},r=this.protocolHandlers.get(t);if(r){try{r(s);}catch{s.readable.cancel("incoming-protocol-handler-failed").catch(()=>{}),s.writable.abort("incoming-protocol-handler-failed").catch(()=>{});}return true}return this.incomingBi.enqueue(s)||(s.readable.cancel("incoming-peer-stream-queue-full").catch(()=>{}),s.writable.abort("incoming-peer-stream-queue-full").catch(()=>{})),true}let i=e.stream;return !i||typeof i.getReader!="function"?false:(this.incomingUni.enqueue({peerId:this.peerId,protocol:t,readable:i})||i.cancel("incoming-peer-stream-queue-full").catch(()=>{}),true)}onProtocol(e,t){let i=R(e);if(this.protocolHandlers.has(i))throw new Error(`[OpenRTC] stream protocol '${i}' already has an owning consumer.`);return this.protocolHandlers.set(i,t),()=>{this.protocolHandlers.get(i)===t&&this.protocolHandlers.delete(i);}}close(){this.closed=true,this.datagrams.close(),this.protocolHandlers.clear(),this.incomingBi.close(),this.incomingUni.close();}},A=class{constructor(e,t){this.client=e;this.capabilityKey=t;this.peers=new Map;this.peerIdsByConnection=new Map;this.registered=false;this.observed=0;this.accepted=0;this.declined=0;this.lastResolution="none";try{e.channels.register({id:b,kind:"application-stream",ownership:"shared",peerModel:"device-first",routing:"stream-envelope",readiness:"settled-peer",promotionPolicy:"never",signalingPolicy:"hosted",delivery:"reliable",description:"Transport-agnostic protected peer streams"}),this.stopIncoming=e.channels.onIncomingChannel(b,i=>this.accept(i)),this.registered=!0;}catch{this.stopIncoming=()=>{};}}forPeer(e){let t=this.peers.get(e);return t||(t=new F(this.client,e,this.client.advanced.runtime,this.capabilityKey),this.peers.set(e,t)),t}onProtocol(e,t,i){return this.forPeer(e).onProtocol(t,i)}bindConnection(e,t){let i=x(e),n=t.trim();!i||!n||this.peerIdsByConnection.set(i,n);}unbindConnection(e){this.peerIdsByConnection.delete(x(e));}diagnostics(){return {registered:this.registered,peers:this.peers.size,boundConnections:this.peerIdsByConnection.size,observed:this.observed,accepted:this.accepted,declined:this.declined,lastResolution:this.lastResolution}}closePeer(e){let t=this.peers.get(e);if(t){t.close(),this.peers.delete(e);for(let[i,n]of this.peerIdsByConnection)n===e&&this.peerIdsByConnection.delete(i);}}close(){this.stopIncoming();for(let e of this.peers.values())e.close();this.peers.clear(),this.peerIdsByConnection.clear(),this.registered&&this.client.channels.unregister(b);}accept(e){if(this.observed+=1,e.channel?.metadata?.[a$3]!==this.capabilityKey)return this.declined+=1,false;let i=e.channel?.metadata?.protocol;if(typeof i!="string")return this.declined+=1,false;let n;try{n=R(i);}catch{return this.declined+=1,false}let r=this.resolveExistingPeer(e.remoteNodeId,e.connectionId)?.accept(e,n)??false;return r?this.accepted+=1:this.declined+=1,r}resolveExistingPeer(e,t=""){let i=x(t);if(i){let r=this.peerIdsByConnection.get(i);if(!r)return this.lastResolution="unbound-connection",null;let o=this.peers.get(r);return o?(this.lastResolution="connection",o):(this.lastResolution="unbound-connection",null)}let n=this.peers.get(e);if(n)return this.lastResolution="remote-peer",n;let s=this.client.peers.get(e)??this.client.peers.listConnected().find(r=>[r.peerId,r.deviceId,r.deviceIdHint,r.connectionId,...r.connectionIds].some(o=>o===e));if(s){let r=new Set([s.peerId,s.deviceId,s.deviceIdHint,s.connectionId,...s.connectionIds].filter(c=>typeof c=="string"&&c.length>0)),o=[...this.peers.entries()].filter(([c])=>r.has(c)).map(([,c])=>c);if(o.length===1)return this.lastResolution="peer-alias",o[0]}return this.lastResolution="none",null}};var w=new WeakMap;function pe(a){let e=w.get(a);if(!e||a.closed)throw new Error("[OpenRTC] Capability runtime is unavailable or already closed.");return e}function Be(a,e){if(w.has(a))throw new Error("[OpenRTC] Capability runtime is already registered.");return w.set(a,pe(e)),()=>{w.delete(a);}}function me(a){let e=a?.trim()??"";if(!/^pk_(?:live|test)_[0-9a-f]{40}$/.test(e))throw new Error("[OpenRTC] apiKey must be a public pk_live_ or pk_test_ key.");return e}function f(a){let e=a?.trim()??"";if(!e||e.length>160||!/^[A-Za-z0-9_.:@-]+$/.test(e))throw new Error("[OpenRTC] Capability id is invalid.");return e}var q=/^[A-Za-z0-9_.:@-]{1,160}$/,ve=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,ne=2,G=8,ge=G;function ye(a){let e=typeof a=="string"?a.trim():"";if(!q.test(e))return null;let t=e.startsWith("device_")?e.slice(7):"";return ve.test(t)?t:e}function fe(a){let e=`openrtc:v2:device-id:${a}`,t,i=(()=>{try{return t=globalThis.localStorage,ye(t?.getItem(e))||crypto.randomUUID()}catch{return crypto.randomUUID()}})();try{t?.setItem(e,i);}catch{}return i}function re(a){let e=typeof a=="string"?a.trim():"";if(!q.test(e))throw new Error("[OpenRTC] The native host returned an invalid durable device ID.");return e}var se=250;function oe(a){if(a===void 0)return [];if(!Array.isArray(a))throw new Error("[OpenRTC] autoConnectExcludedDeviceIds must be an array.");let e=[...new Set(a.map(t=>{let i=typeof t=="string"?t.trim().toLowerCase():"";if(!q.test(i))throw new Error("[OpenRTC] autoConnectExcludedDeviceIds contains an invalid device ID.");return i}))].sort();if(e.length>se)throw new Error(`[OpenRTC] autoConnectExcludedDeviceIds supports at most ${se} devices.`);return e}function N(a){let e=b$1(a.token),t=typeof e.deviceKeyThumbprint=="string"?e.deviceKeyThumbprint.trim():"";if(!/^[A-Za-z0-9_-]{43}$/.test(t))throw new Error("[OpenRTC] Anonymous capability is missing its device-key binding.");return `anon_${t.slice(0,32)}`}var U=class{constructor(){this.descriptors=new Map;this.targets=new Map;}register(e){if(!e?.id?.trim())throw new Error("[OpenRTC] Channel id is required.");this.descriptors.set(e.id,{...e});for(let[t,i]of this.targets)t.channels.register({...e,delivery:e.delivery??i});return ()=>{this.descriptors.delete(e.id);for(let t of this.targets.keys())t.channels.unregister(e.id);}}list(){return [...this.descriptors.values()].map(e=>({...e}))}attach(e,t){this.targets.set(e,t);for(let i of this.descriptors.values())e.channels.register({...i,delivery:i.delivery??t});}detach(e){this.targets.delete(e);}};function ae(a$1){return d(a.TICKET_MESH_ALREADY_ACTIVE,`[OpenRTC] ticket:${a$1} is already active with different options.`,{retryable:false,plane:"admission"})}function le(a){return a.mesh===true?a.maxPeers??ge:a.maxPeers}function we(a){return JSON.stringify({identity:a.identity??(a.mesh===true?"session":null),maxPeers:le(a)??null,mesh:a.mesh===true,advancedFanout:a.advancedFanout===true})}function ce(a){let e=a?.trim()??"";if(!e||e.length>80||!/^[A-Za-z0-9_.:@-]+$/.test(e))throw new Error("[OpenRTC] Message name is invalid.");return e}var H=class{constructor(e,t,i){this.client=e;this.capabilityKey=t;this.rawConnections=new Map;this.logicalConnections=new Map;this.connectionListeners=new Map;this.rawListeners=new Map;this.closeListeners=new Map;this.channelListeners=new Map;this.stateListeners=new Map;this.remoteState=new Map;this.localState=new Map;this.stateSenders=new Map;this.stateReadyGenerations=new Map;this.mediaConnections=new Map;this.mediaRetirements=new Map;this.pendingRawConnections=new Map;this.connectionIdsByPeer=new Map;this.closed=false;this.cleanupComplete=false;this.closeAttempt=null;this.pendingStops=null;this.peerStreams=new A(e,t),this.stopMessage=e.onMessage((n,s)=>this.receive(n,s)),this.stopConnection=e.onConnection(n=>this.add(n)),this.stopDisconnection=e.onDisconnection(n=>this.remove(n)),e.getConnections().forEach(n=>this.add(n)),this.stopPeerLifecycle=e.peers.watchLifecycle(n=>this.observePeerLifecycle(n)),this.roomFanout=i?.create({client:e,capabilityKey:t,connections:()=>[...this.logicalConnections.values()].flatMap(({activeRaw:n})=>n?[n]:[]),deliver:(n,s,r)=>{let o=B(s);!o||o.capability!==this.capabilityKey||r!==void 0&&o.name!==r||r===void 0&&o.kind!=="channel"||this.deliverEnvelope(n,o);}});}state(e){if(this.assertOpen(),this.roomFanout?.isSparse())throw new Error("[OpenRTC] state() is not available in sparse gossip rooms; use a named channel with application-owned latest-state revisions.");let t=ce(e);return {set:i=>{this.assertOpen();let n=I("state",t,i,this.capabilityKey);if(this.localState.set(t,n),!this.roomFanout?.publishState(t,n))for(let{activeRaw:s}of this.logicalConnections.values())s&&this.sendState(s,t,n);},watch:i=>{this.assertOpen();let n=this.stateListeners.get(t);n||this.stateListeners.set(t,n=new Set);let s=(r,o)=>i({peerId:r,value:o});n.add(s);for(let[r,o]of this.remoteState)o.has(t)&&i({peerId:r,value:o.get(t)});return ()=>n?.delete(s)}}}channel(e){this.assertOpen();let t=ce(e),i=n=>I("channel",t,n,this.capabilityKey);return {send:async n=>{this.assertOpen();let s=i(n);await this.roomFanout?.sendChannel(t,s)||(this.assertOpen(),await Promise.all([...this.logicalConnections.values()].flatMap(({activeRaw:r})=>r?[this.sendPayload(r,s)]:[])));},sendTo:async(n,s)=>{this.assertOpen(),this.roomFanout?.assertTargetedSendAllowed();let r=this.logicalConnections.get(n)?.activeRaw;if(r){await this.sendPayload(r,i(s));return}throw d(a.DELIVERY_NOT_READY,`[OpenRTC] Peer '${n}' has no direct authorized route; sparse broadcasts never multi-hop targeted payloads.`,{retryable:true,plane:"delivery"})},onMessage:n=>{this.assertOpen();let s=this.channelListeners.get(t);s||this.channelListeners.set(t,s=new Set);let r=(o,c)=>n({peerId:o,message:c});return s.add(r),()=>s?.delete(r)}}}async sendPayload(e$1,t){try{await e$1.send(t);}catch(i){throw e(i)}}onConnection(e){this.assertOpen();let t=new Set;this.connectionListeners.set(e,t);for(let[i,n]of this.logicalConnections)n.activeRaw&&(t.add(i),e(n.view));return ()=>this.connectionListeners.delete(e)}assertOpen(){if(this.closed)throw new Error("[OpenRTC] Capability messages are closed.")}fence(){this.closed=true;}close(){if(this.cleanupComplete)return Promise.resolve();if(this.closeAttempt)return this.closeAttempt;this.closed=true;let e=this.releaseMessages();return this.closeAttempt=e,e.then(()=>{this.closeAttempt===e&&(this.closeAttempt=null);},()=>{this.closeAttempt===e&&(this.closeAttempt=null);}),e}async releaseMessages(){let e=[];this.pendingStops??(this.pendingStops=[()=>this.stopMessage(),()=>this.stopConnection(),()=>this.stopDisconnection(),()=>this.stopPeerLifecycle(),()=>this.roomFanout?.close()]),this.pendingStops=this.pendingStops.filter(i=>{try{return i(),!1}catch(n){return e.push(n),true}});let t=[];for(let i of this.logicalConnections.keys())try{t.push(this.retire(i));}catch(n){e.push(n);}this.pendingRawConnections.clear();try{this.peerStreams.close();}catch(i){e.push(i);}this.rawConnections.clear(),this.logicalConnections.clear(),this.connectionListeners.clear(),this.channelListeners.clear(),this.stateListeners.clear(),this.localState.clear(),this.remoteState.clear(),this.stateReadyGenerations.clear(),this.rawListeners.clear(),this.closeListeners.clear();for(let i of await Promise.allSettled(t))i.status==="rejected"&&e.push(i.reason);if(e.length===1)throw e[0];if(e.length)throw d(a.INTERNAL,"[OpenRTC] Capability message cleanup failed.",{cause:e,retryable:true,plane:"internal"});this.cleanupComplete=true;}add(e){if(this.closed)return;let t=this.rawConnections.get(e.id);if(t?.raw===e)return;t&&this.remove(t.raw);let i=e.remoteNodeId||e.id,n=this.mediaRetirements.get(i);if(n){let o={raw:e,peerId:i};this.pendingRawConnections.set(e.id,o),n.finally(()=>{this.closed||this.pendingRawConnections.get(e.id)!==o||(this.pendingRawConnections.delete(e.id),this.add(e));});return}this.rawConnections.set(e.id,{raw:e,peerId:i});let s=this.connectionIdsByPeer.get(i);s||this.connectionIdsByPeer.set(i,s=new Set),s.add(e.id),this.peerStreams.bindConnection(e.id,i);let r=this.logicalConnections.get(i);if(!r){let o=this.peerStreams.forPeer(i),c=new b$3(o,this.client.advanced.runtime,(d,h)=>this.peerStreams.onProtocol(i,d,h),()=>this.peerStreams.diagnostics());this.mediaConnections.set(i,c),r={activeRaw:e,rawIds:new Set,view:{id:i,peerId:i,streams:o,media:c,send:async d$1=>{let h=this.logicalConnections.get(i)?.activeRaw;if(!h)throw d(a.DELIVERY_NOT_READY,`[OpenRTC] Peer '${i}' is not connected.`,{retryable:true,plane:"delivery"});await this.sendPayload(h,I("raw","message",d$1,this.capabilityKey));},onMessage:d=>{let h=this.rawListeners.get(i);h||this.rawListeners.set(i,h=new Set);let v=d;return h.add(v),()=>h?.delete(v)},onClose:d=>{let h=this.closeListeners.get(i);return h||this.closeListeners.set(i,h=new Set),h.add(d),()=>h?.delete(d)}}},this.logicalConnections.set(i,r);}r.rawIds.add(e.id),r.activeRaw=e,this.observePeerLifecycle(this.client.peers.listConnected());for(let[o,c]of this.connectionListeners)c.has(i)||(c.add(i),o(r.view));for(let[o,c]of this.localState)this.sendState(e,o,c);}remove(e){if(this.pendingRawConnections.get(e.id)?.raw===e){this.pendingRawConnections.delete(e.id);return}let t=this.rawConnections.get(e.id);if(!t||t.raw!==e)return;this.rawConnections.delete(e.id),this.peerStreams.unbindConnection(e.id);let i=t.peerId,n=this.logicalConnections.get(i);if(n?.rawIds.delete(e.id),n?.activeRaw?.id===e.id){let o=[...n.rawIds],c=o[o.length-1];n.activeRaw=c?this.rawConnections.get(c)?.raw??null:null;}let s=this.connectionIdsByPeer.get(i);if(s?.delete(e.id),s?.size===0&&this.connectionIdsByPeer.delete(i),!n?.activeRaw){let o=this.remoteState.get(i);if(o){for(let c of o.keys())for(let l of this.stateListeners.get(c)??[])l(i,null);this.remoteState.delete(i);}}let r=this.stateSenders.get(e);if(r){for(let o of r.values())o.close();this.stateSenders.delete(e);}}observePeerLifecycle(e){for(let t of this.logicalConnections.keys()){let i=this.connectionIdsByPeer.get(t)??new Set,n=e.find(l=>l.peerId===t||l.connectionId===t||l.connectionIds.some(d=>i.has(d)));if(!n)continue;let s=n.status==="closed"&&n.logicalSessionTerminal===true&&n.routable!==true&&n.settledReady!==true;if(n.manualDisconnect||s){this.retire(t);continue}if(n.settledReady!==true||n.routable!==true){this.stateReadyGenerations.delete(t);continue}let r=n.transportStableId,o=n.transportGeneration,c=n.routeGeneration;if(Number.isSafeInteger(r)&&Number(r)>0&&Number.isSafeInteger(o)&&Number(o)>0&&Number.isSafeInteger(c)&&Number(c)>=0){let l=JSON.stringify([n.connectionId,n.generation,r,o,c]);if(this.stateReadyGenerations.get(t)!==l){this.stateReadyGenerations.set(t,l);let h=this.logicalConnections.get(t)?.activeRaw;if(h)for(let[v,u]of this.localState)this.sendState(h,v,u);}let d=this.mediaConnections.get(t);d&&d.observePhysicalGeneration({transportStableId:Number(r),transportGeneration:Number(o),routeGeneration:Number(c)}).catch(()=>{});}}}retire(e){let t=this.logicalConnections.get(e);if(!t)return this.mediaRetirements.get(e)??Promise.resolve();this.logicalConnections.delete(e),this.stateReadyGenerations.delete(e);for(let r of t.rawIds){let o=this.rawConnections.get(r)?.raw;if(this.rawConnections.delete(r),this.peerStreams.unbindConnection(r),!o)continue;let c=this.stateSenders.get(o);if(c){for(let l of c.values())l.close();this.stateSenders.delete(o);}}this.connectionIdsByPeer.delete(e);let i=this.remoteState.get(e);if(i){for(let r of i.keys())for(let o of this.stateListeners.get(r)??[])o(e,null);this.remoteState.delete(e);}let n=this.mediaConnections.get(e);this.mediaConnections.delete(e);let s=n?.close().catch(()=>{})??Promise.resolve();this.mediaRetirements.set(e,s),s.finally(()=>{this.mediaRetirements.get(e)===s&&this.mediaRetirements.delete(e);}),this.peerStreams.closePeer(e);for(let r of this.closeListeners.get(e)??[])r();this.closeListeners.delete(e),this.rawListeners.delete(e);for(let r of this.connectionListeners.values())r.delete(e);return s}receive(e,t){if(this.closed)return;this.add(e);let i=this.rawConnections.get(e.id)?.peerId??e.remoteNodeId??e.id;if(this.roomFanout?.receive(e,i,t))return;let n=B(t);if(!n){for(let s of this.rawListeners.get(i)??[])s(t);return}if(n.capability===this.capabilityKey){if(n.kind==="raw"){for(let s of this.rawListeners.get(i)??[])s(n.value);return}this.deliverEnvelope(i,n);}}deliverEnvelope(e,t){if(this.closed)return;if(t.kind==="raw"){for(let n of this.rawListeners.get(e)??[])n(t.value);return}if(t.kind==="channel"){for(let n of this.channelListeners.get(t.name)??[])n(e,t.value);return}let i=this.remoteState.get(e);i||this.remoteState.set(e,i=new Map),i.set(t.name,t.value);for(let n of this.stateListeners.get(t.name)??[])n(e,t.value);}sendState(e,t,i){let n=this.stateSenders.get(e);n||this.stateSenders.set(e,n=new Map);let s=n.get(t);s||(s=new a$1(r=>e.send(r)),n.set(t,s)),s.send(i).catch(()=>{});}},T=class{constructor(e,t,i,n,s){this.kind=e;this.id=t;this.client=i;this.onClosed=n;this.roomFanoutFactory=s;this.closed=false;this.retired=false;this.shutdownAttempt=null;w.set(this,i);}get peers(){return this.client.peers}get channels(){return this.client.channels}get diagnostics(){return this.client.diagnostics}state(e){return this.capabilityMessages().state(e)}channel(e){return this.capabilityMessages().channel(e)}onConnection(e){return this.capabilityMessages().onConnection(e)}projectRuntime(e){w.set(this,e);}setArchitecture(e){this.roomFanoutFactory?.setArchitecture(e);}close(){if(this.retired)return Promise.resolve();if(this.shutdownAttempt)return this.shutdownAttempt;this.fenceProductAccess();let e=this.releaseCapability();return this.shutdownAttempt=e,e.then(()=>{this.shutdownAttempt===e&&(this.shutdownAttempt=null);},()=>{this.shutdownAttempt===e&&(this.shutdownAttempt=null);}),e}beforeRuntimeShutdown(){}fenceProductAccess(){this.closed=true,this.messages?.fence();}async releaseCapability(){let e=[];try{this.beforeRuntimeShutdown();}catch(t){e.push(t);}try{await this.messages?.close();}catch(t){e.push(t);}try{await this.client.advanced.runtime.shutdown();}catch(t){e.push(t);}if(e.length===1)throw e[0];if(e.length)throw d(a.INTERNAL,"[OpenRTC] Capability cleanup failed.",{cause:e,retryable:true,plane:"internal"});this.onClosed(),w.delete(this),this.retired=true;}capabilityMessages(){if(this.closed)throw new Error("[OpenRTC] Capability is closed.");return this.messages??(this.messages=new H(this.client,b$2(this.kind,this.id).key,this.roomFanoutFactory))}},K=class extends T{constructor(t,i,n,s){super("space",t,i,n);this.delivery=s;this.kind="space";this.leave=()=>this.close();}},O=class extends T{constructor(t,i,n,s,r,o){super("ticket",t,i,n);this.token=s;this.ownsMesh=o;this.kind="ticket";this.closing=null;this.inviteListeners=new Set;this.stopInviteWatch=()=>{};this.meshStopped=false;if(this.currentInvite=r,o){let c=i.advanced.runtime;this.stopInviteWatch=c.watchTicketMeshInvite?.(t,l=>{this.closed||(this.currentInvite=l,this.inviteListeners.forEach(d=>d(l)));})??this.stopInviteWatch;}}get invite(){return this.closed?null:this.currentInvite}watchInvite(t){return this.closed?(t(null),()=>{}):(this.inviteListeners.add(t),t(this.currentInvite),()=>this.inviteListeners.delete(t))}async issuerNode(){if(this.closed)throw new Error("[OpenRTC] Capability is closed.");if(!this.ownsMesh)throw new Error("[OpenRTC] This ticket is not a mesh.");return this.client.advanced.runtime.ticketMeshIssuerNode(this.id)}get peers(){if(this.scopedPeers)return this.scopedPeers;let t=this.client.peers,i=`ticket:${this.id}`,n=r=>!this.closed&&r.scopes.includes(i)&&r.status==="connected"&&r.settledReady===true&&r.routable!==false&&r.logicalSessionTerminal!==true&&(!this.ownsMesh||this.client.advanced.runtime.isTicketMeshPeerReady(this.id,r)),s=(r,o)=>{let c=[],l=this.ownsMesh?this.client.advanced.runtime.watchTicketMeshPeers(this.id,()=>o(c.filter(n))):()=>{},d=t[r](h=>{c=h,o(h.filter(n));});return ()=>{d(),l();}};return this.scopedPeers={...t,watch:r=>s("watch",r),watchLifecycle:r=>s("watchLifecycle",r),get:r=>{let o=t.get(r);return o&&n(o)?o:void 0},listConnected:()=>t.listConnected().filter(n)}}get diagnostics(){if(this.scopedDiagnostics)return this.scopedDiagnostics;let t=this.client.diagnostics,i=`ticket:${this.id}`;return this.scopedDiagnostics={...t,capture:n=>c(s=>this.client.advanced.runtime.watchPeerStates(r=>s(this.closed?[]:r.filter(o=>o.scopes.includes(i)))),n),watchConnectionMetrics:n=>t.watchConnectionMetrics(s=>{n(this.closed?[]:s.filter(r=>r.scopes?.includes(i)));})}}close(){if(this.retired)return Promise.resolve();if(this.closing)return this.closing;this.fenceProductAccess();let t=this.closeOnce();return this.closing=t,t.catch(()=>{!this.retired&&this.closing===t&&(this.closing=null);}),t}async closeOnce(){this.ownsMesh&&!this.meshStopped&&(await this.client.advanced.runtime.closeTicketMesh(this.id),this.meshStopped=true),await super.close();}beforeRuntimeShutdown(){try{this.stopInviteWatch(),this.stopInviteWatch=()=>{};}finally{this.inviteListeners.clear();}}},D=class D{constructor(e,t){this.options=e;this.internals=t;this.diagnosticClientRef=++D.nextDiagnosticClient;this.nextDiagnosticOperation=0;this.channels=new U;this.broadcastSessions=new Set;this.broadcastPublishers=new Set;this.handles=new Set;this.activations=new Map;this.pendingCapabilityShutdowns=new Map;this.authorityCallableIds=new WeakMap;this.nextAuthorityCallableId=1;this.closed=false;this.closing=null;this.offline={support:async()=>(this.assertOpen(),this.internals.offlineSupport?.()??{provisioning:false,localMesh:false,cloudRequired:false,reason:"Browser-only OpenRTC cannot host the native LAN/Iroh offline runtime."}),createEnrollmentRequest:async e=>{if(this.assertOpen(),!this.internals.createOfflineEnrollmentRequest)throw new Error("[OpenRTC] Offline enrollment request signing requires a native Rust host.");return this.internals.createOfflineEnrollmentRequest({trustDomain:e.trustDomain,deviceId:await this.deviceId(),requestedRoles:e.requestedRoles})}};this.devices={localId:()=>(this.assertOpen(),this.deviceId()),start:(e={})=>{let t=e.auth??this.options.auth;return this.activateOnce("devices",JSON.stringify({autoConnect:e.autoConnect??"online",autoConnectExcludedDeviceIds:oe(e.autoConnectExcludedDeviceIds),maxPeers:e.maxPeers??null,advancedFanout:e.advancedFanout===true,profile:e.profile??null}),t,()=>this.startDevices(e))},listEnrolled:async(e={})=>{this.assertOpen();let t=e.auth??this.options.auth;if(!t)throw new Error("[OpenRTC] devices.listEnrolled() requires an auth provider.");let i=await(await this.controlPlane()).listEnrolledDevices(t,await this.deviceId()),{DeviceHandle:n}=await import('./deviceHandle-Y3SYSCJ6.js');for(let s of this.handles)s instanceof n&&s.replaceEnrolledDevices(i);return i},revoke:async(e,t={})=>{this.assertOpen();let i=t.auth??this.options.auth;if(!i)throw new Error("[OpenRTC] devices.revoke() requires an auth provider.");let n=re(e),s=await this.deviceId();await(await this.controlPlane()).revokeDevice(i,s,n);let{DeviceHandle:r}=await import('./deviceHandle-Y3SYSCJ6.js');for(let o of this.handles)o instanceof r&&o.removeEnrolledDevice(n);n===s&&this.retireAuthCapabilities(i);},revokeAll:async(e={})=>{this.assertOpen();let t=e.auth??this.options.auth;if(!t)throw new Error("[OpenRTC] devices.revokeAll() requires an auth provider.");if(await(await this.controlPlane()).revokeAllDevices(t,await this.deviceId(),e.exceptCurrent===true),e.exceptCurrent===true){let i=await this.deviceId(),{DeviceHandle:n}=await import('./deviceHandle-Y3SYSCJ6.js');for(let s of this.handles)s instanceof n&&s.retainCurrentEnrolledDevice(i);}e.exceptCurrent!==true&&this.retireAuthCapabilities(t);}};this.spaces={join:(e,t={})=>this.activateOnce(`space:${f(e)}`,JSON.stringify({payload:t.payload??"reliable",identity:t.identity??null,maxPeers:t.maxPeers??null,advancedFanout:t.advancedFanout===true}),void 0,()=>this.joinSpace(e,t))};this.rooms={join:async(e,t={})=>(await import('./room-QHKIFLR7.js')).joinRoom(this,e,t)};this.tickets={issue:(e,t={})=>this.activateOnce(`ticket:${f(e)}`,we(t),void 0,()=>this.issueTicket(e,t),t.mesh===true?()=>ae(f(e)):void 0),join:e=>{let t=b$4(e);return t.mesh?this.activateOnce(`ticket:${f(t.id)}`,`join:${e}`,void 0,()=>this.joinTicket(e),()=>ae(f(t.id))):Promise.reject(d(a.TICKET_INVITE_INVALID,"[OpenRTC] This invitation does not describe a ticket mesh.",{retryable:false,plane:"admission"}))}};this.broadcasts={create:async e=>{this.assertOpen();let t=await this.broadcastHost();if(!t?.create)throw new Error("[OpenRTC] Managed broadcast creation is unavailable.");return t.create(e)},open:async e=>{this.assertOpen(),this.validateBroadcastGrant(e);let t=await this.broadcastHost();if(!t)throw new Error("[OpenRTC] Broadcast hosting is unavailable in this runtime.");return this.wrapBroadcastSession(await t.open(e))},subscribe:async e=>{this.assertOpen(),this.validateBroadcastGrant(e);let t=await this.broadcastHost();if(!t)throw new Error("[OpenRTC] Broadcast viewing is unavailable.");return this.wrapBroadcastSession(await t.open(e))},preparePublisher:async()=>{this.assertOpen();let e=await this.broadcastHost();if(!e?.preparePublisher)throw new Error("[OpenRTC] Broadcast publishing is unavailable in this runtime.");let t=await e.preparePublisher(),i=t.verificationKey.slice();if(i.byteLength!==32)throw await t.close(),new Error("[OpenRTC] Broadcast publisher key is invalid.");let n=false,s={verificationKey:i,open:async r=>{if(n)throw new Error("[OpenRTC] Broadcast publisher is closed.");return this.assertOpen(),this.validateBroadcastGrant(r),this.wrapBroadcastSession(await t.open(r))},close:async()=>{n||(n=true,await t.close(),this.broadcastPublishers.delete(s));}};return this.broadcastPublishers.add(s),s},renew:async(e,t={})=>{this.validateBroadcastGrant(e);let i=await this.broadcastHost();if(!i?.renew)throw new Error("[OpenRTC] Broadcast renewal is unavailable.");return i.renew(e,t.auth)},invite:async(e,t)=>{this.validateBroadcastGrant(e);let i=await this.broadcastHost();if(!i?.invite)throw new Error("[OpenRTC] Broadcast invitations are unavailable.");let{auth:n,...s}=t;return i.invite(e,s,n)},accept:async(e,t={})=>{if(!/^obi1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(e))throw new Error("[OpenRTC] Broadcast invitation is invalid.");let i=await this.broadcastHost();if(!i?.accept)throw new Error("[OpenRTC] Broadcast invitation acceptance is unavailable.");return i.accept(e,t.auth)},revoke:async(e,t)=>{if(this.validateBroadcastGrant(e),!/^obi1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(t.invite))throw new Error("[OpenRTC] Broadcast invitation is invalid.");let i=await this.broadcastHost();if(!i?.revoke)throw new Error("[OpenRTC] Broadcast revocation is unavailable.");await i.revoke(e,t.invite,t.auth);},leave:async(e,t={})=>{this.validateBroadcastGrant(e);let i=await this.broadcastHost();if(!i?.leave)throw new Error("[OpenRTC] Broadcast leave is unavailable.");await i.leave(e,t.auth);},close:async(e,t={})=>{this.validateBroadcastGrant(e);let i=await this.broadcastHost();if(!i?.closeGrant)throw new Error("[OpenRTC] Broadcast close is unavailable.");await i.closeGrant(e,t.auth);}};this.onClosed=e=>{this.handles.delete(e);for(let[t,i]of this.activations)i.handle===e&&this.activations.delete(t);};this.apiKey=me(e.apiKey);let i=e.trust?.browserPersistence??"session";if(i!=="session"&&i!=="persistent")throw new Error("[OpenRTC] Invalid browser identity persistence policy.");this.browserPersistence=i,this.appTag=`app_${this.apiKey.slice(-16)}`;}validateBroadcastGrant(e){if(typeof e!="string"||e.length<16||e.length>32768)throw new Error("[OpenRTC] Broadcast grant is invalid.")}broadcastHost(){return this.internals.broadcastHost?Promise.resolve(this.internals.broadcastHost):this.internals.broadcastHostFactory?this.broadcastHostPromise??(this.broadcastHostPromise=this.controlPlane().then(e=>this.internals.broadcastHostFactory({apiKey:this.apiKey,resolve:(t,i)=>e.resolveBroadcastAccess(t,i),manage:e.manageBroadcast.bind(e),deviceId:()=>this.deviceId(),defaultAuth:this.options.auth}))):Promise.resolve(void 0)}wrapBroadcastSession(e){let t=false,i={get id(){return e.id},get role(){return e.role},get state(){return e.state},media:e.media,getStats:()=>e.getStats(),close:async()=>{t||(t=true,this.broadcastSessions.delete(i),await e.close());}};return this.broadcastSessions.add(i),i}makeControlPlane(e){return Promise.all([import('./controlPlane-45AU3CSM.js'),e]).then(([{ControlPlane:t},i])=>new t(this.apiKey,this.internals.endpoints??a$2,i,this.options.trust?.attestation,{onAuthEpochChanged:n=>this.retireAuthCapabilities(n)},this.options.trust?.botVerification))}controlPlane(){return this.controlPlanePromise??(this.controlPlanePromise=this.makeControlPlane(this.internals.deviceKeyProvider?Promise.resolve(this.internals.deviceKeyProvider):import('./deviceKey-2NTRYCSR.js').then(({browserDeviceKeyProvider:e,createSessionDeviceKeyProvider:t})=>this.internals.platform!=="native"&&this.browserPersistence!=="persistent"?t():e)))}sessionPlane(){return this.sessionPlanePromise??(this.sessionPlanePromise=this.makeControlPlane(import('./deviceKey-2NTRYCSR.js').then(({createSessionDeviceKeyProvider:e})=>e())))}assertOpen(){if(this.closed)throw new Error("[OpenRTC] Client is closed.");if(this.closing)throw new Error("[OpenRTC] Client is closing.")}activateOnce(e,t,i,n,s){this.assertOpen();let r=this.activations.get(e);if(r){if(r.handle?.closed)throw new Error(`[OpenRTC] ${e} is closing; retry close() to finish retirement.`);if(r.fingerprint!==t||r.auth!==i)throw s?s():new Error(`[OpenRTC] ${e} is already active with different options.`);return r.promise}let o={fingerprint:t,auth:i},c=this.options.diagnostics?.logger,l=c?performance.now():0,d=c?++this.nextDiagnosticOperation:0,h=e.split(":",1)[0],v=["devices","space","room","ticket"].includes(h)?h:"custom",u=y=>{c&&b$6(c,Object.freeze({sdkVersion:a$4,clientRef:this.diagnosticClientRef,name:"capability.activation",operationRef:d,avenue:v,outcome:y,timestampMs:Date.now(),elapsedMs:performance.now()-l}));},g;try{g=this.pendingCapabilityShutdowns.has(e)?this.settlePendingCapabilityShutdown(e).then(n):n();}catch(y){throw u("started"),u("failed"),y}let z=g.then(y=>(o.handle=y,u("succeeded"),y)).catch(y=>{throw u("failed"),this.activations.get(e)===o&&this.activations.delete(e),y});return o.promise=z,this.activations.set(e,o),u("started"),z}retainPendingCapabilityShutdown(e,t){this.pendingCapabilityShutdowns.has(e)||this.pendingCapabilityShutdowns.set(e,t);}async settlePendingCapabilityShutdown(e){let t=this.pendingCapabilityShutdowns.get(e);t&&(await t(),this.pendingCapabilityShutdowns.get(e)===t&&this.pendingCapabilityShutdowns.delete(e));}authorityCallableId(e){let t=this.authorityCallableIds.get(e);if(t)return t;let i=this.nextAuthorityCallableId++;return this.authorityCallableIds.set(e,i),i}retireAuthCapabilities(e){for(let t of this.activations.values())t.auth===e&&t.promise.then(i=>i.close()).catch(()=>{});}async deviceId(){let e=this.internals.deviceIdProvider?await this.internals.deviceIdProvider(this.appTag):this.internals.platform!=="native"&&this.browserPersistence==="session"?this.sessionDeviceId??(this.sessionDeviceId=crypto.randomUUID()):fe(this.appTag);return re(e)}runtimeOptions(e){let t=this.options.transports,i=e.irohRelay&&t?.relay!==false,n=e.managedTurn&&t?.relay!==false,s=t?.privacy==="relay-only";if(s&&!i)throw new Error("[OpenRTC] transports.privacy: relay-only requires relay access.");let r=s?d$1(t?.priority?[...t.priority]:void 0,true):t?.priority?[...t.priority]:void 0,o=t?.webrtc,c=typeof o=="object"&&o.iceServers?.some(b$5)===true,l=!s||n||c;return {apiKey:this.apiKey,authMode:"external",discoveryMode:e.avenue?.kind==="user"?"user-scoped":"space",space:e.avenue?.id,localDeviceId:e.deviceId,deviceIdPersistence:"persistent",endpointIdPersistence:this.internals.platform==="native"?"persistent":"ephemeral",deviceName:e.deviceName?.trim()||void 0,coordinationPlatformType:e.devicePlatform?.trim()||void 0,initialAutoConnectExcludedDeviceIds:e.initialAutoConnectExcludedDeviceIds,nativeIdentityProvider:this.internals.platform==="native"&&e.nativeAuth?{providerId:e.nativeAuth.providerId,getSessionKey:async()=>e.nativeAuth.getSessionKey?.()??null,getAssertion:d=>e.nativeAuth.getAssertion(d)}:void 0,coordinationAvenueOverride:e.avenue,coordinationRoomGossipFanout:e.roomGossipFanout===true,coordinationRoomArchitecture:e.roomArchitecture,coordinationDevicePublicKeyX:e.devicePublicKeyX,coordinationDeviceSign:e.deviceSign,coordinationGateway:{endpoint:(this.internals.endpoints??a$2).gateway,environment:"production",grantProvider:e.grantProvider,onServiceError:this.options.onServiceError,testingAllowInsecureLoopback:this.internals.testingAllowInsecureLoopback},turnCredentialsProvider:n?e.turnProvider:void 0,transports:{relay:i,iroh:s?{relayOnly:true,relayTransportPolicy:"websocketRequired",localDiscovery:false,persistenceMode:this.internals.platform==="native"?"persistent":"ephemeral",...this.internals.irohTestRelayUrl?{testRelayUrl:this.internals.irohTestRelayUrl}:{}}:this.internals.irohTestRelayUrl?{testRelayUrl:this.internals.irohTestRelayUrl,persistenceMode:this.internals.platform==="native"?"persistent":"ephemeral"}:t?.iroh??true,webrtc:l?typeof o=="object"?s?{...o,privacyMode:true,useTurn:true,useDefaultIceServers:false}:o:o===true?s?{privacyMode:true,useTurn:true,useDefaultIceServers:false}:true:false:false,ble:t?.ble??false,moq:i?t?.moq??false:false,privacy:t?.privacy??"direct",optimizeFor:t?.optimizeFor??"balanced",priority:r},transportPriority:r}}async activate(e){let t=e.authority?null:e.controlPlane??await this.controlPlane(),i=this.options.transports?.relay!==false,n=e.source.irohRelay&&i,s=e.source.managedTurn&&i,r={irohRelay:n,managedTurn:s,moq:n&&!!this.options.transports?.moq,ble:this.options.transports?.ble===true,advancedFanout:e.architecture==="sparse"||e.advancedFanout===true,durableMembership:e.durableMembership===true},o=e.source,c=null,l=()=>e.authority?{userId:e.principalId}:{userId:e.principalId,token:o.token,tokenProvider:async()=>o.token,expiresAtMs:o.expiresAtMs},d=e.authority?.devicePublicKeyX??String((await t.deviceSigningPublicKey()).x??""),h=this.runtimeOptions({avenue:e.source.avenue,grantProvider:e.authority?.grantProvider??t.grantProvider(e.source,{maxPeers:e.maxPeers,features:r,architecture:e.architecture,roomDelivery:e.kind==="room"?e.defaultDelivery:void 0,deviceProfile:e.deviceName&&e.devicePlatform?{name:e.deviceName,platform:e.devicePlatform}:void 0,onSourceRenewed:async g=>{o={...o,...g},await c?.setAuth(l());}}),deviceId:e.deviceId,userId:e.principalId,roomGossipFanout:(e.kind==="room"||e.kind==="space")&&(e.architecture==="sparse"||e.advancedFanout===true),roomArchitecture:e.kind==="room"?e.architecture:void 0,devicePublicKeyX:d,deviceSign:e.authority?.deviceSign??(g=>t.signDeviceBytes(g)),irohRelay:e.source.irohRelay,managedTurn:e.source.managedTurn,turnProvider:s&&t?t.turnProvider(()=>o):void 0,deviceName:e.deviceName,devicePlatform:e.devicePlatform,initialAutoConnectExcludedDeviceIds:e.initialAutoConnectExcludedDeviceIds,nativeAuth:e.nativeAuth}),[v,{wrapAssembly:u}]=await Promise.all([this.internals.runtimeFactory(h),import('./coreClient.js')]);c=u(v,this.internals.platform==="native"?"native":"web"),await c.setAuth(l()),this.channels.attach(c,e.defaultDelivery??"reliable");try{await c.devices.startSession({browserTrustPersistence:this.browserPersistence,sessionKind:e.kind==="devices"?"app-user-device":"scoped-guest",scope:`v2:${e.kind}:${e.id}`,userId:e.principalId,localDeviceId:e.deviceId,metadata:e.deviceMetadata,autoConnectPolicy:e.autoConnect?"enabled":"disabled",presencePolicy:"online"});}catch(g){throw this.channels.detach(c),await c.advanced.runtime.shutdown().catch(()=>{}),g}return c}trackHandle(e){return this.handles.add(e),e}async startDevices(e={}){this.assertOpen();let t=oe(e.autoConnectExcludedDeviceIds),i=e.auth??this.options.auth;if(!i)throw new Error("[OpenRTC] devices.start() requires an auth provider.");let n=await this.deviceId(),{resolveDeviceProfile:s}=await import('./deviceProfile-CR2C7OYR.js'),r=s(e.profile,this.internals.platform==="native"?"native":"web"),o=await this.controlPlane(),c=await o.deviceCertificate(i,n,void 0,r),l=await this.activate({kind:"devices",id:c.principalId,source:c.source,principalId:c.principalId,deviceId:n,maxPeers:e.maxPeers,autoConnect:e.autoConnect!=="none",initialAutoConnectExcludedDeviceIds:t,advancedFanout:e.advancedFanout,deviceName:r.name,devicePlatform:r.platform,deviceMetadata:r.metadata,nativeAuth:i}),d=[];if(this.internals.platform!=="native")try{d=await o.listEnrolledDevices(i,n);}catch(g){throw this.channels.detach(l),await l.advanced.runtime.shutdown().catch(()=>{}),g}let{AuthenticatedDeviceRoster:h}=await import('./deviceRoster-EUF6BBF5.js'),{DeviceHandle:v}=await import('./deviceHandle-Y3SYSCJ6.js'),u;return u=new v(c.principalId,l,()=>{this.channels.detach(l),this.onClosed(u);},new h(d)),this.handles.add(u),u}async joinSpace(e,t={}){this.assertOpen();let i=f(e),n=await(t.identity==="session"?this.sessionPlane():this.controlPlane()),s=await n.capability("space",i,t.maxPeers,t.advancedFanout),r=String(b$1(s.token).principalId),o=await this.activate({kind:"space",id:i,source:s,principalId:r,deviceId:N(s),maxPeers:t.maxPeers,autoConnect:true,defaultDelivery:t.payload??"reliable",advancedFanout:t.advancedFanout,controlPlane:n}),c;return c=new K(i,o,()=>{this.channels.detach(o),this.onClosed(c);},t.payload??"reliable"),this.handles.add(c),c}async openAuthorityRoom(e){return (await import('./room-QHKIFLR7.js')).openAuthorityRoom(this,e)}async issueTicket(e,t={}){this.assertOpen();let i=f(e);if(t.mesh===true&&t.advancedFanout===true)throw d(a.TICKET_MESH_INVALID_OPTIONS,"[OpenRTC] Ticket mesh cannot use advancedFanout.",{retryable:false,plane:"admission"});let n=le(t);if(t.mesh===true&&(!Number.isSafeInteger(n)||n<ne||n>G))throw d(a.TICKET_MESH_INVALID_OPTIONS,`[OpenRTC] Ticket mesh maxPeers must be an integer between ${ne} and ${G}.`,{retryable:false,plane:"admission"});let s=await(t.identity==="session"||t.mesh===true?this.sessionPlane():this.controlPlane()),r=await s.capability("ticket",i,n,t.advancedFanout),o=String(b$1(r.token).principalId),c=await this.activate({kind:"ticket",id:i,source:r,principalId:o,deviceId:N(r),maxPeers:n,autoConnect:false,advancedFanout:t.advancedFanout,controlPlane:s}),l=null;if(t.mesh===true)try{l=await c.advanced.runtime.issueTicketMesh(i,n);}catch(h){await this.shutdownFailedTicketActivation(i,c,h);}let d$1;return d$1=new O(i,c,()=>{this.channels.detach(c),this.onClosed(d$1);},r.token,l,t.mesh===true),this.handles.add(d$1),d$1}async joinTicket(e){this.assertOpen();let t=b$4(e);if(!t.mesh)throw d(a.TICKET_INVITE_INVALID,"[OpenRTC] This invitation does not describe a ticket mesh.",{retryable:false,plane:"admission"});let i=f(t.id),n=await this.sessionPlane(),s=await n.capability("ticket",i,t.maxPeers,false),r=String(b$1(s.token).principalId),o=await this.activate({kind:"ticket",id:i,source:s,principalId:r,deviceId:N(s),maxPeers:t.maxPeers,autoConnect:false,advancedFanout:false,controlPlane:n});try{await o.advanced.runtime.joinTicketMesh(e);}catch(l){await this.shutdownFailedTicketActivation(i,o,l);}let c;return c=new O(i,o,()=>{this.channels.detach(o),this.onClosed(c);},s.token,e,true),this.handles.add(c),c}async shutdownFailedTicketActivation(e,t,i){this.channels.detach(t);try{await t.advanced.runtime.shutdown();}catch(n){throw this.retainPendingCapabilityShutdown(`ticket:${e}`,()=>t.advanced.runtime.shutdown()),d(a.TICKET_MESH_UNAVAILABLE,"[OpenRTC] Ticket mesh startup failed and runtime teardown was not confirmed.",{retryable:true,plane:"coordination",cause:{startError:i,shutdownError:n}})}throw i}async close(){if(this.closed)return;if(this.closing)return this.closing;let e=this.closeOnce();this.closing=e;try{await e;}finally{this.closing===e&&(this.closing=null);}}async closeOnce(){await Promise.allSettled([...this.activations.values()].map(({promise:e})=>e)),await Promise.all([...this.handles].map(e=>e.close())),await Promise.all([...this.pendingCapabilityShutdowns.keys()].map(e=>this.settlePendingCapabilityShutdown(e))),await Promise.all([...this.broadcastSessions].map(e=>e.close())),await Promise.all([...this.broadcastPublishers].map(e=>e.close())),await Promise.all([this.controlPlanePromise,this.sessionPlanePromise].map(e=>e?.then(t=>t.dispose(),()=>{}))),this.activations.clear(),this.broadcastSessions.clear(),this.broadcastPublishers.clear(),await this.broadcastHostPromise?.then(e=>e?.close?.(),()=>{}),await this.internals.broadcastHost?.close?.(),await this.internals.close?.(),this.closed=true;}};D.nextDiagnosticClient=0;var E=D;function xe(a,e){return new E(a,e)}function Le(a,e){if(!(a instanceof E))throw new TypeError("[OpenRTC] ServiceNode requires a client created by this OpenRTC package.");return a.openAuthorityRoom(e)}export{I as a,B as b,pe as c,Be as d,f as e,re as f,N as g,T as h,xe as i,Le as j};
@@ -1,2 +1,2 @@
1
- import {j,d as d$1,c}from'./chunk-WZ2VUWTQ.js';var E=/^[A-Za-z0-9_.:@-]+$/,P=/^[A-Za-z0-9_-]{43}$/,C=/^[A-Za-z0-9_.:@-]+$/,k=/^[A-Za-z0-9._-]+$/,x=120*6e4,A=new TextEncoder;function d(r,e,t=160){let n=r.trim();if(!n||n.length>t||!E.test(n))throw new TypeError(`[OpenRTC] ${e} is invalid.`);return n}function h(r,e,t=Number.MAX_SAFE_INTEGER){if(!Number.isSafeInteger(r)||r<1||r>t)throw new RangeError(`[OpenRTC] ${e} must be a positive safe integer.`);return r}function K(r){let e="";for(let t of r)e+=String.fromCharCode(t);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}async function g(r,e){let t=await r.publicJwk();if(t.kty!=="OKP"||t.crv!=="Ed25519"||typeof t.x!="string"||!P.test(t.x)||t.d!==void 0)throw new TypeError(`[OpenRTC] ${e} must return an Ed25519 public JWK.`);return {kty:"OKP",crv:"Ed25519",x:t.x}}async function y(r,e,t){let n=await r.sign(e);if(!(n instanceof Uint8Array)||n.byteLength!==64)throw new TypeError(`[OpenRTC] ${t} returned an invalid Ed25519 signature.`);return K(n)}function T(r){if(!/^pk_(?:live|test)_[A-Za-z0-9]+$/.test(r))throw new TypeError("[OpenRTC] apiKey is invalid.");return `app_${r.slice(-16)}`}function u(r){return r!==null&&typeof r=="object"&&!Array.isArray(r)?r:null}function v(r,e,t,n){if(typeof r!="string"||r.length<1||r.length>t||r!==r.trim()||n&&!n.test(r))throw new Error(`[OpenRTC] authority service grant ${e} is invalid.`);return r}function O(r){let e=v(r,"gatewayUrl",2048),t;try{t=new URL(e);}catch{throw new Error("[OpenRTC] authority service grant gatewayUrl is invalid.")}let n=t.protocol==="http:"&&["127.0.0.1","localhost","::1"].includes(t.hostname.toLowerCase());if(t.protocol!=="https:"&&!n||t.username||t.password||t.search||t.hash)throw new Error("[OpenRTC] authority service grant gatewayUrl is invalid.");return e}function N(r,e){let t=u(r),n=u(t?.avenue),i=u(t?.roomAuthority),a=u(i?.assignmentPublicKeyJwk),c=Date.now(),o=t?.expiresAtMs,s=t?.maxPeers;if(!t||t.protocolVersion!==2||t.architecture!=="authority"||n?.kind!=="room"||n.id!==e.roomId||i?.serviceId!==e.serviceId||i.generation!==e.generation||!Array.isArray(i.shardIds)||i.shardIds.length!==e.shardIds.length||i.shardIds.some((m,l)=>m!==e.shardIds[l])||a?.kty!=="OKP"||a.crv!=="Ed25519"||a.x!==e.assignmentPublicKeyX||!Number.isSafeInteger(o)||o<=c||o>c+x||!Number.isSafeInteger(s)||s<1||s>e.maxPeers)throw new Error("[OpenRTC] authority service grant response is inconsistent.");return {protocolVersion:2,gatewayUrl:O(t.gatewayUrl),routeKey:v(t.routeKey,"routeKey",256,C),token:v(t.token,"token",24e3,k),expiresAtMs:o,avenue:{kind:"room",id:e.roomId},maxPeers:s,architecture:"authority",roomAuthority:{serviceId:e.serviceId,generation:e.generation,shardIds:[...e.shardIds],assignmentPublicKeyJwk:{kty:"OKP",crv:"Ed25519",x:e.assignmentPublicKeyX}}}}var p=class{constructor(e){if(this.apiKey=e.apiKey,this.applicationTag=T(e.apiKey),typeof e.grantIssuer!="function")throw new TypeError("[OpenRTC] ServiceNode requires a browser-safe grantIssuer.");if(this.grantIssuer=e.grantIssuer,this.serviceId=d(e.serviceId,"serviceId",80),this.generation=h(e.generation,"generation"),this.shardIds=[...new Set(e.shardIds.map(t=>d(t,"shardId",80)))].sort(),this.shardIds.length<1||this.shardIds.length>64||this.shardIds.length!==e.shardIds.length)throw new RangeError("[OpenRTC] shardIds must contain 1..64 unique identifiers.");this.deviceId=d(e.deviceId,"deviceId"),this.deviceSigner=e.deviceSigner,this.assignmentSigner=e.assignmentSigner;}async requestGrant(e){let t=d(e.roomId,"roomId"),n=d(e.runtimeInstanceId,"runtimeInstanceId");if(!P.test(e.ticketFingerprint))throw new TypeError("[OpenRTC] ticketFingerprint is invalid.");e.maxPeers!==void 0&&h(e.maxPeers,"maxPeers",50);let i=await g(this.assignmentSigner,"assignmentSigner.publicJwk()"),a=await g(this.deviceSigner,"deviceSigner.publicJwk()"),c=crypto.randomUUID().replace(/-/g,""),o=Math.floor(Date.now()/1e3),s=["openrtc:v2:authority-service-grant",this.applicationTag,t,this.serviceId,String(this.generation),this.shardIds.join(","),i.x,n,c,o].join(":"),m={avenue:{kind:"room",id:t},serviceId:this.serviceId,generation:this.generation,shardIds:this.shardIds,assignmentPublicKeyJwk:i,deviceId:this.deviceId,runtimeInstanceId:n,ticketFingerprint:e.ticketFingerprint,deviceProof:{publicKeyJwk:a,nonce:c,issuedAt:o,signature:await y(this.deviceSigner,A.encode(s),"deviceSigner.sign()")},...e.maxPeers===void 0?{}:{maxPeers:e.maxPeers},...e.refreshGrant?{refreshGrant:e.refreshGrant}:{},features:e.features??{}},l=`authority_${crypto.randomUUID().replace(/-/g,"")}`,R=await this.grantIssuer({apiKey:this.apiKey,idempotencyKey:l,body:m});return N(R,{roomId:t,serviceId:this.serviceId,generation:this.generation,shardIds:this.shardIds,assignmentPublicKeyX:i.x,maxPeers:e.maxPeers??50})}async devicePublicKey(){return g(this.deviceSigner,"deviceSigner.publicJwk()")}async assignmentPublicKey(){return g(this.assignmentSigner,"assignmentSigner.publicJwk()")}async signDeviceBytes(e){return y(this.deviceSigner,e,"deviceSigner.sign()")}async signAssignment(e){let t=e.ttlMs??6e4;h(t,"ttlMs",2*6e4);let n=d(e.shardId,"shardId",80);if(!this.shardIds.includes(n))throw new RangeError("[OpenRTC] assignment shard is not owned by this service.");let i=e.priorityDeviceIds??[],a=e.relevantEntityIds??[];if(i.length>8||a.length>32)throw new RangeError("[OpenRTC] assignment exceeds the 8-edge or 32-entity bound.");let c=Date.now(),o={policyVersion:"room-authority-assignment-v1",serviceId:this.serviceId,generation:this.generation,revision:h(e.revision,"revision"),subjectDeviceId:d(e.subjectDeviceId,"subjectDeviceId"),shardId:n,priorityDeviceIds:i.map(s=>d(s,"priorityDeviceId")),relevantEntityIds:a.map(s=>d(s,"relevantEntityId")),issuedAtMs:c,expiresAtMs:c+t};if(new Set(o.priorityDeviceIds).size!==o.priorityDeviceIds.length||new Set(o.relevantEntityIds).size!==o.relevantEntityIds.length)throw new RangeError("[OpenRTC] assignment identifiers must be unique.");return {assignment:o,signature:await y(this.assignmentSigner,A.encode(JSON.stringify(o)),"assignmentSigner.sign()")}}},I=class{constructor(e,t,n){this.room=e;this.authority=t;this.onClosed=n;this.releaseRuntimeAlias=d$1(this,e);}get kind(){return this.room.kind}get id(){return this.room.id}get peers(){return this.room.peers}get channels(){return this.room.channels}get diagnostics(){return this.room.diagnostics}get closed(){return this.room.closed}get membership(){return this.room.membership}state(e){return this.room.state(e)}channel(e){return this.room.channel(e)}onConnection(e){return this.room.onConnection(e)}architecture(){return this.room.architecture()}onArchitectureChanged(e){return this.room.onArchitectureChanged(e)}authorityAssignment(){return this.room.authorityAssignment()}onAuthorityAssignmentChanged(e){return this.room.onAuthorityAssignmentChanged(e)}leave(){return this.retire(()=>this.room.leave())}close(){return this.retire(()=>this.room.close())}async publishAssignment(e){let t=await this.authority.signAssignment(e);return await c(this.room).advanced.runtime.publishAuthorityAssignment(t),t.assignment}retire(e){return this.retirement??(this.retirement=e().finally(()=>{this.releaseRuntimeAlias(),this.onClosed();}))}},S=class{constructor(e){this.options=e;this.rooms=new Map;this.connectionListeners=new Set;this.connectionCleanups=new Map;this.closed=false;if("secretKey"in e)throw new TypeError("[OpenRTC] ServiceNode never accepts secretKey; delegate short-lived grants.");this.authority=new p(e);}listen(e){if(this.closed)throw new Error("[OpenRTC] ServiceNode is closed.");let t=d(e,"roomId"),n=this.rooms.get(t);if(n)return n.promise;let i={};return i.promise=this.openRoom(t,()=>this.evictRoom(t,i)).catch(a=>{throw this.evictRoom(t,i),a}),this.rooms.set(t,i),i.promise}onConnection(e){if(this.connectionListeners.add(e),this.connectionListeners.size===1)for(let[t,n]of this.rooms)n.promise.then(i=>this.attachConnectionListener(t,i),()=>{});return ()=>{if(this.connectionListeners.delete(e),this.connectionListeners.size===0){for(let t of this.connectionCleanups.values())t();this.connectionCleanups.clear();}}}async close(){if(this.closed)return;this.closed=true;for(let t of this.connectionCleanups.values())t();this.connectionCleanups.clear();let e=await Promise.allSettled([...this.rooms.values()].map(t=>t.promise));await Promise.all(e.flatMap(t=>t.status==="fulfilled"?[t.value.close()]:[])),this.rooms.clear(),this.connectionListeners.clear();}async openRoom(e,t){let n=await this.options.client.devices.localId();if(n!==this.options.deviceId)throw new Error("[OpenRTC] ServiceNode deviceId must match the client installation.");let[i,a]=await Promise.all([this.authority.devicePublicKey(),this.authority.assignmentPublicKey()]),c=await j(this.options.client,{roomId:e,serviceId:this.options.serviceId,generation:this.options.generation,shardIds:this.options.shardIds,deviceId:n,maxPeers:this.options.maxPeers,irohRelay:this.options.irohRelay!==false,devicePublicKeyX:i.x,assignmentPublicKeyX:a.x,deviceSign:s=>this.authority.signDeviceBytes(s),grantProvider:async s=>{if(s.avenue.kind!=="room"||s.avenue.id!==e)throw new Error("[OpenRTC] ServiceNode grant request escaped its room.");if(s.deviceId!==n)throw new Error("[OpenRTC] ServiceNode grant request escaped its device.");return this.authority.requestGrant({roomId:e,runtimeInstanceId:s.runtimeInstanceId,ticketFingerprint:s.ticketFingerprint,maxPeers:this.options.maxPeers,refreshGrant:s.refreshGrant,features:{irohRelay:this.options.irohRelay!==false}})}}),o=new I(c,this.authority,t);return this.attachConnectionListener(e,o),o}evictRoom(e,t){this.rooms.get(e)===t&&(this.rooms.delete(e),this.connectionCleanups.get(e)?.(),this.connectionCleanups.delete(e));}attachConnectionListener(e,t){this.closed||this.connectionListeners.size===0||this.connectionCleanups.has(e)||this.connectionCleanups.set(e,t.onConnection(n=>{for(let i of this.connectionListeners)i({room:t,connection:n});}));}};
1
+ import {j,d as d$1,c}from'./chunk-4TOWICSH.js';var E=/^[A-Za-z0-9_.:@-]+$/,P=/^[A-Za-z0-9_-]{43}$/,C=/^[A-Za-z0-9_.:@-]+$/,k=/^[A-Za-z0-9._-]+$/,x=120*6e4,A=new TextEncoder;function d(r,e,t=160){let n=r.trim();if(!n||n.length>t||!E.test(n))throw new TypeError(`[OpenRTC] ${e} is invalid.`);return n}function h(r,e,t=Number.MAX_SAFE_INTEGER){if(!Number.isSafeInteger(r)||r<1||r>t)throw new RangeError(`[OpenRTC] ${e} must be a positive safe integer.`);return r}function K(r){let e="";for(let t of r)e+=String.fromCharCode(t);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}async function g(r,e){let t=await r.publicJwk();if(t.kty!=="OKP"||t.crv!=="Ed25519"||typeof t.x!="string"||!P.test(t.x)||t.d!==void 0)throw new TypeError(`[OpenRTC] ${e} must return an Ed25519 public JWK.`);return {kty:"OKP",crv:"Ed25519",x:t.x}}async function y(r,e,t){let n=await r.sign(e);if(!(n instanceof Uint8Array)||n.byteLength!==64)throw new TypeError(`[OpenRTC] ${t} returned an invalid Ed25519 signature.`);return K(n)}function T(r){if(!/^pk_(?:live|test)_[A-Za-z0-9]+$/.test(r))throw new TypeError("[OpenRTC] apiKey is invalid.");return `app_${r.slice(-16)}`}function u(r){return r!==null&&typeof r=="object"&&!Array.isArray(r)?r:null}function v(r,e,t,n){if(typeof r!="string"||r.length<1||r.length>t||r!==r.trim()||n&&!n.test(r))throw new Error(`[OpenRTC] authority service grant ${e} is invalid.`);return r}function O(r){let e=v(r,"gatewayUrl",2048),t;try{t=new URL(e);}catch{throw new Error("[OpenRTC] authority service grant gatewayUrl is invalid.")}let n=t.protocol==="http:"&&["127.0.0.1","localhost","::1"].includes(t.hostname.toLowerCase());if(t.protocol!=="https:"&&!n||t.username||t.password||t.search||t.hash)throw new Error("[OpenRTC] authority service grant gatewayUrl is invalid.");return e}function N(r,e){let t=u(r),n=u(t?.avenue),i=u(t?.roomAuthority),a=u(i?.assignmentPublicKeyJwk),c=Date.now(),o=t?.expiresAtMs,s=t?.maxPeers;if(!t||t.protocolVersion!==2||t.architecture!=="authority"||n?.kind!=="room"||n.id!==e.roomId||i?.serviceId!==e.serviceId||i.generation!==e.generation||!Array.isArray(i.shardIds)||i.shardIds.length!==e.shardIds.length||i.shardIds.some((m,l)=>m!==e.shardIds[l])||a?.kty!=="OKP"||a.crv!=="Ed25519"||a.x!==e.assignmentPublicKeyX||!Number.isSafeInteger(o)||o<=c||o>c+x||!Number.isSafeInteger(s)||s<1||s>e.maxPeers)throw new Error("[OpenRTC] authority service grant response is inconsistent.");return {protocolVersion:2,gatewayUrl:O(t.gatewayUrl),routeKey:v(t.routeKey,"routeKey",256,C),token:v(t.token,"token",24e3,k),expiresAtMs:o,avenue:{kind:"room",id:e.roomId},maxPeers:s,architecture:"authority",roomAuthority:{serviceId:e.serviceId,generation:e.generation,shardIds:[...e.shardIds],assignmentPublicKeyJwk:{kty:"OKP",crv:"Ed25519",x:e.assignmentPublicKeyX}}}}var p=class{constructor(e){if(this.apiKey=e.apiKey,this.applicationTag=T(e.apiKey),typeof e.grantIssuer!="function")throw new TypeError("[OpenRTC] ServiceNode requires a browser-safe grantIssuer.");if(this.grantIssuer=e.grantIssuer,this.serviceId=d(e.serviceId,"serviceId",80),this.generation=h(e.generation,"generation"),this.shardIds=[...new Set(e.shardIds.map(t=>d(t,"shardId",80)))].sort(),this.shardIds.length<1||this.shardIds.length>64||this.shardIds.length!==e.shardIds.length)throw new RangeError("[OpenRTC] shardIds must contain 1..64 unique identifiers.");this.deviceId=d(e.deviceId,"deviceId"),this.deviceSigner=e.deviceSigner,this.assignmentSigner=e.assignmentSigner;}async requestGrant(e){let t=d(e.roomId,"roomId"),n=d(e.runtimeInstanceId,"runtimeInstanceId");if(!P.test(e.ticketFingerprint))throw new TypeError("[OpenRTC] ticketFingerprint is invalid.");e.maxPeers!==void 0&&h(e.maxPeers,"maxPeers",50);let i=await g(this.assignmentSigner,"assignmentSigner.publicJwk()"),a=await g(this.deviceSigner,"deviceSigner.publicJwk()"),c=crypto.randomUUID().replace(/-/g,""),o=Math.floor(Date.now()/1e3),s=["openrtc:v2:authority-service-grant",this.applicationTag,t,this.serviceId,String(this.generation),this.shardIds.join(","),i.x,n,c,o].join(":"),m={avenue:{kind:"room",id:t},serviceId:this.serviceId,generation:this.generation,shardIds:this.shardIds,assignmentPublicKeyJwk:i,deviceId:this.deviceId,runtimeInstanceId:n,ticketFingerprint:e.ticketFingerprint,deviceProof:{publicKeyJwk:a,nonce:c,issuedAt:o,signature:await y(this.deviceSigner,A.encode(s),"deviceSigner.sign()")},...e.maxPeers===void 0?{}:{maxPeers:e.maxPeers},...e.refreshGrant?{refreshGrant:e.refreshGrant}:{},features:e.features??{}},l=`authority_${crypto.randomUUID().replace(/-/g,"")}`,R=await this.grantIssuer({apiKey:this.apiKey,idempotencyKey:l,body:m});return N(R,{roomId:t,serviceId:this.serviceId,generation:this.generation,shardIds:this.shardIds,assignmentPublicKeyX:i.x,maxPeers:e.maxPeers??50})}async devicePublicKey(){return g(this.deviceSigner,"deviceSigner.publicJwk()")}async assignmentPublicKey(){return g(this.assignmentSigner,"assignmentSigner.publicJwk()")}async signDeviceBytes(e){return y(this.deviceSigner,e,"deviceSigner.sign()")}async signAssignment(e){let t=e.ttlMs??6e4;h(t,"ttlMs",2*6e4);let n=d(e.shardId,"shardId",80);if(!this.shardIds.includes(n))throw new RangeError("[OpenRTC] assignment shard is not owned by this service.");let i=e.priorityDeviceIds??[],a=e.relevantEntityIds??[];if(i.length>8||a.length>32)throw new RangeError("[OpenRTC] assignment exceeds the 8-edge or 32-entity bound.");let c=Date.now(),o={policyVersion:"room-authority-assignment-v1",serviceId:this.serviceId,generation:this.generation,revision:h(e.revision,"revision"),subjectDeviceId:d(e.subjectDeviceId,"subjectDeviceId"),shardId:n,priorityDeviceIds:i.map(s=>d(s,"priorityDeviceId")),relevantEntityIds:a.map(s=>d(s,"relevantEntityId")),issuedAtMs:c,expiresAtMs:c+t};if(new Set(o.priorityDeviceIds).size!==o.priorityDeviceIds.length||new Set(o.relevantEntityIds).size!==o.relevantEntityIds.length)throw new RangeError("[OpenRTC] assignment identifiers must be unique.");return {assignment:o,signature:await y(this.assignmentSigner,A.encode(JSON.stringify(o)),"assignmentSigner.sign()")}}},I=class{constructor(e,t,n){this.room=e;this.authority=t;this.onClosed=n;this.releaseRuntimeAlias=d$1(this,e);}get kind(){return this.room.kind}get id(){return this.room.id}get peers(){return this.room.peers}get channels(){return this.room.channels}get diagnostics(){return this.room.diagnostics}get closed(){return this.room.closed}get membership(){return this.room.membership}get members(){return this.room.members}state(e){return this.room.state(e)}channel(e){return this.room.channel(e)}onConnection(e){return this.room.onConnection(e)}architecture(){return this.room.architecture()}onArchitectureChanged(e){return this.room.onArchitectureChanged(e)}authorityAssignment(){return this.room.authorityAssignment()}onAuthorityAssignmentChanged(e){return this.room.onAuthorityAssignmentChanged(e)}leave(){return this.retire(()=>this.room.leave())}close(){return this.retire(()=>this.room.close())}async publishAssignment(e){let t=await this.authority.signAssignment(e);return await c(this.room).advanced.runtime.publishAuthorityAssignment(t),t.assignment}retire(e){return this.retirement??(this.retirement=e().finally(()=>{this.releaseRuntimeAlias(),this.onClosed();}))}},S=class{constructor(e){this.options=e;this.rooms=new Map;this.connectionListeners=new Set;this.connectionCleanups=new Map;this.closed=false;if("secretKey"in e)throw new TypeError("[OpenRTC] ServiceNode never accepts secretKey; delegate short-lived grants.");this.authority=new p(e);}listen(e){if(this.closed)throw new Error("[OpenRTC] ServiceNode is closed.");let t=d(e,"roomId"),n=this.rooms.get(t);if(n)return n.promise;let i={};return i.promise=this.openRoom(t,()=>this.evictRoom(t,i)).catch(a=>{throw this.evictRoom(t,i),a}),this.rooms.set(t,i),i.promise}onConnection(e){if(this.connectionListeners.add(e),this.connectionListeners.size===1)for(let[t,n]of this.rooms)n.promise.then(i=>this.attachConnectionListener(t,i),()=>{});return ()=>{if(this.connectionListeners.delete(e),this.connectionListeners.size===0){for(let t of this.connectionCleanups.values())t();this.connectionCleanups.clear();}}}async close(){if(this.closed)return;this.closed=true;for(let t of this.connectionCleanups.values())t();this.connectionCleanups.clear();let e=await Promise.allSettled([...this.rooms.values()].map(t=>t.promise));await Promise.all(e.flatMap(t=>t.status==="fulfilled"?[t.value.close()]:[])),this.rooms.clear(),this.connectionListeners.clear();}async openRoom(e,t){let n=await this.options.client.devices.localId();if(n!==this.options.deviceId)throw new Error("[OpenRTC] ServiceNode deviceId must match the client installation.");let[i,a]=await Promise.all([this.authority.devicePublicKey(),this.authority.assignmentPublicKey()]),c=await j(this.options.client,{roomId:e,serviceId:this.options.serviceId,generation:this.options.generation,shardIds:this.options.shardIds,deviceId:n,maxPeers:this.options.maxPeers,irohRelay:this.options.irohRelay!==false,devicePublicKeyX:i.x,assignmentPublicKeyX:a.x,deviceSign:s=>this.authority.signDeviceBytes(s),grantProvider:async s=>{if(s.avenue.kind!=="room"||s.avenue.id!==e)throw new Error("[OpenRTC] ServiceNode grant request escaped its room.");if(s.deviceId!==n)throw new Error("[OpenRTC] ServiceNode grant request escaped its device.");return this.authority.requestGrant({roomId:e,runtimeInstanceId:s.runtimeInstanceId,ticketFingerprint:s.ticketFingerprint,maxPeers:this.options.maxPeers,refreshGrant:s.refreshGrant,features:{irohRelay:this.options.irohRelay!==false}})}}),o=new I(c,this.authority,t);return this.attachConnectionListener(e,o),o}evictRoom(e,t){this.rooms.get(e)===t&&(this.rooms.delete(e),this.connectionCleanups.get(e)?.(),this.connectionCleanups.delete(e));}attachConnectionListener(e,t){this.closed||this.connectionListeners.size===0||this.connectionCleanups.has(e)||this.connectionCleanups.set(e,t.onConnection(n=>{for(let i of this.connectionListeners)i({room:t,connection:n});}));}};
2
2
  export{p as a,S as b};
@@ -1 +1 @@
1
- import {r}from'./chunk-NIUTTTJS.js';import {e}from'./chunk-CAUMGKP4.js';function v(i,d){let t=new r(i,d),a=i.spaceKey??i.space,l=(i.discoveryMode===void 0||i.discoveryMode==="space")&&typeof i.apiKey=="string"&&i.apiKey.trim().length>0&&typeof a=="string"&&a.trim().length>0,o={runtime:t,async setAuthContext(e){await t.setAuthContext(e);},async syncPlutoAuth(e$1){if(l)return;let n=e(),c=n.getCurrentUser(),r=(typeof e$1?.userId=="string"?e$1.userId.trim():"")||c?.uid||null;if(!r){await o.setAuthContext(null);return}let m=await n.getIdToken({forceRefresh:e$1?.forceRefresh??false}).catch(()=>null),g=n.getCurrentUser()?.refreshToken??null,h=n.getCurrentUser()?.stsTokenManager?.expirationTime??null;await o.setAuthContext({userId:r,token:m,refreshToken:g,tokenProvider:async y=>n.getIdToken({forceRefresh:y??false}),expiresAtMs:h});},bindPlutoAuthHost(){let e$1=e();return o.syncPlutoAuth({userId:e$1.getCurrentUser()?.uid??null,forceRefresh:false}),e$1.onIdTokenChanged(n=>{o.syncPlutoAuth({userId:n?.uid??null,forceRefresh:false});})},signInWithPluto:()=>t.signInWithPluto(),signOut:()=>t.signOut(),stopManagedSession:()=>t.stopManagedSession(),startManagedSession:e=>t.startManagedSession(e),onAuthChange:e=>t.onIdentityChange(e),getManagedNodeId:e=>t.getManagedNodeId(e),getRuntimeStatus:()=>t.getRuntimeStatus(),listDeviceStatus:()=>t.listDeviceStatus(),watchDeviceStatus:e=>t.watchDeviceStatus(e),connectDevice:(e,n)=>t.connectDevice(e,n),excludeAutoConnect:(e,n)=>t.excludeAutoConnect(e,n)};return Object.defineProperty(o,"identity",{get:()=>t.identity,enumerable:true}),o}export{v as a};
1
+ import {s}from'./chunk-EI6PDMHI.js';import {e}from'./chunk-UCNK7KB6.js';function v(i,d){let t=new s(i,d),a=i.spaceKey??i.space,l=(i.discoveryMode===void 0||i.discoveryMode==="space")&&typeof i.apiKey=="string"&&i.apiKey.trim().length>0&&typeof a=="string"&&a.trim().length>0,o={runtime:t,async setAuthContext(e){await t.setAuthContext(e);},async syncPlutoAuth(e$1){if(l)return;let n=e(),c=n.getCurrentUser(),r=(typeof e$1?.userId=="string"?e$1.userId.trim():"")||c?.uid||null;if(!r){await o.setAuthContext(null);return}let m=await n.getIdToken({forceRefresh:e$1?.forceRefresh??false}).catch(()=>null),g=n.getCurrentUser()?.refreshToken??null,h=n.getCurrentUser()?.stsTokenManager?.expirationTime??null;await o.setAuthContext({userId:r,token:m,refreshToken:g,tokenProvider:async y=>n.getIdToken({forceRefresh:y??false}),expiresAtMs:h});},bindPlutoAuthHost(){let e$1=e();return o.syncPlutoAuth({userId:e$1.getCurrentUser()?.uid??null,forceRefresh:false}),e$1.onIdTokenChanged(n=>{o.syncPlutoAuth({userId:n?.uid??null,forceRefresh:false});})},signInWithPluto:()=>t.signInWithPluto(),signOut:()=>t.signOut(),stopManagedSession:()=>t.stopManagedSession(),startManagedSession:e=>t.startManagedSession(e),onAuthChange:e=>t.onIdentityChange(e),getManagedNodeId:e=>t.getManagedNodeId(e),getRuntimeStatus:()=>t.getRuntimeStatus(),listDeviceStatus:()=>t.listDeviceStatus(),watchDeviceStatus:e=>t.watchDeviceStatus(e),connectDevice:(e,n)=>t.connectDevice(e,n),excludeAutoConnect:(e,n)=>t.excludeAutoConnect(e,n)};return Object.defineProperty(o,"identity",{get:()=>t.identity,enumerable:true}),o}export{v as a};