openrtc 2.9.8 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +17 -18
  2. package/dist/{Connection-DJoPKC0L.d.ts → Connection-BZ6piJsh.d.ts} +0 -2
  3. package/dist/{DelegatingRuntimeAdapter-d1xrjmHE.d.ts → DelegatingRuntimeAdapter-s3QvVuTj.d.ts} +2 -2
  4. package/dist/{IpcRuntimeAdapter-BkJdH7OQ.d.ts → IpcRuntimeAdapter-CghYNfcc.d.ts} +2 -2
  5. package/dist/{WasmBridge-VGIBWCAC.js → WasmBridge-JZGJHSSU.js} +1 -1
  6. package/dist/{assembly-0EnNAgmm.d.ts → assembly-BEMgeExQ.d.ts} +2 -2
  7. package/dist/{capabilities-dnGwtGmQ.d.ts → capabilities-fJ11v3xA.d.ts} +1 -1
  8. package/dist/chunk-2Q75GXGE.js +2 -0
  9. package/dist/{chunk-TWTPJDUN.js → chunk-C3TAFNG6.js} +1 -1
  10. package/dist/chunk-CAUMGKP4.js +2 -0
  11. package/dist/chunk-F3IZBMAT.js +1 -0
  12. package/dist/{chunk-S67YUD3E.js → chunk-LTMH2AIS.js} +1 -1
  13. package/dist/{chunk-WNCBDRFC.js → chunk-R6J4PZDI.js} +1 -1
  14. package/dist/chunk-RSQCDTS2.js +1 -0
  15. package/dist/{chunk-P6G2PAWP.js → chunk-W45XAU3I.js} +1 -1
  16. package/dist/{chunk-O5EGI6OZ.js → chunk-W4IU7H7H.js} +1 -1
  17. package/dist/controlPlane-45AU3CSM.js +1 -0
  18. package/dist/coreClient-BYWmk_1O.d.ts +309 -0
  19. package/dist/coreClient.d.ts +4 -250
  20. package/dist/coreClient.js +1 -1
  21. package/dist/{deviceEnrollment-IPKFITV6.js → deviceEnrollment-OFC6DSZP.js} +2 -2
  22. package/dist/deviceHandle-3P46T7SV.js +1 -0
  23. package/dist/external-broadcast.d.ts +5 -5
  24. package/dist/external-broadcast.js +1 -1
  25. package/dist/index.d.ts +7 -7
  26. package/dist/index.js +1 -1
  27. package/dist/{ipcFactory-L73S4NGQ.js → ipcFactory-2MDPNX5M.js} +1 -1
  28. package/dist/native.d.ts +6 -6
  29. package/dist/native.js +1 -1
  30. package/dist/node.d.ts +7 -7
  31. package/dist/node.js +2 -2
  32. package/dist/openrtc-6RZZ7PEN.js +2 -0
  33. package/dist/openrtc_bg.wasm +0 -0
  34. package/dist/room-P5SHPIGF.js +1 -0
  35. package/dist/runtime/WasmRuntimeAdapter.d.ts +3 -3
  36. package/dist/runtime/WasmRuntimeAdapter.js +1 -1
  37. package/dist/runtime/device-status.d.ts +1 -1
  38. package/dist/runtime/factories.d.ts +5 -5
  39. package/dist/runtime/factories.js +1 -1
  40. package/dist/runtime/index.d.ts +10 -10
  41. package/dist/runtime/index.js +1 -1
  42. package/dist/server-browser.d.ts +5 -5
  43. package/dist/server.d.ts +5 -5
  44. package/dist/server.js +1 -1
  45. package/dist/service-node.d.ts +5 -5
  46. package/dist/service-node.js +1 -1
  47. package/dist/testing/native.d.ts +5 -5
  48. package/dist/testing/native.js +1 -1
  49. package/dist/testing.d.ts +5 -9
  50. package/dist/testing.js +1 -1
  51. package/dist/transport/index.d.ts +2 -2
  52. package/dist/{types-uDwIMPRk.d.ts → types-BXYC9Q5H.d.ts} +7 -47
  53. package/native/darwin-arm64/openrtc-node-host +0 -0
  54. package/native/darwin-arm64/openrtc-node-host.manifest.json +4 -4
  55. package/native/darwin-x64/openrtc-node-host +0 -0
  56. package/native/darwin-x64/openrtc-node-host.manifest.json +4 -4
  57. package/native/linux-x64/openrtc-node-host +0 -0
  58. package/native/linux-x64/openrtc-node-host.manifest.json +4 -4
  59. package/package.json +1 -1
  60. package/dist/chunk-4EOOERQ4.js +0 -2
  61. package/dist/chunk-MTCLMTJN.js +0 -1
  62. package/dist/chunk-XR5JZKFP.js +0 -2
  63. package/dist/controlPlane-HLMTVL5V.js +0 -1
  64. package/dist/deviceHandle-ZYN473A4.js +0 -1
  65. package/dist/openrtc-YI4N7T34.js +0 -2
  66. package/dist/room-5NW3SV4C.js +0 -1
@@ -1,250 +1,4 @@
1
- import { P as PolicySnapshot, a as PeerReconciliationStats, R as RuntimeClient, b as PlutoRuntimeAssembly } from './assembly-0EnNAgmm.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-DJoPKC0L.js';
3
- import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-dnGwtGmQ.js';
4
-
5
- type ChannelConnectOptions = Omit<ScopedChannelOptions, 'scope' | 'deviceId' | 'ticket'> & {
6
- /**
7
- * Device selected from `client.devices.*`. Passing the device object lets
8
- * OpenRTC reuse its current ticket for native and ticket-gated routes.
9
- */
10
- device?: string | RuntimeDevice;
11
- deviceId?: string | null;
12
- ticket?: string;
13
- /**
14
- * Logical channel lifecycle scope. Most app channels should use the default
15
- * `session`; pass a custom scope only when you intentionally manage peer
16
- * lifecycle separately from the channel.
17
- */
18
- scope?: ScopedChannelOptions['scope'];
19
- };
20
- type DeviceSessionOptions = Omit<ManagedOptions, 'platform'> & {
21
- /**
22
- * Runtime host for the managed user-device session. Normal apps can omit
23
- * this: `OpenRTC(...)` defaults to `web`, and `OpenRTC.native(...)` defaults
24
- * to `native`.
25
- */
26
- platform?: ManagedOptions['platform'];
27
- };
28
- interface DeviceNamespace {
29
- requestTransferPeer(request: TransferPeerDemandRequest): Promise<TransferPeerDemandStatus>;
30
- transferPeerDemandStatus(id: string, generation: number): Promise<TransferPeerDemandStatus | null>;
31
- releaseTransferPeer(id: string, generation: number): Promise<boolean>;
32
- setTransferPeerBudget(budget: number, generation: number): Promise<void>;
33
- startSession(options?: DeviceSessionOptions): Promise<ManagedSession>;
34
- stopSession(options?: {
35
- preserveBackendSession?: boolean;
36
- }): Promise<void>;
37
- list(): Promise<RuntimeDevice[]>;
38
- listWithStatus(): Promise<DeviceStatus[]>;
39
- watch(callback: (devices: RuntimeDevice[]) => void): () => void;
40
- watchWithStatus(callback: (devices: DeviceStatus[]) => void): () => void;
41
- connect(device: string | RuntimeDevice, options?: DeviceConnectOptions): Promise<ConnectDeviceResult>;
42
- /**
43
- * @deprecated Use `devices.connect()`. Retry and route recovery are owned by
44
- * OpenRTC; legacy consumer-provided connection hooks are ignored.
45
- */
46
- connectWithRetry(device: string | RuntimeDevice, hooks: ConnectDeviceHooks, options: ConnectDeviceOptions): Promise<ConnectDeviceResult>;
47
- disconnect(deviceId: string): Promise<void>;
48
- update(deviceId: string, updates: {
49
- deviceName?: string;
50
- capabilities?: RuntimeDevice['capabilities'];
51
- metadata?: string;
52
- }): Promise<void>;
53
- delete(deviceId: string): Promise<void>;
54
- localId(): Promise<string | null>;
55
- localInfo(): Promise<LocalDeviceInfo | null>;
56
- localProfile(options?: {
57
- deviceName?: string;
58
- localDeviceId?: string | null;
59
- platform?: 'native' | 'web';
60
- userId?: string | null;
61
- }): Promise<DeviceProfile>;
62
- updateLocalName(deviceName: string): Promise<LocalDeviceInfo | null>;
63
- }
64
- interface PeerNamespace {
65
- watch(callback: (peers: RuntimePeerState[]) => void): () => void;
66
- watchLifecycle(callback: (peers: RuntimePeerState[]) => void): () => void;
67
- get(id: string): RuntimePeerState | undefined;
68
- listConnected(): RuntimePeerState[];
69
- connect(options: PeerConnectOptions): Promise<Connection>;
70
- disconnect(id: string, scope?: string): Promise<void>;
71
- forceDisconnect(id: string): Promise<void>;
72
- session(id: string): Promise<PeerSessionSnapshot | null>;
73
- sessions(): Promise<PeerSessionSnapshot[]>;
74
- waitConnected(id: string, timeoutMs?: number): Promise<PeerSessionSnapshot | null>;
75
- readiness(id: string, timeoutMs?: number): Promise<PeerReadiness>;
76
- health(id: string): Promise<RuntimePeerHealth>;
77
- identity(id: string): Promise<ResolvedPeerIdentity>;
78
- addScope(id: string, scope?: string): RuntimePeerState | undefined;
79
- releaseScope(id: string, scope?: string): RuntimePeerState | undefined;
80
- scopes(id: string): string[];
81
- refresh(): Promise<RuntimePeerState[]>;
82
- }
83
- interface ChannelNamespace {
84
- register(descriptor: ChannelDescriptor): void;
85
- unregister(channelId: string): void;
86
- list(): ChannelDescriptor[];
87
- openBi(id: string, channelId: string, options?: Omit<PeerStreamOptions, 'channelId'>): Promise<{
88
- connection: Connection;
89
- readable: ReadableStream<Uint8Array>;
90
- writable: WritableStream<Uint8Array>;
91
- }>;
92
- openUni(id: string, channelId: string, options?: Omit<PeerStreamOptions, 'channelId'>): Promise<{
93
- connection: Connection;
94
- writable: WritableStream<Uint8Array>;
95
- }>;
96
- onIncoming(callback: (stream: IncomingStream) => boolean | void): () => void;
97
- onIncomingChannel(channelId: string, callback: (stream: IncomingStream & {
98
- channel: NonNullable<IncomingStream['channel']>;
99
- }) => boolean | void): () => void;
100
- connect(options: ChannelConnectOptions): Promise<ScopedLogicalChannel>;
101
- connectScoped(options: ScopedChannelOptions): Promise<ScopedLogicalChannel>;
102
- }
103
- interface RoomNamespace {
104
- create(roomId?: string): Promise<string>;
105
- join(roomId: string, options?: JoinRoomOptions): Promise<Connection[]>;
106
- leave(roomId: string): Promise<void>;
107
- watch(roomId: string, callback: (members: RuntimeRoomMember[]) => void): () => void;
108
- members(roomId: string): Promise<RuntimeRoomMember[]>;
109
- }
110
- interface TicketNamespace {
111
- raw(): Promise<string>;
112
- share(options?: {
113
- maxConnections?: number;
114
- }): Promise<string>;
115
- grant(scope: GrantScope, options?: {
116
- maxConnections?: number;
117
- }): Promise<string>;
118
- revoke(scope: GrantScope): Promise<string[]>;
119
- }
120
- interface DiagnosticsNamespace {
121
- status(): Promise<{
122
- runtime: 'tauri' | 'browser' | 'unknown';
123
- wasmLoaded: boolean;
124
- localNodeId?: string;
125
- userId?: string;
126
- }>;
127
- policy(): PolicySnapshot;
128
- capabilities(): RuntimeCapabilities;
129
- capabilityProfile(): CapabilityProfile;
130
- /** SDK-owned local metrics observer. No application pings or coordination reads. */
131
- watchConnectionMetrics(callback: (states: readonly ConnectionState[]) => void): () => void;
132
- connectionStates(): Promise<ConnectionState[]>;
133
- onStateChange(callback: (state: ConnectionState) => void): Promise<() => void> | (() => void);
134
- connections(): Connection[];
135
- applicationReadyConnections(options?: ReadinessOptions): Connection[];
136
- onConnection(callback: (connection: Connection) => void): () => void;
137
- onDisconnection(callback: (connection: Connection) => void): () => void;
138
- onConnectionEvent(callback: (event: ConnectionEvent) => void): () => void;
139
- forceReconnect(): void;
140
- peerReconciliation(): Readonly<PeerReconciliationStats>;
141
- }
142
- interface AdvancedNamespace {
143
- readonly runtime: RuntimeClient;
144
- readonly assembly: PlutoRuntimeAssembly;
145
- nodeId(): Promise<string>;
146
- nodeIdFromTicket(ticket: string): Promise<string | null>;
147
- endpointTicket(): Promise<string>;
148
- connectRaw(target: {
149
- ticket: string;
150
- timeoutMs?: number;
151
- }): Promise<RawConnection>;
152
- openBi(nodeId: string): Promise<{
153
- readable: ReadableStream<Uint8Array>;
154
- writable: WritableStream<Uint8Array>;
155
- }>;
156
- openUni(nodeId: string): Promise<WritableStream<Uint8Array>>;
157
- isConnected(nodeId: string): Promise<boolean>;
158
- disconnectNode(nodeId: string): Promise<void>;
159
- excludeAutoConnect(deviceId: string, excluded: boolean): Promise<void>;
160
- notifyNetworkChange(reason?: string): Promise<void>;
161
- }
162
- /**
163
- * Client extends RuntimeClient with auth helpers that were
164
- * previously only available on PlutoRuntimeAssembly.
165
- *
166
- * This is the unified type returned by OpenRTC() and OpenRTC.native().
167
- */
168
- interface Client extends RuntimeClient {
169
- readonly devices: DeviceNamespace;
170
- readonly peers: PeerNamespace;
171
- readonly channels: ChannelNamespace;
172
- readonly rooms: RoomNamespace;
173
- readonly tickets: TicketNamespace;
174
- readonly diagnostics: DiagnosticsNamespace;
175
- readonly advanced: AdvancedNamespace;
176
- /** @deprecated Use setAuth() instead */
177
- setAuthContext(context: AuthContext | null): Promise<void>;
178
- /** Set auth context for the runtime */
179
- setAuth(context: AuthContext | null): Promise<void>;
180
- /** Sync Pluto-hosted auth to the runtime */
181
- syncPlutoAuth(options?: {
182
- userId?: string | null;
183
- forceRefresh?: boolean;
184
- }): Promise<void>;
185
- /** Bind Pluto auth host to auto-sync on token changes */
186
- bindPlutoAuthHost(): () => void;
187
- /** Sign in via Pluto SSO */
188
- signIn(): Promise<void>;
189
- /** Sign out and clear auth context */
190
- signOut(): Promise<void>;
191
- /**
192
- * @deprecated Use `client.devices.startSession(...)` for the public
193
- * user-device avenue lifecycle. This top-level method remains for
194
- * RuntimeClient compatibility and advanced integrations.
195
- */
196
- startManagedSession(options: ManagedOptions): Promise<ManagedSession>;
197
- /**
198
- * @deprecated Use `client.devices.stopSession(...)` for the public
199
- * user-device avenue lifecycle.
200
- */
201
- stopManagedSession(options?: {
202
- preserveBackendSession?: boolean;
203
- }): Promise<void>;
204
- /** @deprecated Use `client.rooms.create(...)`. */
205
- createRoom(roomId?: string): Promise<string>;
206
- /** @deprecated Use `client.rooms.join(...)`. */
207
- joinRoom(roomId: string, options?: JoinRoomOptions): Promise<Connection[]>;
208
- /** @deprecated Use `client.rooms.leave(...)`. */
209
- leaveRoom(roomId: string): Promise<void>;
210
- /** @deprecated Use `client.rooms.watch(...)`. */
211
- watchRoom(roomId: string, callback: (members: RuntimeRoomMember[]) => void): () => void;
212
- /** @deprecated Use `client.rooms.members(...)`. */
213
- getRoomMembers(roomId: string): Promise<RuntimeRoomMember[]>;
214
- /** @deprecated Use `client.tickets.raw(...)`. */
215
- getInvite(): Promise<string>;
216
- /** @deprecated Use `client.tickets.raw(...)`. */
217
- getTicket(): Promise<string>;
218
- /** @deprecated Use `client.tickets.share(...)` or `client.tickets.grant(...)`. */
219
- getTicketWithToken(scope: GrantScope, maxConnections?: number): Promise<string>;
220
- /** @deprecated Use `client.tickets.revoke(...)`. */
221
- revokeTokensByScope(scope: GrantScope): Promise<string[]>;
222
- /** @deprecated Use `client.peers.connect(...)`. */
223
- connectPeer(options: PeerConnectOptions): Promise<Connection>;
224
- /** @deprecated Use `client.peers.connect(...)`. */
225
- connectTo(options: PeerConnectOptions): Promise<Connection>;
226
- /** @deprecated Use `client.peers.waitConnected(...)`. */
227
- waitForConnectedPeer(id: string, timeoutMs?: number): Promise<PeerSessionSnapshot | null>;
228
- /** @deprecated Use `client.channels.connect(...)`; use `client.channels.connectScoped(...)` only for custom lifecycle scopes. */
229
- connectScopedChannel(options: ScopedChannelOptions): Promise<ScopedLogicalChannel>;
230
- /** @deprecated Use `client.channels.openBi(...)`. */
231
- openPeerBi(id: string, options?: PeerStreamOptions): Promise<{
232
- connection: Connection;
233
- readable: ReadableStream<Uint8Array>;
234
- writable: WritableStream<Uint8Array>;
235
- }>;
236
- /** @deprecated Use `client.channels.openUni(...)`. */
237
- openPeerUni(id: string, options?: PeerStreamOptions): Promise<{
238
- connection: Connection;
239
- writable: WritableStream<Uint8Array>;
240
- }>;
241
- /**
242
- * Access to the underlying PlutoRuntimeAssembly for backward compatibility.
243
- * @deprecated Access methods directly on the client instead.
244
- */
245
- readonly runtime: RuntimeClient;
246
- }
247
- declare function resolveOptions(options: RuntimeClientOptions): RuntimeClientOptions;
248
- declare function wrapAssembly(assembly: PlutoRuntimeAssembly, defaultManagedSessionPlatform: ManagedOptions['platform']): Client;
249
-
250
- export { type AdvancedNamespace, type ChannelConnectOptions, type ChannelNamespace, type Client, type DeviceNamespace, type DeviceSessionOptions, type DiagnosticsNamespace, type PeerNamespace, type RoomNamespace, type TicketNamespace, resolveOptions, wrapAssembly };
1
+ import './assembly-BEMgeExQ.js';
2
+ import './Connection-BZ6piJsh.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-BYWmk_1O.js';
4
+ import './capabilities-fJ11v3xA.js';
@@ -1 +1 @@
1
- import {l}from'./chunk-L4HWDDXL.js';import'./chunk-OWKAJPOI.js';import'./chunk-2GX6GB6L.js';function I(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 D(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},u=async e=>({...e,localDeviceId:e?.localDeviceId??await n.getLocalDeviceId()??""}),g=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},P={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 u(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)},v={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()},C={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 g(e)),connectScoped:e=>n.connectScopedChannel(e)},h={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)},S={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)},f={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()},b={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:()=>P,enumerable:true},peers:{get:()=>v,enumerable:true},channels:{get:()=>C,enumerable:true},rooms:{get:()=>h,enumerable:true},tickets:{get:()=>S,enumerable:true},diagnostics:{get:()=>f,enumerable:true},advanced:{get:()=>b,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{I as resolveOptions,D as wrapAssembly};
1
+ import {l}from'./chunk-L4HWDDXL.js';import'./chunk-OWKAJPOI.js';import {c}from'./chunk-F3IZBMAT.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,2 +1,2 @@
1
- import {d,a}from'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';function v(e){return e.status===403&&e.reason==="device-enrollment-revoked"}async function p(e){let r=e.identity,a$1=async(o=false,t=e.recoverRevokedEnrollment)=>{let n=await e.key.proof((d,l)=>["openrtc:v2:device-enroll",e.appTag,r.principalId,e.deviceId,d,l].join(":")),i=e.attestation?{kind:e.attestation.kind,...await e.attestation.getEvidence({challenge:`openrtc:v2:attestation:${e.appTag}:${r.principalId}:${e.deviceId}:${n.nonce}`,apiKey:e.apiKey})}:void 0;return e.post("/v2/devices/enroll",{identitySession:r.identitySession,deviceId:e.deviceId,deviceProof:n,...e.profile?.name||e.profile?.platform?{deviceProfile:{...e.profile.name?{name:e.profile.name}:{},...e.profile.platform?{platform:e.profile.platform}:{}}}:{},...t?{recoverRevokedEnrollment:true}:{},...o?{recoverDeviceKey:true}:{},...i?{attestation:i}:{}})};try{return {identity:r,enrollment:await a$1()}}catch(o){let t=o;if(!(t instanceof Error))throw o;if(v(t)){if(r.deviceRecoveryAuthorized===false)throw d(a.AUTH_DEVICE_REENROLLMENT_REQUIRED,"This device was removed. Sign in again to authorize re-enrollment.",{retryable:true,plane:"auth",cause:o});return {identity:r,enrollment:await a$1(false,true)}}if(t.status!==412||t.reason!=="device-key-recovery-required")throw o;let n=await e.auth.getAssertion({audience:"https://api.openrtc.app/v2/assertions/exchange",forceRefresh:true,deviceId:e.deviceId,recoveryReason:"device-key-rotation"});if(!n)throw new Error("The OpenRTC auth provider returned no assertion.");let i=await e.post("/v2/assertions/exchange",{assertion:n,...e.auth.providerId?{providerId:e.auth.providerId}:{}});if(e.recordAssertionExchange(),i.principalId!==r.principalId)throw new Error("The authenticated principal changed during device-key recovery.");return r=i,{identity:r,enrollment:await a$1(true)}}}
2
- export{p as enrollDevice};
1
+ import {d,a}from'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';function v(e){return e.status===403&&e.reason==="device-enrollment-revoked"}async function y(e){let r=e.identity,a$1=async(o=false,t=e.recoverRevokedEnrollment)=>{let n=await e.key.proof((d,c)=>["openrtc:v2:device-enroll",e.appTag,r.principalId,e.deviceId,d,c].join(":")),i=e.attestation?{kind:e.attestation.kind,...await e.attestation.getEvidence({challenge:`openrtc:v2:attestation:${e.appTag}:${r.principalId}:${e.deviceId}:${n.nonce}`,apiKey:e.apiKey})}:void 0;return e.post("/v2/devices/enroll",{identitySession:r.identitySession,deviceId:e.deviceId,deviceProof:n,...e.profile?.name||e.profile?.platform?{deviceProfile:{...e.profile.name?{name:e.profile.name}:{},...e.profile.platform?{platform:e.profile.platform}:{}}}:{},...t?{recoverRevokedEnrollment:true}:{},...o?{recoverDeviceKey:true}:{},...i?{attestation:i}:{}})};try{return {identity:r,enrollment:await a$1()}}catch(o){let t=o;if(!(t instanceof Error))throw o;if(v(t)){if(r.deviceRecoveryAuthorized===false)throw d(a.AUTH_DEVICE_REENROLLMENT_REQUIRED,"This device was removed. Sign in again to authorize re-enrollment.",{retryable:true,plane:"auth",cause:o});return {identity:r,enrollment:await a$1(false,true)}}if(t.status!==412||t.reason!=="device-key-recovery-required")throw o;let n=await e.auth.getAssertion({audience:"https://api.openrtc.app/v2/assertions/exchange",forceRefresh:true,deviceId:e.deviceId,recoveryReason:"device-key-rotation"});if(!n)throw new Error("The OpenRTC auth provider returned no assertion.");let i=await e.post("/v2/assertions/exchange",{assertion:n,...e.auth.providerId?{providerId:e.auth.providerId}:{}});if(i.principalId!==r.principalId)throw new Error("The authenticated principal changed during device-key recovery.");return r=i,{identity:r,enrollment:await a$1(true)}}}
2
+ export{y as enrollDevice};
@@ -0,0 +1 @@
1
+ import {h as h$1}from'./chunk-RSQCDTS2.js';import'./chunk-FKAQDDUM.js';import'./chunk-ZA44REGI.js';import'./chunk-F3IZBMAT.js';import'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.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,8 +1,8 @@
1
- import { C as Client, e as BroadcastGrant, O as Options } from './types-uDwIMPRk.js';
2
- import './coreClient.js';
3
- import './assembly-0EnNAgmm.js';
4
- import './Connection-DJoPKC0L.js';
5
- import './capabilities-dnGwtGmQ.js';
1
+ import { C as Client, e as BroadcastGrant, O as Options } from './types-BXYC9Q5H.js';
2
+ import './coreClient-BYWmk_1O.js';
3
+ import './assembly-BEMgeExQ.js';
4
+ import './Connection-BZ6piJsh.js';
5
+ import './capabilities-fJ11v3xA.js';
6
6
 
7
7
  type ExternalBroadcastRelay = {
8
8
  kind: 'sfu';
@@ -1,2 +1,2 @@
1
- import {a as a$1}from'./chunk-5VJXDYP6.js';import'./chunk-IXQ4KWGP.js';import'./chunk-AYHD4X2R.js';import {a}from'./chunk-IAYQJZQQ.js';import'./chunk-GMPEZXPD.js';import {i}from'./chunk-MTCLMTJN.js';import'./chunk-FKAQDDUM.js';import'./chunk-ZA44REGI.js';import'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';async function K(r,e){if(!/^pk_(?:live|test)_[0-9a-f]{40}$/.test(r)||!/^[A-Za-z0-9_-]{1,64}$/.test(e))throw new Error("[OpenRTC] External broadcast identity is invalid.");return (await a(e).getOrCreate(`app_${r.slice(-16)}`)).publicKeyJwk}function h(r){let e=new URL(r),t=["localhost","127.0.0.1","[::1]"].includes(e.hostname);if(e.protocol!=="https:"&&!(t&&e.protocol==="http:")||e.pathname!=="/"||e.username||e.password||e.search||e.hash||r!==e.origin&&r!==`${e.origin}/`)throw new Error("[OpenRTC] External broadcast service must be an exact HTTPS origin.");return e.origin}function k(r){let e=r.replace(/-/g,"+").replace(/_/g,"/").padEnd(Math.ceil(r.length/4)*4,"=");return Uint8Array.from(atob(e),t=>t.charCodeAt(0))}function x(r){let e="";for(let t of r)e+=String.fromCharCode(t);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function C(r,e){if(!(r.issuerPublicKey instanceof Uint8Array)||r.issuerPublicKey.length!==32)throw new Error("[OpenRTC] External broadcast issuer key must be 32 bytes.");let t=r.relay;if(t.kind==="sfu"){let a=new URL(t.controlUrl,e);if(a.origin!==e||a.protocol!==new URL(e).protocol||a.pathname==="/"||a.username||a.password||a.search||a.hash)throw new Error("[OpenRTC] External SFU control must stay on the trusted service origin.");return {issuerPublicKey:r.issuerPublicKey,relay:{kind:"sfu",controlUrl:a.href.replace(/\/$/,"")}}}else {let a=new URL(t.relayUrl);if(a.protocol!=="https:"||a.username||a.password||!t.token||!t.namespace)throw new Error("[OpenRTC] External MoQ relay access is invalid.");if(t.serverCertificateHash&&!["localhost","127.0.0.1","[::1]"].includes(a.hostname))throw new Error("[OpenRTC] Custom relay certificate hashes are limited to loopback.")}return r}function P(r,e){if(!r||typeof r.apiKey!="string"||!/^pk_(?:live|test)_[0-9a-f]{40}$/.test(r.apiKey))throw new Error("[OpenRTC] External broadcast identity is invalid.");let t=h(e.serviceOrigin);if(!/^[A-Za-z0-9_-]{1,64}$/.test(e.keyNamespace)||typeof e.resolve!="function")throw new Error("[OpenRTC] External broadcast configuration is invalid.");let a$2=a(e.keyNamespace),d=`app_${r.apiKey.slice(-16)}`,l=()=>a$2.getOrCreate(d),u=async()=>{let{loadBrowserWasmRuntimeModule:i}=await import('./WasmBridge-VGIBWCAC.js'),n=await i();return await n.initWasm(),n.start(),new n.WasmClient(r.apiKey)},w,f=()=>w??(w=u()),m=new a$1({loadWasm:f,resolve:async(i,n)=>{let o=await l(),s=C(await e.resolve(i,o.publicKeyJwk,n),t),g=s.relay.kind==="sfu"?{kind:"sfu",controlUrl:s.relay.controlUrl,grant:i,bindingPublicJwk:o.publicKeyJwk,...n?{publicationVerifyingKey:x(n)}:{}}:s.relay;return {token:i,issuerPublicKey:s.issuerPublicKey,relay:g,signBindingChallenge:async b=>k(await o.sign(b))}}});return {client:i(r,{platform:"web",endpoints:{controlPlane:t,gateway:t},testingAllowInsecureLoopback:t.startsWith("http:"),deviceKeyProvider:a$2,broadcastHost:m,runtimeFactory:async i=>{let{createWasmClient:n}=await import('./runtime/factories.js');return n(i)}}),bindingPublicJwk:async()=>(await l()).publicKeyJwk}}
1
+ import {a as a$1}from'./chunk-5VJXDYP6.js';import'./chunk-IXQ4KWGP.js';import'./chunk-AYHD4X2R.js';import {a}from'./chunk-IAYQJZQQ.js';import'./chunk-GMPEZXPD.js';import {i}from'./chunk-RSQCDTS2.js';import'./chunk-FKAQDDUM.js';import'./chunk-ZA44REGI.js';import'./chunk-F3IZBMAT.js';import'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';async function K(r,e){if(!/^pk_(?:live|test)_[0-9a-f]{40}$/.test(r)||!/^[A-Za-z0-9_-]{1,64}$/.test(e))throw new Error("[OpenRTC] External broadcast identity is invalid.");return (await a(e).getOrCreate(`app_${r.slice(-16)}`)).publicKeyJwk}function h(r){let e=new URL(r),t=["localhost","127.0.0.1","[::1]"].includes(e.hostname);if(e.protocol!=="https:"&&!(t&&e.protocol==="http:")||e.pathname!=="/"||e.username||e.password||e.search||e.hash||r!==e.origin&&r!==`${e.origin}/`)throw new Error("[OpenRTC] External broadcast service must be an exact HTTPS origin.");return e.origin}function k(r){let e=r.replace(/-/g,"+").replace(/_/g,"/").padEnd(Math.ceil(r.length/4)*4,"=");return Uint8Array.from(atob(e),t=>t.charCodeAt(0))}function x(r){let e="";for(let t of r)e+=String.fromCharCode(t);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function C(r,e){if(!(r.issuerPublicKey instanceof Uint8Array)||r.issuerPublicKey.length!==32)throw new Error("[OpenRTC] External broadcast issuer key must be 32 bytes.");let t=r.relay;if(t.kind==="sfu"){let a=new URL(t.controlUrl,e);if(a.origin!==e||a.protocol!==new URL(e).protocol||a.pathname==="/"||a.username||a.password||a.search||a.hash)throw new Error("[OpenRTC] External SFU control must stay on the trusted service origin.");return {issuerPublicKey:r.issuerPublicKey,relay:{kind:"sfu",controlUrl:a.href.replace(/\/$/,"")}}}else {let a=new URL(t.relayUrl);if(a.protocol!=="https:"||a.username||a.password||!t.token||!t.namespace)throw new Error("[OpenRTC] External MoQ relay access is invalid.");if(t.serverCertificateHash&&!["localhost","127.0.0.1","[::1]"].includes(a.hostname))throw new Error("[OpenRTC] Custom relay certificate hashes are limited to loopback.")}return r}function P(r,e){if(!r||typeof r.apiKey!="string"||!/^pk_(?:live|test)_[0-9a-f]{40}$/.test(r.apiKey))throw new Error("[OpenRTC] External broadcast identity is invalid.");let t=h(e.serviceOrigin);if(!/^[A-Za-z0-9_-]{1,64}$/.test(e.keyNamespace)||typeof e.resolve!="function")throw new Error("[OpenRTC] External broadcast configuration is invalid.");let a$2=a(e.keyNamespace),d=`app_${r.apiKey.slice(-16)}`,l=()=>a$2.getOrCreate(d),u=async()=>{let{loadBrowserWasmRuntimeModule:i}=await import('./WasmBridge-JZGJHSSU.js'),n=await i();return await n.initWasm(),n.start(),new n.WasmClient(r.apiKey)},w,f=()=>w??(w=u()),m=new a$1({loadWasm:f,resolve:async(i,n)=>{let o=await l(),s=C(await e.resolve(i,o.publicKeyJwk,n),t),g=s.relay.kind==="sfu"?{kind:"sfu",controlUrl:s.relay.controlUrl,grant:i,bindingPublicJwk:o.publicKeyJwk,...n?{publicationVerifyingKey:x(n)}:{}}:s.relay;return {token:i,issuerPublicKey:s.issuerPublicKey,relay:g,signBindingChallenge:async b=>k(await o.sign(b))}}});return {client:i(r,{platform:"web",endpoints:{controlPlane:t,gateway:t},testingAllowInsecureLoopback:t.startsWith("http:"),deviceKeyProvider:a$2,broadcastHost:m,runtimeFactory:async i=>{let{createWasmClient:n}=await import('./runtime/factories.js');return n(i)}}),bindingPublicJwk:async()=>(await l()).publicKeyJwk}}
2
2
  export{P as createExternalBroadcastClient,K as externalBroadcastBindingPublicJwk};
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { P as PlutoIpcBridge } from './ipc-DgzKqHH3.js';
2
- import { O as Options, C as Client } from './types-uDwIMPRk.js';
3
- export { a as AttestationProvider, b as AuthProvider, c as Avenue, e as BroadcastGrant, i as BroadcastPublisher, j as BroadcastRole, k as BroadcastSession, l as BroadcastSource, m as BroadcastState, n as BroadcastStats, o as BroadcastTrackEvent, p as Channel, r as Connection, s as DeviceOptions, t as DeviceProfile, u as Devices, E as EnrolledDevice, N as Offline, P as OfflineAssurance, Q as OfflineEnrollmentRequest, R as OfflineRuntimeSupport, X as Room, Y as RoomOptions, $ as Space, a0 as SpaceOptions, a1 as State, a2 as Ticket, a3 as TicketOptions, a4 as Transports, a6 as UsageUpdate, a7 as UsageWarning } from './types-uDwIMPRk.js';
4
- import { am as ServiceErrorMetadata } from './Connection-DJoPKC0L.js';
5
- export { S as ServiceErrorObservation, T as TransferPeerDemandPurpose, d as TransferPeerDemandRequest, e as TransferPeerDemandState, f as TransferPeerDemandStatus } from './Connection-DJoPKC0L.js';
6
- import './coreClient.js';
7
- import './assembly-0EnNAgmm.js';
8
- import './capabilities-dnGwtGmQ.js';
2
+ import { O as Options, C as Client } from './types-BXYC9Q5H.js';
3
+ export { a as AttestationProvider, b as AuthProvider, c as Avenue, e as BroadcastGrant, i as BroadcastPublisher, j as BroadcastRole, k as BroadcastSession, l as BroadcastSource, m as BroadcastState, n as BroadcastStats, o as BroadcastTrackEvent, p as Channel, r as Connection, s as DeviceOptions, t as DeviceProfile, u as Devices, E as EnrolledDevice, N as Offline, P as OfflineAssurance, Q as OfflineEnrollmentRequest, R as OfflineRuntimeSupport, X as Room, Y as RoomOptions, Z as Space, _ as SpaceOptions, $ as State, a0 as Ticket, a1 as TicketOptions, a2 as Transports } from './types-BXYC9Q5H.js';
4
+ import { am as ServiceErrorMetadata } from './Connection-BZ6piJsh.js';
5
+ export { S as ServiceErrorObservation, T as TransferPeerDemandPurpose, d as TransferPeerDemandRequest, e as TransferPeerDemandState, f as TransferPeerDemandStatus } from './Connection-BZ6piJsh.js';
6
+ export { c as DiagnosticBundle, d as DiagnosticCapture, e as DiagnosticCaptureOptions, f as DiagnosticEvent, b as DiagnosticOperationEvent, g as DiagnosticPeer } from './coreClient-BYWmk_1O.js';
7
+ import './assembly-BEMgeExQ.js';
8
+ import './capabilities-fJ11v3xA.js';
9
9
 
10
10
  /**
11
11
  * Create a lazy OpenRTC 2.0 browser client. Construction validates only local
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import {a}from'./chunk-NS32P65Z.js';import {d}from'./chunk-72NEEJQG.js';import'./chunk-GMPEZXPD.js';import {i}from'./chunk-MTCLMTJN.js';import'./chunk-FKAQDDUM.js';import'./chunk-ZA44REGI.js';export{b as parseTicketInvite}from'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';export{a as ERROR_CODES,b as RTCError,e as classifyError,d as createError,c as projectError}from'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';function c(a){return i(a,{platform:"web",broadcastHostFactory:async e=>{let[{BrowserManagedBroadcastHost:o},{loadBrowserWasmRuntimeModule:n}]=await Promise.all([import('./BrowserManagedBroadcastHost-6VGHQQMF.js'),import('./WasmBridge-VGIBWCAC.js')]),t=n().then(async r=>(await r.initWasm(),r.start(),new r.WasmClient(e.apiKey)));return new o({resolve:e.resolve,manage:e.manage,deviceId:e.deviceId,defaultAuth:e.defaultAuth,loadWasm:()=>t})},runtimeFactory:async e=>{let{createWasmClient:o}=await import('./runtime/factories.js');return o(e)}})}c.native=function(a$1,e=d()){let o,n=()=>o??(o=import('./NativeProjectionBroker-Z6LCR4WB.js').then(({NativeProjectionBroker:t})=>new t));return i(a$1,{platform:"native",broadcastHostFactory:async t=>{let{NativeManagedBroadcastHost:r}=await import('./NativeManagedBroadcastHost-6A2QP3A7.js');return new r(e,t)},offlineSupport:()=>e.invoke("openrtc_offline_runtime_support"),createOfflineEnrollmentRequest:async t=>{let r=await e.invoke("start_iroh_node");return e.invoke("openrtc_create_offline_enrollment_request",{trustDomain:t.trustDomain,deviceId:t.deviceId,endpointId:r,enrollmentNonce:crypto.randomUUID(),requestedRoles:t.requestedRoles})},close:async()=>{o&&await(await o).close();},deviceKeyProvider:a(e),deviceIdProvider:async()=>{let t=await e.invoke("get_rtc_local_device_info");return String(t?.deviceId??"")},runtimeFactory:async t=>{let[{createIpcClient:r},y]=await Promise.all([import('./ipcFactory-L73S4NGQ.js'),n()]);return r(t,e,y)}})};export{c as OpenRTC};
1
+ import {a}from'./chunk-NS32P65Z.js';import {d}from'./chunk-72NEEJQG.js';import'./chunk-GMPEZXPD.js';import {i}from'./chunk-RSQCDTS2.js';import'./chunk-FKAQDDUM.js';import'./chunk-ZA44REGI.js';import'./chunk-F3IZBMAT.js';export{b as parseTicketInvite}from'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';export{a as ERROR_CODES,b as RTCError,e as classifyError,d as createError,c as projectError}from'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';function c(n){return i(n,{platform:"web",broadcastHostFactory:async e=>{let[{BrowserManagedBroadcastHost:o},{loadBrowserWasmRuntimeModule:a}]=await Promise.all([import('./BrowserManagedBroadcastHost-6VGHQQMF.js'),import('./WasmBridge-JZGJHSSU.js')]),t=a().then(async r=>(await r.initWasm(),r.start(),new r.WasmClient(e.apiKey)));return new o({resolve:e.resolve,manage:e.manage,deviceId:e.deviceId,defaultAuth:e.defaultAuth,loadWasm:()=>t})},runtimeFactory:async e=>{let{createWasmClient:o}=await import('./runtime/factories.js');return o(e)}})}c.native=function(n,e=d()){let o,a$1=()=>o??(o=import('./NativeProjectionBroker-Z6LCR4WB.js').then(({NativeProjectionBroker:t})=>new t));return i(n,{platform:"native",broadcastHostFactory:async t=>{let{NativeManagedBroadcastHost:r}=await import('./NativeManagedBroadcastHost-6A2QP3A7.js');return new r(e,t)},offlineSupport:()=>e.invoke("openrtc_offline_runtime_support"),createOfflineEnrollmentRequest:async t=>{let r=await e.invoke("start_iroh_node");return e.invoke("openrtc_create_offline_enrollment_request",{trustDomain:t.trustDomain,deviceId:t.deviceId,endpointId:r,enrollmentNonce:crypto.randomUUID(),requestedRoles:t.requestedRoles})},close:async()=>{o&&await(await o).close();},deviceKeyProvider:a(e),deviceIdProvider:async()=>{let t=await e.invoke("get_rtc_local_device_info");return String(t?.deviceId??"")},runtimeFactory:async t=>{let[{createIpcClient:r},y]=await Promise.all([import('./ipcFactory-2MDPNX5M.js'),a$1()]);return r(t,e,y)}})};export{c as OpenRTC};
@@ -1 +1 @@
1
- import {a as a$2}from'./chunk-TWTPJDUN.js';import {s}from'./chunk-WNCBDRFC.js';import'./chunk-IXQ4KWGP.js';import'./chunk-P6G2PAWP.js';import'./chunk-XR5JZKFP.js';import {a as a$1}from'./chunk-L4HWDDXL.js';import'./chunk-TYZS5LXQ.js';import'./chunk-OT7IPLZE.js';import'./chunk-OWKAJPOI.js';import {a}from'./chunk-XXZEDZUU.js';import'./chunk-TPF643LU.js';import'./chunk-72NEEJQG.js';import'./chunk-L2ZZXECX.js';import'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';function l(p,n,m=new a){let t=a$1(p);return a$2(t,new s({...t,bridge:n,projectionBroker:m}))}export{l as createIpcClient};
1
+ import {a as a$2}from'./chunk-C3TAFNG6.js';import {s}from'./chunk-R6J4PZDI.js';import'./chunk-IXQ4KWGP.js';import'./chunk-W45XAU3I.js';import'./chunk-CAUMGKP4.js';import {a as a$1}from'./chunk-L4HWDDXL.js';import'./chunk-TYZS5LXQ.js';import'./chunk-OT7IPLZE.js';import'./chunk-OWKAJPOI.js';import {a}from'./chunk-XXZEDZUU.js';import'./chunk-TPF643LU.js';import'./chunk-72NEEJQG.js';import'./chunk-L2ZZXECX.js';import'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';function l(p,n,m=new a){let t=a$1(p);return a$2(t,new s({...t,bridge:n,projectionBroker:m}))}export{l as createIpcClient};
package/dist/native.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { O as Options, C as Client } from './types-uDwIMPRk.js';
2
- export { A as AccessMode, a as AttestationProvider, b as AuthProvider, c as Avenue, B as BotVerificationProvider, d as BroadcastCreateOptions, e as BroadcastGrant, f as BroadcastInvite, g as BroadcastInviteOptions, h as BroadcastMedia, i as BroadcastPublisher, j as BroadcastRole, k as BroadcastSession, l as BroadcastSource, m as BroadcastState, n as BroadcastStats, o as BroadcastTrackEvent, p as Channel, q as Channels, r as Connection, D as Delivery, s as DeviceOptions, t as DeviceProfile, u as Devices, E as EnrolledDevice, I as IncomingPeerBidirectionalStream, v as IncomingPeerUnidirectionalStream, M as MediaConnection, w as MediaIncomingDemuxStats, x as MediaKind, y as MediaLatencySummary, z as MediaReceiver, F as MediaReceiverStats, G as MediaSender, H as MediaSenderStats, J as MediaStats, K as MediaTrackEvent, L as MediaTrackOptions, N as Offline, P as OfflineAssurance, Q as OfflineEnrollmentRequest, R as OfflineRuntimeSupport, S as PeerBidirectionalStream, T as PeerDatagramDuplexStream, U as PeerDatagramStats, V as PeerStreamOptions, W as PeerStreamTransport, X as Room, Y as RoomOptions, Z as RoomUsageEstimate, _ as RoomUsageEstimateInput, $ as Space, a0 as SpaceOptions, a1 as State, a2 as Ticket, a3 as TicketOptions, a4 as Transports, a5 as Usage, a6 as UsageUpdate, a7 as UsageWarning } from './types-uDwIMPRk.js';
1
+ import { O as Options, C as Client } from './types-BXYC9Q5H.js';
2
+ export { A as AccessMode, a as AttestationProvider, b as AuthProvider, c as Avenue, B as BotVerificationProvider, d as BroadcastCreateOptions, e as BroadcastGrant, f as BroadcastInvite, g as BroadcastInviteOptions, h as BroadcastMedia, i as BroadcastPublisher, j as BroadcastRole, k as BroadcastSession, l as BroadcastSource, m as BroadcastState, n as BroadcastStats, o as BroadcastTrackEvent, p as Channel, q as Channels, r as Connection, D as Delivery, s as DeviceOptions, t as DeviceProfile, u as Devices, E as EnrolledDevice, I as IncomingPeerBidirectionalStream, v as IncomingPeerUnidirectionalStream, M as MediaConnection, w as MediaIncomingDemuxStats, x as MediaKind, y as MediaLatencySummary, z as MediaReceiver, F as MediaReceiverStats, G as MediaSender, H as MediaSenderStats, J as MediaStats, K as MediaTrackEvent, L as MediaTrackOptions, N as Offline, P as OfflineAssurance, Q as OfflineEnrollmentRequest, R as OfflineRuntimeSupport, S as PeerBidirectionalStream, T as PeerDatagramDuplexStream, U as PeerDatagramStats, V as PeerStreamOptions, W as PeerStreamTransport, X as Room, Y as RoomOptions, Z as Space, _ as SpaceOptions, $ as State, a0 as Ticket, a1 as TicketOptions, a2 as Transports } from './types-BXYC9Q5H.js';
3
3
  import { P as PlutoIpcBridge } from './ipc-DgzKqHH3.js';
4
- export { E as EffectiveRoomArchitecture, R as RoomArchitectureMode, a as RoomArchitectureReason, b as RoomArchitectureSnapshot, c as RoomAuthorityAssignment, T as TransferPeerDemandPurpose, d as TransferPeerDemandRequest, e as TransferPeerDemandState, f as TransferPeerDemandStatus } from './Connection-DJoPKC0L.js';
5
- import './coreClient.js';
6
- import './assembly-0EnNAgmm.js';
7
- import './capabilities-dnGwtGmQ.js';
4
+ export { E as EffectiveRoomArchitecture, R as RoomArchitectureMode, a as RoomArchitectureReason, b as RoomArchitectureSnapshot, c as RoomAuthorityAssignment, T as TransferPeerDemandPurpose, d as TransferPeerDemandRequest, e as TransferPeerDemandState, f as TransferPeerDemandStatus } from './Connection-BZ6piJsh.js';
5
+ import './coreClient-BYWmk_1O.js';
6
+ import './assembly-BEMgeExQ.js';
7
+ import './capabilities-fJ11v3xA.js';
8
8
 
9
9
  /**
10
10
  * Native-only OpenRTC entrypoint for Tauri and other IPC-backed frontends.
package/dist/native.js CHANGED
@@ -1 +1 @@
1
- import {a}from'./chunk-XXZEDZUU.js';import'./chunk-TPF643LU.js';import {a as a$1}from'./chunk-NS32P65Z.js';import {d}from'./chunk-72NEEJQG.js';import'./chunk-GMPEZXPD.js';import {i}from'./chunk-MTCLMTJN.js';import'./chunk-FKAQDDUM.js';import'./chunk-ZA44REGI.js';import'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';function u(p,t=d()){let r=new a;return i(p,{platform:"native",broadcastHostFactory:async e=>{let{NativeManagedBroadcastHost:o}=await import('./NativeManagedBroadcastHost-6A2QP3A7.js');return new o(t,e)},offlineSupport:()=>t.invoke("openrtc_offline_runtime_support"),createOfflineEnrollmentRequest:async e=>{let o=await t.invoke("start_iroh_node");return t.invoke("openrtc_create_offline_enrollment_request",{trustDomain:e.trustDomain,deviceId:e.deviceId,endpointId:o,enrollmentNonce:crypto.randomUUID(),requestedRoles:e.requestedRoles})},close:()=>r.close(),deviceKeyProvider:a$1(t),deviceIdProvider:async()=>{let e=await t.invoke("get_rtc_local_device_info");return String(e?.deviceId??"")},runtimeFactory:async e=>{let{createIpcClient:o}=await import('./ipcFactory-L73S4NGQ.js');return o(e,t,r)}})}export{u as OpenRTC};
1
+ import {a}from'./chunk-XXZEDZUU.js';import'./chunk-TPF643LU.js';import {a as a$1}from'./chunk-NS32P65Z.js';import {d}from'./chunk-72NEEJQG.js';import'./chunk-GMPEZXPD.js';import {i}from'./chunk-RSQCDTS2.js';import'./chunk-FKAQDDUM.js';import'./chunk-ZA44REGI.js';import'./chunk-F3IZBMAT.js';import'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';function u(p,t=d()){let r=new a;return i(p,{platform:"native",broadcastHostFactory:async e=>{let{NativeManagedBroadcastHost:o}=await import('./NativeManagedBroadcastHost-6A2QP3A7.js');return new o(t,e)},offlineSupport:()=>t.invoke("openrtc_offline_runtime_support"),createOfflineEnrollmentRequest:async e=>{let o=await t.invoke("start_iroh_node");return t.invoke("openrtc_create_offline_enrollment_request",{trustDomain:e.trustDomain,deviceId:e.deviceId,endpointId:o,enrollmentNonce:crypto.randomUUID(),requestedRoles:e.requestedRoles})},close:()=>r.close(),deviceKeyProvider:a$1(t),deviceIdProvider:async()=>{let e=await t.invoke("get_rtc_local_device_info");return String(e?.deviceId??"")},runtimeFactory:async e=>{let{createIpcClient:o}=await import('./ipcFactory-2MDPNX5M.js');return o(e,t,r)}})}export{u as OpenRTC};
package/dist/node.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { O as Options, C as Client } from './types-uDwIMPRk.js';
2
- export { A as AccessMode, a as AttestationProvider, b as AuthProvider, c as Avenue, B as BotVerificationProvider, d as BroadcastCreateOptions, e as BroadcastGrant, f as BroadcastInvite, g as BroadcastInviteOptions, h as BroadcastMedia, i as BroadcastPublisher, j as BroadcastRole, k as BroadcastSession, l as BroadcastSource, m as BroadcastState, n as BroadcastStats, o as BroadcastTrackEvent, p as Channel, q as Channels, r as Connection, D as Delivery, s as DeviceOptions, t as DeviceProfile, u as Devices, E as EnrolledDevice, I as IncomingPeerBidirectionalStream, v as IncomingPeerUnidirectionalStream, M as MediaConnection, w as MediaIncomingDemuxStats, x as MediaKind, y as MediaLatencySummary, z as MediaReceiver, F as MediaReceiverStats, G as MediaSender, H as MediaSenderStats, J as MediaStats, K as MediaTrackEvent, L as MediaTrackOptions, N as Offline, P as OfflineAssurance, Q as OfflineEnrollmentRequest, R as OfflineRuntimeSupport, S as PeerBidirectionalStream, T as PeerDatagramDuplexStream, U as PeerDatagramStats, V as PeerStreamOptions, W as PeerStreamTransport, X as Room, Y as RoomOptions, Z as RoomUsageEstimate, _ as RoomUsageEstimateInput, $ as Space, a0 as SpaceOptions, a1 as State, a2 as Ticket, a3 as TicketOptions, a4 as Transports, a5 as Usage, a6 as UsageUpdate, a7 as UsageWarning } from './types-uDwIMPRk.js';
1
+ import { O as Options, C as Client } from './types-BXYC9Q5H.js';
2
+ export { A as AccessMode, a as AttestationProvider, b as AuthProvider, c as Avenue, B as BotVerificationProvider, d as BroadcastCreateOptions, e as BroadcastGrant, f as BroadcastInvite, g as BroadcastInviteOptions, h as BroadcastMedia, i as BroadcastPublisher, j as BroadcastRole, k as BroadcastSession, l as BroadcastSource, m as BroadcastState, n as BroadcastStats, o as BroadcastTrackEvent, p as Channel, q as Channels, r as Connection, D as Delivery, s as DeviceOptions, t as DeviceProfile, u as Devices, E as EnrolledDevice, I as IncomingPeerBidirectionalStream, v as IncomingPeerUnidirectionalStream, M as MediaConnection, w as MediaIncomingDemuxStats, x as MediaKind, y as MediaLatencySummary, z as MediaReceiver, F as MediaReceiverStats, G as MediaSender, H as MediaSenderStats, J as MediaStats, K as MediaTrackEvent, L as MediaTrackOptions, N as Offline, P as OfflineAssurance, Q as OfflineEnrollmentRequest, R as OfflineRuntimeSupport, S as PeerBidirectionalStream, T as PeerDatagramDuplexStream, U as PeerDatagramStats, V as PeerStreamOptions, W as PeerStreamTransport, X as Room, Y as RoomOptions, Z as Space, _ as SpaceOptions, $ as State, a0 as Ticket, a1 as TicketOptions, a2 as Transports } from './types-BXYC9Q5H.js';
3
3
  import { P as PlutoIpcBridge } from './ipc-DgzKqHH3.js';
4
- import { S as ServiceErrorObservation } from './Connection-DJoPKC0L.js';
5
- export { E as EffectiveRoomArchitecture, R as RoomArchitectureMode, a as RoomArchitectureReason, b as RoomArchitectureSnapshot, c as RoomAuthorityAssignment, T as TransferPeerDemandPurpose, d as TransferPeerDemandRequest, e as TransferPeerDemandState, f as TransferPeerDemandStatus } from './Connection-DJoPKC0L.js';
4
+ import { S as ServiceErrorObservation } from './Connection-BZ6piJsh.js';
5
+ export { E as EffectiveRoomArchitecture, R as RoomArchitectureMode, a as RoomArchitectureReason, b as RoomArchitectureSnapshot, c as RoomAuthorityAssignment, T as TransferPeerDemandPurpose, d as TransferPeerDemandRequest, e as TransferPeerDemandState, f as TransferPeerDemandStatus } from './Connection-BZ6piJsh.js';
6
6
  import { AuthorityAssignmentInput, AuthorityInterestAssignment } from './service-node.js';
7
- import './coreClient.js';
8
- import './assembly-0EnNAgmm.js';
9
- import './capabilities-dnGwtGmQ.js';
7
+ import './coreClient-BYWmk_1O.js';
8
+ import './assembly-BEMgeExQ.js';
9
+ import './capabilities-fJ11v3xA.js';
10
10
 
11
11
  interface NodeServiceNodeOptions {
12
12
  apiKey: string;
package/dist/node.js CHANGED
@@ -1,2 +1,2 @@
1
- import {a}from'./chunk-XXZEDZUU.js';import {a as a$2}from'./chunk-TPF643LU.js';import {a as a$1}from'./chunk-NS32P65Z.js';import {c}from'./chunk-72NEEJQG.js';import'./chunk-GMPEZXPD.js';import {i,b as b$2,a as a$3}from'./chunk-MTCLMTJN.js';import'./chunk-FKAQDDUM.js';import'./chunk-ZA44REGI.js';import'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import {e as e$1,b as b$3}from'./chunk-L7N4T2PX.js';import {b as b$1,d,e}from'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';import {spawn}from'child_process';import {constants}from'fs';import {access,readFile}from'fs/promises';import {isAbsolute,resolve,dirname}from'path';import {fileURLToPath}from'url';import {isDeepStrictEqual}from'util';import {randomUUID,verify,createHash}from'crypto';var E=1,F=24*1024,U=96*1024,N=128*1024,C=64*1024,ne=256,ie=256,L=3e4,se=/^[A-Za-z0-9_.:@-]+$/,ae=/(?:^|_)(?:SECRET|TOKEN|PASSWORD|PRIVATE(?:_KEY)?|CREDENTIALS?)(?:_|$)/i,ce=1;function de(r){return Buffer.from(JSON.stringify({schema:r.schema,kind:r.kind,platform:r.platform,arch:r.arch,rustTarget:r.rustTarget,sourceCommit:r.sourceCommit,sourceDigest:r.sourceDigest,binarySha256:r.binarySha256,protocol:r.protocol,signingKeySha256:r.signingKeySha256,signatureAlgorithm:r.signatureAlgorithm}),"utf8")}async function le(r,e,t){let[o,n,c]=await Promise.all([readFile(t),readFile(resolve(e,"openrtc-node-host.manifest.json")),readFile(resolve(r,"native","openrtc-node-host-signing-public.pem"))]).catch(()=>{throw new Error("[OpenRTC] Packaged Node host provenance is incomplete.")}),i;try{i=JSON.parse(n.toString("utf8"));}catch{throw new Error("[OpenRTC] Packaged Node host manifest is invalid.")}let a=s=>createHash("sha256").update(s).digest("hex"),u={"darwin-arm64":"aarch64-apple-darwin","darwin-x64":"x86_64-apple-darwin","linux-x64":"x86_64-unknown-linux-gnu"}[`${process.platform}-${process.arch}`];if(!(i!=null&&u!==void 0&&i.schema===ce&&i.kind==="openrtc-node-host"&&i.platform===process.platform&&i.arch===process.arch&&i.rustTarget===u&&/^[0-9a-f]{40}$/.test(i.sourceCommit)&&/^[0-9a-f]{64}$/.test(i.sourceDigest)&&i.binarySha256===a(o)&&i.signingKeySha256===a(c)&&i.signatureAlgorithm==="ed25519"&&/^[A-Za-z0-9+/]{86}==$/.test(i.signature)&&verify(null,de(i),c,Buffer.from(i.signature,"base64"))))throw new Error("[OpenRTC] Packaged Node host provenance verification failed.")}function z(r){return Object.fromEntries(Object.entries(process.env).filter(([e,t])=>!ae.test(e)&&(!r||!t?.includes(r))))}function f(r,e){queueMicrotask(()=>{try{let t=r(e);t&&typeof t.then=="function"&&t.catch(()=>{try{process.emitWarning("[OpenRTC] ServiceNode callback failed.",{code:"OPENRTC_SERVICE_CALLBACK"});}catch{}});}catch{try{process.emitWarning("[OpenRTC] ServiceNode callback failed.",{code:"OPENRTC_SERVICE_CALLBACK"});}catch{}}});}function $(r){let e=/^\d{1,20}$/;return typeof r.transportStableId!="string"||!e.test(r.transportStableId)||!e.test(r.transportGeneration)||!e.test(r.routeGeneration)?null:{transportStableId:r.transportStableId,transportGeneration:r.transportGeneration,routeGeneration:r.routeGeneration}}function ue(r,e){return r.transportStableId===e.transportStableId&&r.transportGeneration===e.transportGeneration&&r.routeGeneration===e.routeGeneration}function m(r,e,t=160){let o=r.trim();if(!o||o.length>t||!se.test(o))throw new TypeError(`[OpenRTC] ${e} is invalid.`);return o}function v(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 pe(r){if(!/^pk_(?:live|test)_[A-Za-z0-9]+$/.test(r.apiKey))throw new TypeError("[OpenRTC] apiKey is invalid.");if(!/^sk_(?:live|test)_[A-Za-z0-9_-]+$/.test(r.secretKey)||r.secretKey.length>128)throw new TypeError("[OpenRTC] secretKey is invalid.");let e=[...r.shardIds].map(t=>m(t,"shardId",80)).sort();if(e.length<1||e.length>64||new Set(e).size!==e.length)throw new RangeError("[OpenRTC] shardIds must contain 1..64 unique identifiers.");if(!isAbsolute(r.stateDirectory))throw new TypeError("[OpenRTC] stateDirectory must be absolute.");return r.maxPeers!==void 0&&v(r.maxPeers,"maxPeers",50),r.startupTimeoutMs!==void 0&&v(r.startupTimeoutMs,"startupTimeoutMs",12e4),{...r,serviceId:m(r.serviceId,"serviceId",80),generation:v(r.generation,"generation"),shardIds:e,deviceId:m(r.deviceId,"deviceId"),deviceName:r.deviceName?.trim()||"OpenRTC Node service"}}async function y(r){try{return await access(r,process.platform==="win32"?constants.F_OK:constants.X_OK),!0}catch{return false}}async function V(r,e,t,o,n){return new Promise((c,i)=>{let a=spawn(r,e,{cwd:t,env:z(n),stdio:["ignore","pipe","pipe"]}),d=Buffer.alloc(0),u=Buffer.alloc(0),l=(p,Y)=>Buffer.concat([p,Y]).subarray(-N);a.stdout.on("data",p=>{d=l(d,p);}),a.stderr.on("data",p=>{u=l(u,p);});let s=setTimeout(()=>{a.kill(),i(new Error(`[OpenRTC] Node host command timed out: ${r}.`));},o);a.once("error",p=>{clearTimeout(s),i(p);}),a.once("exit",p=>{clearTimeout(s),p===0?c(d.toString("utf8")):i(new Error(`[OpenRTC] Node host command failed (${p??"signal"}): ${u.toString("utf8").trim().slice(-4096)}`));});})}async function J(r){let e=r.binaryPath||process.env.OPENRTC_NODE_HOST_BINARY;if(e){if(!isAbsolute(e)||!await y(e))throw new Error("[OpenRTC] Node host binaryPath must name an executable absolute path.");return {command:e,args:[...r.binaryArgs??[]]}}if(r.buildFromSource){let c=r.sourceRoot||process.env.OPENRTC_SOURCE_ROOT;if(!c||!isAbsolute(c))throw new Error("[OpenRTC] buildFromSource requires an absolute sourceRoot or OPENRTC_SOURCE_ROOT.");let i=resolve(c,"crates/openrtc/Cargo.toml"),a=resolve(c,"target");await V("cargo",["build","--locked","--manifest-path",i,"--features","node-host","--bin","openrtc-node-host","--target-dir",a],c,12e4,r.secretKey);let d=resolve(a,"debug",`openrtc-node-host${process.platform==="win32"?".exe":""}`);if(!await y(d))throw new Error("[OpenRTC] local Node host build did not produce an executable.");return {command:d,args:[]}}let t=resolve(dirname(fileURLToPath(import.meta.url)),".."),o=resolve(t,"native",`${process.platform}-${process.arch}`),n=resolve(o,`openrtc-node-host${process.platform==="win32"?".exe":""}`);if(!await y(n))throw new Error(`[OpenRTC] This package has no Node host for ${process.platform}-${process.arch}. Install a supported OpenRTC package, set OPENRTC_NODE_HOST_BINARY, or use buildFromSource with sourceRoot.`);return await le(t,o,n),{command:n,args:[]}}async function X(r,e){let t=await V(r.command,[...r.args,"--protocol-info"],process.cwd(),12e4,e),o=JSON.parse(t);if(o.protocolVersion!==E||o.lifecycleOwner!=="rust-peer-session"||o.maxConfigBytes!==F||o.maxCommandBytes!==U||o.maxApplicationPayloadBytes!==C)throw new Error("[OpenRTC] Node host protocol is incompatible.");return o}var I=class{constructor(e,t,o){this.options=e;this.roomId=t;this.onEvent=o;this.child=null;this.childClosed=Promise.resolve();this.output=Buffer.alloc(0);this.stderr=Buffer.alloc(0);this.pending=new Map;this.writeQueue=Promise.resolve();this.stopped=false;this.closing=null;}async start(){let e=await J(this.options),t=await X(e,this.options.secretKey),o=new Promise((n,c)=>{let i=spawn(e.command,[...e.args],{env:z(this.options.secretKey),stdio:["pipe","pipe","pipe"]});this.child=i,this.childClosed=new Promise(l=>i.once("close",()=>l()));let a,d=setTimeout(()=>{c(this.failure("Node host startup timed out")),i.kill();},this.options.startupTimeoutMs??L),u=l=>{clearTimeout(d);let s=b$3.is(l)?l:this.failure(l.message);this.terminalFailure=a??s,c(s),this.failAll(s);};i.once("error",u),i.stdin.on("error",l=>{u(a??l),i.kill();}),i.stderr.on("data",l=>{this.stderr=Buffer.concat([this.stderr,l]).subarray(-4096);}),i.stdout.on("data",l=>{try{for(let s of this.parse(l)){if(s.type==="failure"){a=this.failure(s.error,s.serviceError),u(a);continue}if(t.testLane&&process.env.OPENRTC_NODE_HOST_LOCAL_TRACE==="1"&&s.type==="connection-state"&&console.error("[openrtc-local-node]",this.options.deviceId,{connectionId:s.snapshot.connectionId,deviceId:s.snapshot.deviceId,state:s.snapshot.state,routable:s.snapshot.routable,transportStableId:s.transportStableId,transportGeneration:s.transportGeneration,routeGeneration:s.routeGeneration}),s.type==="ready"){if(s.protocolVersion!==E||s.roomId!==this.roomId||s.deviceId!==this.options.deviceId||!isDeepStrictEqual(s.testLane,t.testLane))throw new Error("Node host returned inconsistent readiness metadata");clearTimeout(d),n();}this.dispatch(s);}}catch(s){u(s instanceof Error?s:new Error(String(s))),i.kill();}}),i.once("exit",(l,s)=>{clearTimeout(d),this.stopped=true;let p=a??this.failure(`Node host exited (${l??s??"unknown"})`);this.onEvent({type:"host-exit",error:p}),u(p);});});o.catch(()=>{});try{await this.writeLine({protocolVersion:E,apiKey:this.options.apiKey,secretKey:this.options.secretKey,serviceId:this.options.serviceId,generation:this.options.generation,shardIds:this.options.shardIds,deviceId:this.options.deviceId,roomId:this.roomId,deviceName:this.options.deviceName,stateDirectory:this.options.stateDirectory,maxPeers:this.options.maxPeers,irohRelay:this.options.irohRelay!==!1},F),await o;}catch(n){throw this.terminalFailure??n}}async request(e,t){if(!this.child||this.stopped||!this.child.stdin.writable)throw new Error("[OpenRTC] Node host is closed.");if(this.pending.size>=ne)throw new Error("[OpenRTC] Node host has too many pending requests.");let o=randomUUID(),n=new Promise((c,i)=>{let a=setTimeout(()=>{this.pending.delete(o),i(new Error(`[OpenRTC] Node host ${e} response timed out.`));},L);this.pending.set(o,{resolve:c,reject:i,timer:a});});n.catch(()=>{});try{await this.writeLine({type:e,id:o,...t},U);}catch(c){let i=this.pending.get(o);i&&(clearTimeout(i.timer),this.pending.delete(o),i.reject(this.terminalFailure??this.failure(c instanceof Error?c.message:String(c))));}return n}close(){return this.closing??(this.closing=this.stop())}async stop(){if(!this.child)return;let e=this.child;try{this.stopped||await this.request("shutdown",{});}finally{e.stdin.end();let t=setTimeout(()=>e.kill("SIGTERM"),2e3),o=setTimeout(()=>e.kill("SIGKILL"),4e3);try{await this.childClosed;}finally{clearTimeout(t),clearTimeout(o);}}}parse(e){if(this.output=Buffer.concat([this.output,e]),this.output.length>N&&!this.output.includes(10))throw new Error("Node host output line exceeded its byte limit");let t=[];for(;;){let o=this.output.indexOf(10);if(o<0)break;if(o>N)throw new Error("Node host output line exceeded its byte limit");let n=this.output.subarray(0,o).toString("utf8").trim();this.output=this.output.subarray(o+1),n&&t.push(JSON.parse(n));}return t}writeLine(e,t){let o=`${JSON.stringify(e)}
2
- `;if(Buffer.byteLength(o,"utf8")-1>t)return Promise.reject(new Error("Node host input line exceeded its byte limit"));let n=this.writeQueue.then(()=>new Promise((c,i)=>{if(!this.child||this.stopped||!this.child.stdin.writable){i(new Error("Node host is closed"));return}this.child.stdin.write(o,a=>{a?i(a):c();});}));return this.writeQueue=n.catch(()=>{}),n}dispatch(e){if(e.type!=="response"){this.onEvent(e);return}let t=this.pending.get(e.id);t&&(clearTimeout(t.timer),this.pending.delete(e.id),e.ok?t.resolve(e.value):t.reject(this.failure(e.error||"Node host request failed",e.serviceError)));}failure(e$2,t){let o=a=>a.split(this.options.secretKey).join("[REDACTED]"),n=o(e$2),c=o(this.stderr.toString("utf8")).trim(),i=`[OpenRTC] ${n}.${c?` Host stderr: ${c}`:""}`;if(t&&typeof t=="object"&&!Array.isArray(t)){let a=t,d$1=b$1(a.code);if(d(a.code)||d$1){let u=e(a);return e$1({...u,requestId:u.requestId?o(u.requestId):void 0,code:a.code,retryable:typeof a.retryable=="boolean"?a.retryable:!!d$1,message:i})}}return new Error(i)}failAll(e){for(let t of this.pending.values())clearTimeout(t.timer),t.reject(e);this.pending.clear();}},S=class{constructor(e,t,o,n,c){this.id=e;this.peerId=t;this.host=o;this.nativeGeneration=n;this.capabilityKey=c;this.messages=new Set;this.closeListeners=new Set;this.queued=[];this.isClosed=false;}async send(e){if(this.isClosed)throw new Error("[OpenRTC] Connection is closed.");let t=he(e instanceof Uint8Array||e instanceof ArrayBuffer?e:a$3("raw","message",e,this.capabilityKey));await this.host.request("send",{connectionId:this.id,payloadBase64:t.toString("base64")});}onMessage(e){let t=e;this.messages.add(t);for(let o of this.queued.splice(0))f(t,o);return ()=>this.messages.delete(t)}onClose(e){return this.isClosed?f(e,void 0):this.closeListeners.add(e),()=>this.closeListeners.delete(e)}receive(e){if(!this.isClosed){if(this.messages.size===0){this.queued.length===ie&&this.queued.shift(),this.queued.push(e);return}for(let t of this.messages)f(t,e);}}close(){if(!this.isClosed){this.isClosed=true,this.queued.length=0;for(let e of this.closeListeners)f(e,void 0);this.messages.clear(),this.closeListeners.clear();}}accepts(e){return ue(e,this.nativeGeneration)}replaceGeneration(e){this.nativeGeneration=e;}},T=class{constructor(e,t,o){this.id=e;this.host=t;this.onServiceError=o;this.kind="room";this.listeners=new Set;this.connections=new Map;this.closed=false;}publishAssignment(e){if(this.closed)return Promise.reject(new Error("[OpenRTC] Service room is closed."));let t=(e.priorityDeviceIds??[]).map(n=>m(n,"priorityDeviceId")),o=(e.relevantEntityIds??[]).map(n=>m(n,"relevantEntityId"));return t.length>8||o.length>32||new Set(t).size!==t.length||new Set(o).size!==o.length?Promise.reject(new Error("[OpenRTC] Authority assignment identifiers are invalid.")):this.host.request("publish-assignment",{revision:v(e.revision,"revision"),subjectDeviceId:m(e.subjectDeviceId,"subjectDeviceId"),shardId:m(e.shardId,"shardId",80),priorityDeviceIds:t,relevantEntityIds:o,ttlMs:e.ttlMs===void 0?void 0:v(e.ttlMs,"ttlMs",12e4)})}onConnection(e){this.listeners.add(e);for(let t of this.connections.values())f(e,t);return ()=>this.listeners.delete(e)}project(e){if(this.closed)return;if(e.type==="host-exit"){this.closed=true;for(let d of this.connections.values())d.close();this.connections.clear(),this.listeners.clear();return}if(e.type==="service-error"){let d=e.avenue;if(!d||typeof d!="object"||Array.isArray(d))return;let u=d;if(u.kind!=="room"||u.id!==this.id||typeof e.runtimeInstanceId!="string"||e.runtimeInstanceId.trim().length===0)return;let l=a$2(e.serviceError,{kind:"room",id:this.id});l&&this.onServiceError&&f(()=>{if(!this.closed)return this.onServiceError?.(l)},void 0);return}if(e.type==="peer-message"){let d=this.connections.get(e.connectionId),u=$(e);if(d&&u&&d.accepts(u)){let l=fe(e.payloadBase64),s=b$2(l);s?s.capability===`room:${this.id}`&&s.kind==="raw"&&d.receive(s.value):d.receive(l);}return}if(e.type!=="connection-state")return;let t=e.snapshot,o=$(e);if(typeof t.connectionId!="string"||!o)return;let n=this.connections.get(t.connectionId);if(typeof t.state=="string"&&["closed","failed"].includes(t.state.toLowerCase())){n?.accepts(o)&&(n.close(),this.connections.delete(t.connectionId));return}if(n){t.routable===true&&n.replaceGeneration(o);return}let i=typeof t.remoteNodeId=="string"?t.remoteNodeId:null;if(t.routable!==true||!i)return;let a=new S(t.connectionId,i,this.host,o,`room:${this.id}`);this.connections.set(a.id,a);for(let d of this.listeners)f(d,a);}async close(){if(this.closed)return this.host.close();this.closed=true;for(let e of this.connections.values())e.close();this.connections.clear(),this.listeners.clear(),await this.host.close();}};function he(r){let e;if(r instanceof Uint8Array)e=Buffer.from(r);else if(r instanceof ArrayBuffer)e=Buffer.from(r);else if(typeof r=="string")e=Buffer.from(r,"utf8");else {let t=JSON.stringify(r);if(t===void 0)throw new TypeError("[OpenRTC] Message must be a string, bytes, or JSON value.");e=Buffer.from(t,"utf8");}if(e.length>C)throw new RangeError("[OpenRTC] Message exceeds the Node host payload limit.");return e}function fe(r){let e=Buffer.from(r,"base64");if(e.length>C)throw new Error("[OpenRTC] Node host returned an oversized application payload.");try{let t=new TextDecoder("utf-8",{fatal:!0}).decode(e);try{return JSON.parse(t)}catch{return t}}catch{return new Uint8Array(e)}}var b=class{constructor(e){this.listeners=new Set;this.roomPromise=null;this.roomId=null;this.closed=false;this.closing=null;this.options=pe(e);}onConnection(e){if(this.closed)throw new Error("[OpenRTC] ServiceNode is closed.");return this.listeners.add(e),()=>this.listeners.delete(e)}listen(e){return this.closed?Promise.reject(new Error("[OpenRTC] ServiceNode is closed.")):(e=m(e,"roomId"),this.roomId&&this.roomId!==e?Promise.reject(new Error("[OpenRTC] A Node ServiceNode owns exactly one room.")):this.roomPromise?this.roomPromise:(this.roomId=e,this.roomPromise=this.open(e),this.roomPromise))}close(){return this.closing??(this.closing=this.stop())}async stop(){this.closed=true,await(await this.roomPromise?.catch(()=>null))?.close(),this.listeners.clear();}async open(e){let t,o=new I(this.options,e,n=>t?.project(n));t=new T(e,o,this.options.onServiceError);try{return await o.start(),t.onConnection(n=>{for(let c of this.listeners)f(c,{room:t,connection:n});}),t}catch(n){throw await o.close().catch(()=>{}),this.roomPromise=null,this.roomId=null,n}}};async function me(r){let e=await J(r);return X(e)}function ke(r,e){let t=c(e,"openrtc/node"),o=new a;return i(r,{platform:"native",broadcastHostFactory:async n=>{let{NativeManagedBroadcastHost:c}=await import('./NativeManagedBroadcastHost-6A2QP3A7.js');return new c(t,n)},offlineSupport:()=>t.invoke("openrtc_offline_runtime_support"),createOfflineEnrollmentRequest:async n=>{let c=await t.invoke("start_iroh_node");return t.invoke("openrtc_create_offline_enrollment_request",{trustDomain:n.trustDomain,deviceId:n.deviceId,endpointId:c,enrollmentNonce:crypto.randomUUID(),requestedRoles:n.requestedRoles})},close:()=>o.close(),deviceKeyProvider:a$1(t),deviceIdProvider:async()=>{let n=await t.invoke("get_rtc_local_device_info");return String(n?.deviceId??"")},runtimeFactory:async n=>{let{createIpcClient:c}=await import('./ipcFactory-L73S4NGQ.js');return c(n,t,o)}})}export{ke as OpenRTC,b as ServiceNode,me as inspectNodeHost};
1
+ import {a}from'./chunk-XXZEDZUU.js';import {a as a$2}from'./chunk-TPF643LU.js';import {a as a$1}from'./chunk-NS32P65Z.js';import {c}from'./chunk-72NEEJQG.js';import'./chunk-GMPEZXPD.js';import {i,b as b$2,a as a$3}from'./chunk-RSQCDTS2.js';import'./chunk-FKAQDDUM.js';import'./chunk-ZA44REGI.js';import'./chunk-F3IZBMAT.js';import'./chunk-O7Z6WLGA.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import {e as e$1,b as b$3}from'./chunk-L7N4T2PX.js';import {b as b$1,d,e}from'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';import {spawn}from'child_process';import {constants}from'fs';import {access,readFile}from'fs/promises';import {isAbsolute,resolve,dirname}from'path';import {fileURLToPath}from'url';import {isDeepStrictEqual}from'util';import {randomUUID,verify,createHash}from'crypto';var E=1,F=24*1024,U=96*1024,N=128*1024,C=64*1024,ne=256,ie=256,L=3e4,se=/^[A-Za-z0-9_.:@-]+$/,ae=/(?:^|_)(?:SECRET|TOKEN|PASSWORD|PRIVATE(?:_KEY)?|CREDENTIALS?)(?:_|$)/i,ce=1;function de(r){return Buffer.from(JSON.stringify({schema:r.schema,kind:r.kind,platform:r.platform,arch:r.arch,rustTarget:r.rustTarget,sourceCommit:r.sourceCommit,sourceDigest:r.sourceDigest,binarySha256:r.binarySha256,protocol:r.protocol,signingKeySha256:r.signingKeySha256,signatureAlgorithm:r.signatureAlgorithm}),"utf8")}async function le(r,e,t){let[o,n,c]=await Promise.all([readFile(t),readFile(resolve(e,"openrtc-node-host.manifest.json")),readFile(resolve(r,"native","openrtc-node-host-signing-public.pem"))]).catch(()=>{throw new Error("[OpenRTC] Packaged Node host provenance is incomplete.")}),i;try{i=JSON.parse(n.toString("utf8"));}catch{throw new Error("[OpenRTC] Packaged Node host manifest is invalid.")}let a=s=>createHash("sha256").update(s).digest("hex"),u={"darwin-arm64":"aarch64-apple-darwin","darwin-x64":"x86_64-apple-darwin","linux-x64":"x86_64-unknown-linux-gnu"}[`${process.platform}-${process.arch}`];if(!(i!=null&&u!==void 0&&i.schema===ce&&i.kind==="openrtc-node-host"&&i.platform===process.platform&&i.arch===process.arch&&i.rustTarget===u&&/^[0-9a-f]{40}$/.test(i.sourceCommit)&&/^[0-9a-f]{64}$/.test(i.sourceDigest)&&i.binarySha256===a(o)&&i.signingKeySha256===a(c)&&i.signatureAlgorithm==="ed25519"&&/^[A-Za-z0-9+/]{86}==$/.test(i.signature)&&verify(null,de(i),c,Buffer.from(i.signature,"base64"))))throw new Error("[OpenRTC] Packaged Node host provenance verification failed.")}function z(r){return Object.fromEntries(Object.entries(process.env).filter(([e,t])=>!ae.test(e)&&(!r||!t?.includes(r))))}function f(r,e){queueMicrotask(()=>{try{let t=r(e);t&&typeof t.then=="function"&&t.catch(()=>{try{process.emitWarning("[OpenRTC] ServiceNode callback failed.",{code:"OPENRTC_SERVICE_CALLBACK"});}catch{}});}catch{try{process.emitWarning("[OpenRTC] ServiceNode callback failed.",{code:"OPENRTC_SERVICE_CALLBACK"});}catch{}}});}function $(r){let e=/^\d{1,20}$/;return typeof r.transportStableId!="string"||!e.test(r.transportStableId)||!e.test(r.transportGeneration)||!e.test(r.routeGeneration)?null:{transportStableId:r.transportStableId,transportGeneration:r.transportGeneration,routeGeneration:r.routeGeneration}}function ue(r,e){return r.transportStableId===e.transportStableId&&r.transportGeneration===e.transportGeneration&&r.routeGeneration===e.routeGeneration}function m(r,e,t=160){let o=r.trim();if(!o||o.length>t||!se.test(o))throw new TypeError(`[OpenRTC] ${e} is invalid.`);return o}function v(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 pe(r){if(!/^pk_(?:live|test)_[A-Za-z0-9]+$/.test(r.apiKey))throw new TypeError("[OpenRTC] apiKey is invalid.");if(!/^sk_(?:live|test)_[A-Za-z0-9_-]+$/.test(r.secretKey)||r.secretKey.length>128)throw new TypeError("[OpenRTC] secretKey is invalid.");let e=[...r.shardIds].map(t=>m(t,"shardId",80)).sort();if(e.length<1||e.length>64||new Set(e).size!==e.length)throw new RangeError("[OpenRTC] shardIds must contain 1..64 unique identifiers.");if(!isAbsolute(r.stateDirectory))throw new TypeError("[OpenRTC] stateDirectory must be absolute.");return r.maxPeers!==void 0&&v(r.maxPeers,"maxPeers",50),r.startupTimeoutMs!==void 0&&v(r.startupTimeoutMs,"startupTimeoutMs",12e4),{...r,serviceId:m(r.serviceId,"serviceId",80),generation:v(r.generation,"generation"),shardIds:e,deviceId:m(r.deviceId,"deviceId"),deviceName:r.deviceName?.trim()||"OpenRTC Node service"}}async function y(r){try{return await access(r,process.platform==="win32"?constants.F_OK:constants.X_OK),!0}catch{return false}}async function V(r,e,t,o,n){return new Promise((c,i)=>{let a=spawn(r,e,{cwd:t,env:z(n),stdio:["ignore","pipe","pipe"]}),d=Buffer.alloc(0),u=Buffer.alloc(0),l=(p,Y)=>Buffer.concat([p,Y]).subarray(-N);a.stdout.on("data",p=>{d=l(d,p);}),a.stderr.on("data",p=>{u=l(u,p);});let s=setTimeout(()=>{a.kill(),i(new Error(`[OpenRTC] Node host command timed out: ${r}.`));},o);a.once("error",p=>{clearTimeout(s),i(p);}),a.once("exit",p=>{clearTimeout(s),p===0?c(d.toString("utf8")):i(new Error(`[OpenRTC] Node host command failed (${p??"signal"}): ${u.toString("utf8").trim().slice(-4096)}`));});})}async function J(r){let e=r.binaryPath||process.env.OPENRTC_NODE_HOST_BINARY;if(e){if(!isAbsolute(e)||!await y(e))throw new Error("[OpenRTC] Node host binaryPath must name an executable absolute path.");return {command:e,args:[...r.binaryArgs??[]]}}if(r.buildFromSource){let c=r.sourceRoot||process.env.OPENRTC_SOURCE_ROOT;if(!c||!isAbsolute(c))throw new Error("[OpenRTC] buildFromSource requires an absolute sourceRoot or OPENRTC_SOURCE_ROOT.");let i=resolve(c,"crates/openrtc/Cargo.toml"),a=resolve(c,"target");await V("cargo",["build","--locked","--manifest-path",i,"--features","node-host","--bin","openrtc-node-host","--target-dir",a],c,12e4,r.secretKey);let d=resolve(a,"debug",`openrtc-node-host${process.platform==="win32"?".exe":""}`);if(!await y(d))throw new Error("[OpenRTC] local Node host build did not produce an executable.");return {command:d,args:[]}}let t=resolve(dirname(fileURLToPath(import.meta.url)),".."),o=resolve(t,"native",`${process.platform}-${process.arch}`),n=resolve(o,`openrtc-node-host${process.platform==="win32"?".exe":""}`);if(!await y(n))throw new Error(`[OpenRTC] This package has no Node host for ${process.platform}-${process.arch}. Install a supported OpenRTC package, set OPENRTC_NODE_HOST_BINARY, or use buildFromSource with sourceRoot.`);return await le(t,o,n),{command:n,args:[]}}async function X(r,e){let t=await V(r.command,[...r.args,"--protocol-info"],process.cwd(),12e4,e),o=JSON.parse(t);if(o.protocolVersion!==E||o.lifecycleOwner!=="rust-peer-session"||o.maxConfigBytes!==F||o.maxCommandBytes!==U||o.maxApplicationPayloadBytes!==C)throw new Error("[OpenRTC] Node host protocol is incompatible.");return o}var I=class{constructor(e,t,o){this.options=e;this.roomId=t;this.onEvent=o;this.child=null;this.childClosed=Promise.resolve();this.output=Buffer.alloc(0);this.stderr=Buffer.alloc(0);this.pending=new Map;this.writeQueue=Promise.resolve();this.stopped=false;this.closing=null;}async start(){let e=await J(this.options),t=await X(e,this.options.secretKey),o=new Promise((n,c)=>{let i=spawn(e.command,[...e.args],{env:z(this.options.secretKey),stdio:["pipe","pipe","pipe"]});this.child=i,this.childClosed=new Promise(l=>i.once("close",()=>l()));let a,d=setTimeout(()=>{c(this.failure("Node host startup timed out")),i.kill();},this.options.startupTimeoutMs??L),u=l=>{clearTimeout(d);let s=b$3.is(l)?l:this.failure(l.message);this.terminalFailure=a??s,c(s),this.failAll(s);};i.once("error",u),i.stdin.on("error",l=>{u(a??l),i.kill();}),i.stderr.on("data",l=>{this.stderr=Buffer.concat([this.stderr,l]).subarray(-4096);}),i.stdout.on("data",l=>{try{for(let s of this.parse(l)){if(s.type==="failure"){a=this.failure(s.error,s.serviceError),u(a);continue}if(t.testLane&&process.env.OPENRTC_NODE_HOST_LOCAL_TRACE==="1"&&s.type==="connection-state"&&console.error("[openrtc-local-node]",this.options.deviceId,{connectionId:s.snapshot.connectionId,deviceId:s.snapshot.deviceId,state:s.snapshot.state,routable:s.snapshot.routable,transportStableId:s.transportStableId,transportGeneration:s.transportGeneration,routeGeneration:s.routeGeneration}),s.type==="ready"){if(s.protocolVersion!==E||s.roomId!==this.roomId||s.deviceId!==this.options.deviceId||!isDeepStrictEqual(s.testLane,t.testLane))throw new Error("Node host returned inconsistent readiness metadata");clearTimeout(d),n();}this.dispatch(s);}}catch(s){u(s instanceof Error?s:new Error(String(s))),i.kill();}}),i.once("exit",(l,s)=>{clearTimeout(d),this.stopped=true;let p=a??this.failure(`Node host exited (${l??s??"unknown"})`);this.onEvent({type:"host-exit",error:p}),u(p);});});o.catch(()=>{});try{await this.writeLine({protocolVersion:E,apiKey:this.options.apiKey,secretKey:this.options.secretKey,serviceId:this.options.serviceId,generation:this.options.generation,shardIds:this.options.shardIds,deviceId:this.options.deviceId,roomId:this.roomId,deviceName:this.options.deviceName,stateDirectory:this.options.stateDirectory,maxPeers:this.options.maxPeers,irohRelay:this.options.irohRelay!==!1},F),await o;}catch(n){throw this.terminalFailure??n}}async request(e,t){if(!this.child||this.stopped||!this.child.stdin.writable)throw new Error("[OpenRTC] Node host is closed.");if(this.pending.size>=ne)throw new Error("[OpenRTC] Node host has too many pending requests.");let o=randomUUID(),n=new Promise((c,i)=>{let a=setTimeout(()=>{this.pending.delete(o),i(new Error(`[OpenRTC] Node host ${e} response timed out.`));},L);this.pending.set(o,{resolve:c,reject:i,timer:a});});n.catch(()=>{});try{await this.writeLine({type:e,id:o,...t},U);}catch(c){let i=this.pending.get(o);i&&(clearTimeout(i.timer),this.pending.delete(o),i.reject(this.terminalFailure??this.failure(c instanceof Error?c.message:String(c))));}return n}close(){return this.closing??(this.closing=this.stop())}async stop(){if(!this.child)return;let e=this.child;try{this.stopped||await this.request("shutdown",{});}finally{e.stdin.end();let t=setTimeout(()=>e.kill("SIGTERM"),2e3),o=setTimeout(()=>e.kill("SIGKILL"),4e3);try{await this.childClosed;}finally{clearTimeout(t),clearTimeout(o);}}}parse(e){if(this.output=Buffer.concat([this.output,e]),this.output.length>N&&!this.output.includes(10))throw new Error("Node host output line exceeded its byte limit");let t=[];for(;;){let o=this.output.indexOf(10);if(o<0)break;if(o>N)throw new Error("Node host output line exceeded its byte limit");let n=this.output.subarray(0,o).toString("utf8").trim();this.output=this.output.subarray(o+1),n&&t.push(JSON.parse(n));}return t}writeLine(e,t){let o=`${JSON.stringify(e)}
2
+ `;if(Buffer.byteLength(o,"utf8")-1>t)return Promise.reject(new Error("Node host input line exceeded its byte limit"));let n=this.writeQueue.then(()=>new Promise((c,i)=>{if(!this.child||this.stopped||!this.child.stdin.writable){i(new Error("Node host is closed"));return}this.child.stdin.write(o,a=>{a?i(a):c();});}));return this.writeQueue=n.catch(()=>{}),n}dispatch(e){if(e.type!=="response"){this.onEvent(e);return}let t=this.pending.get(e.id);t&&(clearTimeout(t.timer),this.pending.delete(e.id),e.ok?t.resolve(e.value):t.reject(this.failure(e.error||"Node host request failed",e.serviceError)));}failure(e$2,t){let o=a=>a.split(this.options.secretKey).join("[REDACTED]"),n=o(e$2),c=o(this.stderr.toString("utf8")).trim(),i=`[OpenRTC] ${n}.${c?` Host stderr: ${c}`:""}`;if(t&&typeof t=="object"&&!Array.isArray(t)){let a=t,d$1=b$1(a.code);if(d(a.code)||d$1){let u=e(a);return e$1({...u,requestId:u.requestId?o(u.requestId):void 0,code:a.code,retryable:typeof a.retryable=="boolean"?a.retryable:!!d$1,message:i})}}return new Error(i)}failAll(e){for(let t of this.pending.values())clearTimeout(t.timer),t.reject(e);this.pending.clear();}},S=class{constructor(e,t,o,n,c){this.id=e;this.peerId=t;this.host=o;this.nativeGeneration=n;this.capabilityKey=c;this.messages=new Set;this.closeListeners=new Set;this.queued=[];this.isClosed=false;}async send(e){if(this.isClosed)throw new Error("[OpenRTC] Connection is closed.");let t=he(e instanceof Uint8Array||e instanceof ArrayBuffer?e:a$3("raw","message",e,this.capabilityKey));await this.host.request("send",{connectionId:this.id,payloadBase64:t.toString("base64")});}onMessage(e){let t=e;this.messages.add(t);for(let o of this.queued.splice(0))f(t,o);return ()=>this.messages.delete(t)}onClose(e){return this.isClosed?f(e,void 0):this.closeListeners.add(e),()=>this.closeListeners.delete(e)}receive(e){if(!this.isClosed){if(this.messages.size===0){this.queued.length===ie&&this.queued.shift(),this.queued.push(e);return}for(let t of this.messages)f(t,e);}}close(){if(!this.isClosed){this.isClosed=true,this.queued.length=0;for(let e of this.closeListeners)f(e,void 0);this.messages.clear(),this.closeListeners.clear();}}accepts(e){return ue(e,this.nativeGeneration)}replaceGeneration(e){this.nativeGeneration=e;}},T=class{constructor(e,t,o){this.id=e;this.host=t;this.onServiceError=o;this.kind="room";this.listeners=new Set;this.connections=new Map;this.closed=false;}publishAssignment(e){if(this.closed)return Promise.reject(new Error("[OpenRTC] Service room is closed."));let t=(e.priorityDeviceIds??[]).map(n=>m(n,"priorityDeviceId")),o=(e.relevantEntityIds??[]).map(n=>m(n,"relevantEntityId"));return t.length>8||o.length>32||new Set(t).size!==t.length||new Set(o).size!==o.length?Promise.reject(new Error("[OpenRTC] Authority assignment identifiers are invalid.")):this.host.request("publish-assignment",{revision:v(e.revision,"revision"),subjectDeviceId:m(e.subjectDeviceId,"subjectDeviceId"),shardId:m(e.shardId,"shardId",80),priorityDeviceIds:t,relevantEntityIds:o,ttlMs:e.ttlMs===void 0?void 0:v(e.ttlMs,"ttlMs",12e4)})}onConnection(e){this.listeners.add(e);for(let t of this.connections.values())f(e,t);return ()=>this.listeners.delete(e)}project(e){if(this.closed)return;if(e.type==="host-exit"){this.closed=true;for(let d of this.connections.values())d.close();this.connections.clear(),this.listeners.clear();return}if(e.type==="service-error"){let d=e.avenue;if(!d||typeof d!="object"||Array.isArray(d))return;let u=d;if(u.kind!=="room"||u.id!==this.id||typeof e.runtimeInstanceId!="string"||e.runtimeInstanceId.trim().length===0)return;let l=a$2(e.serviceError,{kind:"room",id:this.id});l&&this.onServiceError&&f(()=>{if(!this.closed)return this.onServiceError?.(l)},void 0);return}if(e.type==="peer-message"){let d=this.connections.get(e.connectionId),u=$(e);if(d&&u&&d.accepts(u)){let l=fe(e.payloadBase64),s=b$2(l);s?s.capability===`room:${this.id}`&&s.kind==="raw"&&d.receive(s.value):d.receive(l);}return}if(e.type!=="connection-state")return;let t=e.snapshot,o=$(e);if(typeof t.connectionId!="string"||!o)return;let n=this.connections.get(t.connectionId);if(typeof t.state=="string"&&["closed","failed"].includes(t.state.toLowerCase())){n?.accepts(o)&&(n.close(),this.connections.delete(t.connectionId));return}if(n){t.routable===true&&n.replaceGeneration(o);return}let i=typeof t.remoteNodeId=="string"?t.remoteNodeId:null;if(t.routable!==true||!i)return;let a=new S(t.connectionId,i,this.host,o,`room:${this.id}`);this.connections.set(a.id,a);for(let d of this.listeners)f(d,a);}async close(){if(this.closed)return this.host.close();this.closed=true;for(let e of this.connections.values())e.close();this.connections.clear(),this.listeners.clear(),await this.host.close();}};function he(r){let e;if(r instanceof Uint8Array)e=Buffer.from(r);else if(r instanceof ArrayBuffer)e=Buffer.from(r);else if(typeof r=="string")e=Buffer.from(r,"utf8");else {let t=JSON.stringify(r);if(t===void 0)throw new TypeError("[OpenRTC] Message must be a string, bytes, or JSON value.");e=Buffer.from(t,"utf8");}if(e.length>C)throw new RangeError("[OpenRTC] Message exceeds the Node host payload limit.");return e}function fe(r){let e=Buffer.from(r,"base64");if(e.length>C)throw new Error("[OpenRTC] Node host returned an oversized application payload.");try{let t=new TextDecoder("utf-8",{fatal:!0}).decode(e);try{return JSON.parse(t)}catch{return t}}catch{return new Uint8Array(e)}}var b=class{constructor(e){this.listeners=new Set;this.roomPromise=null;this.roomId=null;this.closed=false;this.closing=null;this.options=pe(e);}onConnection(e){if(this.closed)throw new Error("[OpenRTC] ServiceNode is closed.");return this.listeners.add(e),()=>this.listeners.delete(e)}listen(e){return this.closed?Promise.reject(new Error("[OpenRTC] ServiceNode is closed.")):(e=m(e,"roomId"),this.roomId&&this.roomId!==e?Promise.reject(new Error("[OpenRTC] A Node ServiceNode owns exactly one room.")):this.roomPromise?this.roomPromise:(this.roomId=e,this.roomPromise=this.open(e),this.roomPromise))}close(){return this.closing??(this.closing=this.stop())}async stop(){this.closed=true,await(await this.roomPromise?.catch(()=>null))?.close(),this.listeners.clear();}async open(e){let t,o=new I(this.options,e,n=>t?.project(n));t=new T(e,o,this.options.onServiceError);try{return await o.start(),t.onConnection(n=>{for(let c of this.listeners)f(c,{room:t,connection:n});}),t}catch(n){throw await o.close().catch(()=>{}),this.roomPromise=null,this.roomId=null,n}}};async function me(r){let e=await J(r);return X(e)}function ke(r,e){let t=c(e,"openrtc/node"),o=new a;return i(r,{platform:"native",broadcastHostFactory:async n=>{let{NativeManagedBroadcastHost:c}=await import('./NativeManagedBroadcastHost-6A2QP3A7.js');return new c(t,n)},offlineSupport:()=>t.invoke("openrtc_offline_runtime_support"),createOfflineEnrollmentRequest:async n=>{let c=await t.invoke("start_iroh_node");return t.invoke("openrtc_create_offline_enrollment_request",{trustDomain:n.trustDomain,deviceId:n.deviceId,endpointId:c,enrollmentNonce:crypto.randomUUID(),requestedRoles:n.requestedRoles})},close:()=>o.close(),deviceKeyProvider:a$1(t),deviceIdProvider:async()=>{let n=await t.invoke("get_rtc_local_device_info");return String(n?.deviceId??"")},runtimeFactory:async n=>{let{createIpcClient:c}=await import('./ipcFactory-2MDPNX5M.js');return c(n,t,o)}})}export{ke as OpenRTC,b as ServiceNode,me as inspectNodeHost};