openrtc 3.1.1 → 3.1.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 (58) hide show
  1. package/dist/{Connection-BGVBMbWg.d.ts → Connection-U3fEt8_4.d.ts} +35 -1
  2. package/dist/{DelegatingRuntimeAdapter-JmhmwKTC.d.ts → DelegatingRuntimeAdapter-Coo5BVM2.d.ts} +2 -2
  3. package/dist/{IpcRuntimeAdapter-DMQoN2XL.d.ts → IpcRuntimeAdapter-D188hRAr.d.ts} +2 -2
  4. package/dist/{assembly-DGrOqsLW.d.ts → assembly-CtrHmP4j.d.ts} +2 -2
  5. package/dist/{capabilities-DsKud7Sw.d.ts → capabilities-Dxb0XOti.d.ts} +1 -1
  6. package/dist/chunk-5336XOTL.js +2 -0
  7. package/dist/chunk-KI7XXVXH.js +1 -0
  8. package/dist/chunk-M2QMGAL2.js +2 -0
  9. package/dist/{chunk-KN7DF3NH.js → chunk-RUOVYQ2P.js} +1 -1
  10. package/dist/{chunk-IVNXIG7J.js → chunk-SSBR3IHA.js} +1 -1
  11. package/dist/chunk-V57WKJSB.js +2 -0
  12. package/dist/chunk-XNJI6KCI.js +2 -0
  13. package/dist/controlPlane-HOFWXQJW.js +1 -0
  14. package/dist/{coreClient-ByXs38IP.d.ts → coreClient-AVGEwlhT.d.ts} +3 -3
  15. package/dist/coreClient.d.ts +4 -4
  16. package/dist/coreClient.js +1 -1
  17. package/dist/{deviceHandle-URNIFFXC.js → deviceHandle-DFG3CCY3.js} +1 -1
  18. package/dist/deviceKey-4DLS246L.js +1 -0
  19. package/dist/external-broadcast.d.ts +5 -5
  20. package/dist/external-broadcast.js +1 -1
  21. package/dist/index.d.ts +7 -7
  22. package/dist/index.js +1 -1
  23. package/dist/native.d.ts +6 -6
  24. package/dist/native.js +1 -1
  25. package/dist/node.d.ts +7 -7
  26. package/dist/node.js +1 -1
  27. package/dist/openrtc_bg.wasm +0 -0
  28. package/dist/{room-7ZEAAY7Z.js → room-ZQU7JFRG.js} +1 -1
  29. package/dist/runtime/WasmRuntimeAdapter.d.ts +3 -3
  30. package/dist/runtime/device-status.d.ts +1 -1
  31. package/dist/runtime/factories.d.ts +5 -5
  32. package/dist/runtime/index.d.ts +10 -10
  33. package/dist/runtime/index.js +1 -1
  34. package/dist/server-browser.d.ts +5 -5
  35. package/dist/server.d.ts +5 -5
  36. package/dist/server.js +1 -1
  37. package/dist/service-node.d.ts +8 -7
  38. package/dist/service-node.js +1 -1
  39. package/dist/testing/native.d.ts +5 -5
  40. package/dist/testing/native.js +1 -1
  41. package/dist/testing.d.ts +7 -36
  42. package/dist/testing.js +1 -1
  43. package/dist/transport/index.d.ts +2 -2
  44. package/dist/{types-Cruu-MsF.d.ts → types-DvZvz4EL.d.ts} +2 -2
  45. package/native/darwin-arm64/openrtc-node-host +0 -0
  46. package/native/darwin-arm64/openrtc-node-host.manifest.json +4 -4
  47. package/native/darwin-x64/openrtc-node-host +0 -0
  48. package/native/darwin-x64/openrtc-node-host.manifest.json +4 -4
  49. package/native/linux-x64/openrtc-node-host +0 -0
  50. package/native/linux-x64/openrtc-node-host.manifest.json +4 -4
  51. package/package.json +1 -1
  52. package/dist/chunk-2Q75GXGE.js +0 -2
  53. package/dist/chunk-AZ74VBU2.js +0 -2
  54. package/dist/chunk-GMPEZXPD.js +0 -2
  55. package/dist/chunk-IAYQJZQQ.js +0 -1
  56. package/dist/chunk-NS32P65Z.js +0 -2
  57. package/dist/controlPlane-45AU3CSM.js +0 -1
  58. package/dist/deviceKey-2NTRYCSR.js +0 -1
@@ -325,6 +325,38 @@ interface MoQObjectQuantities {
325
325
  completedReceivedBytes: number;
326
326
  }
327
327
 
328
+ interface DeviceProof {
329
+ publicKeyJwk: JsonWebKey;
330
+ signature: string;
331
+ nonce: string;
332
+ issuedAt: number;
333
+ }
334
+ interface DeviceKey {
335
+ readonly publicKeyJwk: JsonWebKey;
336
+ readonly thumbprint: string;
337
+ /** Signs Rust-canonical protocol bytes without exporting private key material. */
338
+ sign(message: Uint8Array): Promise<string>;
339
+ proof(challenge: (nonce: string, issuedAt: number) => string): Promise<DeviceProof>;
340
+ }
341
+ interface DeviceKeyProvider {
342
+ /** Host-owned ephemeral root signer, distinct from the enrollment key. */
343
+ getRootClientKey?(appTag: string): Promise<DeviceKey>;
344
+ /** Session-only providers cannot enroll retained devices. Host providers
345
+ * may omit this; the host owns their durable identity contract. */
346
+ persistence?: 'session' | 'persistent';
347
+ getOrCreate(appTag: string): Promise<DeviceKey>;
348
+ delete?(appTag: string): Promise<void>;
349
+ /**
350
+ * Optional host-private record storage. Native hosts use this for the
351
+ * device certificate bound to their non-exported signing key; the host
352
+ * chooses a prompt-free implementation. Browsers retain their same-origin
353
+ * storage implementation.
354
+ */
355
+ readSecureRecord?(appTag: string, key: string): Promise<string | null>;
356
+ writeSecureRecord?(appTag: string, key: string, value: string): Promise<void>;
357
+ deleteSecureRecord?(appTag: string, key: string): Promise<void>;
358
+ }
359
+
328
360
  /** Public protocol identifiers; provider prices and safety ceilings stay private. */
329
361
  declare const SERVICE_ERROR_CODES: {
330
362
  readonly CREDIT_EXHAUSTED: "credit-exhausted";
@@ -488,6 +520,8 @@ interface CoordinationGatewayGrantRequest {
488
520
  ticketFingerprint: string;
489
521
  purpose: 'presence' | 'device-control';
490
522
  refreshGrant?: string;
523
+ /** Internal root possession proof for delegated authority issuance. */
524
+ rootProof?: DeviceProof;
491
525
  }
492
526
  interface CoordinationGatewayGrant {
493
527
  protocolVersion: 1 | 2;
@@ -1710,4 +1744,4 @@ declare class Connection {
1710
1744
  private close;
1711
1745
  }
1712
1746
 
1713
- export { type RoomMember as $, type ConnectDeviceResult as A, type ConnectDeviceHooks as B, type ChannelDescriptor$1 as C, type DeviceStatus as D, type EffectiveRoomArchitecture as E, type ConnectDeviceOptions as F, type DeviceProfile as G, type RawConnection as H, type IncomingStream as I, type JoinRoomOptions$1 as J, type RuntimeRoomMember as K, type LocalDeviceInfo$1 as L, type ManagedOptions as M, type GrantScope as N, type AuthContext as O, type PlutoIrohConfiguration as P, type RuntimeClientOptions as Q, type RoomArchitectureMode as R, type ServiceErrorObservation as S, type TransferPeerDemandPurpose as T, type DiscoveryMode as U, type AuthMode as V, type SignalingMode as W, type ClientOptions as X, type ExplicitFileDataSendParams as Y, type ISignalingBackend as Z, type RuntimeIdentity as _, type RoomArchitectureReason as a, type DevicePresence as a$, type Device as a0, type DeviceStatusSnapshot as a1, type ManagedConnectionRecord as a2, type SignalingEnvelope as a3, type DeviceEvent as a4, type DesiredPeerProjection as a5, type SignalingSession as a6, type SessionEvent as a7, type LocalDeviceInfo as a8, type NativeManagedSessionStartResult as a9, type CryptoBiStream as aA, type RouteFamily as aB, type RouteKind as aC, type RuntimeAuthIdentity as aD, type RuntimeSession as aE, type AppLimits as aF, type ConnectionTarget as aG, type PresenceLoopOptions as aH, type SignalingOptions as aI, type JoinRoomOptions as aJ, type ChannelMetadata as aK, type RoomCreationMode as aL, type ProtocolCapabilityMap as aM, type ScanningLoopOptions as aN, type ScanningLoopHandle as aO, type RuntimeBootstrapOptions as aP, type RuntimeBootstrapResult as aQ, type ApplicationPayloadReadinessOptions as aR, type ManagedApplicationRouteOptions as aS, type PeerState as aT, type PeerScope as aU, type PeerHealth as aV, type ChannelDescriptor as aW, type JoinRequest as aX, type AutoConnectPolicy as aY, type ChannelFraming as aZ, type ConnectionStatus as a_, type TicketMeshPeerReadiness as aa, type BackendPeerBiStream as ab, type BackendPeerUniStream as ac, type PortableMediaPublish as ad, type PortableMediaPublicationStart as ae, type PortableMediaSample as af, type PortableMediaChunk as ag, type PortableMediaControl as ah, type NativeConnectParams as ai, type NativeConnectResult as aj, type BackendConnectionState as ak, type NativePeerDataEvent as al, type ServiceErrorMetadata as am, type CoordinationGatewayGrantRequest as an, type CoordinationGatewayGrant as ao, type BrowserWasmRuntimeModule as ap, type BrowserProtocolStore as aq, type NamespaceDescriptor as ar, type IrohMutationReceipt as as, type IrohDocEntry as at, type CoordinationSignalingStore as au, type ManagedRoomMessage as av, type CoreClientBridgeHost as aw, type RouteDescriptor as ax, type PayloadCrypto as ay, type CryptoStreams as az, type RoomArchitectureSnapshot as b, type PayloadRouteOptions as b0, type PeerLifecycleStatus$1 as b1, type PeerSessionSnapshot$1 as b2, type PresencePolicy as b3, type RuntimeAuthContext as b4, type RuntimePeerScope as b5, type SessionKind as b6, type SessionPlatform as b7, type RoomAuthorityAssignment as c, type TransferPeerDemandRequest as d, type TransferPeerDemandState as e, type TransferPeerDemandStatus as f, type PlutoRTCConfiguration as g, type PlutoMoQConfiguration as h, type RouteOptimization as i, type ProtocolName as j, type RuntimePeerState as k, type PeerConnectOptions as l, Connection as m, type PeerSessionSnapshot as n, type PeerReadiness as o, type RuntimePeerHealth as p, type ResolvedPeerIdentity as q, type PeerStreamOptions as r, type ScopedChannelOptions as s, type RuntimeDevice as t, type ScopedLogicalChannel as u, type ConnectionState as v, type ReadinessOptions as w, type ConnectionEvent as x, type ManagedSession as y, type DeviceConnectOptions as z };
1747
+ export { type SignalingMode as $, type ReadinessOptions as A, type ConnectionEvent as B, type ChannelDescriptor$1 as C, type DeviceProof as D, type EffectiveRoomArchitecture as E, type ManagedSession as F, type DeviceStatus as G, type DeviceConnectOptions as H, type IncomingStream as I, type ConnectDeviceResult as J, type ConnectDeviceHooks as K, type ConnectDeviceOptions as L, type ManagedOptions as M, type LocalDeviceInfo$1 as N, type DeviceProfile as O, type PlutoIrohConfiguration as P, type RawConnection as Q, type RoomArchitectureMode as R, type ServiceErrorObservation as S, type TransferPeerDemandPurpose as T, type JoinRoomOptions$1 as U, type RuntimeRoomMember as V, type GrantScope as W, type AuthContext as X, type RuntimeClientOptions as Y, type DiscoveryMode as Z, type AuthMode as _, type RoomArchitectureReason as a, type AutoConnectPolicy as a$, type ClientOptions as a0, type ExplicitFileDataSendParams as a1, type ISignalingBackend as a2, type RuntimeIdentity as a3, type RoomMember as a4, type Device as a5, type DeviceStatusSnapshot as a6, type ManagedConnectionRecord as a7, type SignalingEnvelope as a8, type DeviceEvent as a9, type RouteDescriptor as aA, type PayloadCrypto as aB, type CryptoStreams as aC, type CryptoBiStream as aD, type RouteFamily as aE, type RouteKind as aF, type RuntimeAuthIdentity as aG, type RuntimeSession as aH, type AppLimits as aI, type ConnectionTarget as aJ, type PresenceLoopOptions as aK, type SignalingOptions as aL, type JoinRoomOptions as aM, type ChannelMetadata as aN, type RoomCreationMode as aO, type ProtocolCapabilityMap as aP, type ScanningLoopOptions as aQ, type ScanningLoopHandle as aR, type RuntimeBootstrapOptions as aS, type RuntimeBootstrapResult as aT, type ApplicationPayloadReadinessOptions as aU, type ManagedApplicationRouteOptions as aV, type PeerState as aW, type PeerScope as aX, type PeerHealth as aY, type ChannelDescriptor as aZ, type JoinRequest as a_, type DesiredPeerProjection as aa, type SignalingSession as ab, type SessionEvent as ac, type LocalDeviceInfo as ad, type NativeManagedSessionStartResult as ae, type TicketMeshPeerReadiness as af, type BackendPeerBiStream as ag, type BackendPeerUniStream as ah, type PortableMediaPublish as ai, type PortableMediaPublicationStart as aj, type PortableMediaSample as ak, type PortableMediaChunk as al, type PortableMediaControl as am, type NativeConnectParams as an, type NativeConnectResult as ao, type BackendConnectionState as ap, type NativePeerDataEvent as aq, type ServiceErrorMetadata as ar, type BrowserWasmRuntimeModule as as, type BrowserProtocolStore as at, type NamespaceDescriptor as au, type IrohMutationReceipt as av, type IrohDocEntry as aw, type CoordinationSignalingStore as ax, type ManagedRoomMessage as ay, type CoreClientBridgeHost as az, type RoomArchitectureSnapshot as b, type ChannelFraming as b0, type ConnectionStatus as b1, type DevicePresence as b2, type PayloadRouteOptions as b3, type PeerLifecycleStatus$1 as b4, type PeerSessionSnapshot$1 as b5, type PresencePolicy as b6, type RuntimeAuthContext as b7, type RuntimePeerScope as b8, type SessionKind as b9, type SessionPlatform as ba, type RoomAuthorityAssignment as c, type TransferPeerDemandRequest as d, type TransferPeerDemandState as e, type TransferPeerDemandStatus as f, type PlutoRTCConfiguration as g, type PlutoMoQConfiguration as h, type RouteOptimization as i, type ProtocolName as j, type DeviceKeyProvider as k, type DeviceKey as l, type CoordinationGatewayGrantRequest as m, type CoordinationGatewayGrant as n, type RuntimePeerState as o, type PeerConnectOptions as p, Connection as q, type PeerSessionSnapshot as r, type PeerReadiness as s, type RuntimePeerHealth as t, type ResolvedPeerIdentity as u, type PeerStreamOptions as v, type ScopedChannelOptions as w, type RuntimeDevice as x, type ScopedLogicalChannel as y, type ConnectionState as z };
@@ -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-BGVBMbWg.js';
2
- import { R as RuntimeCapabilities } from './capabilities-DsKud7Sw.js';
1
+ import { Z as DiscoveryMode, _ as AuthMode, $ as SignalingMode, a0 as ClientOptions, a1 as ExplicitFileDataSendParams, a2 as ISignalingBackend, a3 as RuntimeIdentity, X as AuthContext, a4 as RoomMember, a5 as Device, a6 as DeviceStatusSnapshot, r as PeerSessionSnapshot, u as ResolvedPeerIdentity, a7 as ManagedConnectionRecord, a8 as SignalingEnvelope, a9 as DeviceEvent, d as TransferPeerDemandRequest, f as TransferPeerDemandStatus, aa as DesiredPeerProjection, ab as SignalingSession, ac as SessionEvent, ad as LocalDeviceInfo, ae as NativeManagedSessionStartResult, j as ProtocolName, W as GrantScope, af as TicketMeshPeerReadiness, ag as BackendPeerBiStream, ah as BackendPeerUniStream, ai as PortableMediaPublish, aj as PortableMediaPublicationStart, ak as PortableMediaSample, al as PortableMediaChunk, am as PortableMediaControl, an as NativeConnectParams, ao as NativeConnectResult, ap as BackendConnectionState, aq as NativePeerDataEvent } from './Connection-U3fEt8_4.js';
2
+ import { R as RuntimeCapabilities } from './capabilities-Dxb0XOti.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-JmhmwKTC.js';
1
+ import { R as RuntimeBridgeOptions, D as DelegatingRuntimeAdapter } from './DelegatingRuntimeAdapter-Coo5BVM2.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-BGVBMbWg.js';
3
+ import { S as ServiceErrorObservation, ap as BackendConnectionState, aq as NativePeerDataEvent, a5 as Device } from './Connection-U3fEt8_4.js';
4
4
 
5
5
  /**
6
6
  * Root-client owner for the one native WebView projection.
@@ -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-BGVBMbWg.js';
2
- import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-DsKud7Sw.js';
1
+ import { o as RuntimePeerState, z as ConnectionState, s as PeerReadiness, p as PeerConnectOptions, q as Connection, I as IncomingStream, W as GrantScope, Y as RuntimeClientOptions, a2 as ISignalingBackend, aG as RuntimeAuthIdentity, X as AuthContext, j as ProtocolName, N as LocalDeviceInfo, O as DeviceProfile, at as BrowserProtocolStore, au as NamespaceDescriptor, av as IrohMutationReceipt, aw as IrohDocEntry, ao as NativeConnectResult, x as RuntimeDevice, M as ManagedOptions, F as ManagedSession, G as DeviceStatus, K as ConnectDeviceHooks, L as ConnectDeviceOptions, J as ConnectDeviceResult, H as DeviceConnectOptions, a7 as ManagedConnectionRecord, r as PeerSessionSnapshot, u as ResolvedPeerIdentity, aH as RuntimeSession, aI as AppLimits, U as JoinRoomOptions, V as RuntimeRoomMember, aJ as ConnectionTarget, w as ScopedChannelOptions, y as ScopedLogicalChannel, v as PeerStreamOptions, an as NativeConnectParams, Q as RawConnection, C as ChannelDescriptor, a1 as ExplicitFileDataSendParams, aK as PresenceLoopOptions, d as TransferPeerDemandRequest, f as TransferPeerDemandStatus, b as RoomArchitectureSnapshot, c as RoomAuthorityAssignment, t as RuntimePeerHealth, A as ReadinessOptions, B as ConnectionEvent } from './Connection-U3fEt8_4.js';
2
+ import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-Dxb0XOti.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-BGVBMbWg.js';
1
+ import { j as ProtocolName, i as RouteOptimization } from './Connection-U3fEt8_4.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,2 @@
1
+ function u(){let r=crypto.getRandomValues(new Uint8Array(24)),e="";for(let t of r)e+=String.fromCharCode(t);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function v(r){if(!r||typeof r!="object")throw new Error("[OpenRTC] Native host returned no device public key.");let e=r;if(e.kty!=="OKP"||e.crv!=="Ed25519"||typeof e.x!="string"||!/^[A-Za-z0-9_-]{43}$/.test(e.x)||e.d!==void 0)throw new Error("[OpenRTC] Native host returned an invalid Ed25519 public key.");return {kty:"OKP",crv:"Ed25519",x:e.x}}function l(r,e){return {getRootClientKey:e?void 0:t=>l(r,"root-client").getOrCreate(t),async readSecureRecord(t,n){return r.invoke("openrtc_read_secure_record",{appTag:t,key:n})},async writeSecureRecord(t,n,c){await r.invoke("openrtc_write_secure_record",{appTag:t,key:n,value:c});},async deleteSecureRecord(t,n){await r.invoke("openrtc_delete_secure_record",{appTag:t,key:n});},async delete(t){await r.invoke("openrtc_delete_device_key",{appTag:t});},async getOrCreate(t){let n=v(await r.invoke("openrtc_device_public_key",{appTag:t,...e?{keyScope:e}:{}})),{deviceKeyThumbprint:c}=await import('./deviceKey-4DLS246L.js'),d=await c(n);return {publicKeyJwk:n,thumbprint:d,async sign(a){let i=new TextDecoder("utf-8",{fatal:true}).decode(a),o=await r.invoke("openrtc_sign_device_proof",{appTag:t,challenge:i,...e?{keyScope:e}:{}});if(!/^[A-Za-z0-9_-]{80,128}$/.test(o))throw new Error("[OpenRTC] Native host returned an invalid device signature.");return o},async proof(a){let i=u(),o=Math.floor(Date.now()/1e3),s=await r.invoke("openrtc_sign_device_proof",{appTag:t,challenge:a(i,o),...e?{keyScope:e}:{}});if(!/^[A-Za-z0-9_-]{80,128}$/.test(s))throw new Error("[OpenRTC] Native host returned an invalid device proof.");return {publicKeyJwk:n,signature:s,nonce:i,issuedAt:o}}}}}}
2
+ export{l as a};
@@ -0,0 +1 @@
1
+ import {f}from'./chunk-XNJI6KCI.js';function s(t){let o=e=>`${e}:${t}`;return {getOrCreate:e=>f.getOrCreate(o(e)),delete:async e=>{await f.delete?.(o(e));},readSecureRecord:(e,c)=>f.readSecureRecord?.(o(e),c)??Promise.resolve(null),writeSecureRecord:(e,c,d)=>f.writeSecureRecord?.(o(e),c,d)??Promise.resolve(),deleteSecureRecord:(e,c)=>f.deleteSecureRecord?.(o(e),c)??Promise.resolve()}}export{s as a};
@@ -0,0 +1,2 @@
1
+ import {b as b$3,c}from'./chunk-XNJI6KCI.js';import {b as b$2}from'./chunk-ZA44REGI.js';import {e,a}from'./chunk-L7N4T2PX.js';import {d,b as b$1,e as e$1}from'./chunk-72MN7BNQ.js';function b(s){return {irohRelay:s.irohRelay===true||s.irohRelay===void 0&&s.relay!==false,managedTurn:s.managedTurn===true}}var G=1440*6e4,m=class extends Error{constructor(r,n,a$1){super(r);this.status=n;this.reason=a$1;this.name="RTCError";let e=[502,503,504].includes(n),o=a$1==="device-reenrollment-auth-required",i=n===412&&a$1==="device-key-recovery-required";this.code=i?a.AUTH_DEVICE_KEY_RECOVERY_REQUIRED:o?"auth/device-reenrollment-required":e?"coordination/service-unavailable":n===429?"coordination/rate-limited":n===401?"auth/expired":n===403?"admission/denied":"internal/error",this.retryable=o||e,this.plane=i||o||n===401?"auth":e||n===429?"coordination":n===403?"admission":"internal";}};function I(s){return !(s instanceof m)||s.status!==403?false:s.reason==="device-certificate-stale"||s.reason==="device-certificate-revoked"?true:!s.reason&&s.message==="Device certificate is revoked or stale."}function P(s,t,r){return `openrtc:v2:device-certificate:${s}:${t}:${r}`}function A(s,t){return `openrtc:v2:device-session:${s}:${t}`}async function $(s,t,r){let n=new TextEncoder().encode(`openrtc:v2:session\0${s}\0${t}\0${r}`),a=new Uint8Array(await crypto.subtle.digest("SHA-256",n)),e="";for(let o of a)e+=String.fromCharCode(o);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function k(s){let t=s.replace(/-/g,"+").replace(/_/g,"/"),r=t.padEnd(Math.ceil(t.length/4)*4,"="),n=atob(r);return Uint8Array.from(n,a=>a.charCodeAt(0))}function w(s){let t="";for(let r of s)t+=String.fromCharCode(r);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}async function O(s,t,r,n,a){if(typeof s.token!="string"||typeof s.expiresAtMs!="number"||s.expiresAtMs<=Date.now()+G||!s.signingPublicJwk||s.signingPublicJwk.kty!=="OKP"||s.signingPublicJwk.crv!=="Ed25519"||typeof s.signingPublicJwk.x!="string")return null;let e=s.token.split(".");if(e.length!==3)return null;let o,i;try{o=JSON.parse(new TextDecoder().decode(k(e[0]))),i=b$2(s.token);}catch{return null}if(o.alg!=="EdDSA"||s.signingPublicJwk.kid&&o.kid!==s.signingPublicJwk.kid)return null;try{let y=await crypto.subtle.importKey("jwk",s.signingPublicJwk,{name:"Ed25519"},!1,["verify"]);if(!await crypto.subtle.verify({name:"Ed25519"},y,k(e[2]),new TextEncoder().encode(`${e[0]}.${e[1]}`)))return null}catch{return null}let c=typeof i.principalId=="string"?i.principalId:"",d=Number(i.iat),l=Number(i.exp);if(i.iss!=="openrtc"||i.aud!=="openrtc:v2:gateway-grant"||i.typ!=="device-certificate"||i.appTag!==t||!c||a!==void 0&&c!==a||typeof i.principalKey!="string"||i.principalKey.length===0||i.deviceId!==r||i.deviceKeyThumbprint!==n||typeof i.jti!="string"||i.jti.length===0||!Number.isSafeInteger(d)||!Number.isSafeInteger(l)||d>=l||l*1e3!==s.expiresAtMs)return null;let u=b(i);return {token:s.token,expiresAtMs:s.expiresAtMs,principalId:c,signingPublicJwk:s.signingPublicJwk,enrolled:false,...u}}async function j(s,t,r,n,a){try{let e=P(t,r,n),o=s.readSecureRecord?await s.readSecureRecord(t,e):globalThis.localStorage?.getItem(e);if(!o)return null;let i=JSON.parse(o),c=await O(i,t,n,a,r);return c?{token:c.token,expiresAtMs:c.expiresAtMs,principalId:r,signingPublicJwk:c.signingPublicJwk}:null}catch(e){if(s.readSecureRecord)throw e;return null}}async function N(s,t,r,n,a){try{let e=A(t,n),o=s.readSecureRecord?await s.readSecureRecord(r,e):globalThis.localStorage?.getItem(e);return o?await O(JSON.parse(o),r,n,a):null}catch(e){if(s.readSecureRecord)throw e;return null}}async function z(s,t,r,n,a){try{let e=P(t,r,n),o=JSON.stringify(a);s.writeSecureRecord?await s.writeSecureRecord(t,e,o):globalThis.localStorage?.setItem(e,o);}catch(e){if(s.writeSecureRecord)throw e}}async function H(s,t,r,n,a){try{let e=A(r,n),o=JSON.stringify({token:a.token,expiresAtMs:a.expiresAtMs,principalId:a.principalId,signingPublicJwk:a.signingPublicJwk});s.writeSecureRecord?await s.writeSecureRecord(t,e,o):globalThis.localStorage?.setItem(e,o);}catch(e){if(s.writeSecureRecord)throw e}}async function C(s,t,r,n,a){try{let e=P(t,r,n);if(s.deleteSecureRecord?await s.deleteSecureRecord(t,e):globalThis.localStorage?.removeItem(e),a){let o=A(a,n);s.deleteSecureRecord?await s.deleteSecureRecord(t,o):globalThis.localStorage?.removeItem(o);}}catch(e){if(s.deleteSecureRecord)throw e}}function _(s){return `${s}_${crypto.randomUUID()}`}function F(s){if(s instanceof TypeError)return true;if(!s||typeof s!="object")return false;let t=Reflect.get(s,"name");return t==="TimeoutError"||t==="AbortError"}async function V(s,t){let r=new TextEncoder().encode(`${s}:${t}`);return [...new Uint8Array(await crypto.subtle.digest("SHA-256",r))].map(a=>a.toString(16).padStart(2,"0")).join("")}var J=class{constructor(t,r,n,a,e={},o,i){this.apiKey=t;this.endpoints=r;this.keyProvider=n;this.attestation=a;this.events=e;this.botVerification=o;this.rootClientKey=i;this.keyPromise=null;this.authEpochs=new Map;this.appTag=`app_${t.slice(-16)}`;}authEpoch(t){let r=this.authEpochs.get(t);if(r)return r;let n={generation:0,devices:new Map};return this.authEpochs.set(t,n),t.subscribe&&(n.unsubscribe=t.subscribe(a=>{a?.type==="principal-changed"&&(n.generation+=1,n.devices.clear(),n.sessionKeyHash=void 0,this.events.onAuthEpochChanged?.(t));})),n}dispose(){for(let t of this.authEpochs.values())t.unsubscribe?.();this.authEpochs.clear();}key(){return this.keyPromise??(this.keyPromise=this.keyProvider.getOrCreate(this.appTag))}async deviceSigningPublicKey(){return (await this.key()).publicKeyJwk}async signDeviceBytes(t){return (await this.key()).sign(t)}async resolveBroadcastAccess(t,r){if(!/^orb1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(t)||t.length>32768)throw new Error("Broadcast grant is invalid.");if(r&&r.byteLength!==32)throw new Error("Broadcast publisher verification key is invalid.");let n=await this.key(),a=w(new Uint8Array(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(t)))),e=r?w(r):"",o=await n.proof((l,u)=>["openrtc:v2:broadcast-access",this.apiKey,a,e,l,u].join(":")),i=await this.post("/v2/broadcasts",{action:"access",grant:t,...e?{publicationVerifyingKey:e}:{},deviceProof:o});if(i.grant!==t)throw new Error("Broadcast access grant mismatch.");let c=k(i.issuerPublicKey);if(c.byteLength!==32)throw new Error("Broadcast issuer key is invalid.");let d=new URL(i.relay?.relayUrl);if(d.protocol!=="https:"||d.username||d.password)throw new Error("Broadcast relay URL is invalid.");if(typeof i.relay.token!="string"||!/^[A-Za-z0-9._-]{16,16384}$/.test(i.relay.token)||typeof i.relay.namespace!="string"||!/^[A-Za-z0-9._/-]{1,512}$/.test(i.relay.namespace))throw new Error("Broadcast relay allocation is invalid.");return {token:t,issuerPublicKey:c,signBindingChallenge:async l=>{if(!(l instanceof Uint8Array)||l.byteLength>2048)throw new Error("Broadcast binding challenge is invalid.");return k(await n.sign(l))},relay:{relayUrl:d.toString(),token:i.relay.token,namespace:i.relay.namespace}}}async manageBroadcast(t){let r=await this.deviceCertificate(t.auth,t.deviceId),n=t.grant??"",a=t.invite??"",e=t.create,o=t.invitation,i=e?w(e.publisher.verificationKey):o?.publicationVerificationKey?w(o.publicationVerificationKey):"",c=e?{maxPublishers:e.maxPublishers,maxSubscribers:e.maxSubscribers,maxBitrateBps:e.maxBitrateBps,maxDurationSeconds:e.maxDurationSeconds,maxEgressBytes:e.maxEgressBytes}:void 0,d=e?{bitrateBps:e.publisherBitrateBps,durationSeconds:e.maxDurationSeconds,reservedEgressBytes:e.reservedEgressBytes}:o?{role:o.role,sourceSlot:o.sourceSlot??"",bitrateBps:o.bitrateBps,durationSeconds:o.durationSeconds,reservedEgressBytes:o.reservedEgressBytes}:void 0,l=w(new Uint8Array(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(JSON.stringify({action:t.action,grant:n,invite:a,publicationKey:i,sourceSlot:e?.sourceSlot??o?.sourceSlot??"host-a",limits:c,reservation:d}))))),y=await(await this.key()).proof((g,v)=>["openrtc:v2:broadcast-manage",r.source.token,t.action,l,g,v].join(":")),p=await this.post("/v2/broadcasts",{action:t.action,deviceId:t.deviceId,deviceCertificate:r.source.token,deviceProof:y,...n?{grant:n}:{},...a?{invite:a}:{},...i?{publicationVerifyingKey:i}:{},...e?{sourceSlot:e.sourceSlot??"host-a",limits:c,reservation:d}:{},...o?{invitation:{...d,publicationVerifyingKey:i}}:{}});if(t.action==="create"||t.action==="renew"){if(typeof p.grant!="string"||!/^orb1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(p.grant))throw new Error("Managed broadcast grant is invalid.");return p.grant}if(t.action==="invite"){if(typeof p.invite!="string"||!/^obi1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(p.invite))throw new Error("Managed broadcast invitation is invalid.");return p.invite}if(t.action==="accept"){if(typeof p.grant!="string"||!/^orb1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(p.grant))throw new Error("Managed broadcast accepted grant is invalid.");return p.grant}}async post(t,r){let n=_("request"),a=JSON.stringify({apiKey:this.apiKey,...r}),e$2=null;for(let o=0;o<2;o+=1)try{let i=await fetch(`${this.endpoints.controlPlane}${t}`,{method:"POST",headers:{"Content-Type":"application/json","X-OpenRTC-Idempotency-Key":n},body:a,signal:AbortSignal.timeout(15e3)});if(i.ok)return i.json();let c=`OpenRTC request failed (${i.status}).`,d$1,l;try{let y=await i.json();typeof y.error=="string"&&(c=y.error.slice(0,256)),typeof y.reason=="string"&&/^[a-z0-9-]{1,80}$/.test(y.reason)&&(d$1=y.reason),(d(y.code)||b$1(y.code))&&(l=e({...e$1(y),code:y.code,message:c,retryable:y.retryable}));}catch{}let u=l?Object.assign(l,{status:i.status,reason:d$1}):new m(c,i.status,d$1);if(e$2=u,!l&&o===0&&[502,503,504].includes(i.status))continue;throw u}catch(i){if(e$2=i,o===0&&F(i))continue;throw i}throw e$2 instanceof Error?e$2:new Error("OpenRTC request failed.")}async capability(t,r,n,a=false,e,o){let i=t==="space"?await V(this.apiKey,r):r,d=await(await this.key()).proof((p,g)=>["openrtc:v2:capability",this.apiKey,t,i,p,g].join(":")),l=this.botVerification?await this.botVerification.getToken({action:"openrtc_capability",apiKey:this.apiKey}):void 0,u=await this.post("/v2/capabilities",{avenue:{kind:t,id:i},deviceProof:d,...n?{maxPeers:n}:{},...a?{advancedFanout:true}:{},...t==="room"&&e?{architecture:e}:{},...t==="room"&&o?{roomDelivery:o}:{},...l?{turnstileToken:l}:{}}),y={type:"capability",token:u.capability,avenue:t==="ticket"?{kind:"session",id:i}:u.avenue,expiresAtMs:u.expiresAt*1e3,...b(u)};return y.renew=()=>this.capability(t,r,n,a,e,o),y}async deviceCertificate(t,r,n,a,e){if(this.keyProvider.persistence==="session")throw new Error("[OpenRTC] Durable browser device enrollment requires trust.browserPersistence: persistent. Select it explicitly before creating the client; session keys cannot enroll retained devices.");let o=this.authEpoch(t),i=o.devices.get(r)??{};if(o.devices.set(r,i),e&&i.current&&i.current.token!==e.token)return this.deviceCertificateResult(t,r,n,a,{...i.current,enrolled:false});if(!e&&i.current&&i.current.expiresAtMs>Date.now()+G)return this.deviceCertificateResult(t,r,n,a,{...i.current,enrolled:false});if(!i.inFlight){let d=o.generation;e&&(i.current=void 0,i.recoverRevokedEnrollment=true);let l=e?C(this.keyProvider,this.appTag,e.principalId,r,o.sessionKeyHash).then(()=>this.enrollAuthenticatedDevice(t,r,o.sessionKeyHash,a,true)):this.resolveAuthenticatedDevice(t,r,o,a,i.recoverRevokedEnrollment===true);i.inFlight=l.then(u=>{if(o.generation!==d)throw new Error("The OpenRTC authentication identity changed during enrollment.");return i.recoverRevokedEnrollment=false,i.current=u,u}).finally(()=>{i.inFlight=void 0;});}let c=await i.inFlight;return this.deviceCertificateResult(t,r,n,a,c)}async resolveAuthenticatedDevice(t,r,n,a,e=false){let o=await this.key();if(t.getSessionKey){let i=await t.getSessionKey();if(!i)throw new Error("The OpenRTC auth provider has no active principal.");let c=await $(this.appTag,o.thumbprint,i);n.sessionKeyHash=c;let d=await N(this.keyProvider,c,this.appTag,r,o.thumbprint);if(d)return d}return this.enrollAuthenticatedDevice(t,r,n.sessionKeyHash,a,e)}deviceCertificateResult(t,r,n,a,e){let o={type:"device-certificate",token:e.token,avenue:n??{kind:"user",id:e.principalId},expiresAtMs:e.expiresAtMs,irohRelay:e.irohRelay,managedTurn:e.managedTurn};return o.renew=async()=>(await this.deviceCertificate(t,r,n,a)).source,o.recoverRejectedCertificate=async()=>(await this.deviceCertificate(t,r,n,a,e)).source,{principalId:e.principalId,source:o,enrolled:e.enrolled}}async enrollAuthenticatedDevice(t,r,n,a,e=false){let o=async(g,v)=>{let f=await t.getAssertion({audience:"https://api.openrtc.app/v2/assertions/exchange",forceRefresh:g,deviceId:r,...{}});if(!f)throw new Error("The OpenRTC auth provider returned no assertion.");return this.post("/v2/assertions/exchange",{assertion:f,deviceId:r,...t.providerId?{providerId:t.providerId}:{}})},i;try{i=await o(!1);}catch(g){if(!(g instanceof m)||g.status!==401)throw g;i=await o(true);}let c=await this.key(),d=await j(this.keyProvider,this.appTag,i.principalId,r,c.thumbprint);if(d)return {...d,principalId:i.principalId,enrolled:false,...b(i)};let{enrollDevice:l}=await import('./deviceEnrollment-OFC6DSZP.js'),u=await l({apiKey:this.apiKey,appTag:this.appTag,auth:t,attestation:this.attestation,deviceId:r,identity:i,key:c,profile:a,recoverRevokedEnrollment:e||i.deviceRecoveryAuthorized===true,post:(g,v)=>this.post(g,v)});i=u.identity;let y=u.enrollment,p={principalId:i.principalId,token:y.deviceCertificate,expiresAtMs:y.expiresAt*1e3,signingPublicJwk:y.signingPublicJwk,enrolled:true,...b(i)};return await z(this.keyProvider,this.appTag,i.principalId,r,{token:p.token,expiresAtMs:p.expiresAtMs,signingPublicJwk:p.signingPublicJwk}),n&&await H(this.keyProvider,this.appTag,n,r,p),p}async listEnrolledDevices(t,r){let n=await this.deviceCertificate(t,r);return (await this.deviceManagement(n.source,r,"list")).devices??[]}async revokeDevice(t,r,n){let a=await this.deviceCertificate(t,r);if(await this.deviceManagement(a.source,r,"revoke",n),n===r){let e=this.authEpoch(t);await C(this.keyProvider,this.appTag,a.principalId,r,e.sessionKeyHash),e.devices.delete(r),await this.deleteDeviceKey();}}async revokeAllDevices(t,r,n){let a=await this.deviceCertificate(t,r);await this.deviceManagement(a.source,r,"revoke-all",void 0,n);let e=this.authEpoch(t);await C(this.keyProvider,this.appTag,a.principalId,r,e.sessionKeyHash),e.devices.delete(r),n?await this.deviceCertificate(t,r):(e.devices.clear(),await this.deleteDeviceKey());}async deleteDeviceKey(){this.keyPromise=null,await this.keyProvider.delete?.(this.appTag);}async deviceManagement(t,r,n,a,e=false){let{manageDevice:o}=await import('./deviceManagement-SUMBRXXC.js');return await o({source:t,currentDeviceId:r,action:n,targetDeviceId:a,exceptCurrent:e,key:()=>this.key(),post:c=>this.post("/v2/devices/manage",c),isStale:I})}async durableRoomMembership(t,r,n){if(t.type!=="device-certificate")throw new Error("Durable rooms require a device certificate.");let a=b$2(t.token),e=String(a.jti??""),i=await(await this.key()).proof((c,d)=>["openrtc:v2:room-membership",e,n,r,c,d].join(":"));await this.post("/v2/rooms/memberships",{action:n,roomId:r,deviceCertificate:t.token,deviceProof:i});}grantProvider(t,r={}){let n=Promise.resolve(),a=t;return e=>{let o=n.then(async()=>{let i=false;a.expiresAtMs<=Date.now()+3e5&&a.renew&&(a=await a.renew(),i=true);let c$1=async l=>{let u=b$2(l.token),y=String(u.jti??""),p=await this.key(),g=await this.rootClientKey,v=["gateway-grant",this.appTag,y,e.avenue.kind,e.avenue.id,e.runtimeInstanceId,e.ticketFingerprint],f=g?await b$3(g,v):void 0,U=await p.proof((S,E)=>g?c(v,g.thumbprint,S,E):["openrtc:v2:gateway-grant",y,e.avenue.kind,e.avenue.id,e.runtimeInstanceId,S,E].join(":"));return this.post("/v2/gateway/grants",{credentialType:l.type,credential:l.token,avenue:e.avenue,runtimeInstanceId:e.runtimeInstanceId,ticketFingerprint:e.ticketFingerprint,deviceProof:U,...f?{rootProof:f}:{},...e.refreshGrant?{refreshGrant:e.refreshGrant}:{},...r.maxPeers?{maxPeers:r.maxPeers}:{},...r.features?{features:r.features}:{},...e.avenue.kind==="room"&&r.architecture?{architecture:r.architecture}:{},...e.avenue.kind==="room"&&r.roomDelivery?{roomDelivery:r.roomDelivery}:{},...l.type==="device-certificate"&&r.deviceProfile?{deviceProfile:r.deviceProfile}:{}})},d;try{d=await c$1(a);}catch(l){if(!I(l))throw l;let u=await a.recoverRejectedCertificate?.();if(!u)throw l;a=u,i=true,d=await c$1(a);}return i&&await r.onSourceRenewed?.({token:a.token,expiresAtMs:a.expiresAtMs}),d});return n=o.then(()=>{},()=>{}),o}}turnProvider(t){let r=_("relay"),n=null,a=null;return async()=>{if(n&&n.expiresAtMs>Date.now()+5*6e4)return n;if(a)return a;let e=(async()=>{let o=t(),i=b$2(o.token),c=String(i.jti??""),l=await(await this.key()).proof((y,p)=>["openrtc:v2:relay-turn",c,r,y,p].join(":")),u=await this.post("/v2/relay/turn",{credentialType:o.type,credential:o.token,sessionId:r,deviceProof:l});return n=u,u})();a=e;try{return await e}finally{a===e&&(a=null);}}}};
2
+ export{J as a};
@@ -1 +1 @@
1
- import {b as b$3}from'./chunk-FKAQDDUM.js';import {b as b$6,a as a$4,c}from'./chunk-IVNXIG7J.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 {b as b$1,a as a$2}from'./chunk-ZA44REGI.js';import {d,a,e}from'./chunk-L7N4T2PX.js';import {d as d$1,b as b$5}from'./chunk-2GX6GB6L.js';function R(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 S(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();}},A=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 A;this.incomingUni=new A;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=S(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=S(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=S(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();}},O=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=S(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 y(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,U=8,ge=U;function fe(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 ye(a){let e=`openrtc:v2:device-id:${a}`,t,i=(()=>{try{return t=globalThis.localStorage,fe(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 H=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 G=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 O(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=R("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=>R("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,(h,l)=>this.peerStreams.onProtocol(i,h,l),()=>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 h=>{let l=this.logicalConnections.get(i)?.activeRaw;if(!l)throw d(a.DELIVERY_NOT_READY,`[OpenRTC] Peer '${i}' is not connected.`,{retryable:true,plane:"delivery"});await this.sendPayload(l,R("raw","message",h,this.capabilityKey));},onMessage:h=>{let l=this.rawListeners.get(i);l||this.rawListeners.set(i,l=new Set);let u=h;return l.add(u),()=>l?.delete(u)},onClose:h=>{let l=this.closeListeners.get(i);return l||this.closeListeners.set(i,l=new Set),l.add(h),()=>l?.delete(h)}}},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 d of this.stateListeners.get(c)??[])d(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(d=>d.peerId===t||d.connectionId===t||d.connectionIds.some(h=>i.has(h)));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 d=JSON.stringify([n.connectionId,n.generation,r,o,c]);if(this.stateReadyGenerations.get(t)!==d){this.stateReadyGenerations.set(t,d);let l=this.logicalConnections.get(t)?.activeRaw;if(l)for(let[u,p]of this.localState)this.sendState(l,u,p);}let h=this.mediaConnections.get(t);h&&h.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 d of c.values())d.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 G(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();}},E=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,d=>{this.closed||(this.currentInvite=d,this.inviteListeners.forEach(h=>h(d)));})??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=[],d=this.ownsMesh?this.client.advanced.runtime.watchTicketMeshPeers(this.id,()=>o(c.filter(n))):()=>{},h=t[r](l=>{c=l,o(l.filter(n));});return ()=>{h(),d();}};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();}}},k=class k{constructor(e,t){this.options=e;this.internals=t;this.diagnosticClientRef=++k.nextDiagnosticClient;this.nextDiagnosticOperation=0;this.channels=new H;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-URNIFFXC.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-URNIFFXC.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-URNIFFXC.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:${y(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-7ZEAAY7Z.js')).joinRoom(this,e,t)};this.tickets={issue:(e,t={})=>this.activateOnce(`ticket:${y(e)}`,we(t),void 0,()=>this.issueTicket(e,t),t.mesh===true?()=>ae(y(e)):void 0),join:e=>{let t=b$4(e);return t.mesh?this.activateOnce(`ticket:${y(t.id)}`,`join:${e}`,void 0,()=>this.joinTicket(e),()=>ae(y(t.id))):Promise.reject(d(a.TICKET_INVITE_INVALID,"[OpenRTC] This invitation does not describe a ticket mesh.",{retryable:false,plane:"admission"}))}};this.liveSession=null;this.liveRetirementConfirmed=false;this.liveOpening=null;this.live={open:async e=>{if(this.assertOpen(),this.liveOpening||this.liveSession&&!this.liveRetirementConfirmed)throw new Error("[OpenRTC] A live session is already active on this root.");if(!e||typeof e.credentials!="function"||!this.internals.liveHostFactory)throw new Error("[OpenRTC] Live coordination requires an app credential provider and a supported host.");let t={canceled:false,retirementUnconfirmed:false,host:void 0};this.liveOpening=t;try{let i=new URL("/v3/live",(this.internals.endpoints??a$2).gateway).toString(),n=await this.internals.liveHostFactory(i,this.internals.testingAllowInsecureLoopback===!0);if(t.host=n,t.canceled)throw await n.close(),new Error("[OpenRTC] Live activation was closed.");if(await n.open(e),t.canceled)throw await n.close(),new Error("[OpenRTC] Live activation was closed.");let s=new Set,r=new Set,o=l=>{try{l();}catch{}},c=n.onEvent(l=>{if(l.type==="message")for(let u of s)o(()=>u(Object.freeze({channel:l.channel,from:l.from,data:l.data})));if(l.type==="closed"){this.liveSession===h&&(this.liveRetirementConfirmed=!0);for(let u of r)o(u);s.clear(),r.clear();}}),d=l=>{if(typeof l!="string"||!/^[A-Za-z0-9_.:@/-]{1,128}$/.test(l))throw new Error("[OpenRTC] Invalid live channel.");return l},h={get closed(){return n.closed},renew:()=>n.renew(),subscribe:async l=>{await n.request({type:"subscribe",channel:d(l)});},unsubscribe:async l=>{await n.request({type:"unsubscribe",channel:d(l)});},publish:async(l,u)=>{if(typeof u!="string"||new TextEncoder().encode(u).byteLength>65536)throw new Error("[OpenRTC] Live publication exceeds 64 KiB.");let p=await n.request({type:"publish",channel:d(l),data:u});if(!Number.isSafeInteger(p.units)||p.units<1)throw new Error("[OpenRTC] Invalid live publication receipt.");return {units:p.units}},onMessage:l=>(n.closed||s.add(l),()=>{s.delete(l);}),onClose:l=>(n.closed?o(l):r.add(l),()=>{r.delete(l);}),close:async()=>{await n.close(),this.liveSession===h&&(this.liveRetirementConfirmed=!0),c(),s.clear(),r.clear();}};return this.liveSession=h,this.liveRetirementConfirmed=!1,h}catch(i){try{await t.host?.close();}catch(n){throw t.retirementUnconfirmed=true,n}throw i}finally{this.liveOpening===t&&!t.retirementUnconfirmed&&(this.liveOpening=null);}}};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="profile"in e&&e.profile==="live"?"":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=this.apiKey?`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(){if("profile"in this.options&&this.options.profile==="live")throw new Error("[OpenRTC] This live-only root does not activate managed devices, rooms or peers.");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(){if("profile"in this.options&&this.options.profile==="live")throw new Error("[OpenRTC] This live-only root does not activate managed devices, rooms or peers.");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,d=c?performance.now():0,h=c?++this.nextDiagnosticOperation:0,l=e.split(":",1)[0],u=["devices","space","room","ticket"].includes(l)?l:"custom",p=f=>{c&&b$6(c,Object.freeze({sdkVersion:a$4,clientRef:this.diagnosticClientRef,name:"capability.activation",operationRef:h,avenue:u,outcome:f,timestampMs:Date.now(),elapsedMs:performance.now()-d}));},g;try{g=this.pendingCapabilityShutdowns.has(e)?this.settlePendingCapabilityShutdown(e).then(n):n();}catch(f){throw p("started"),p("failed"),f}let z=g.then(f=>(o.handle=f,p("succeeded"),f)).catch(f=>{throw p("failed"),this.activations.get(e)===o&&this.activations.delete(e),f});return o.promise=z,this.activations.set(e,o),p("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()):ye(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,d=!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:h=>e.nativeAuth.getAssertion(h)}: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:d?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,d=()=>e.authority?{userId:e.principalId}:{userId:e.principalId,token:o.token,tokenProvider:async()=>o.token,expiresAtMs:o.expiresAtMs},h=e.authority?.devicePublicKeyX??String((await t.deviceSigningPublicKey()).x??""),l=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(d());}}),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:h,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}),[u,{wrapAssembly:p}]=await Promise.all([this.internals.runtimeFactory(l),import('./coreClient.js')]);c=p(u,this.internals.platform==="native"?"native":"web"),await c.setAuth(d()),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),d=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}),h=[];if(this.internals.platform!=="native")try{h=await o.listEnrolledDevices(i,n);}catch(g){throw this.channels.detach(d),await d.advanced.runtime.shutdown().catch(()=>{}),g}let{AuthenticatedDeviceRoster:l}=await import('./deviceRoster-EUF6BBF5.js'),{DeviceHandle:u}=await import('./deviceHandle-URNIFFXC.js'),p;return p=new u(c.principalId,d,()=>{this.channels.detach(d),this.onClosed(p);},new l(h)),this.handles.add(p),p}async joinSpace(e,t={}){this.assertOpen();let i=y(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-7ZEAAY7Z.js')).openAuthorityRoom(this,e)}async issueTicket(e,t={}){this.assertOpen();let i=y(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>U))throw d(a.TICKET_MESH_INVALID_OPTIONS,`[OpenRTC] Ticket mesh maxPeers must be an integer between ${ne} and ${U}.`,{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}),d$1=null;if(t.mesh===true)try{d$1=await c.advanced.runtime.issueTicketMesh(i,n);}catch(l){await this.shutdownFailedTicketActivation(i,c,l);}let h;return h=new E(i,c,()=>{this.channels.detach(c),this.onClosed(h);},r.token,d$1,t.mesh===true),this.handles.add(h),h}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=y(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(d){await this.shutdownFailedTicketActivation(i,o,d);}let c;return c=new E(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(){if(this.liveOpening){let e=this.liveOpening;e.canceled=true,await e.host?.close(),this.liveOpening===e&&(this.liveOpening=null);}await this.liveSession?.close(),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;}};k.nextDiagnosticClient=0;var D=k;function xe(a,e){return new D(a,e)}function Le(a,e){if(!(a instanceof D))throw new TypeError("[OpenRTC] ServiceNode requires a client created by this OpenRTC package.");return a.openAuthorityRoom(e)}export{R as a,B as b,pe as c,Be as d,y as e,re as f,N as g,T as h,xe as i,Le as j};
1
+ import {b as b$3}from'./chunk-FKAQDDUM.js';import {b as b$6,a as a$4,c}from'./chunk-SSBR3IHA.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 {b as b$1,a as a$2}from'./chunk-ZA44REGI.js';import {d,a,e}from'./chunk-L7N4T2PX.js';import {d as d$1,b as b$5}from'./chunk-2GX6GB6L.js';function S(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 x(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",ue=32,ee=16,_=4294967295,pe=/^[A-Za-z0-9][A-Za-z0-9._/+:-]{0,127}$/,me=/^([0-9a-f]{64})-([0-9a-f]{64})$/i;function A(a){let e=a?.trim()??"";if(!pe.test(e))throw new Error("[OpenRTC] stream protocol must be 1-128 safe ASCII characters.");return e}function L(a){let e=a?.trim()??"",t=me.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(_,Math.ceil(a))}function ie(a){if(!Number.isSafeInteger(a)||a<1||a>_)throw new RangeError(`[OpenRTC] datagram buffer limits must be integers from 1 to ${_}.`);return a}var F=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();}},O=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:ue});}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);}},K=class{constructor(e,t,i,n){this.client=e;this.peerId=t;this.capabilityKey=n;this.incomingBi=new O;this.incomingUni=new O;this.incomingBidirectionalStreams=this.incomingBi.readable;this.incomingUnidirectionalStreams=this.incomingUni.readable;this.closed=false;this.protocolHandlers=new Map;this.datagrams=new F(i,this.peerId);}async createBidirectionalStream(e){let t=A(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=A(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=A(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();}},T=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 K(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=L(e),n=t.trim();!i||!n||this.peerIdsByConnection.set(i,n);}unbindConnection(e){this.peerIdsByConnection.delete(L(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=A(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=L(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 y=new WeakMap;function ve(a){let e=y.get(a);if(!e||a.closed)throw new Error("[OpenRTC] Capability runtime is unavailable or already closed.");return e}function Le(a,e){if(y.has(a))throw new Error("[OpenRTC] Capability runtime is already registered.");return y.set(a,ve(e)),()=>{y.delete(a);}}function ge(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 z=/^[A-Za-z0-9_.:@-]{1,160}$/,fe=/^[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,U=8,ye=U;function we(a){let e=typeof a=="string"?a.trim():"";if(!z.test(e))return null;let t=e.startsWith("device_")?e.slice(7):"";return fe.test(t)?t:e}function Ce(a){let e=`openrtc:v2:device-id:${a}`,t,i=(()=>{try{return t=globalThis.localStorage,we(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(!z.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(!z.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 G=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??ye:a.maxPeers}function be(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 T(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=x(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=S("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=>S("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,(h,l)=>this.peerStreams.onProtocol(i,h,l),()=>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 h=>{let l=this.logicalConnections.get(i)?.activeRaw;if(!l)throw d(a.DELIVERY_NOT_READY,`[OpenRTC] Peer '${i}' is not connected.`,{retryable:true,plane:"delivery"});await this.sendPayload(l,S("raw","message",h,this.capabilityKey));},onMessage:h=>{let l=this.rawListeners.get(i);l||this.rawListeners.set(i,l=new Set);let p=h;return l.add(p),()=>l?.delete(p)},onClose:h=>{let l=this.closeListeners.get(i);return l||this.closeListeners.set(i,l=new Set),l.add(h),()=>l?.delete(h)}}},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 d of this.stateListeners.get(c)??[])d(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(d=>d.peerId===t||d.connectionId===t||d.connectionIds.some(h=>i.has(h)));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 d=JSON.stringify([n.connectionId,n.generation,r,o,c]);if(this.stateReadyGenerations.get(t)!==d){this.stateReadyGenerations.set(t,d);let l=this.logicalConnections.get(t)?.activeRaw;if(l)for(let[p,m]of this.localState)this.sendState(l,p,m);}let h=this.mediaConnections.get(t);h&&h.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 d of c.values())d.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=x(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(()=>{});}},E=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;y.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){y.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(),y.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))}},q=class extends E{constructor(t,i,n,s){super("space",t,i,n);this.delivery=s;this.kind="space";this.leave=()=>this.close();}},D=class extends E{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,d=>{this.closed||(this.currentInvite=d,this.inviteListeners.forEach(h=>h(d)));})??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=[],d=this.ownsMesh?this.client.advanced.runtime.watchTicketMeshPeers(this.id,()=>o(c.filter(n))):()=>{},h=t[r](l=>{c=l,o(l.filter(n));});return ()=>{h(),d();}};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();}}},M=class M{constructor(e,t){this.options=e;this.internals=t;this.diagnosticClientRef=++M.nextDiagnosticClient;this.nextDiagnosticOperation=0;this.channels=new G;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-DFG3CCY3.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-DFG3CCY3.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-DFG3CCY3.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-ZQU7JFRG.js')).joinRoom(this,e,t)};this.tickets={issue:(e,t={})=>this.activateOnce(`ticket:${f(e)}`,be(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.liveSession=null;this.liveRetirementConfirmed=false;this.liveOpening=null;this.live={open:async e=>{if(this.assertOpen(),this.liveOpening||this.liveSession&&!this.liveRetirementConfirmed)throw new Error("[OpenRTC] A live session is already active on this root.");if(!e||typeof e.credentials!="function"||!this.internals.liveHostFactory)throw new Error("[OpenRTC] Live coordination requires an app credential provider and a supported host.");let t={canceled:false,retirementUnconfirmed:false,host:void 0};this.liveOpening=t;try{let i=new URL("/v3/live",(this.internals.endpoints??a$2).gateway).toString(),n=await this.internals.liveHostFactory(i,this.internals.testingAllowInsecureLoopback===!0);if(t.host=n,t.canceled)throw await n.close(),new Error("[OpenRTC] Live activation was closed.");if(await n.open(e),t.canceled)throw await n.close(),new Error("[OpenRTC] Live activation was closed.");let s=new Set,r=new Set,o=l=>{try{l();}catch{}},c=n.onEvent(l=>{if(l.type==="message")for(let p of s)o(()=>p(Object.freeze({channel:l.channel,from:l.from,data:l.data})));if(l.type==="closed"){this.liveSession===h&&(this.liveRetirementConfirmed=!0);for(let p of r)o(p);s.clear(),r.clear();}}),d=l=>{if(typeof l!="string"||!/^[A-Za-z0-9_.:@/-]{1,128}$/.test(l))throw new Error("[OpenRTC] Invalid live channel.");return l},h={get closed(){return n.closed},renew:()=>n.renew(),subscribe:async l=>{await n.request({type:"subscribe",channel:d(l)});},unsubscribe:async l=>{await n.request({type:"unsubscribe",channel:d(l)});},publish:async(l,p)=>{if(typeof p!="string"||new TextEncoder().encode(p).byteLength>65536)throw new Error("[OpenRTC] Live publication exceeds 64 KiB.");let m=await n.request({type:"publish",channel:d(l),data:p});if(!Number.isSafeInteger(m.units)||m.units<1)throw new Error("[OpenRTC] Invalid live publication receipt.");return {units:m.units}},onMessage:l=>(n.closed||s.add(l),()=>{s.delete(l);}),onClose:l=>(n.closed?o(l):r.add(l),()=>{r.delete(l);}),close:async()=>{await n.close(),this.liveSession===h&&(this.liveRetirementConfirmed=!0),c(),s.clear(),r.clear();}};return this.liveSession=h,this.liveRetirementConfirmed=!1,h}catch(i){try{await t.host?.close();}catch(n){throw t.retirementUnconfirmed=true,n}throw i}finally{this.liveOpening===t&&!t.retirementUnconfirmed&&(this.liveOpening=null);}}};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="profile"in e&&e.profile==="live"?"":ge(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=this.apiKey?`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-HOFWXQJW.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,this.rootClientKey()))}rootClientKey(){return this.rootClientKeyPromise??(this.rootClientKeyPromise=this.internals.deviceKeyProvider?.getRootClientKey?this.internals.deviceKeyProvider.getRootClientKey(this.appTag):import('./deviceKey-4DLS246L.js').then(({createSessionDeviceKeyProvider:e})=>e().getOrCreate(this.appTag)))}controlPlane(){if("profile"in this.options&&this.options.profile==="live")throw new Error("[OpenRTC] This live-only root does not activate managed devices, rooms or peers.");return this.controlPlanePromise??(this.controlPlanePromise=this.makeControlPlane(this.internals.deviceKeyProvider?Promise.resolve(this.internals.deviceKeyProvider):import('./deviceKey-4DLS246L.js').then(({browserDeviceKeyProvider:e,createSessionDeviceKeyProvider:t})=>this.internals.platform!=="native"&&this.browserPersistence!=="persistent"?t():e)))}sessionPlane(){if("profile"in this.options&&this.options.profile==="live")throw new Error("[OpenRTC] This live-only root does not activate managed devices, rooms or peers.");return this.sessionPlanePromise??(this.sessionPlanePromise=this.makeControlPlane(import('./deviceKey-4DLS246L.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,d=c?performance.now():0,h=c?++this.nextDiagnosticOperation:0,l=e.split(":",1)[0],p=["devices","space","room","ticket"].includes(l)?l:"custom",m=u=>{c&&b$6(c,Object.freeze({sdkVersion:a$4,clientRef:this.diagnosticClientRef,name:"capability.activation",operationRef:h,avenue:p,outcome:u,timestampMs:Date.now(),elapsedMs:performance.now()-d}));},w;try{w=this.pendingCapabilityShutdowns.has(e)?this.settlePendingCapabilityShutdown(e).then(n):n();}catch(u){throw m("started"),m("failed"),u}let P=w.then(u=>(o.handle=u,m("succeeded"),u)).catch(u=>{throw m("failed"),this.activations.get(e)===o&&this.activations.delete(e),u});return o.promise=P,this.activations.set(e,o),m("started"),P}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()):Ce(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,d=!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:h=>e.nativeAuth.getAssertion(h)}: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:d?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,d=()=>e.authority?{userId:e.principalId}:{userId:e.principalId,token:o.token,tokenProvider:async()=>o.token,expiresAtMs:o.expiresAtMs},h=e.authority?.devicePublicKeyX??String((await t.deviceSigningPublicKey()).x??""),l=e.authority,p=l?async u=>{let{rootClientProof:de}=await import('./deviceKey-4DLS246L.js'),he=await de(await this.rootClientKey(),["authority-service-grant",this.appTag,u.avenue.id,l.serviceId,String(l.generation),[...l.shardIds].sort().join(","),l.assignmentPublicKeyX,u.deviceId,u.runtimeInstanceId,u.ticketFingerprint]);return l.grantProvider({...u,rootProof:he})}:void 0,m=this.runtimeOptions({avenue:e.source.avenue,grantProvider:p??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 u=>{o={...o,...u},await c?.setAuth(d());}}),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:h,deviceSign:e.authority?.deviceSign??(u=>t.signDeviceBytes(u)),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}),[w,{wrapAssembly:P}]=await Promise.all([this.internals.runtimeFactory(m),import('./coreClient.js')]);c=P(w,this.internals.platform==="native"?"native":"web"),await c.setAuth(d()),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(u){throw this.channels.detach(c),await c.advanced.runtime.shutdown().catch(()=>{}),u}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),d=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}),h=[];if(this.internals.platform!=="native")try{h=await o.listEnrolledDevices(i,n);}catch(w){throw this.channels.detach(d),await d.advanced.runtime.shutdown().catch(()=>{}),w}let{AuthenticatedDeviceRoster:l}=await import('./deviceRoster-EUF6BBF5.js'),{DeviceHandle:p}=await import('./deviceHandle-DFG3CCY3.js'),m;return m=new p(c.principalId,d,()=>{this.channels.detach(d),this.onClosed(m);},new l(h)),this.handles.add(m),m}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 q(i,o,()=>{this.channels.detach(o),this.onClosed(c);},t.payload??"reliable"),this.handles.add(c),c}async openAuthorityRoom(e){return (await import('./room-ZQU7JFRG.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>U))throw d(a.TICKET_MESH_INVALID_OPTIONS,`[OpenRTC] Ticket mesh maxPeers must be an integer between ${ne} and ${U}.`,{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}),d$1=null;if(t.mesh===true)try{d$1=await c.advanced.runtime.issueTicketMesh(i,n);}catch(l){await this.shutdownFailedTicketActivation(i,c,l);}let h;return h=new D(i,c,()=>{this.channels.detach(c),this.onClosed(h);},r.token,d$1,t.mesh===true),this.handles.add(h),h}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(d){await this.shutdownFailedTicketActivation(i,o,d);}let c;return c=new D(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(){if(this.liveOpening){let e=this.liveOpening;e.canceled=true,await e.host?.close(),this.liveOpening===e&&(this.liveOpening=null);}await this.liveSession?.close(),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;}};M.nextDiagnosticClient=0;var k=M;function _e(a,e){return new k(a,e)}function Fe(a,e){if(!(a instanceof k))throw new TypeError("[OpenRTC] ServiceNode requires a client created by this OpenRTC package.");return a.openAuthorityRoom(e)}export{S as a,x as b,ve as c,Le as d,f as e,re as f,N as g,E as h,_e as i,Fe as j};
@@ -1 +1 @@
1
- var w="3.1.1";function R(t,o){if(t)try{Promise.resolve(t(o)).catch(()=>{});}catch{}}var y=new Set(["transport-healthy","missing-active-transport","native-main-route-pending","session-admission-pending","application-crypto-key-pending","application-crypto-confirmation-pending","bounded-health-confirmation-pending","authoritative-device-binding-pending","device-offline","manual-disconnect","waiting-for-transport","transport-attached-awaiting-readiness-confirmation","transport-connected-health-check-pending","readiness-confirmation-timed-out","transport-closed","connection-failed"]),_=new Set(["user-device","persistent","trusted-device","ticket","room","space","share","drive-grant"]),O=new Set(["connected","connecting","disconnected","failed","closed"]),P=new Set(["unknown","pending","admitted","rejected","expired"]),x=new Set(["iroh","iroh-quic","iroh-lan","iroh-relay","webrtc","moq","ble"]),g=t=>Number.isSafeInteger(t)&&t>=0?t:null;function k(t,o={}){let a=o.maxEvents??256;if(!Number.isInteger(a)||a<1||a>1024)throw new RangeError("Diagnostic maxEvents must be an integer between 1 and 1024");let h=Date.now(),S=performance.now(),r=new Map,c=new Map,d=[],D=0,f=0,p=false,v=false,b=(s,n)=>{let e=Object.freeze({sequence:++D,timestampMs:Date.now(),elapsedMs:performance.now()-S,level:n.hasError||n.state==="failed"?"warn":n.ready?"info":"debug",name:s,peer:Object.freeze({...n,scopeKinds:Object.freeze([...n.scopeKinds])})});d.length===a&&(d.shift(),f++),d.push(e),R(o.logger,e);},E=t(s=>{if(p)return;let n=new Map;for(let e of s){let i=r.get(e.peerId);if(!i){if(r.size===64){v=true;continue}i=`peer-${r.size+1}`,r.set(e.peerId,i);}let m=e.readinessReason==="manual disconnect"?"manual-disconnect":e.readinessReason,l={peerRef:i,state:O.has(e.status)?e.status:"unknown",admission:e.admissionState&&P.has(e.admissionState)?e.admissionState:"unknown",ready:e.settledReady===true,readinessCode:m&&y.has(m)?m:"unclassified",scopeKinds:[...new Set(e.scopes.map(u=>u.split(":",1)[0]).map(u=>_.has(u)?u:"custom"))].sort(),transportGeneration:g(e.transportGeneration),routeGeneration:g(e.routeGeneration),transportStableId:g(e.transportStableId??void 0),transport:e.activeTransport&&x.has(e.activeTransport)?e.activeTransport:"unknown",hasError:!!e.error};n.set(i,l),JSON.stringify(c.get(i))!==JSON.stringify(l)&&b("peer.changed",l);}for(let[e,i]of c)n.has(e)||b("peer.removed",{...i,ready:false,state:"disconnected"});c=n;});return {snapshot:()=>({schemaVersion:1,sdkVersion:w,startedAtMs:h,stopped:p,droppedEvents:f,peerLimitReached:v,events:d.map(s=>({...s,peer:{...s.peer,scopeKinds:[...s.peer.scopeKinds]}}))}),stop:()=>{p||(p=true,E(),r.clear(),c.clear());}}}export{w as a,R as b,k as c};
1
+ var w="3.1.2";function R(t,o){if(t)try{Promise.resolve(t(o)).catch(()=>{});}catch{}}var y=new Set(["transport-healthy","missing-active-transport","native-main-route-pending","session-admission-pending","application-crypto-key-pending","application-crypto-confirmation-pending","bounded-health-confirmation-pending","authoritative-device-binding-pending","device-offline","manual-disconnect","waiting-for-transport","transport-attached-awaiting-readiness-confirmation","transport-connected-health-check-pending","readiness-confirmation-timed-out","transport-closed","connection-failed"]),_=new Set(["user-device","persistent","trusted-device","ticket","room","space","share","drive-grant"]),O=new Set(["connected","connecting","disconnected","failed","closed"]),P=new Set(["unknown","pending","admitted","rejected","expired"]),x=new Set(["iroh","iroh-quic","iroh-lan","iroh-relay","webrtc","moq","ble"]),g=t=>Number.isSafeInteger(t)&&t>=0?t:null;function k(t,o={}){let a=o.maxEvents??256;if(!Number.isInteger(a)||a<1||a>1024)throw new RangeError("Diagnostic maxEvents must be an integer between 1 and 1024");let h=Date.now(),S=performance.now(),r=new Map,c=new Map,d=[],D=0,f=0,p=false,v=false,b=(s,n)=>{let e=Object.freeze({sequence:++D,timestampMs:Date.now(),elapsedMs:performance.now()-S,level:n.hasError||n.state==="failed"?"warn":n.ready?"info":"debug",name:s,peer:Object.freeze({...n,scopeKinds:Object.freeze([...n.scopeKinds])})});d.length===a&&(d.shift(),f++),d.push(e),R(o.logger,e);},E=t(s=>{if(p)return;let n=new Map;for(let e of s){let i=r.get(e.peerId);if(!i){if(r.size===64){v=true;continue}i=`peer-${r.size+1}`,r.set(e.peerId,i);}let m=e.readinessReason==="manual disconnect"?"manual-disconnect":e.readinessReason,l={peerRef:i,state:O.has(e.status)?e.status:"unknown",admission:e.admissionState&&P.has(e.admissionState)?e.admissionState:"unknown",ready:e.settledReady===true,readinessCode:m&&y.has(m)?m:"unclassified",scopeKinds:[...new Set(e.scopes.map(u=>u.split(":",1)[0]).map(u=>_.has(u)?u:"custom"))].sort(),transportGeneration:g(e.transportGeneration),routeGeneration:g(e.routeGeneration),transportStableId:g(e.transportStableId??void 0),transport:e.activeTransport&&x.has(e.activeTransport)?e.activeTransport:"unknown",hasError:!!e.error};n.set(i,l),JSON.stringify(c.get(i))!==JSON.stringify(l)&&b("peer.changed",l);}for(let[e,i]of c)n.has(e)||b("peer.removed",{...i,ready:false,state:"disconnected"});c=n;});return {snapshot:()=>({schemaVersion:1,sdkVersion:w,startedAtMs:h,stopped:p,droppedEvents:f,peerLimitReached:v,events:d.map(s=>({...s,peer:{...s.peer,scopeKinds:[...s.peer.scopeKinds]}}))}),stop:()=>{p||(p=true,E(),r.clear(),c.clear());}}}export{w as a,R as b,k as c};
@@ -0,0 +1,2 @@
1
+ import {g,b,d as d$1,c}from'./chunk-XNJI6KCI.js';import {j,d as d$2,c as c$1}from'./chunk-RUOVYQ2P.js';var N=/^[A-Za-z0-9_.:@-]+$/,k=/^[A-Za-z0-9_-]{43}$/,_=/^[A-Za-z0-9_.:@-]+$/,G=/^[A-Za-z0-9._-]+$/,U=120*6e4,E=new TextEncoder;function d(r,e,t=160){let n=r.trim();if(!n||n.length>t||!N.test(n))throw new TypeError(`[OpenRTC] ${e} is invalid.`);return n}function u(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 M(r){let e="";for(let t of r)e+=String.fromCharCode(t);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}async function m(r,e){let t=await r.publicJwk();if(t.kty!=="OKP"||t.crv!=="Ed25519"||typeof t.x!="string"||!k.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 M(n)}function J(r){if(!/^pk_(?:live|test)_[A-Za-z0-9]+$/.test(r))throw new TypeError("[OpenRTC] apiKey is invalid.");return `app_${r.slice(-16)}`}function l(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 L(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 $(r,e){let t=l(r),n=l(t?.avenue),i=l(t?.roomAuthority),a=l(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((g,h)=>g!==e.shardIds[h])||a?.kty!=="OKP"||a.crv!=="Ed25519"||a.x!==e.assignmentPublicKeyX||!Number.isSafeInteger(o)||o<=c||o>c+U||!Number.isSafeInteger(s)||s<1||s>e.maxPeers)throw new Error("[OpenRTC] authority service grant response is inconsistent.");return {protocolVersion:2,gatewayUrl:L(t.gatewayUrl),routeKey:v(t.routeKey,"routeKey",256,_),token:v(t.token,"token",24e3,G),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=J(e.apiKey),this.rootClientKey=g().getOrCreate(this.applicationTag),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=u(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(!k.test(e.ticketFingerprint))throw new TypeError("[OpenRTC] ticketFingerprint is invalid.");e.maxPeers!==void 0&&u(e.maxPeers,"maxPeers",50);let i=await m(this.assignmentSigner,"assignmentSigner.publicJwk()"),a=await m(this.deviceSigner,"deviceSigner.publicJwk()"),c$1=crypto.randomUUID().replace(/-/g,""),o=Math.floor(Date.now()/1e3),s=["authority-service-grant",this.applicationTag,t,this.serviceId,String(this.generation),this.shardIds.join(","),String(i.x),this.deviceId,n,e.ticketFingerprint],g=e.rootProof===void 0?await this.rootClientKey:void 0,h=e.rootProof??(g?await b(g,s):void 0),f=h?await d$1(h.publicKeyJwk):void 0,x=f?c(s,f,c$1,o):["openrtc:v2:authority-service-grant",this.applicationTag,t,this.serviceId,String(this.generation),this.shardIds.join(","),i.x,n,c$1,o].join(":"),T={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$1,issuedAt:o,signature:await y(this.deviceSigner,E.encode(x),"deviceSigner.sign()")},...e.maxPeers===void 0?{}:{maxPeers:e.maxPeers},...e.refreshGrant?{refreshGrant:e.refreshGrant}:{},...h?{rootProof:h}:{},features:e.features??{}},O=`authority_${crypto.randomUUID().replace(/-/g,"")}`,D=await this.grantIssuer({apiKey:this.apiKey,idempotencyKey:O,body:T});return $(D,{roomId:t,serviceId:this.serviceId,generation:this.generation,shardIds:this.shardIds,assignmentPublicKeyX:i.x,maxPeers:e.maxPeers??50})}async devicePublicKey(){return m(this.deviceSigner,"deviceSigner.publicJwk()")}async assignmentPublicKey(){return m(this.assignmentSigner,"assignmentSigner.publicJwk()")}async signDeviceBytes(e){return y(this.deviceSigner,e,"deviceSigner.sign()")}async signAssignment(e){let t=e.ttlMs??6e4;u(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:u(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,E.encode(JSON.stringify(o)),"assignmentSigner.sign()")}}},I=class{constructor(e,t,n){this.room=e;this.authority=t;this.onClosed=n;this.releaseRuntimeAlias=d$2(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$1(this.room).advanced.runtime.publishAuthorityAssignment(t),t.assignment}retire(e){return this.retirement??(this.retirement=e().finally(()=>{this.releaseRuntimeAlias(),this.onClosed();}))}},K=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,rootProof:s.rootProof,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
+ export{p as a,K as b};
@@ -0,0 +1,2 @@
1
+ import d from'tweetnacl';function w(t,r,e){return JSON.stringify(["openrtc:root-client:v1",t,r,e])}async function k(t,r){let e=await t.proof((n,o)=>w(r,n,o));return {...e,publicKeyJwk:{kty:"OKP",crv:"Ed25519",x:e.publicKeyJwk.x}}}function C(t,r,e,n){return JSON.stringify(["openrtc:device-root-binding:v1",t,r,e,n])}function c(t){let r=t instanceof Uint8Array?t:new Uint8Array(t),e="";for(let n of r)e+=String.fromCharCode(n);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function g(t){let r=JSON.stringify({crv:t.crv,kty:t.kty,x:t.x});return c(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(r)))}function p(){return c(crypto.getRandomValues(new Uint8Array(24)).buffer)}async function y(){return typeof indexedDB>"u"?null:new Promise((t,r)=>{let e=indexedDB.open("openrtc-v2-device-keys",1);e.onupgradeneeded=()=>{e.result.objectStoreNames.contains("keys")||e.result.createObjectStore("keys");},e.onsuccess=()=>t(e.result),e.onerror=()=>r(e.error);})}async function v(t){let r=await y().catch(()=>null);if(!r)throw new Error("[OpenRTC] Persistent browser identity storage is unavailable.");try{return await new Promise((e,n)=>{let o=r.transaction("keys","readonly").objectStore("keys").get(t);o.onsuccess=()=>e(o.result??null),o.onerror=()=>n(o.error);})}finally{r.close();}}async function K(t,r){let e=await y().catch(()=>null);if(!e)throw new Error("[OpenRTC] Persistent browser identity storage is unavailable.");try{return await new Promise((n,o)=>{let i=e.transaction("keys","readwrite"),s=r;i.oncomplete=()=>n(s),i.onabort=()=>o(i.error??new Error("[OpenRTC] Persistent browser identity storage transaction aborted."));let u=i.objectStore("keys"),a=u.get(t);a.onerror=()=>o(a.error),a.onsuccess=()=>{if(a.result!==void 0&&a.result!==null){s=a.result;return}let l=u.put(r,t);l.onerror=()=>o(l.error);};})}finally{e.close();}}async function P(t){let r=await y().catch(()=>null);if(r)try{await new Promise((e,n)=>{let o=r.transaction("keys","readwrite").objectStore("keys").delete(t);o.onsuccess=()=>e(),o.onerror=()=>n(o.error);});}finally{r.close();}}async function b(t){let r=await v(t);if(r)return r;let e=await crypto.subtle.generateKey({name:"Ed25519"},false,["sign","verify"]);return K(t,e)}async function f(t){let r=await crypto.subtle.exportKey("jwk",t.publicKey),e=await g(r);return {publicKeyJwk:r,thumbprint:e,async sign(n){return c(await crypto.subtle.sign({name:"Ed25519"},t.privateKey,n))},async proof(n){let o=p(),i=Math.floor(Date.now()/1e3),s=await crypto.subtle.sign({name:"Ed25519"},t.privateKey,new TextEncoder().encode(n(o,i)));return {publicKeyJwk:r,signature:c(s),nonce:o,issuedAt:i}}}}async function m(){return f(await crypto.subtle.generateKey({name:"Ed25519"},false,["sign","verify"]))}async function D(){try{return await m()}catch(o){if(!(o instanceof Error)||o.name!=="NotSupportedError")throw o}let t=d.sign.keyPair(),r={kty:"OKP",crv:"Ed25519",x:c(t.publicKey)},e=await g(r),n=async o=>c(d.sign.detached(o,t.secretKey));return {publicKeyJwk:r,thumbprint:e,sign:n,async proof(o){let i=p(),s=Math.floor(Date.now()/1e3);return {publicKeyJwk:r,signature:await n(new TextEncoder().encode(o(i,s))),nonce:i,issuedAt:s}}}}var S={persistence:"persistent",async getOrCreate(t){return f(await b(t))},delete:P};function h(){let t=new Map,r=new Map;return {persistence:"session",getOrCreate(e){let n=t.get(e);return n||(n=D(),t.set(e,n)),n},async delete(e){t.delete(e),r.delete(e);},async readSecureRecord(e,n){return r.get(e)?.get(n)??null},async writeSecureRecord(e,n,o){let i=r.get(e);i||(i=new Map,r.set(e,i)),i.set(n,o);},async deleteSecureRecord(e,n){r.get(e)?.delete(n);}}}
2
+ export{w as a,k as b,C as c,g as d,m as e,S as f,h as g};
@@ -0,0 +1 @@
1
+ export{a as ControlPlane}from'./chunk-M2QMGAL2.js';import'./chunk-XNJI6KCI.js';export{a as PRODUCTION_ENDPOINTS,b as decodeClaims}from'./chunk-ZA44REGI.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';
@@ -1,6 +1,6 @@
1
- import { P as PolicySnapshot, a as PeerReconciliationStats, R as RuntimeClient, b as PlutoRuntimeAssembly } from './assembly-DGrOqsLW.js';
2
- import { k as RuntimePeerState, l as PeerConnectOptions, m as Connection, n as PeerSessionSnapshot, o as PeerReadiness, p as RuntimePeerHealth, q as ResolvedPeerIdentity, C as ChannelDescriptor, r as PeerStreamOptions, I as IncomingStream, s as ScopedChannelOptions, t as RuntimeDevice, u as ScopedLogicalChannel, v as ConnectionState, w as ReadinessOptions, x as ConnectionEvent, d as TransferPeerDemandRequest, f as TransferPeerDemandStatus, M as ManagedOptions, y as ManagedSession, D as DeviceStatus, z as DeviceConnectOptions, A as ConnectDeviceResult, B as ConnectDeviceHooks, F as ConnectDeviceOptions, L as LocalDeviceInfo, G as DeviceProfile, H as RawConnection, J as JoinRoomOptions, K as RuntimeRoomMember, N as GrantScope, O as AuthContext, Q as RuntimeClientOptions } from './Connection-BGVBMbWg.js';
3
- import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-DsKud7Sw.js';
1
+ import { P as PolicySnapshot, a as PeerReconciliationStats, R as RuntimeClient, b as PlutoRuntimeAssembly } from './assembly-CtrHmP4j.js';
2
+ import { o as RuntimePeerState, p as PeerConnectOptions, q as Connection, r as PeerSessionSnapshot, s as PeerReadiness, t as RuntimePeerHealth, u as ResolvedPeerIdentity, C as ChannelDescriptor, v as PeerStreamOptions, I as IncomingStream, w as ScopedChannelOptions, x as RuntimeDevice, y as ScopedLogicalChannel, z as ConnectionState, A as ReadinessOptions, B as ConnectionEvent, d as TransferPeerDemandRequest, f as TransferPeerDemandStatus, M as ManagedOptions, F as ManagedSession, G as DeviceStatus, H as DeviceConnectOptions, J as ConnectDeviceResult, K as ConnectDeviceHooks, L as ConnectDeviceOptions, N as LocalDeviceInfo, O as DeviceProfile, Q as RawConnection, U as JoinRoomOptions, V as RuntimeRoomMember, W as GrantScope, X as AuthContext, Y as RuntimeClientOptions } from './Connection-U3fEt8_4.js';
3
+ import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-Dxb0XOti.js';
4
4
 
5
5
  interface DiagnosticPeer {
6
6
  /** Capture-local alias. Full user/device/node/connection IDs are excluded. */
@@ -1,4 +1,4 @@
1
- import './assembly-DGrOqsLW.js';
2
- import './Connection-BGVBMbWg.js';
3
- export { A as AdvancedNamespace, i as ChannelConnectOptions, C as ChannelNamespace, h as Client, a as DeviceNamespace, j as DeviceSessionOptions, D as DiagnosticsNamespace, P as PeerNamespace, R as RoomNamespace, T as TicketNamespace, r as resolveOptions, w as wrapAssembly } from './coreClient-ByXs38IP.js';
4
- import './capabilities-DsKud7Sw.js';
1
+ import './assembly-CtrHmP4j.js';
2
+ import './Connection-U3fEt8_4.js';
3
+ export { A as AdvancedNamespace, i as ChannelConnectOptions, C as ChannelNamespace, h as Client, a as DeviceNamespace, j as DeviceSessionOptions, D as DiagnosticsNamespace, P as PeerNamespace, R as RoomNamespace, T as TicketNamespace, r as resolveOptions, w as wrapAssembly } from './coreClient-AVGEwlhT.js';
4
+ import './capabilities-Dxb0XOti.js';
@@ -1 +1 @@
1
- import {l}from'./chunk-WTOA6B2A.js';import'./chunk-OWKAJPOI.js';import {c}from'./chunk-IVNXIG7J.js';import'./chunk-2GX6GB6L.js';function w(o){let r=l({...o});if("auth"in o&&!o.authMode){let n=o.auth;r.authMode=n==="none"?"anonymous":n;}if("identity"in o){let n=o.identity,s=n==="temporary"?"ephemeral":n;!o.deviceIdPersistence&&!o.nodeIdPersistence&&(r.deviceIdPersistence=s),!o.endpointIdPersistence&&!o.nodeIdPersistence&&(r.endpointIdPersistence=s);}return "namespace"in o&&!o.storagePrefix&&(r.storagePrefix=o.namespace),"privacy"in o&&o.strictMode===void 0&&(r.strictMode=!!o.privacy),r}function O(o,r){let n=o.runtime,s=Object.create(n),d=async e=>{if(typeof e!="string")return e;let i=(await n.listDevices()).find(a=>a.deviceId===e);if(!i)throw new Error(`OpenRTC device '${e}' is not currently discoverable.`);return i},g=async e=>({...e,localDeviceId:e?.localDeviceId??await n.getLocalDeviceId()??""}),P=async e=>{let{device:t,scope:i,...a}=e,c=a.deviceId??(typeof t=="string"?t:t?.deviceId)??null,l=a.ticket??(typeof t=="string"?void 0:t?.ticket);c&&!l&&(l=(await d(c).catch(()=>null))?.ticket);let m={...a,scope:i??"session"};return c&&(m.deviceId=c),l&&(m.ticket=l),m},v={requestTransferPeer:e=>n.requestTransferPeer(e),transferPeerDemandStatus:(e,t)=>n.transferPeerDemandStatus(e,t),releaseTransferPeer:(e,t)=>n.releaseTransferPeer(e,t),setTransferPeerBudget:(e,t)=>n.setTransferPeerBudget(e,t),list:()=>n.listDevices(),startSession:(e={})=>n.startManagedSession({...e,platform:e.platform??r}),stopSession:e=>n.stopManagedSession(e),listWithStatus:()=>n.listDeviceStatus(),watch:e=>n.watchDevices(e),watchWithStatus:e=>n.watchDeviceStatus(e),connect:async(e,t)=>n.connectDevice(await d(e),await g(t)),connectWithRetry:async(e,t,i)=>n.connectWithRetry(await d(e),t,i),disconnect:e=>n.disconnectDevice(e),update:(e,t)=>n.updateDevice(e,t),delete:e=>n.deleteDevice(e),localId:()=>n.getLocalDeviceId(),localInfo:()=>n.getLocalDeviceInfo(),localProfile:e=>n.localDeviceProfile(e),updateLocalName:e=>n.updateDeviceName(e)},C={watch:e=>n.watchPeerStates(e),watchLifecycle:e=>typeof n.watchPeerLifecycle=="function"?n.watchPeerLifecycle(e):typeof n.watchPeerStates=="function"?n.watchPeerStates(e):()=>{},get:e=>n.getPeerState(e),listConnected:()=>n.listConnectedPeers(),connect:e=>n.connectPeer(e),disconnect:(e,t)=>n.disconnectPeer(e,t),forceDisconnect:e=>n.forceDisconnectPeer(e),session:e=>n.getPeerSession(e),sessions:()=>n.listPeerSessions(),waitConnected:(e,t)=>n.waitForConnectedPeer(e,t),readiness:(e,t)=>n.getPeerReadiness(e,t),health:e=>n.getPeerHealth(e),identity:e=>n.resolvePeerIdentity(e),addScope:(e,t)=>n.addPeerScope(e,t),releaseScope:(e,t)=>n.releasePeerScope(e,t),scopes:e=>n.getPeerScopes(e),refresh:()=>n.refreshPeerSnapshot()},h={register:e=>n.registerChannel(e),unregister:e=>n.unregisterChannel(e),list:()=>n.listChannels(),openBi:(e,t,i)=>n.openPeerBi(e,{...i,channelId:t}),openUni:(e,t,i)=>n.openPeerUni(e,{...i,channelId:t}),onIncoming:e=>n.onIncomingStream(e),onIncomingChannel:(e,t)=>n.onChannelStream(e,i=>{if(i.channel)return t(i)}),connect:async e=>n.connectScopedChannel(await P(e)),connectScoped:e=>n.connectScopedChannel(e)},S={create:e=>n.createRoom(e),join:(e,t)=>n.joinRoom(e,t),leave:e=>n.leaveRoom(e),watch:(e,t)=>n.watchRoom(e,t),members:e=>n.getRoomMembers(e)},f={raw:()=>n.getInvite(),share:e=>n.getTicketWithToken("share",e?.maxConnections??1),grant:(e,t)=>n.getTicketWithToken(e,t?.maxConnections??0),revoke:e=>n.revokeTokensByScope(e)},b={capture:e=>c(t=>n.watchPeerStates(t),e),status:()=>n.getRuntimeStatus(),policy:()=>n.getRuntimePolicy(),capabilities:()=>n.capabilities(),capabilityProfile:()=>n.getCapabilityProfile(),watchConnectionMetrics:e=>n.watchConnectionMetrics(e),connectionStates:()=>n.getConnectionStates(),onStateChange:e=>n.onStateChange(e),connections:()=>n.getConnections(),applicationReadyConnections:e=>n.readyConnections(e),onConnection:e=>n.onConnection(e),onDisconnection:e=>n.onDisconnection(e),onConnectionEvent:e=>n.onConnectionEvent(e),forceReconnect:()=>n.forceReconnect(),peerReconciliation:()=>n.reconciliationStats()},y={runtime:n,assembly:o,nodeId:()=>n.getNodeId(),nodeIdFromTicket:e=>n.getNodeIdFromTicket(e),endpointTicket:()=>n.getEndpointTicket(),connectRaw:e=>n.connectRaw(e),openBi:e=>n.openBi(e),openUni:e=>n.openUni(e),isConnected:e=>n.isConnected(e),disconnectNode:e=>n.disconnectNode(e),excludeAutoConnect:(e,t)=>n.excludeAutoConnect(e,t),notifyNetworkChange:e=>n.notifyNetworkChange(e)};return Object.defineProperties(s,{devices:{get:()=>v,enumerable:true},peers:{get:()=>C,enumerable:true},channels:{get:()=>h,enumerable:true},rooms:{get:()=>S,enumerable:true},tickets:{get:()=>f,enumerable:true},diagnostics:{get:()=>b,enumerable:true},advanced:{get:()=>y,enumerable:true},setAuth:{value:e=>o.setAuthContext(e),enumerable:true,writable:true,configurable:true},setAuthContext:{value:e=>o.setAuthContext(e),enumerable:true,writable:true,configurable:true},syncPlutoAuth:{value:e=>o.syncPlutoAuth(e),enumerable:true,writable:true,configurable:true},bindPlutoAuthHost:{value:()=>o.bindPlutoAuthHost(),enumerable:true,writable:true,configurable:true},signIn:{value:()=>o.signInWithPluto(),enumerable:true,writable:true,configurable:true},signOut:{value:()=>o.signOut(),enumerable:true,writable:true,configurable:true},runtime:{get:()=>n,enumerable:false},_assembly:{get:()=>o,enumerable:false}}),s}export{w as resolveOptions,O as wrapAssembly};
1
+ import {l}from'./chunk-WTOA6B2A.js';import'./chunk-OWKAJPOI.js';import {c}from'./chunk-SSBR3IHA.js';import'./chunk-2GX6GB6L.js';function w(o){let r=l({...o});if("auth"in o&&!o.authMode){let n=o.auth;r.authMode=n==="none"?"anonymous":n;}if("identity"in o){let n=o.identity,s=n==="temporary"?"ephemeral":n;!o.deviceIdPersistence&&!o.nodeIdPersistence&&(r.deviceIdPersistence=s),!o.endpointIdPersistence&&!o.nodeIdPersistence&&(r.endpointIdPersistence=s);}return "namespace"in o&&!o.storagePrefix&&(r.storagePrefix=o.namespace),"privacy"in o&&o.strictMode===void 0&&(r.strictMode=!!o.privacy),r}function O(o,r){let n=o.runtime,s=Object.create(n),d=async e=>{if(typeof e!="string")return e;let i=(await n.listDevices()).find(a=>a.deviceId===e);if(!i)throw new Error(`OpenRTC device '${e}' is not currently discoverable.`);return i},g=async e=>({...e,localDeviceId:e?.localDeviceId??await n.getLocalDeviceId()??""}),P=async e=>{let{device:t,scope:i,...a}=e,c=a.deviceId??(typeof t=="string"?t:t?.deviceId)??null,l=a.ticket??(typeof t=="string"?void 0:t?.ticket);c&&!l&&(l=(await d(c).catch(()=>null))?.ticket);let m={...a,scope:i??"session"};return c&&(m.deviceId=c),l&&(m.ticket=l),m},v={requestTransferPeer:e=>n.requestTransferPeer(e),transferPeerDemandStatus:(e,t)=>n.transferPeerDemandStatus(e,t),releaseTransferPeer:(e,t)=>n.releaseTransferPeer(e,t),setTransferPeerBudget:(e,t)=>n.setTransferPeerBudget(e,t),list:()=>n.listDevices(),startSession:(e={})=>n.startManagedSession({...e,platform:e.platform??r}),stopSession:e=>n.stopManagedSession(e),listWithStatus:()=>n.listDeviceStatus(),watch:e=>n.watchDevices(e),watchWithStatus:e=>n.watchDeviceStatus(e),connect:async(e,t)=>n.connectDevice(await d(e),await g(t)),connectWithRetry:async(e,t,i)=>n.connectWithRetry(await d(e),t,i),disconnect:e=>n.disconnectDevice(e),update:(e,t)=>n.updateDevice(e,t),delete:e=>n.deleteDevice(e),localId:()=>n.getLocalDeviceId(),localInfo:()=>n.getLocalDeviceInfo(),localProfile:e=>n.localDeviceProfile(e),updateLocalName:e=>n.updateDeviceName(e)},C={watch:e=>n.watchPeerStates(e),watchLifecycle:e=>typeof n.watchPeerLifecycle=="function"?n.watchPeerLifecycle(e):typeof n.watchPeerStates=="function"?n.watchPeerStates(e):()=>{},get:e=>n.getPeerState(e),listConnected:()=>n.listConnectedPeers(),connect:e=>n.connectPeer(e),disconnect:(e,t)=>n.disconnectPeer(e,t),forceDisconnect:e=>n.forceDisconnectPeer(e),session:e=>n.getPeerSession(e),sessions:()=>n.listPeerSessions(),waitConnected:(e,t)=>n.waitForConnectedPeer(e,t),readiness:(e,t)=>n.getPeerReadiness(e,t),health:e=>n.getPeerHealth(e),identity:e=>n.resolvePeerIdentity(e),addScope:(e,t)=>n.addPeerScope(e,t),releaseScope:(e,t)=>n.releasePeerScope(e,t),scopes:e=>n.getPeerScopes(e),refresh:()=>n.refreshPeerSnapshot()},h={register:e=>n.registerChannel(e),unregister:e=>n.unregisterChannel(e),list:()=>n.listChannels(),openBi:(e,t,i)=>n.openPeerBi(e,{...i,channelId:t}),openUni:(e,t,i)=>n.openPeerUni(e,{...i,channelId:t}),onIncoming:e=>n.onIncomingStream(e),onIncomingChannel:(e,t)=>n.onChannelStream(e,i=>{if(i.channel)return t(i)}),connect:async e=>n.connectScopedChannel(await P(e)),connectScoped:e=>n.connectScopedChannel(e)},S={create:e=>n.createRoom(e),join:(e,t)=>n.joinRoom(e,t),leave:e=>n.leaveRoom(e),watch:(e,t)=>n.watchRoom(e,t),members:e=>n.getRoomMembers(e)},f={raw:()=>n.getInvite(),share:e=>n.getTicketWithToken("share",e?.maxConnections??1),grant:(e,t)=>n.getTicketWithToken(e,t?.maxConnections??0),revoke:e=>n.revokeTokensByScope(e)},b={capture:e=>c(t=>n.watchPeerStates(t),e),status:()=>n.getRuntimeStatus(),policy:()=>n.getRuntimePolicy(),capabilities:()=>n.capabilities(),capabilityProfile:()=>n.getCapabilityProfile(),watchConnectionMetrics:e=>n.watchConnectionMetrics(e),connectionStates:()=>n.getConnectionStates(),onStateChange:e=>n.onStateChange(e),connections:()=>n.getConnections(),applicationReadyConnections:e=>n.readyConnections(e),onConnection:e=>n.onConnection(e),onDisconnection:e=>n.onDisconnection(e),onConnectionEvent:e=>n.onConnectionEvent(e),forceReconnect:()=>n.forceReconnect(),peerReconciliation:()=>n.reconciliationStats()},y={runtime:n,assembly:o,nodeId:()=>n.getNodeId(),nodeIdFromTicket:e=>n.getNodeIdFromTicket(e),endpointTicket:()=>n.getEndpointTicket(),connectRaw:e=>n.connectRaw(e),openBi:e=>n.openBi(e),openUni:e=>n.openUni(e),isConnected:e=>n.isConnected(e),disconnectNode:e=>n.disconnectNode(e),excludeAutoConnect:(e,t)=>n.excludeAutoConnect(e,t),notifyNetworkChange:e=>n.notifyNetworkChange(e)};return Object.defineProperties(s,{devices:{get:()=>v,enumerable:true},peers:{get:()=>C,enumerable:true},channels:{get:()=>h,enumerable:true},rooms:{get:()=>S,enumerable:true},tickets:{get:()=>f,enumerable:true},diagnostics:{get:()=>b,enumerable:true},advanced:{get:()=>y,enumerable:true},setAuth:{value:e=>o.setAuthContext(e),enumerable:true,writable:true,configurable:true},setAuthContext:{value:e=>o.setAuthContext(e),enumerable:true,writable:true,configurable:true},syncPlutoAuth:{value:e=>o.syncPlutoAuth(e),enumerable:true,writable:true,configurable:true},bindPlutoAuthHost:{value:()=>o.bindPlutoAuthHost(),enumerable:true,writable:true,configurable:true},signIn:{value:()=>o.signInWithPluto(),enumerable:true,writable:true,configurable:true},signOut:{value:()=>o.signOut(),enumerable:true,writable:true,configurable:true},runtime:{get:()=>n,enumerable:false},_assembly:{get:()=>o,enumerable:false}}),s}export{w as resolveOptions,O as wrapAssembly};
@@ -1 +1 @@
1
- import {h as h$1}from'./chunk-KN7DF3NH.js';import'./chunk-FKAQDDUM.js';import'./chunk-IVNXIG7J.js';import'./chunk-IUU6JCLK.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-ZA44REGI.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';var h=class extends h$1{constructor(e,t,u,S){super("devices",e,t,u);this.roster=S;this.kind="devices";this.rosterStopped=false;this.localId=()=>this.client.devices.localId();this.localInfo=()=>this.client.devices.localInfo();this.list=async()=>this.roster.mergeDevices(await this.client.devices.list());this.listWithStatus=async()=>this.roster.mergeStatus(await this.client.devices.listWithStatus());this.watch=e=>this.client.devices.watch(t=>e(this.roster.mergeDevices(t)));this.requestTransferPeer=async e=>{if(this.closed)throw new Error("[OpenRTC] Capability is closed.");return this.client.devices.requestTransferPeer(e)};this.transferPeerDemandStatus=async(e,t)=>{if(this.closed)throw new Error("[OpenRTC] Capability is closed.");return this.client.devices.transferPeerDemandStatus(e,t)};this.releaseTransferPeer=async(e,t)=>{if(this.closed)throw new Error("[OpenRTC] Capability is closed.");return this.client.devices.releaseTransferPeer(e,t)};this.setTransferPeerBudget=async(e,t)=>{if(this.closed)throw new Error("[OpenRTC] Capability is closed.");return this.client.devices.setTransferPeerBudget(e,t)};this.connect=this.client.devices.connect;this.disconnect=this.client.devices.disconnect;let p=t.devices.list,m=t.devices.listWithStatus,c=t.devices.watch,f=t.devices.watchWithStatus,i=s=>(this.roster.reconcileLiveSnapshot(s),s),a=async()=>this.roster.mergeDevices(i(await p())),o=async()=>this.roster.mergeStatus(await m()),n=s=>c(r=>s(this.roster.mergeDevices(i(r)))),l=s=>f(r=>s(this.roster.mergeStatus(r))),d=Object.create(t);Object.defineProperties(d,{listDevices:{value:a,enumerable:false},listDeviceStatus:{value:o,enumerable:false},watchDevices:{value:n,enumerable:false},watchDeviceStatus:{value:l,enumerable:false},devices:{value:{...t.devices,list:a,listWithStatus:o,watch:n,watchWithStatus:l},enumerable:true}}),this.projectRuntime(d),this.stopRosterSync=c(i);}replaceEnrolledDevices(e){this.roster.replace(e);}removeEnrolledDevice(e){this.roster.remove(e);}retainCurrentEnrolledDevice(e){this.roster.retain(e);}beforeRuntimeShutdown(){this.rosterStopped||(this.stopRosterSync(),this.rosterStopped=true);}};export{h as DeviceHandle};
1
+ import {h as h$1}from'./chunk-RUOVYQ2P.js';import'./chunk-FKAQDDUM.js';import'./chunk-SSBR3IHA.js';import'./chunk-IUU6JCLK.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-ZA44REGI.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';var h=class extends h$1{constructor(e,t,u,S){super("devices",e,t,u);this.roster=S;this.kind="devices";this.rosterStopped=false;this.localId=()=>this.client.devices.localId();this.localInfo=()=>this.client.devices.localInfo();this.list=async()=>this.roster.mergeDevices(await this.client.devices.list());this.listWithStatus=async()=>this.roster.mergeStatus(await this.client.devices.listWithStatus());this.watch=e=>this.client.devices.watch(t=>e(this.roster.mergeDevices(t)));this.requestTransferPeer=async e=>{if(this.closed)throw new Error("[OpenRTC] Capability is closed.");return this.client.devices.requestTransferPeer(e)};this.transferPeerDemandStatus=async(e,t)=>{if(this.closed)throw new Error("[OpenRTC] Capability is closed.");return this.client.devices.transferPeerDemandStatus(e,t)};this.releaseTransferPeer=async(e,t)=>{if(this.closed)throw new Error("[OpenRTC] Capability is closed.");return this.client.devices.releaseTransferPeer(e,t)};this.setTransferPeerBudget=async(e,t)=>{if(this.closed)throw new Error("[OpenRTC] Capability is closed.");return this.client.devices.setTransferPeerBudget(e,t)};this.connect=this.client.devices.connect;this.disconnect=this.client.devices.disconnect;let p=t.devices.list,m=t.devices.listWithStatus,c=t.devices.watch,f=t.devices.watchWithStatus,i=s=>(this.roster.reconcileLiveSnapshot(s),s),a=async()=>this.roster.mergeDevices(i(await p())),o=async()=>this.roster.mergeStatus(await m()),n=s=>c(r=>s(this.roster.mergeDevices(i(r)))),l=s=>f(r=>s(this.roster.mergeStatus(r))),d=Object.create(t);Object.defineProperties(d,{listDevices:{value:a,enumerable:false},listDeviceStatus:{value:o,enumerable:false},watchDevices:{value:n,enumerable:false},watchDeviceStatus:{value:l,enumerable:false},devices:{value:{...t.devices,list:a,listWithStatus:o,watch:n,watchWithStatus:l},enumerable:true}}),this.projectRuntime(d),this.stopRosterSync=c(i);}replaceEnrolledDevices(e){this.roster.replace(e);}removeEnrolledDevice(e){this.roster.remove(e);}retainCurrentEnrolledDevice(e){this.roster.retain(e);}beforeRuntimeShutdown(){this.rosterStopped||(this.stopRosterSync(),this.rosterStopped=true);}};export{h as DeviceHandle};
@@ -0,0 +1 @@
1
+ export{f as browserDeviceKeyProvider,e as createDeviceKey,g as createSessionDeviceKeyProvider,d as deviceKeyThumbprint,c as rootBoundDeviceChallenge,a as rootClientChallenge,b as rootClientProof}from'./chunk-XNJI6KCI.js';