openrtc 2.9.6 → 2.9.8

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 (81) hide show
  1. package/dist/BrowserManagedBroadcastHost-6VGHQQMF.js +1 -0
  2. package/dist/{Connection-gaN-X7kf.d.ts → Connection-DJoPKC0L.d.ts} +34 -1
  3. package/dist/{DelegatingRuntimeAdapter-Bh0rLvly.d.ts → DelegatingRuntimeAdapter-d1xrjmHE.d.ts} +7 -2
  4. package/dist/{IpcRuntimeAdapter-DZj7Rn-o.d.ts → IpcRuntimeAdapter-BkJdH7OQ.d.ts} +2 -2
  5. package/dist/NativeProjectionBroker-Z6LCR4WB.js +1 -0
  6. package/dist/WasmBridge-VGIBWCAC.js +1 -0
  7. package/dist/{assembly-DX6MlDlZ.d.ts → assembly-0EnNAgmm.d.ts} +6 -2
  8. package/dist/{capabilities-wJO8ZWyF.d.ts → capabilities-dnGwtGmQ.d.ts} +1 -1
  9. package/dist/{chunk-IJXTRVQS.js → chunk-4EOOERQ4.js} +1 -1
  10. package/dist/{chunk-RB4UWXK6.js → chunk-5VJXDYP6.js} +1 -1
  11. package/dist/chunk-72MN7BNQ.js +2 -0
  12. package/dist/chunk-IXQ4KWGP.js +2 -0
  13. package/dist/{chunk-XMYBBLYK.js → chunk-L4HWDDXL.js} +2 -2
  14. package/dist/{chunk-F5ORG763.js → chunk-L7N4T2PX.js} +1 -1
  15. package/dist/chunk-MTCLMTJN.js +1 -0
  16. package/dist/{chunk-QO5WF4IG.js → chunk-O5EGI6OZ.js} +1 -1
  17. package/dist/{chunk-2QE5HAPB.js → chunk-O7Z6WLGA.js} +1 -1
  18. package/dist/chunk-P6G2PAWP.js +1 -0
  19. package/dist/chunk-S67YUD3E.js +1 -0
  20. package/dist/{chunk-COXQYBTI.js → chunk-TPF643LU.js} +1 -1
  21. package/dist/chunk-TWTPJDUN.js +1 -0
  22. package/dist/chunk-WNCBDRFC.js +2 -0
  23. package/dist/chunk-XR5JZKFP.js +2 -0
  24. package/dist/{chunk-LJBVXWWV.js → chunk-XXZEDZUU.js} +1 -1
  25. package/dist/controlPlane-HLMTVL5V.js +1 -0
  26. package/dist/coreClient.d.ts +7 -3
  27. package/dist/coreClient.js +1 -1
  28. package/dist/{deviceEnrollment-3AOGMX7C.js → deviceEnrollment-IPKFITV6.js} +1 -1
  29. package/dist/deviceHandle-ZYN473A4.js +1 -0
  30. package/dist/external-broadcast.d.ts +4 -4
  31. package/dist/external-broadcast.js +1 -1
  32. package/dist/index.d.ts +7 -6
  33. package/dist/index.js +1 -1
  34. package/dist/ipcFactory-L73S4NGQ.js +1 -0
  35. package/dist/native.d.ts +5 -5
  36. package/dist/native.js +1 -1
  37. package/dist/node.d.ts +6 -6
  38. package/dist/node.js +2 -2
  39. package/dist/openrtc-YI4N7T34.js +2 -0
  40. package/dist/openrtc_bg.wasm +0 -0
  41. package/dist/{room-5FG5L44X.js → room-5NW3SV4C.js} +1 -1
  42. package/dist/runtime/WasmRuntimeAdapter.d.ts +3 -3
  43. package/dist/runtime/WasmRuntimeAdapter.js +1 -1
  44. package/dist/runtime/device-status.d.ts +1 -1
  45. package/dist/runtime/factories.d.ts +13 -5
  46. package/dist/runtime/factories.js +1 -1
  47. package/dist/runtime/index.d.ts +10 -9
  48. package/dist/runtime/index.js +1 -1
  49. package/dist/server-browser.d.ts +4 -4
  50. package/dist/server.d.ts +4 -4
  51. package/dist/server.js +1 -1
  52. package/dist/service-node.d.ts +4 -4
  53. package/dist/service-node.js +1 -1
  54. package/dist/testing/native.d.ts +4 -4
  55. package/dist/testing/native.js +1 -1
  56. package/dist/testing.d.ts +4 -4
  57. package/dist/testing.js +1 -1
  58. package/dist/transport/index.d.ts +2 -2
  59. package/dist/{types-CzogmfJl.d.ts → types-uDwIMPRk.d.ts} +5 -1
  60. package/native/darwin-arm64/openrtc-node-host +0 -0
  61. package/native/darwin-arm64/openrtc-node-host.manifest.json +4 -4
  62. package/native/darwin-x64/openrtc-node-host +0 -0
  63. package/native/darwin-x64/openrtc-node-host.manifest.json +4 -4
  64. package/native/linux-x64/openrtc-node-host +0 -0
  65. package/native/linux-x64/openrtc-node-host.manifest.json +4 -4
  66. package/package.json +1 -1
  67. package/dist/BrowserManagedBroadcastHost-GLSYJIOR.js +0 -1
  68. package/dist/NativeProjectionBroker-VFPBNUGH.js +0 -1
  69. package/dist/WasmBridge-3TYL6SE7.js +0 -1
  70. package/dist/chunk-AZHDR5G7.js +0 -2
  71. package/dist/chunk-BGWJHPBC.js +0 -2
  72. package/dist/chunk-DMCUS3TY.js +0 -2
  73. package/dist/chunk-DZR5WWVW.js +0 -1
  74. package/dist/chunk-FXVEX4SB.js +0 -1
  75. package/dist/chunk-TOKXRZSS.js +0 -1
  76. package/dist/chunk-TRUMV4SI.js +0 -1
  77. package/dist/chunk-WALOTASO.js +0 -2
  78. package/dist/controlPlane-U6XREYI4.js +0 -1
  79. package/dist/deviceHandle-2DLEXKFM.js +0 -1
  80. package/dist/ipcFactory-7DTAMYUQ.js +0 -1
  81. package/dist/openrtc-DW7MUYZN.js +0 -2
@@ -0,0 +1 @@
1
+ export{a as BrowserManagedBroadcastHost}from'./chunk-5VJXDYP6.js';import'./chunk-IXQ4KWGP.js';import'./chunk-AYHD4X2R.js';import'./chunk-FKAQDDUM.js';import'./chunk-JPBW67B3.js';
@@ -314,10 +314,18 @@ type TicketMeshPeerReadiness = {
314
314
  routeGeneration: number;
315
315
  };
316
316
 
317
+ interface MoQObjectQuantities {
318
+ acceptedWriteObjects: number;
319
+ acceptedWriteBytes: number;
320
+ completedReceivedObjects: number;
321
+ completedReceivedBytes: number;
322
+ }
323
+
317
324
  /** Public protocol identifiers; provider prices and safety ceilings stay private. */
318
325
  declare const SERVICE_ERROR_CODES: {
319
326
  readonly CREDIT_EXHAUSTED: "credit-exhausted";
320
327
  readonly APP_BUDGET_EXHAUSTED: "app-budget-exhausted";
328
+ readonly PRINCIPAL_BUDGET_EXHAUSTED: "principal-budget-exhausted";
321
329
  readonly APP_RATE_LIMITED: "app-rate-limited";
322
330
  readonly PRINCIPAL_RATE_LIMITED: "principal-rate-limited";
323
331
  readonly EDGE_RATE_LIMITED: "edge-rate-limited";
@@ -486,6 +494,20 @@ interface CoordinationGatewayGrant {
486
494
  avenue: CoordinationGatewayGrantRequest['avenue'];
487
495
  }
488
496
 
497
+ type TransferPeerDemandPurpose = 'fileTransfer' | 'driveAccess' | 'contentSync';
498
+ type TransferPeerDemandState = 'waitingForPeer' | 'queued' | 'admitted';
499
+ /** Typed input to the Rust connection owner. Product jobs remain product-owned. */
500
+ interface TransferPeerDemandRequest {
501
+ id: string;
502
+ deviceId: string;
503
+ purpose: TransferPeerDemandPurpose;
504
+ }
505
+ /** Admission reserves a bulk peer slot; it does not confirm readiness or delivery. */
506
+ interface TransferPeerDemandStatus extends TransferPeerDemandRequest {
507
+ generation: number;
508
+ state: TransferPeerDemandState;
509
+ }
510
+
489
511
  interface AppLimits {
490
512
  /** Max devices per authenticated user. -1 = unlimited. */
491
513
  devicesPerUser: number;
@@ -876,6 +898,8 @@ interface BackendConnectionState {
876
898
  /** Observed Iroh path/carrier; never a second public connection. */
877
899
  carrier?: ProtocolName | null;
878
900
  metricsSampledAtMs?: number | null;
901
+ /** Completed local MoQ object work; not provider wire, delivery, or money. */
902
+ moqObjectQuantities?: Readonly<MoQObjectQuantities> | null;
879
903
  replacementInProgress?: boolean;
880
904
  lastTransitionAtMs?: number;
881
905
  transitionCount?: number;
@@ -1235,6 +1259,8 @@ interface ExplicitFileDataSendParams {
1235
1259
  */
1236
1260
  interface DesiredPeerProjection {
1237
1261
  deviceId: string;
1262
+ /** Observe membership without automatically dialing. Requires intent-aware Rust. */
1263
+ connectionIntent?: 'automatic' | 'observe';
1238
1264
  nodeId?: string | null;
1239
1265
  ticket?: string | null;
1240
1266
  online?: boolean;
@@ -1304,6 +1330,7 @@ interface ISignalingBackend {
1304
1330
  setCoordinationHostAvailability?(input: {
1305
1331
  available: boolean;
1306
1332
  reason: string;
1333
+ backgrounded?: boolean;
1307
1334
  }): void;
1308
1335
  usesCoordinationGateway?(): boolean;
1309
1336
  joinCoordinationRoom?(roomId: string, nodeId: string, ticket: string): Promise<void>;
@@ -1361,6 +1388,12 @@ interface ISignalingBackend {
1361
1388
  sendMessage(targetId: string, payload: string, state?: string, replyPayload?: string): Promise<string>;
1362
1389
  pollMessages(targetId: string): Promise<SignalingEnvelope[]>;
1363
1390
  subscribeDevices(userId: string): Promise<ReadableStream<DeviceEvent[]>>;
1391
+ requestTransferPeer?(request: TransferPeerDemandRequest): Promise<TransferPeerDemandStatus>;
1392
+ transferPeerDemandStatus?(id: string, generation: number): Promise<TransferPeerDemandStatus | null>;
1393
+ releaseTransferPeer?(id: string, generation: number): Promise<boolean>;
1394
+ setTransferPeerBudget?(budget: number, generation: number): Promise<void>;
1395
+ /** Starts the Rust directory owner without automatic connection demand. */
1396
+ startPeerObservation?(userId: string, localDeviceId: string): Promise<void>;
1364
1397
  startAutoConnectOnce?(userId: string, localDeviceId: string): Promise<void>;
1365
1398
  startAutoConnect(userId: string, localDeviceId: string): void;
1366
1399
  submitDesiredPeerProjection?(revision: number, peers: DesiredPeerProjection[]): Promise<void>;
@@ -1674,4 +1707,4 @@ declare class Connection {
1674
1707
  private close;
1675
1708
  }
1676
1709
 
1677
- export { type SignalingEnvelope as $, type DeviceProfile as A, type RawConnection as B, type ChannelDescriptor$1 as C, type DeviceStatus as D, type EffectiveRoomArchitecture as E, type RuntimeRoomMember as F, type GrantScope as G, type AuthContext as H, type IncomingStream as I, type JoinRoomOptions$1 as J, type RuntimeClientOptions as K, type LocalDeviceInfo$1 as L, type ManagedOptions as M, type DiscoveryMode as N, type AuthMode as O, type PlutoIrohConfiguration as P, type SignalingMode as Q, type RoomArchitectureMode as R, type ServiceErrorObservation as S, type ClientOptions as T, type ExplicitFileDataSendParams as U, type ISignalingBackend as V, type RuntimeIdentity as W, type RoomMember as X, type Device as Y, type DeviceStatusSnapshot as Z, type ManagedConnectionRecord as _, type RoomArchitectureReason as a, type PresencePolicy as a$, type DeviceEvent as a0, type DesiredPeerProjection as a1, type SignalingSession as a2, type SessionEvent as a3, type LocalDeviceInfo as a4, type NativeManagedSessionStartResult as a5, type TicketMeshPeerReadiness as a6, type BackendPeerBiStream as a7, type BackendPeerUniStream as a8, type PortableMediaPublish as a9, type RuntimeSession as aA, type AppLimits as aB, type ConnectionTarget as aC, type PresenceLoopOptions as aD, type SignalingOptions as aE, type JoinRoomOptions as aF, type ChannelMetadata as aG, type RoomCreationMode as aH, type ProtocolCapabilityMap as aI, type ScanningLoopOptions as aJ, type ScanningLoopHandle as aK, type RuntimeBootstrapOptions as aL, type RuntimeBootstrapResult as aM, type ApplicationPayloadReadinessOptions as aN, type ManagedApplicationRouteOptions as aO, type PeerState as aP, type PeerScope as aQ, type PeerHealth as aR, type ChannelDescriptor as aS, type JoinRequest as aT, type AutoConnectPolicy as aU, type ChannelFraming as aV, type ConnectionStatus as aW, type DevicePresence as aX, type PayloadRouteOptions as aY, type PeerLifecycleStatus$1 as aZ, type PeerSessionSnapshot$1 as a_, type PortableMediaPublicationStart as aa, type PortableMediaSample as ab, type PortableMediaChunk as ac, type PortableMediaControl as ad, type NativeConnectParams as ae, type NativeConnectResult as af, type BackendConnectionState as ag, type NativePeerDataEvent as ah, type ServiceErrorMetadata as ai, type CoordinationGatewayGrantRequest as aj, type CoordinationGatewayGrant as ak, type BrowserWasmRuntimeModule as al, type BrowserProtocolStore as am, type NamespaceDescriptor as an, type IrohMutationReceipt as ao, type IrohDocEntry as ap, type CoordinationSignalingStore as aq, type ManagedRoomMessage as ar, type CoreClientBridgeHost as as, type RouteDescriptor as at, type PayloadCrypto as au, type CryptoStreams as av, type CryptoBiStream as aw, type RouteFamily as ax, type RouteKind as ay, type RuntimeAuthIdentity as az, type RoomArchitectureSnapshot as b, type RuntimeAuthContext as b0, type RuntimePeerScope as b1, type SessionKind as b2, type SessionPlatform as b3, type RoomAuthorityAssignment as c, type PlutoRTCConfiguration as d, type PlutoMoQConfiguration as e, type RouteOptimization as f, type ProtocolName as g, type RuntimePeerState as h, type PeerConnectOptions as i, Connection as j, type PeerSessionSnapshot as k, type PeerReadiness as l, type RuntimePeerHealth as m, type ResolvedPeerIdentity as n, type PeerStreamOptions as o, type ScopedChannelOptions as p, type RuntimeDevice as q, type ScopedLogicalChannel as r, type ConnectionState as s, type ReadinessOptions as t, type ConnectionEvent as u, type ManagedSession as v, type DeviceConnectOptions as w, type ConnectDeviceResult as x, type ConnectDeviceHooks as y, type ConnectDeviceOptions as z };
1710
+ export { type RoomMember as $, type ConnectDeviceResult as A, type ConnectDeviceHooks as B, type ChannelDescriptor$1 as C, type DeviceStatus as D, type EffectiveRoomArchitecture as E, type ConnectDeviceOptions as F, type DeviceProfile as G, type RawConnection as H, type IncomingStream as I, type JoinRoomOptions$1 as J, type RuntimeRoomMember as K, type LocalDeviceInfo$1 as L, type ManagedOptions as M, type GrantScope as N, type AuthContext as O, type PlutoIrohConfiguration as P, type RuntimeClientOptions as Q, type RoomArchitectureMode as R, type ServiceErrorObservation as S, type TransferPeerDemandPurpose as T, type DiscoveryMode as U, type AuthMode as V, type SignalingMode as W, type ClientOptions as X, type ExplicitFileDataSendParams as Y, type ISignalingBackend as Z, type RuntimeIdentity as _, type RoomArchitectureReason as a, type DevicePresence as a$, type Device as a0, type DeviceStatusSnapshot as a1, type ManagedConnectionRecord as a2, type SignalingEnvelope as a3, type DeviceEvent as a4, type DesiredPeerProjection as a5, type SignalingSession as a6, type SessionEvent as a7, type LocalDeviceInfo as a8, type NativeManagedSessionStartResult as a9, type CryptoBiStream as aA, type RouteFamily as aB, type RouteKind as aC, type RuntimeAuthIdentity as aD, type RuntimeSession as aE, type AppLimits as aF, type ConnectionTarget as aG, type PresenceLoopOptions as aH, type SignalingOptions as aI, type JoinRoomOptions as aJ, type ChannelMetadata as aK, type RoomCreationMode as aL, type ProtocolCapabilityMap as aM, type ScanningLoopOptions as aN, type ScanningLoopHandle as aO, type RuntimeBootstrapOptions as aP, type RuntimeBootstrapResult as aQ, type ApplicationPayloadReadinessOptions as aR, type ManagedApplicationRouteOptions as aS, type PeerState as aT, type PeerScope as aU, type PeerHealth as aV, type ChannelDescriptor as aW, type JoinRequest as aX, type AutoConnectPolicy as aY, type ChannelFraming as aZ, type ConnectionStatus as a_, type TicketMeshPeerReadiness as aa, type BackendPeerBiStream as ab, type BackendPeerUniStream as ac, type PortableMediaPublish as ad, type PortableMediaPublicationStart as ae, type PortableMediaSample as af, type PortableMediaChunk as ag, type PortableMediaControl as ah, type NativeConnectParams as ai, type NativeConnectResult as aj, type BackendConnectionState as ak, type NativePeerDataEvent as al, type ServiceErrorMetadata as am, type CoordinationGatewayGrantRequest as an, type CoordinationGatewayGrant as ao, type BrowserWasmRuntimeModule as ap, type BrowserProtocolStore as aq, type NamespaceDescriptor as ar, type IrohMutationReceipt as as, type IrohDocEntry as at, type CoordinationSignalingStore as au, type ManagedRoomMessage as av, type CoreClientBridgeHost as aw, type RouteDescriptor as ax, type PayloadCrypto as ay, type CryptoStreams as az, type RoomArchitectureSnapshot as b, type PayloadRouteOptions as b0, type PeerLifecycleStatus$1 as b1, type PeerSessionSnapshot$1 as b2, type PresencePolicy as b3, type RuntimeAuthContext as b4, type RuntimePeerScope as b5, type SessionKind as b6, type SessionPlatform as b7, type RoomAuthorityAssignment as c, type TransferPeerDemandRequest as d, type TransferPeerDemandState as e, type TransferPeerDemandStatus as f, type PlutoRTCConfiguration as g, type PlutoMoQConfiguration as h, type RouteOptimization as i, type ProtocolName as j, type RuntimePeerState as k, type PeerConnectOptions as l, Connection as m, type PeerSessionSnapshot as n, type PeerReadiness as o, type RuntimePeerHealth as p, type ResolvedPeerIdentity as q, type PeerStreamOptions as r, type ScopedChannelOptions as s, type RuntimeDevice as t, type ScopedLogicalChannel as u, type ConnectionState as v, type ReadinessOptions as w, type ConnectionEvent as x, type ManagedSession as y, type DeviceConnectOptions as z };
@@ -1,5 +1,5 @@
1
- import { N as DiscoveryMode, O as AuthMode, Q as SignalingMode, T as ClientOptions, U as ExplicitFileDataSendParams, V as ISignalingBackend, W as RuntimeIdentity, H as AuthContext, X as RoomMember, Y as Device, Z as DeviceStatusSnapshot, k as PeerSessionSnapshot, n as ResolvedPeerIdentity, _ as ManagedConnectionRecord, $ as SignalingEnvelope, a0 as DeviceEvent, a1 as DesiredPeerProjection, a2 as SignalingSession, a3 as SessionEvent, a4 as LocalDeviceInfo, a5 as NativeManagedSessionStartResult, g as ProtocolName, G as GrantScope, a6 as TicketMeshPeerReadiness, a7 as BackendPeerBiStream, a8 as BackendPeerUniStream, a9 as PortableMediaPublish, aa as PortableMediaPublicationStart, ab as PortableMediaSample, ac as PortableMediaChunk, ad as PortableMediaControl, ae as NativeConnectParams, af as NativeConnectResult, ag as BackendConnectionState, ah as NativePeerDataEvent } from './Connection-gaN-X7kf.js';
2
- import { R as RuntimeCapabilities } from './capabilities-wJO8ZWyF.js';
1
+ import { U as DiscoveryMode, V as AuthMode, W as SignalingMode, X as ClientOptions, Y as ExplicitFileDataSendParams, Z as ISignalingBackend, _ as RuntimeIdentity, O as AuthContext, $ as RoomMember, a0 as Device, a1 as DeviceStatusSnapshot, n as PeerSessionSnapshot, q as ResolvedPeerIdentity, a2 as ManagedConnectionRecord, a3 as SignalingEnvelope, a4 as DeviceEvent, d as TransferPeerDemandRequest, f as TransferPeerDemandStatus, a5 as DesiredPeerProjection, a6 as SignalingSession, a7 as SessionEvent, a8 as LocalDeviceInfo, a9 as NativeManagedSessionStartResult, j as ProtocolName, N as GrantScope, aa as TicketMeshPeerReadiness, ab as BackendPeerBiStream, ac as BackendPeerUniStream, ad as PortableMediaPublish, ae as PortableMediaPublicationStart, af as PortableMediaSample, ag as PortableMediaChunk, ah as PortableMediaControl, ai as NativeConnectParams, aj as NativeConnectResult, ak as BackendConnectionState, al as NativePeerDataEvent } from './Connection-DJoPKC0L.js';
2
+ import { R as RuntimeCapabilities } from './capabilities-dnGwtGmQ.js';
3
3
 
4
4
  /** Host-neutral configuration shared by browser/WASM and native/IPC adapters. */
5
5
  interface RuntimeBridgeOptions {
@@ -86,6 +86,11 @@ declare abstract class DelegatingRuntimeAdapter implements ISignalingBackend {
86
86
  watchFriendDevices(friendUserIds: string[], callback: (friendDevices: Map<string, Device[]>) => void): () => void;
87
87
  updateFriendTicket(friendTicket: string | null): Promise<void>;
88
88
  subscribeDevices(userId: string): Promise<ReadableStream<DeviceEvent[]>>;
89
+ requestTransferPeer(request: TransferPeerDemandRequest): Promise<TransferPeerDemandStatus>;
90
+ transferPeerDemandStatus(id: string, generation: number): Promise<TransferPeerDemandStatus | null>;
91
+ releaseTransferPeer(id: string, generation: number): Promise<boolean>;
92
+ setTransferPeerBudget(budget: number, generation: number): Promise<void>;
93
+ startPeerObservation(userId: string, localDeviceId: string): Promise<void>;
89
94
  startAutoConnect(userId: string, localDeviceId: string): void;
90
95
  submitDesiredPeerProjection(revision: number, peers: DesiredPeerProjection[]): Promise<void>;
91
96
  startPresenceLoop(userId: string, localNodeId: string, deviceName: string, ticket: string, metadata?: string): Promise<void>;
@@ -1,6 +1,6 @@
1
- import { R as RuntimeBridgeOptions, D as DelegatingRuntimeAdapter } from './DelegatingRuntimeAdapter-Bh0rLvly.js';
1
+ import { R as RuntimeBridgeOptions, D as DelegatingRuntimeAdapter } from './DelegatingRuntimeAdapter-d1xrjmHE.js';
2
2
  import { P as PlutoIpcBridge } from './ipc-DgzKqHH3.js';
3
- import { S as ServiceErrorObservation, ag as BackendConnectionState, ah as NativePeerDataEvent, Y as Device } from './Connection-gaN-X7kf.js';
3
+ import { S as ServiceErrorObservation, ak as BackendConnectionState, al as NativePeerDataEvent, a0 as Device } from './Connection-DJoPKC0L.js';
4
4
 
5
5
  /**
6
6
  * Root-client owner for the one native WebView projection.
@@ -0,0 +1 @@
1
+ export{a as NativeProjectionBroker}from'./chunk-XXZEDZUU.js';import'./chunk-TPF643LU.js';import'./chunk-72MN7BNQ.js';
@@ -0,0 +1 @@
1
+ export{b as WasmBridge,a as loadBrowserWasmRuntimeModule}from'./chunk-S67YUD3E.js';import'./chunk-AYHD4X2R.js';import'./chunk-XR5JZKFP.js';import'./chunk-L4HWDDXL.js';import'./chunk-OT7IPLZE.js';import'./chunk-OWKAJPOI.js';import'./chunk-TPF643LU.js';import'./chunk-L2ZZXECX.js';import'./chunk-CCCYE3XN.js';import'./chunk-JPBW67B3.js';import'./chunk-L7N4T2PX.js';import'./chunk-72MN7BNQ.js';import'./chunk-2GX6GB6L.js';
@@ -1,5 +1,5 @@
1
- import { h as RuntimePeerState, s as ConnectionState, l as PeerReadiness, i as PeerConnectOptions, j as Connection, I as IncomingStream, G as GrantScope, K as RuntimeClientOptions, V as ISignalingBackend, az as RuntimeAuthIdentity, H as AuthContext, g as ProtocolName, L as LocalDeviceInfo, A as DeviceProfile, am as BrowserProtocolStore, an as NamespaceDescriptor, ao as IrohMutationReceipt, ap as IrohDocEntry, af as NativeConnectResult, q as RuntimeDevice, M as ManagedOptions, v as ManagedSession, D as DeviceStatus, y as ConnectDeviceHooks, z as ConnectDeviceOptions, x as ConnectDeviceResult, w as DeviceConnectOptions, _ as ManagedConnectionRecord, k as PeerSessionSnapshot, n as ResolvedPeerIdentity, aA as RuntimeSession, aB as AppLimits, J as JoinRoomOptions, F as RuntimeRoomMember, aC as ConnectionTarget, p as ScopedChannelOptions, r as ScopedLogicalChannel, o as PeerStreamOptions, ae as NativeConnectParams, B as RawConnection, C as ChannelDescriptor, U as ExplicitFileDataSendParams, aD as PresenceLoopOptions, b as RoomArchitectureSnapshot, c as RoomAuthorityAssignment, m as RuntimePeerHealth, t as ReadinessOptions, u as ConnectionEvent } from './Connection-gaN-X7kf.js';
2
- import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-wJO8ZWyF.js';
1
+ import { k as RuntimePeerState, v as ConnectionState, o as PeerReadiness, l as PeerConnectOptions, m as Connection, I as IncomingStream, N as GrantScope, Q as RuntimeClientOptions, Z as ISignalingBackend, aD as RuntimeAuthIdentity, O as AuthContext, j as ProtocolName, L as LocalDeviceInfo, G as DeviceProfile, aq as BrowserProtocolStore, ar as NamespaceDescriptor, as as IrohMutationReceipt, at as IrohDocEntry, aj as NativeConnectResult, t as RuntimeDevice, M as ManagedOptions, y as ManagedSession, D as DeviceStatus, B as ConnectDeviceHooks, F as ConnectDeviceOptions, A as ConnectDeviceResult, z as DeviceConnectOptions, a2 as ManagedConnectionRecord, n as PeerSessionSnapshot, q as ResolvedPeerIdentity, aE as RuntimeSession, aF as AppLimits, J as JoinRoomOptions, K as RuntimeRoomMember, aG as ConnectionTarget, s as ScopedChannelOptions, u as ScopedLogicalChannel, r as PeerStreamOptions, ai as NativeConnectParams, H as RawConnection, C as ChannelDescriptor, Y as ExplicitFileDataSendParams, aH as PresenceLoopOptions, d as TransferPeerDemandRequest, f as TransferPeerDemandStatus, b as RoomArchitectureSnapshot, c as RoomAuthorityAssignment, p as RuntimePeerHealth, w as ReadinessOptions, x as ConnectionEvent } from './Connection-DJoPKC0L.js';
2
+ import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-dnGwtGmQ.js';
3
3
 
4
4
  /**
5
5
  * Coalesced peer reconciliation scheduler and full reconcile orchestration.
@@ -654,6 +654,10 @@ declare class RuntimeClient {
654
654
  isConnected(nodeId: string): Promise<boolean>;
655
655
  disconnectNode(nodeId: string): Promise<void>;
656
656
  recordSparseFanoutForwardQueueDrop(capability: string, count: number): Promise<void>;
657
+ requestTransferPeer(request: TransferPeerDemandRequest): Promise<TransferPeerDemandStatus>;
658
+ transferPeerDemandStatus(id: string, generation: number): Promise<TransferPeerDemandStatus | null>;
659
+ releaseTransferPeer(id: string, generation: number): Promise<boolean>;
660
+ setTransferPeerBudget(budget: number, generation: number): Promise<void>;
657
661
  disconnectDevice(deviceId: string): Promise<void>;
658
662
  /** Observe the gateway-owned room policy without taking topology ownership. */
659
663
  onRoomArchitectureChange(callback: (snapshot: RoomArchitectureSnapshot) => void): () => void;
@@ -1,4 +1,4 @@
1
- import { g as ProtocolName, f as RouteOptimization } from './Connection-gaN-X7kf.js';
1
+ import { j as ProtocolName, i as RouteOptimization } from './Connection-DJoPKC0L.js';
2
2
 
3
3
  type RuntimeAdapterKind = 'browser-wasm' | 'native-ipc' | 'tauri-ipc' | 'unknown';
4
4
  type CapabilityMaturity = 'stable' | 'preview' | 'support-only' | 'unavailable';
@@ -1,2 +1,2 @@
1
- import {b as b$2}from'./chunk-ZA44REGI.js';import {e,a}from'./chunk-F5ORG763.js';import {d,b as b$1,e as e$1}from'./chunk-WALOTASO.js';function b(s){return {irohRelay:s.irohRelay===true||s.irohRelay===void 0&&s.relay!==false,managedTurn:s.managedTurn===true}}var B=1440*6e4,w=class extends Error{constructor(r,n,a$1){super(r);this.status=n;this.reason=a$1;this.name="RTCError";let t=[502,503,504].includes(n),o=a$1==="device-reenrollment-auth-required",i=n===412&&a$1==="device-key-recovery-required";this.code=i?a.AUTH_DEVICE_KEY_RECOVERY_REQUIRED:o?"auth/device-reenrollment-required":t?"coordination/service-unavailable":n===429?"coordination/rate-limited":n===401?"auth/expired":n===403?"admission/denied":"internal/error",this.retryable=o||t,this.plane=i||o||n===401?"auth":t||n===429?"coordination":n===403?"admission":"internal";}};function K(s){return !(s instanceof w)||s.status!==403?false:s.reason==="device-certificate-stale"||s.reason==="device-certificate-revoked"?true:!s.reason&&s.message==="Device certificate is revoked or stale."}function C(s,e,r){return `openrtc:v2:device-certificate:${s}:${e}:${r}`}function P(s,e){return `openrtc:v2:device-session:${s}:${e}`}async function O(s,e,r){let n=new TextEncoder().encode(`openrtc:v2:session\0${s}\0${e}\0${r}`),a=new Uint8Array(await crypto.subtle.digest("SHA-256",n)),t="";for(let o of a)t+=String.fromCharCode(o);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function k(s){let e=s.replace(/-/g,"+").replace(/_/g,"/"),r=e.padEnd(Math.ceil(e.length/4)*4,"="),n=atob(r);return Uint8Array.from(n,a=>a.charCodeAt(0))}function f(s){let e="";for(let r of s)e+=String.fromCharCode(r);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}async function I(s,e,r,n,a){if(typeof s.token!="string"||typeof s.expiresAtMs!="number"||s.expiresAtMs<=Date.now()+B||!s.signingPublicJwk||s.signingPublicJwk.kty!=="OKP"||s.signingPublicJwk.crv!=="Ed25519"||typeof s.signingPublicJwk.x!="string")return null;let t=s.token.split(".");if(t.length!==3)return null;let o,i;try{o=JSON.parse(new TextDecoder().decode(k(t[0]))),i=b$2(s.token);}catch{return null}if(o.alg!=="EdDSA"||s.signingPublicJwk.kid&&o.kid!==s.signingPublicJwk.kid)return null;try{let y=await crypto.subtle.importKey("jwk",s.signingPublicJwk,{name:"Ed25519"},!1,["verify"]);if(!await crypto.subtle.verify({name:"Ed25519"},y,k(t[2]),new TextEncoder().encode(`${t[0]}.${t[1]}`)))return null}catch{return null}let c=typeof i.principalId=="string"?i.principalId:"",l=Number(i.iat),u=Number(i.exp);if(i.iss!=="openrtc"||i.aud!=="openrtc:v2:gateway-grant"||i.typ!=="device-certificate"||i.appTag!==e||!c||a!==void 0&&c!==a||typeof i.principalKey!="string"||i.principalKey.length===0||i.deviceId!==r||i.deviceKeyThumbprint!==n||typeof i.jti!="string"||i.jti.length===0||!Number.isSafeInteger(l)||!Number.isSafeInteger(u)||l>=u||u*1e3!==s.expiresAtMs)return null;let d=b(i);return {token:s.token,expiresAtMs:s.expiresAtMs,principalId:c,signingPublicJwk:s.signingPublicJwk,enrolled:false,...d}}async function G(s,e,r,n,a){try{let t=C(e,r,n),o=s.readSecureRecord?await s.readSecureRecord(e,t):globalThis.localStorage?.getItem(t);if(!o)return null;let i=JSON.parse(o),c=await I(i,e,n,a,r);return c?{token:c.token,expiresAtMs:c.expiresAtMs,principalId:r,signingPublicJwk:c.signingPublicJwk}:null}catch(t){if(s.readSecureRecord)throw t;return null}}async function J(s,e,r,n,a){try{let t=P(e,n),o=s.readSecureRecord?await s.readSecureRecord(r,t):globalThis.localStorage?.getItem(t);return o?await I(JSON.parse(o),r,n,a):null}catch(t){if(s.readSecureRecord)throw t;return null}}async function U(s,e,r,n,a){try{let t=C(e,r,n),o=JSON.stringify(a);s.writeSecureRecord?await s.writeSecureRecord(e,t,o):globalThis.localStorage?.setItem(t,o);}catch(t){if(s.writeSecureRecord)throw t}}async function $(s,e,r,n,a){try{let t=P(r,n),o=JSON.stringify({token:a.token,expiresAtMs:a.expiresAtMs,principalId:a.principalId,signingPublicJwk:a.signingPublicJwk});s.writeSecureRecord?await s.writeSecureRecord(e,t,o):globalThis.localStorage?.setItem(t,o);}catch(t){if(s.writeSecureRecord)throw t}}async function A(s,e,r,n,a){try{let t=C(e,r,n);if(s.deleteSecureRecord?await s.deleteSecureRecord(e,t):globalThis.localStorage?.removeItem(t),a){let o=P(a,n);s.deleteSecureRecord?await s.deleteSecureRecord(e,o):globalThis.localStorage?.removeItem(o);}}catch(t){if(s.deleteSecureRecord)throw t}}function x(s){return `${s}_${crypto.randomUUID()}`}function j(s){if(s instanceof TypeError)return true;if(!s||typeof s!="object")return false;let e=Reflect.get(s,"name");return e==="TimeoutError"||e==="AbortError"}async function N(s,e){let r=new TextEncoder().encode(`${s}:${e}`);return [...new Uint8Array(await crypto.subtle.digest("SHA-256",r))].map(a=>a.toString(16).padStart(2,"0")).join("")}var M=class{constructor(e,r,n,a,t={},o){this.apiKey=e;this.endpoints=r;this.keyProvider=n;this.attestation=a;this.events=t;this.botVerification=o;this.keyPromise=null;this.authEpochs=new Map;this.appTag=`app_${e.slice(-16)}`;}record(e){this.events.onLogicalOperation?.(e);}before(e){this.events.beforeLogicalOperation?.(e);}authEpoch(e){let r=this.authEpochs.get(e);if(r)return r;let n={generation:0,devices:new Map};return this.authEpochs.set(e,n),e.subscribe&&(n.unsubscribe=e.subscribe(a=>{a?.type==="principal-changed"&&(n.generation+=1,n.devices.clear(),n.sessionKeyHash=void 0,this.events.onAuthEpochChanged?.(e));})),n}dispose(){for(let e of this.authEpochs.values())e.unsubscribe?.();this.authEpochs.clear();}key(){return this.keyPromise??(this.keyPromise=this.keyProvider.getOrCreate(this.appTag))}async deviceSigningPublicKey(){return (await this.key()).publicKeyJwk}async signDeviceBytes(e){return (await this.key()).sign(e)}async resolveBroadcastAccess(e,r){if(!/^orb1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(e)||e.length>32768)throw new Error("Broadcast grant is invalid.");if(r&&r.byteLength!==32)throw new Error("Broadcast publisher verification key is invalid.");let n=await this.key(),a=f(new Uint8Array(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(e)))),t=r?f(r):"",o=await n.proof((u,d)=>["openrtc:v2:broadcast-access",this.apiKey,a,t,u,d].join(":")),i=await this.post("/v2/broadcasts",{action:"access",grant:e,...t?{publicationVerifyingKey:t}:{},deviceProof:o});if(i.grant!==e)throw new Error("Broadcast access grant mismatch.");let c=k(i.issuerPublicKey);if(c.byteLength!==32)throw new Error("Broadcast issuer key is invalid.");let l=new URL(i.relay?.relayUrl);if(l.protocol!=="https:"||l.username||l.password)throw new Error("Broadcast relay URL is invalid.");if(typeof i.relay.token!="string"||!/^[A-Za-z0-9._-]{16,16384}$/.test(i.relay.token)||typeof i.relay.namespace!="string"||!/^[A-Za-z0-9._/-]{1,512}$/.test(i.relay.namespace))throw new Error("Broadcast relay allocation is invalid.");return {token:e,issuerPublicKey:c,signBindingChallenge:async u=>{if(!(u instanceof Uint8Array)||u.byteLength>2048)throw new Error("Broadcast binding challenge is invalid.");return k(await n.sign(u))},relay:{relayUrl:l.toString(),token:i.relay.token,namespace:i.relay.namespace}}}async manageBroadcast(e){let r=await this.deviceCertificate(e.auth,e.deviceId),n=e.grant??"",a=e.invite??"",t=e.create,o=e.invitation,i=t?f(t.publisher.verificationKey):o?.publicationVerificationKey?f(o.publicationVerificationKey):"",c=t?{maxPublishers:t.maxPublishers,maxSubscribers:t.maxSubscribers,maxBitrateBps:t.maxBitrateBps,maxDurationSeconds:t.maxDurationSeconds,maxEgressBytes:t.maxEgressBytes}:void 0,l=t?{bitrateBps:t.publisherBitrateBps,durationSeconds:t.maxDurationSeconds,reservedEgressBytes:t.reservedEgressBytes}:o?{role:o.role,sourceSlot:o.sourceSlot??"",bitrateBps:o.bitrateBps,durationSeconds:o.durationSeconds,reservedEgressBytes:o.reservedEgressBytes}:void 0,u=f(new Uint8Array(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(JSON.stringify({action:e.action,grant:n,invite:a,publicationKey:i,sourceSlot:t?.sourceSlot??o?.sourceSlot??"host-a",limits:c,reservation:l}))))),y=await(await this.key()).proof((v,g)=>["openrtc:v2:broadcast-manage",r.source.token,e.action,u,v,g].join(":")),p=await this.post("/v2/broadcasts",{action:e.action,deviceId:e.deviceId,deviceCertificate:r.source.token,deviceProof:y,...n?{grant:n}:{},...a?{invite:a}:{},...i?{publicationVerifyingKey:i}:{},...t?{sourceSlot:t.sourceSlot??"host-a",limits:c,reservation:l}:{},...o?{invitation:{...l,publicationVerifyingKey:i}}:{}});if(e.action==="create"||e.action==="renew"){if(typeof p.grant!="string"||!/^orb1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(p.grant))throw new Error("Managed broadcast grant is invalid.");return p.grant}if(e.action==="invite"){if(typeof p.invite!="string"||!/^obi1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(p.invite))throw new Error("Managed broadcast invitation is invalid.");return p.invite}if(e.action==="accept"){if(typeof p.grant!="string"||!/^orb1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(p.grant))throw new Error("Managed broadcast accepted grant is invalid.");return p.grant}}async post(e$2,r){let n=x("request"),a=JSON.stringify({apiKey:this.apiKey,...r}),t=null;for(let o=0;o<2;o+=1)try{let i=await fetch(`${this.endpoints.controlPlane}${e$2}`,{method:"POST",headers:{"Content-Type":"application/json","X-OpenRTC-Idempotency-Key":n},body:a,signal:AbortSignal.timeout(15e3)});if(i.ok)return i.json();let c=`OpenRTC request failed (${i.status}).`,l,u;try{let y=await i.json();typeof y.error=="string"&&(c=y.error.slice(0,256)),typeof y.reason=="string"&&/^[a-z0-9-]{1,80}$/.test(y.reason)&&(l=y.reason),(d(y.code)||b$1(y.code))&&(u=e({...e$1(y),code:y.code,message:c,retryable:y.retryable}));}catch{}let d$1=u?Object.assign(u,{status:i.status,reason:l}):new w(c,i.status,l);if(t=d$1,!u&&o===0&&[502,503,504].includes(i.status))continue;throw d$1}catch(i){if(t=i,o===0&&j(i))continue;throw i}throw t instanceof Error?t:new Error("OpenRTC request failed.")}async capability(e,r,n,a=false,t,o){this.before("capability.issue");let i=e==="space"?await N(this.apiKey,r):r,l=await(await this.key()).proof((p,v)=>["openrtc:v2:capability",this.apiKey,e,i,p,v].join(":")),u=this.botVerification?await this.botVerification.getToken({action:"openrtc_capability",apiKey:this.apiKey}):void 0,d=await this.post("/v2/capabilities",{avenue:{kind:e,id:i},deviceProof:l,...n?{maxPeers:n}:{},...a?{advancedFanout:true}:{},...e==="room"&&t?{architecture:t}:{},...e==="room"&&o?{roomDelivery:o}:{},...u?{turnstileToken:u}:{}});this.record("capability.issue");let y={type:"capability",token:d.capability,avenue:e==="ticket"?{kind:"session",id:i}:d.avenue,expiresAtMs:d.expiresAt*1e3,...b(d)};return y.renew=()=>this.capability(e,r,n,a,t,o),y}async deviceCertificate(e,r,n,a,t){if(this.keyProvider.persistence==="session")throw new Error("[OpenRTC] Durable browser device enrollment requires trust.browserPersistence: persistent. Select it explicitly before creating the client; session keys cannot enroll retained devices.");let o=this.authEpoch(e),i=o.devices.get(r)??{};if(o.devices.set(r,i),t&&i.current&&i.current.token!==t.token)return this.deviceCertificateResult(e,r,n,a,{...i.current,enrolled:false});if(!t&&i.current&&i.current.expiresAtMs>Date.now()+B)return this.deviceCertificateResult(e,r,n,a,{...i.current,enrolled:false});if(!i.inFlight){let l=o.generation;t&&(i.current=void 0,i.recoverRevokedEnrollment=true);let u=t?A(this.keyProvider,this.appTag,t.principalId,r,o.sessionKeyHash).then(()=>this.enrollAuthenticatedDevice(e,r,o.sessionKeyHash,a,true)):this.resolveAuthenticatedDevice(e,r,o,a,i.recoverRevokedEnrollment===true);i.inFlight=u.then(d=>{if(o.generation!==l)throw new Error("The OpenRTC authentication identity changed during enrollment.");return i.recoverRevokedEnrollment=false,i.current=d,d}).finally(()=>{i.inFlight=void 0;});}let c=await i.inFlight;return this.deviceCertificateResult(e,r,n,a,c)}async resolveAuthenticatedDevice(e,r,n,a,t=false){let o=await this.key();if(e.getSessionKey){let i=await e.getSessionKey();if(!i)throw new Error("The OpenRTC auth provider has no active principal.");let c=await O(this.appTag,o.thumbprint,i);n.sessionKeyHash=c;let l=await J(this.keyProvider,c,this.appTag,r,o.thumbprint);if(l)return l}return this.enrollAuthenticatedDevice(e,r,n.sessionKeyHash,a,t)}deviceCertificateResult(e,r,n,a,t){let o={type:"device-certificate",token:t.token,avenue:n??{kind:"user",id:t.principalId},expiresAtMs:t.expiresAtMs,irohRelay:t.irohRelay,managedTurn:t.managedTurn};return o.renew=async()=>(await this.deviceCertificate(e,r,n,a)).source,o.recoverRejectedCertificate=async()=>(await this.deviceCertificate(e,r,n,a,t)).source,{principalId:t.principalId,source:o,enrolled:t.enrolled}}async enrollAuthenticatedDevice(e,r,n,a,t=false){this.before("identity.assertion.exchange"),this.before("identity.monthly-active-principal");let o=async(v,g)=>{let m=await e.getAssertion({audience:"https://api.openrtc.app/v2/assertions/exchange",forceRefresh:v,deviceId:r,...{}});if(!m)throw new Error("The OpenRTC auth provider returned no assertion.");return this.post("/v2/assertions/exchange",{assertion:m,deviceId:r,...e.providerId?{providerId:e.providerId}:{}})},i;try{i=await o(!1);}catch(v){if(!(v instanceof w)||v.status!==401)throw v;i=await o(true);}this.record("identity.assertion.exchange"),this.record("identity.monthly-active-principal");let c=await this.key(),l=await G(this.keyProvider,this.appTag,i.principalId,r,c.thumbprint);if(l)return {...l,principalId:i.principalId,enrolled:false,...b(i)};this.before("device.enroll"),this.attestation&&this.before("security.attestation.verify");let{enrollDevice:u}=await import('./deviceEnrollment-3AOGMX7C.js'),d=await u({apiKey:this.apiKey,appTag:this.appTag,auth:e,attestation:this.attestation,deviceId:r,identity:i,key:c,profile:a,recoverRevokedEnrollment:t||i.deviceRecoveryAuthorized===true,post:(v,g)=>this.post(v,g),recordAssertionExchange:()=>this.record("identity.assertion.exchange")});i=d.identity;let y=d.enrollment;this.record("device.enroll"),this.attestation&&this.record("security.attestation.verify");let p={principalId:i.principalId,token:y.deviceCertificate,expiresAtMs:y.expiresAt*1e3,signingPublicJwk:y.signingPublicJwk,enrolled:true,...b(i)};return await U(this.keyProvider,this.appTag,i.principalId,r,{token:p.token,expiresAtMs:p.expiresAtMs,signingPublicJwk:p.signingPublicJwk}),n&&await $(this.keyProvider,this.appTag,n,r,p),p}async listEnrolledDevices(e,r){let n=await this.deviceCertificate(e,r);return (await this.deviceManagement(n.source,r,"list")).devices??[]}async revokeDevice(e,r,n){let a=await this.deviceCertificate(e,r);if(await this.deviceManagement(a.source,r,"revoke",n),n===r){let t=this.authEpoch(e);await A(this.keyProvider,this.appTag,a.principalId,r,t.sessionKeyHash),t.devices.delete(r),await this.deleteDeviceKey();}}async revokeAllDevices(e,r,n){let a=await this.deviceCertificate(e,r);await this.deviceManagement(a.source,r,"revoke-all",void 0,n);let t=this.authEpoch(e);await A(this.keyProvider,this.appTag,a.principalId,r,t.sessionKeyHash),t.devices.delete(r),n?await this.deviceCertificate(e,r):(t.devices.clear(),await this.deleteDeviceKey());}async deleteDeviceKey(){this.keyPromise=null,await this.keyProvider.delete?.(this.appTag);}async deviceManagement(e,r,n,a,t=false){let o=n==="revoke"?"device.revoke":n==="revoke-all"?"identity.revoke-all":null;o&&this.before(o);let{manageDevice:i}=await import('./deviceManagement-SUMBRXXC.js'),c=await i({source:e,currentDeviceId:r,action:n,targetDeviceId:a,exceptCurrent:t,key:()=>this.key(),post:l=>this.post("/v2/devices/manage",l),isStale:K});return o&&this.record(o),c}async durableRoomMembership(e,r,n){if(e.type!=="device-certificate")throw new Error("Durable rooms require a device certificate.");this.before(n==="join"?"room.join":"room.leave");let a=b$2(e.token),t=String(a.jti??""),i=await(await this.key()).proof((c,l)=>["openrtc:v2:room-membership",t,n,r,c,l].join(":"));await this.post("/v2/rooms/memberships",{action:n,roomId:r,deviceCertificate:e.token,deviceProof:i}),this.record(n==="join"?"room.join":"room.leave");}grantProvider(e,r={}){let n=Promise.resolve(),a=e;return t=>{let o=n.then(async()=>{let i=false;a.expiresAtMs<=Date.now()+3e5&&a.renew&&(a=await a.renew(),i=true);let c=t.refreshGrant?"gateway.grant.refresh":"gateway.grant.issue";this.before(c),t.refreshGrant&&this.before("coordination.credential.refresh");let l=async d=>{let y=b$2(d.token),p=String(y.jti??""),g=await(await this.key()).proof((m,_)=>["openrtc:v2:gateway-grant",p,t.avenue.kind,t.avenue.id,t.runtimeInstanceId,m,_].join(":"));return this.post("/v2/gateway/grants",{credentialType:d.type,credential:d.token,avenue:t.avenue,runtimeInstanceId:t.runtimeInstanceId,ticketFingerprint:t.ticketFingerprint,deviceProof:g,...t.refreshGrant?{refreshGrant:t.refreshGrant}:{},...r.maxPeers?{maxPeers:r.maxPeers}:{},...r.features?{features:r.features}:{},...t.avenue.kind==="room"&&r.architecture?{architecture:r.architecture}:{},...t.avenue.kind==="room"&&r.roomDelivery?{roomDelivery:r.roomDelivery}:{},...d.type==="device-certificate"&&r.deviceProfile?{deviceProfile:r.deviceProfile}:{}})},u;try{u=await l(a);}catch(d){if(!K(d))throw d;let y=await a.recoverRejectedCertificate?.();if(!y)throw d;a=y,i=true,u=await l(a);}return this.record(c),t.refreshGrant&&this.record("coordination.credential.refresh"),i&&await r.onSourceRenewed?.({token:a.token,expiresAtMs:a.expiresAtMs}),u});return n=o.then(()=>{},()=>{}),o}}turnProvider(e){let r=x("relay"),n=null,a=null;return async()=>{if(n&&n.expiresAtMs>Date.now()+5*6e4)return n;if(a)return a;let t=(async()=>{let o=e(),i=b$2(o.token),c=String(i.jti??""),u=await(await this.key()).proof((y,p)=>["openrtc:v2:relay-turn",c,r,y,p].join(":")),d=await this.post("/v2/relay/turn",{credentialType:o.type,credential:o.token,sessionId:r,deviceProof:u});return n=d,d})();a=t;try{return await t}finally{a===t&&(a=null);}}}};
1
+ import {b as b$2}from'./chunk-ZA44REGI.js';import {e,a}from'./chunk-L7N4T2PX.js';import {d,b as b$1,e as e$1}from'./chunk-72MN7BNQ.js';function b(s){return {irohRelay:s.irohRelay===true||s.irohRelay===void 0&&s.relay!==false,managedTurn:s.managedTurn===true}}var B=1440*6e4,w=class extends Error{constructor(r,n,a$1){super(r);this.status=n;this.reason=a$1;this.name="RTCError";let t=[502,503,504].includes(n),o=a$1==="device-reenrollment-auth-required",i=n===412&&a$1==="device-key-recovery-required";this.code=i?a.AUTH_DEVICE_KEY_RECOVERY_REQUIRED:o?"auth/device-reenrollment-required":t?"coordination/service-unavailable":n===429?"coordination/rate-limited":n===401?"auth/expired":n===403?"admission/denied":"internal/error",this.retryable=o||t,this.plane=i||o||n===401?"auth":t||n===429?"coordination":n===403?"admission":"internal";}};function K(s){return !(s instanceof w)||s.status!==403?false:s.reason==="device-certificate-stale"||s.reason==="device-certificate-revoked"?true:!s.reason&&s.message==="Device certificate is revoked or stale."}function C(s,e,r){return `openrtc:v2:device-certificate:${s}:${e}:${r}`}function P(s,e){return `openrtc:v2:device-session:${s}:${e}`}async function O(s,e,r){let n=new TextEncoder().encode(`openrtc:v2:session\0${s}\0${e}\0${r}`),a=new Uint8Array(await crypto.subtle.digest("SHA-256",n)),t="";for(let o of a)t+=String.fromCharCode(o);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function k(s){let e=s.replace(/-/g,"+").replace(/_/g,"/"),r=e.padEnd(Math.ceil(e.length/4)*4,"="),n=atob(r);return Uint8Array.from(n,a=>a.charCodeAt(0))}function f(s){let e="";for(let r of s)e+=String.fromCharCode(r);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}async function I(s,e,r,n,a){if(typeof s.token!="string"||typeof s.expiresAtMs!="number"||s.expiresAtMs<=Date.now()+B||!s.signingPublicJwk||s.signingPublicJwk.kty!=="OKP"||s.signingPublicJwk.crv!=="Ed25519"||typeof s.signingPublicJwk.x!="string")return null;let t=s.token.split(".");if(t.length!==3)return null;let o,i;try{o=JSON.parse(new TextDecoder().decode(k(t[0]))),i=b$2(s.token);}catch{return null}if(o.alg!=="EdDSA"||s.signingPublicJwk.kid&&o.kid!==s.signingPublicJwk.kid)return null;try{let y=await crypto.subtle.importKey("jwk",s.signingPublicJwk,{name:"Ed25519"},!1,["verify"]);if(!await crypto.subtle.verify({name:"Ed25519"},y,k(t[2]),new TextEncoder().encode(`${t[0]}.${t[1]}`)))return null}catch{return null}let c=typeof i.principalId=="string"?i.principalId:"",l=Number(i.iat),u=Number(i.exp);if(i.iss!=="openrtc"||i.aud!=="openrtc:v2:gateway-grant"||i.typ!=="device-certificate"||i.appTag!==e||!c||a!==void 0&&c!==a||typeof i.principalKey!="string"||i.principalKey.length===0||i.deviceId!==r||i.deviceKeyThumbprint!==n||typeof i.jti!="string"||i.jti.length===0||!Number.isSafeInteger(l)||!Number.isSafeInteger(u)||l>=u||u*1e3!==s.expiresAtMs)return null;let d=b(i);return {token:s.token,expiresAtMs:s.expiresAtMs,principalId:c,signingPublicJwk:s.signingPublicJwk,enrolled:false,...d}}async function G(s,e,r,n,a){try{let t=C(e,r,n),o=s.readSecureRecord?await s.readSecureRecord(e,t):globalThis.localStorage?.getItem(t);if(!o)return null;let i=JSON.parse(o),c=await I(i,e,n,a,r);return c?{token:c.token,expiresAtMs:c.expiresAtMs,principalId:r,signingPublicJwk:c.signingPublicJwk}:null}catch(t){if(s.readSecureRecord)throw t;return null}}async function J(s,e,r,n,a){try{let t=P(e,n),o=s.readSecureRecord?await s.readSecureRecord(r,t):globalThis.localStorage?.getItem(t);return o?await I(JSON.parse(o),r,n,a):null}catch(t){if(s.readSecureRecord)throw t;return null}}async function U(s,e,r,n,a){try{let t=C(e,r,n),o=JSON.stringify(a);s.writeSecureRecord?await s.writeSecureRecord(e,t,o):globalThis.localStorage?.setItem(t,o);}catch(t){if(s.writeSecureRecord)throw t}}async function $(s,e,r,n,a){try{let t=P(r,n),o=JSON.stringify({token:a.token,expiresAtMs:a.expiresAtMs,principalId:a.principalId,signingPublicJwk:a.signingPublicJwk});s.writeSecureRecord?await s.writeSecureRecord(e,t,o):globalThis.localStorage?.setItem(t,o);}catch(t){if(s.writeSecureRecord)throw t}}async function A(s,e,r,n,a){try{let t=C(e,r,n);if(s.deleteSecureRecord?await s.deleteSecureRecord(e,t):globalThis.localStorage?.removeItem(t),a){let o=P(a,n);s.deleteSecureRecord?await s.deleteSecureRecord(e,o):globalThis.localStorage?.removeItem(o);}}catch(t){if(s.deleteSecureRecord)throw t}}function x(s){return `${s}_${crypto.randomUUID()}`}function j(s){if(s instanceof TypeError)return true;if(!s||typeof s!="object")return false;let e=Reflect.get(s,"name");return e==="TimeoutError"||e==="AbortError"}async function N(s,e){let r=new TextEncoder().encode(`${s}:${e}`);return [...new Uint8Array(await crypto.subtle.digest("SHA-256",r))].map(a=>a.toString(16).padStart(2,"0")).join("")}var M=class{constructor(e,r,n,a,t={},o){this.apiKey=e;this.endpoints=r;this.keyProvider=n;this.attestation=a;this.events=t;this.botVerification=o;this.keyPromise=null;this.authEpochs=new Map;this.appTag=`app_${e.slice(-16)}`;}record(e){this.events.onLogicalOperation?.(e);}before(e){this.events.beforeLogicalOperation?.(e);}authEpoch(e){let r=this.authEpochs.get(e);if(r)return r;let n={generation:0,devices:new Map};return this.authEpochs.set(e,n),e.subscribe&&(n.unsubscribe=e.subscribe(a=>{a?.type==="principal-changed"&&(n.generation+=1,n.devices.clear(),n.sessionKeyHash=void 0,this.events.onAuthEpochChanged?.(e));})),n}dispose(){for(let e of this.authEpochs.values())e.unsubscribe?.();this.authEpochs.clear();}key(){return this.keyPromise??(this.keyPromise=this.keyProvider.getOrCreate(this.appTag))}async deviceSigningPublicKey(){return (await this.key()).publicKeyJwk}async signDeviceBytes(e){return (await this.key()).sign(e)}async resolveBroadcastAccess(e,r){if(!/^orb1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(e)||e.length>32768)throw new Error("Broadcast grant is invalid.");if(r&&r.byteLength!==32)throw new Error("Broadcast publisher verification key is invalid.");let n=await this.key(),a=f(new Uint8Array(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(e)))),t=r?f(r):"",o=await n.proof((u,d)=>["openrtc:v2:broadcast-access",this.apiKey,a,t,u,d].join(":")),i=await this.post("/v2/broadcasts",{action:"access",grant:e,...t?{publicationVerifyingKey:t}:{},deviceProof:o});if(i.grant!==e)throw new Error("Broadcast access grant mismatch.");let c=k(i.issuerPublicKey);if(c.byteLength!==32)throw new Error("Broadcast issuer key is invalid.");let l=new URL(i.relay?.relayUrl);if(l.protocol!=="https:"||l.username||l.password)throw new Error("Broadcast relay URL is invalid.");if(typeof i.relay.token!="string"||!/^[A-Za-z0-9._-]{16,16384}$/.test(i.relay.token)||typeof i.relay.namespace!="string"||!/^[A-Za-z0-9._/-]{1,512}$/.test(i.relay.namespace))throw new Error("Broadcast relay allocation is invalid.");return {token:e,issuerPublicKey:c,signBindingChallenge:async u=>{if(!(u instanceof Uint8Array)||u.byteLength>2048)throw new Error("Broadcast binding challenge is invalid.");return k(await n.sign(u))},relay:{relayUrl:l.toString(),token:i.relay.token,namespace:i.relay.namespace}}}async manageBroadcast(e){let r=await this.deviceCertificate(e.auth,e.deviceId),n=e.grant??"",a=e.invite??"",t=e.create,o=e.invitation,i=t?f(t.publisher.verificationKey):o?.publicationVerificationKey?f(o.publicationVerificationKey):"",c=t?{maxPublishers:t.maxPublishers,maxSubscribers:t.maxSubscribers,maxBitrateBps:t.maxBitrateBps,maxDurationSeconds:t.maxDurationSeconds,maxEgressBytes:t.maxEgressBytes}:void 0,l=t?{bitrateBps:t.publisherBitrateBps,durationSeconds:t.maxDurationSeconds,reservedEgressBytes:t.reservedEgressBytes}:o?{role:o.role,sourceSlot:o.sourceSlot??"",bitrateBps:o.bitrateBps,durationSeconds:o.durationSeconds,reservedEgressBytes:o.reservedEgressBytes}:void 0,u=f(new Uint8Array(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(JSON.stringify({action:e.action,grant:n,invite:a,publicationKey:i,sourceSlot:t?.sourceSlot??o?.sourceSlot??"host-a",limits:c,reservation:l}))))),y=await(await this.key()).proof((v,g)=>["openrtc:v2:broadcast-manage",r.source.token,e.action,u,v,g].join(":")),p=await this.post("/v2/broadcasts",{action:e.action,deviceId:e.deviceId,deviceCertificate:r.source.token,deviceProof:y,...n?{grant:n}:{},...a?{invite:a}:{},...i?{publicationVerifyingKey:i}:{},...t?{sourceSlot:t.sourceSlot??"host-a",limits:c,reservation:l}:{},...o?{invitation:{...l,publicationVerifyingKey:i}}:{}});if(e.action==="create"||e.action==="renew"){if(typeof p.grant!="string"||!/^orb1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(p.grant))throw new Error("Managed broadcast grant is invalid.");return p.grant}if(e.action==="invite"){if(typeof p.invite!="string"||!/^obi1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(p.invite))throw new Error("Managed broadcast invitation is invalid.");return p.invite}if(e.action==="accept"){if(typeof p.grant!="string"||!/^orb1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(p.grant))throw new Error("Managed broadcast accepted grant is invalid.");return p.grant}}async post(e$2,r){let n=x("request"),a=JSON.stringify({apiKey:this.apiKey,...r}),t=null;for(let o=0;o<2;o+=1)try{let i=await fetch(`${this.endpoints.controlPlane}${e$2}`,{method:"POST",headers:{"Content-Type":"application/json","X-OpenRTC-Idempotency-Key":n},body:a,signal:AbortSignal.timeout(15e3)});if(i.ok)return i.json();let c=`OpenRTC request failed (${i.status}).`,l,u;try{let y=await i.json();typeof y.error=="string"&&(c=y.error.slice(0,256)),typeof y.reason=="string"&&/^[a-z0-9-]{1,80}$/.test(y.reason)&&(l=y.reason),(d(y.code)||b$1(y.code))&&(u=e({...e$1(y),code:y.code,message:c,retryable:y.retryable}));}catch{}let d$1=u?Object.assign(u,{status:i.status,reason:l}):new w(c,i.status,l);if(t=d$1,!u&&o===0&&[502,503,504].includes(i.status))continue;throw d$1}catch(i){if(t=i,o===0&&j(i))continue;throw i}throw t instanceof Error?t:new Error("OpenRTC request failed.")}async capability(e,r,n,a=false,t,o){this.before("capability.issue");let i=e==="space"?await N(this.apiKey,r):r,l=await(await this.key()).proof((p,v)=>["openrtc:v2:capability",this.apiKey,e,i,p,v].join(":")),u=this.botVerification?await this.botVerification.getToken({action:"openrtc_capability",apiKey:this.apiKey}):void 0,d=await this.post("/v2/capabilities",{avenue:{kind:e,id:i},deviceProof:l,...n?{maxPeers:n}:{},...a?{advancedFanout:true}:{},...e==="room"&&t?{architecture:t}:{},...e==="room"&&o?{roomDelivery:o}:{},...u?{turnstileToken:u}:{}});this.record("capability.issue");let y={type:"capability",token:d.capability,avenue:e==="ticket"?{kind:"session",id:i}:d.avenue,expiresAtMs:d.expiresAt*1e3,...b(d)};return y.renew=()=>this.capability(e,r,n,a,t,o),y}async deviceCertificate(e,r,n,a,t){if(this.keyProvider.persistence==="session")throw new Error("[OpenRTC] Durable browser device enrollment requires trust.browserPersistence: persistent. Select it explicitly before creating the client; session keys cannot enroll retained devices.");let o=this.authEpoch(e),i=o.devices.get(r)??{};if(o.devices.set(r,i),t&&i.current&&i.current.token!==t.token)return this.deviceCertificateResult(e,r,n,a,{...i.current,enrolled:false});if(!t&&i.current&&i.current.expiresAtMs>Date.now()+B)return this.deviceCertificateResult(e,r,n,a,{...i.current,enrolled:false});if(!i.inFlight){let l=o.generation;t&&(i.current=void 0,i.recoverRevokedEnrollment=true);let u=t?A(this.keyProvider,this.appTag,t.principalId,r,o.sessionKeyHash).then(()=>this.enrollAuthenticatedDevice(e,r,o.sessionKeyHash,a,true)):this.resolveAuthenticatedDevice(e,r,o,a,i.recoverRevokedEnrollment===true);i.inFlight=u.then(d=>{if(o.generation!==l)throw new Error("The OpenRTC authentication identity changed during enrollment.");return i.recoverRevokedEnrollment=false,i.current=d,d}).finally(()=>{i.inFlight=void 0;});}let c=await i.inFlight;return this.deviceCertificateResult(e,r,n,a,c)}async resolveAuthenticatedDevice(e,r,n,a,t=false){let o=await this.key();if(e.getSessionKey){let i=await e.getSessionKey();if(!i)throw new Error("The OpenRTC auth provider has no active principal.");let c=await O(this.appTag,o.thumbprint,i);n.sessionKeyHash=c;let l=await J(this.keyProvider,c,this.appTag,r,o.thumbprint);if(l)return l}return this.enrollAuthenticatedDevice(e,r,n.sessionKeyHash,a,t)}deviceCertificateResult(e,r,n,a,t){let o={type:"device-certificate",token:t.token,avenue:n??{kind:"user",id:t.principalId},expiresAtMs:t.expiresAtMs,irohRelay:t.irohRelay,managedTurn:t.managedTurn};return o.renew=async()=>(await this.deviceCertificate(e,r,n,a)).source,o.recoverRejectedCertificate=async()=>(await this.deviceCertificate(e,r,n,a,t)).source,{principalId:t.principalId,source:o,enrolled:t.enrolled}}async enrollAuthenticatedDevice(e,r,n,a,t=false){this.before("identity.assertion.exchange"),this.before("identity.monthly-active-principal");let o=async(v,g)=>{let m=await e.getAssertion({audience:"https://api.openrtc.app/v2/assertions/exchange",forceRefresh:v,deviceId:r,...{}});if(!m)throw new Error("The OpenRTC auth provider returned no assertion.");return this.post("/v2/assertions/exchange",{assertion:m,deviceId:r,...e.providerId?{providerId:e.providerId}:{}})},i;try{i=await o(!1);}catch(v){if(!(v instanceof w)||v.status!==401)throw v;i=await o(true);}this.record("identity.assertion.exchange"),this.record("identity.monthly-active-principal");let c=await this.key(),l=await G(this.keyProvider,this.appTag,i.principalId,r,c.thumbprint);if(l)return {...l,principalId:i.principalId,enrolled:false,...b(i)};this.before("device.enroll"),this.attestation&&this.before("security.attestation.verify");let{enrollDevice:u}=await import('./deviceEnrollment-IPKFITV6.js'),d=await u({apiKey:this.apiKey,appTag:this.appTag,auth:e,attestation:this.attestation,deviceId:r,identity:i,key:c,profile:a,recoverRevokedEnrollment:t||i.deviceRecoveryAuthorized===true,post:(v,g)=>this.post(v,g),recordAssertionExchange:()=>this.record("identity.assertion.exchange")});i=d.identity;let y=d.enrollment;this.record("device.enroll"),this.attestation&&this.record("security.attestation.verify");let p={principalId:i.principalId,token:y.deviceCertificate,expiresAtMs:y.expiresAt*1e3,signingPublicJwk:y.signingPublicJwk,enrolled:true,...b(i)};return await U(this.keyProvider,this.appTag,i.principalId,r,{token:p.token,expiresAtMs:p.expiresAtMs,signingPublicJwk:p.signingPublicJwk}),n&&await $(this.keyProvider,this.appTag,n,r,p),p}async listEnrolledDevices(e,r){let n=await this.deviceCertificate(e,r);return (await this.deviceManagement(n.source,r,"list")).devices??[]}async revokeDevice(e,r,n){let a=await this.deviceCertificate(e,r);if(await this.deviceManagement(a.source,r,"revoke",n),n===r){let t=this.authEpoch(e);await A(this.keyProvider,this.appTag,a.principalId,r,t.sessionKeyHash),t.devices.delete(r),await this.deleteDeviceKey();}}async revokeAllDevices(e,r,n){let a=await this.deviceCertificate(e,r);await this.deviceManagement(a.source,r,"revoke-all",void 0,n);let t=this.authEpoch(e);await A(this.keyProvider,this.appTag,a.principalId,r,t.sessionKeyHash),t.devices.delete(r),n?await this.deviceCertificate(e,r):(t.devices.clear(),await this.deleteDeviceKey());}async deleteDeviceKey(){this.keyPromise=null,await this.keyProvider.delete?.(this.appTag);}async deviceManagement(e,r,n,a,t=false){let o=n==="revoke"?"device.revoke":n==="revoke-all"?"identity.revoke-all":null;o&&this.before(o);let{manageDevice:i}=await import('./deviceManagement-SUMBRXXC.js'),c=await i({source:e,currentDeviceId:r,action:n,targetDeviceId:a,exceptCurrent:t,key:()=>this.key(),post:l=>this.post("/v2/devices/manage",l),isStale:K});return o&&this.record(o),c}async durableRoomMembership(e,r,n){if(e.type!=="device-certificate")throw new Error("Durable rooms require a device certificate.");this.before(n==="join"?"room.join":"room.leave");let a=b$2(e.token),t=String(a.jti??""),i=await(await this.key()).proof((c,l)=>["openrtc:v2:room-membership",t,n,r,c,l].join(":"));await this.post("/v2/rooms/memberships",{action:n,roomId:r,deviceCertificate:e.token,deviceProof:i}),this.record(n==="join"?"room.join":"room.leave");}grantProvider(e,r={}){let n=Promise.resolve(),a=e;return t=>{let o=n.then(async()=>{let i=false;a.expiresAtMs<=Date.now()+3e5&&a.renew&&(a=await a.renew(),i=true);let c=t.refreshGrant?"gateway.grant.refresh":"gateway.grant.issue";this.before(c),t.refreshGrant&&this.before("coordination.credential.refresh");let l=async d=>{let y=b$2(d.token),p=String(y.jti??""),g=await(await this.key()).proof((m,_)=>["openrtc:v2:gateway-grant",p,t.avenue.kind,t.avenue.id,t.runtimeInstanceId,m,_].join(":"));return this.post("/v2/gateway/grants",{credentialType:d.type,credential:d.token,avenue:t.avenue,runtimeInstanceId:t.runtimeInstanceId,ticketFingerprint:t.ticketFingerprint,deviceProof:g,...t.refreshGrant?{refreshGrant:t.refreshGrant}:{},...r.maxPeers?{maxPeers:r.maxPeers}:{},...r.features?{features:r.features}:{},...t.avenue.kind==="room"&&r.architecture?{architecture:r.architecture}:{},...t.avenue.kind==="room"&&r.roomDelivery?{roomDelivery:r.roomDelivery}:{},...d.type==="device-certificate"&&r.deviceProfile?{deviceProfile:r.deviceProfile}:{}})},u;try{u=await l(a);}catch(d){if(!K(d))throw d;let y=await a.recoverRejectedCertificate?.();if(!y)throw d;a=y,i=true,u=await l(a);}return this.record(c),t.refreshGrant&&this.record("coordination.credential.refresh"),i&&await r.onSourceRenewed?.({token:a.token,expiresAtMs:a.expiresAtMs}),u});return n=o.then(()=>{},()=>{}),o}}turnProvider(e){let r=x("relay"),n=null,a=null;return async()=>{if(n&&n.expiresAtMs>Date.now()+5*6e4)return n;if(a)return a;let t=(async()=>{let o=e(),i=b$2(o.token),c=String(i.jti??""),u=await(await this.key()).proof((y,p)=>["openrtc:v2:relay-turn",c,r,y,p].join(":")),d=await this.post("/v2/relay/turn",{credentialType:o.type,credential:o.token,sessionId:r,deviceProof:u});return n=d,d})();a=t;try{return await t}finally{a===t&&(a=null);}}}};
2
2
  export{M as a};
@@ -1 +1 @@
1
- import {b,a as a$2}from'./chunk-BGWJHPBC.js';import {a}from'./chunk-AYHD4X2R.js';import {b as b$1,a as a$1}from'./chunk-FKAQDDUM.js';var g=class{constructor(e){this.deps=e;this.active=null;this.opening=null;this.commands=Promise.resolve();}apply(e){let t=this.commands.then(()=>this.applyOrdered(e));return this.commands=t.catch(()=>{}),t}dispose(){this.opening=null,this.retire();}async applyOrdered(e){if(e.type==="open"){await this.open(e);return}if(this.isCurrent(e)){if(e.type==="publish"){if(!this.active||!["owner","publisher","processor"].includes(this.active.role))throw new Error("broadcast role cannot publish");let t=await this.duplex(e.sourceSlot,true),r=this.active.writers.get(e.sourceSlot);r||(r=t.writable.getWriter(),this.active.writers.set(e.sourceSlot,r)),await b(r.write(e.object),6e4,"broadcast object write");return}if(e.type==="subscribe"){if(!this.active||!["owner","subscriber","processor"].includes(this.active.role))throw new Error("broadcast role cannot subscribe");await Promise.all(e.sourceSlots.map(async t=>{let r=await this.duplex(t,false),a=this.active;this.readObjects(a,t,r.readable).catch(async()=>{if(!(this.active!==a||a.closed))try{await this.deps.observe({type:"failed",broadcastGeneration:a.broadcastGeneration,grantGeneration:a.grantGeneration,retryable:!1,code:"relay-object-rejected"});}catch{}});}));return}this.retire(),await this.deps.observe({type:"closed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,code:e.reason});}}async open(e){this.retire(),this.opening=e;try{if(e.relay.kind==="sfu")throw new Error("SFU relay passed to MoQ adapter");let t=this.deps.openSession?await this.deps.openSession(e.relay.relayUrl,e.relay.token):await E(e.relay.relayUrl,e.relay.token,e.relay.serverCertificateHash),r={broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,role:e.role,namespace:e.relay.namespace,controlNamespace:`${e.relay.namespace}/control/${crypto.randomUUID()}`,session:t,duplexes:new Map,writers:new Map,closed:!1};if(this.active=r,t.onClose(()=>{this.active!==r||r.closed||this.deps.observe({type:"failed",broadcastGeneration:r.broadcastGeneration,grantGeneration:r.grantGeneration,retryable:!0,code:"relay-session-closed"});}),await b(t.init(),1e4,"broadcast MoQ Draft 14 setup"),await b(t.waitForSetup(),5e3,"broadcast MoQ Draft 14 setup"),this.active!==r||this.opening!==e)return;await this.deps.observe({type:"opened",broadcastGeneration:r.broadcastGeneration,grantGeneration:r.grantGeneration});}catch{this.opening===e&&(this.retire(),await this.deps.observe({type:"failed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,retryable:true,code:"relay-open-failed"}));}finally{this.opening===e&&(this.opening=null);}}async duplex(e,t){let r=this.active;if(!r)throw new Error("broadcast session is unavailable");let a=`${t?"pub":"sub"}:${e}`,o=r.duplexes.get(a);if(o)return o;let n=`${r.namespace}/source/${e}`,c=`${r.controlNamespace}/${e}`,i=await b(r.session.openObjectStreamDuplex(t?n:c,t?c:n,"openrtc-broadcast-1"),12e3,"broadcast MoQ Draft 14 object stream");if(this.active!==r)throw i.close(),new Error("broadcast generation retired during setup");return r.duplexes.set(a,i),i}async readObjects(e,t,r){let a=r.getReader();try{for(;this.active===e;){let o=await a.read();if(o.done)break;await this.deps.onObject({broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,sourceSlot:t,object:o.value})&&await this.deps.observe({type:"usage",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,deliveredBytes:o.value.byteLength});}}finally{a.releaseLock();}}isCurrent(e){return this.matches(e)&&this.active?.closed===false}matches(e){return this.active?.broadcastGeneration===e.broadcastGeneration&&this.active.grantGeneration===e.grantGeneration}retire(){let e=this.active;if(this.active=null,!!e){e.closed=true;for(let t of e.writers.values())try{t.releaseLock();}catch{}for(let t of e.duplexes.values())try{t.close();}catch{}e.session.close();}}};async function E(b$1,e,t){let r=new URL(b$1);if(r.protocol!=="https:"||r.search||r.hash||!/^[A-Za-z0-9._-]{16,16384}$/.test(e))throw new Error("broadcast relay access is invalid");let a=new URL(r.toString());if(a.pathname=`${a.pathname.replace(/\/+$/,"")}/${encodeURIComponent(e)}`,t&&t.byteLength!==32)throw new Error("broadcast relay certificate hash is invalid");let o=new WebTransport(a.toString(),t?{serverCertificateHashes:[{algorithm:"sha-256",value:t}]}:void 0);return await b(o.ready,15e3,"broadcast relay connection"),new a$2(o,r)}var y=class{constructor(e){this.deps=e;this.active=null;this.commands=Promise.resolve();}apply(e){let t=this.commands.then(()=>this.applyOrdered(e));return this.commands=t.catch(()=>{}),t}dispose(){this.retire();}async call(e,t,r={}){let a=await fetch(`${e.controlUrl}/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant:e.grant,bindingPublicJwk:e.bindingPublicJwk,publicationVerifyingKey:e.publicationVerifyingKey,...r})}),o=await a.json();if(!a.ok)throw new Error(o.error||`SFU ${t} failed (${a.status})`);return o}async applyOrdered(e){if(e.type==="open"){await this.open(e);return}let t=this.active;if(!(!t||t.closed||t.broadcastGeneration!==e.broadcastGeneration||t.grantGeneration!==e.grantGeneration))if(e.type==="publish"){if(!["owner","publisher","processor"].includes(t.role))throw new Error("SFU role cannot publish");let r=await this.channel(t,e.sourceSlot);await this.send(r,t,e.object);}else if(e.type==="subscribe"){if(!["owner","subscriber","processor"].includes(t.role))throw new Error("SFU role cannot subscribe");for(let r of e.sourceSlots)await this.channel(t,r);}else await this.retire(),await this.deps.observe({type:"closed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,code:e.reason});}async open(e){if(await this.retire(),e.relay.kind!=="sfu")throw new Error("MoQ relay passed to SFU adapter");let t=null,r=null;try{let a=e.relay;if({sessionId:r}=await this.call(a,"session"),!r)throw new Error("SFU session is missing");t=new RTCPeerConnection,t.addEventListener("datachannel",c=>{c.channel.label!=="server-events"&&c.channel.close();});let o=await this.call(a,"establish",{sessionId:r});await t.setRemoteDescription(o.sessionDescription),await t.setLocalDescription(await t.createAnswer()),await this.waitIce(t),await this.call(a,"answer",{sessionId:r,sessionDescription:t.localDescription}),await this.waitConnected(t);let n={broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,role:e.role,access:a,sessionId:r,pc:t,channels:new Map,nextObjectId:0,receiving:Promise.resolve(),fragments:new Map,closed:!1};this.active=n,t.addEventListener("connectionstatechange",()=>{this.active!==n||n.closed||["failed","closed","disconnected"].includes(t.connectionState)&&this.deps.observe({type:"failed",broadcastGeneration:n.broadcastGeneration,grantGeneration:n.grantGeneration,retryable:!0,code:"sfu-connection-lost"});}),await this.deps.observe({type:"opened",broadcastGeneration:n.broadcastGeneration,grantGeneration:n.grantGeneration});}catch{t?.close(),r&&await this.call(e.relay,"close",{sessionId:r}).catch(()=>{}),await this.deps.observe({type:"failed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,retryable:true,code:"sfu-open-failed"});}}async channel(e,t){let r=e.channels.get(t);if(r)return r;let{channelId:a}=await this.call(e.access,"channel",{sessionId:e.sessionId,sourceSlot:t});if(!Number.isInteger(a))throw new Error("SFU channel ID is invalid");let o=e.pc.createDataChannel(`openrtc-${t}`,{negotiated:true,id:a});return o.binaryType="arraybuffer",["owner","subscriber","processor"].includes(e.role)&&o.addEventListener("message",n=>{this.active!==e||e.closed||!(n.data instanceof ArrayBuffer)||(e.receiving=e.receiving.then(()=>this.receive(e,t,new Uint8Array(n.data))).catch(()=>{this.deps.observe({type:"failed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,retryable:false,code:"sfu-object-rejected"});}));}),e.channels.set(t,o),await new Promise((n,c)=>{if(o.readyState==="open")return n();let i=setTimeout(()=>c(new Error("SFU channel timed out")),15e3);o.addEventListener("open",()=>{clearTimeout(i),n();},{once:true}),o.addEventListener("error",()=>{clearTimeout(i),c(new Error("SFU channel failed"));},{once:true});}),o}async send(e,t,r){let a=r instanceof Uint8Array?r:Uint8Array.from(r);if(!a.length||a.length>1e6)throw new Error("SFU object exceeds bound");let o=Math.ceil(a.length/8e3),n=t.nextObjectId++>>>0;for(let c=0;c<o;c++){let i=a.subarray(c*8e3,(c+1)*8e3),s=new Uint8Array(12+i.length),d=new DataView(s.buffer);d.setUint32(0,1330795587),d.setUint32(4,n),d.setUint16(8,c),d.setUint16(10,o),s.set(i,12);let p=Date.now()+1e4;for(;e.bufferedAmount>128e3;){if(Date.now()>p||e.readyState!=="open")throw new Error("SFU send stalled");await new Promise(u=>setTimeout(u,10));}e.send(s);}}async receive(e,t,r){if(r.length<=12||r.length>8012)throw new Error("SFU fragment bound");let a=new DataView(r.buffer,r.byteOffset,r.byteLength);if(a.getUint32(0)!==1330795587)throw new Error("SFU fragment magic");let o=a.getUint32(4),n=a.getUint16(8),c=a.getUint16(10);if(!c||c>Math.ceil(1e6/8e3)||n>=c)throw new Error("SFU fragment count");let i=e.fragments.get(t);if(n===0&&(i={id:o,count:c,parts:[],bytes:0,started:Date.now()},e.fragments.set(t,i)),!i||i.id!==o||i.count!==c||i.parts.length!==n||Date.now()-i.started>5e3){e.fragments.delete(t);return}let s=r.slice(12);if(i.bytes+=s.length,i.bytes>1e6)throw new Error("SFU object bound");if(i.parts.push(s),i.parts.length!==c)return;e.fragments.delete(t);let d=new Uint8Array(i.bytes),p=0;for(let m of i.parts)d.set(m,p),p+=m.length;await this.deps.onObject({broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,sourceSlot:t,object:d})&&await this.deps.observe({type:"usage",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,deliveredBytes:d.length});}async retire(){let e=this.active;if(this.active=null,!!e){e.closed=true;for(let t of e.channels.values())t.close();e.pc.close(),await this.call(e.access,"close",{sessionId:e.sessionId}).catch(()=>{});}}async waitIce(e){e.iceGatheringState!=="complete"&&await new Promise((t,r)=>{let a=setTimeout(()=>r(new Error("SFU ICE gathering timed out")),15e3);e.addEventListener("icegatheringstatechange",()=>{e.iceGatheringState==="complete"&&(clearTimeout(a),t());});});}async waitConnected(e){e.connectionState!=="connected"&&await new Promise((t,r)=>{let a=setTimeout(()=>r(new Error("SFU connection timed out")),15e3);e.addEventListener("connectionstatechange",()=>{e.connectionState==="connected"&&(clearTimeout(a),t()),e.connectionState==="failed"&&(clearTimeout(a),r(new Error("SFU connection failed")));});});}};var f=class{constructor(e,t,r,a,o){this.wasm=e;this.handleId=t;this.drain=o;this.incoming=null;this.incomingWriters=new Map;this.sources=new Map;this.closed=false;let n=a[0]??"",c={beginOpenRtcMediaPublication:async s=>{let d=this.wasm.__beginOpenRtcBroadcastPublication(this.handleId,n,s.publicationId||void 0,s.kind,s.codec,s.clockRate,s.codedWidth,s.codedHeight,s.channels);return await this.drain(),{...d,control:new Uint8Array(d.control??[])}},encodeOpenRtcMediaSample:async s=>(this.wasm.__publishOpenRtcBroadcastSample(this.handleId,s.publicationId,s.timestampUs,s.durationUs,s.keyframe,s.discardable,s.payload),await this.drain(),new Uint8Array),pauseOpenRtcMediaPublication:async s=>{this.wasm.__pauseOpenRtcBroadcastPublication(this.handleId,s);},retireOpenRtcMediaPublication:async s=>{this.wasm.__retireOpenRtcBroadcastPublication(this.handleId,s);},retireOpenRtcMediaReceiver:async(s,d)=>{this.wasm.__retireOpenRtcMediaReceiver(s,d);},decodeOpenRtcMediaControl:async s=>this.wasm.__decodeOpenRtcMediaControl(s),decodeOpenRtcMediaChunk:async s=>{let d=this.wasm.__decodeOpenRtcMediaChunk(s);return {...d,payload:new Uint8Array(d.payload)}}},i={createBidirectionalStream:async()=>({protocol:"openrtc-media/1",readable:new ReadableStream({start(s){s.close();}}),writable:new WritableStream})};if(this.media=new b$1(i,c,(s,d)=>(this.incoming=d,()=>{this.incoming=null;})),["owner","publisher","processor"].includes(r)&&!n)throw new Error("[OpenRTC] Broadcast publisher grant has no source slot.")}addTrack(e,t){return this.media.addTrack(e,t)}removeTrack(e){return this.media.removeTrack(e)}onTrack(e){return this.media.onTrack(t=>e({...t,source:{id:this.sources.get(t.receiver.id)??"unknown"}}))}senders(){return this.media.senders()}receivers(){return this.media.receivers()}async accept(e,t){if(this.closed)return false;let r=this.wasm.__acceptOpenRtcBroadcastObject(this.handleId,e,t);if(!r)return false;let a=r.publicationId;if(this.sources.set(a,r.sourceSlot),r.control){let n=this.incomingWriters.get(a);if(r.controlType==="stop")return n?.generation===r.mediaGeneration&&(this.incomingWriters.delete(a),await n.writer.close().catch(()=>{})),this.sources.delete(a),true;if(r.controlType!=="publish"||n&&n.generation>=r.mediaGeneration)return true;n&&await n.writer.close().catch(()=>{});let c=new TransformStream,i=c.writable.getWriter();return this.incomingWriters.set(a,{generation:r.mediaGeneration,writer:i}),this.incoming?.({peerId:r.sourceSlot,protocol:"openrtc-media/1",readable:c.readable,writable:new WritableStream}),await i.write(a$1(new Uint8Array(r.control))),true}if(!r.media)return true;let o=this.incomingWriters.get(a);return !o||o.generation!==r.mediaGeneration||await o.writer.write(a$1(new Uint8Array(r.media))),true}async close(){this.closed||(this.closed=true,await Promise.all([...this.incomingWriters.values()].map(({writer:e})=>e.close().catch(()=>{}))),this.incomingWriters.clear(),this.sources.clear(),await this.media.close());}};var _=class{constructor(e){this.deps=e;this.wasmPromise=null;this.sessions=new Set;this.publishers=new Set;}async open(e){return this.openResolved(e)}async create(e){let t=e.auth??this.deps.defaultAuth;if(!t||!this.deps.manage||!this.deps.deviceId)throw new Error("Managed broadcast creation requires authenticated control-plane access.");let r=await this.deps.manage({action:"create",deviceId:await this.deps.deviceId(),auth:t,create:e});if(!r)throw new Error("Managed broadcast creation returned no grant.");return r}async renew(e,t){let r=await this.manageGrant("renew",e,t);if(!r)throw new Error("Managed broadcast renewal returned no grant.");return r}async invite(e,t,r){let a=await this.manage("invite",r,{grant:e,invitation:t});if(!a)throw new Error("Managed broadcast invitation returned no token.");return a}async accept(e,t){let r=await this.manage("accept",t,{invite:e});if(!r)throw new Error("Managed broadcast invitation acceptance returned no grant.");return r}async revoke(e,t,r){await this.manage("revoke",r,{grant:e,invite:t});}async leave(e,t){await this.manageGrant("leave",e,t);}async closeGrant(e,t){await this.manageGrant("close",e,t);}async preparePublisher(){let e=await this.wasm(),t=a.create(e);this.publishers.add(t);let r=false;return {verificationKey:t.verificationKey.slice(),open:a=>{if(r)throw new Error("broadcast publisher signer is closed");return this.openResolved(a,t)},close:async()=>{r||(r=true,t.close(),this.publishers.delete(t));}}}async close(){await Promise.all([...this.sessions].map(e=>e.close()));for(let e of this.publishers)e.close();this.publishers.clear();}wasm(){return this.wasmPromise??(this.wasmPromise=this.deps.loadWasm())}async manageGrant(e,t,r){return this.manage(e,r,{grant:t})}async manage(e,t,r){let a=t??this.deps.defaultAuth;if(!a||!this.deps.manage||!this.deps.deviceId)throw new Error(`Managed broadcast ${e} requires authenticated control-plane access.`);return this.deps.manage({action:e,deviceId:await this.deps.deviceId(),auth:a,...r})}async openResolved(e,t){let[r,a]=await Promise.all([this.wasm(),this.deps.resolve(e,t?.verificationKey)]),o=Date.now(),n;if(t)n=await t.open(a,o);else {let l=r.__prepareOpenRtcBroadcastGrant(a.token,a.issuerPublicKey,o),B=await a.signBindingChallenge(l.signingBytes);n=r.__openOpenRtcBroadcast(a.token,a.issuerPublicKey,l.handle,B,void 0,o);}let c={...a.relay},i=n.state,s=false,d=false,p=false,u=null,m={openSession:this.deps.openSession,observe:async l=>{if(!s){l.type==="opened"&&(i="live"),l.type==="failed"&&(i="retrying"),l.type==="closed"&&(i="closed");try{r.__observeOpenRtcBroadcastAdapter(n.handleId,l);}finally{await v();}}},onObject:async l=>s||!u?false:u.accept(l.sourceSlot,l.object)},S=c.kind==="sfu"?new y(m):new g(m),v=async()=>{if(!s){if(d){p=true;return}d=true;try{do{p=!1;let l=r.__takeOpenRtcBroadcastActions(n.handleId,32);for(let B of l)await S.apply(this.adapterAction(B,c));l.length===32&&(p=!0);}while(p)}finally{d=false;}}};u=new f(r,n.handleId,n.role,n.sourceSlots??[],v);let w={id:n.id,role:n.role,get state(){return i},media:u,getStats:async()=>({...r.__getOpenRtcBroadcastStats(n.handleId)}),close:async()=>{s||(s=true,S.dispose(),await u?.close(),r.__closeOpenRtcBroadcast(n.handleId),this.sessions.delete(w));}};this.sessions.add(w);try{return await v(),w}catch(l){throw await w.close(),l}}adapterAction(e,t){let r={broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration};if(e.type==="open"&&e.role)return {type:"open",role:e.role,relay:t,...r};if(e.type==="publish"&&e.sourceSlot&&e.object)return {type:"publish",sourceSlot:e.sourceSlot,object:e.object,discardable:e.discardable===true,control:e.control===true,...r};if(e.type==="subscribe"&&e.sourceSlots)return {type:"subscribe",sourceSlots:e.sourceSlots,...r};if(e.type==="close"&&e.reason)return {type:"close",reason:e.reason,...r};throw new Error("Rust returned an invalid broadcast adapter action")}};export{_ as a};
1
+ import {b,a as a$2}from'./chunk-IXQ4KWGP.js';import {a}from'./chunk-AYHD4X2R.js';import {b as b$1,a as a$1}from'./chunk-FKAQDDUM.js';var g=class{constructor(e){this.deps=e;this.active=null;this.opening=null;this.commands=Promise.resolve();}apply(e){let t=this.commands.then(()=>this.applyOrdered(e));return this.commands=t.catch(()=>{}),t}dispose(){this.opening=null,this.retire();}async applyOrdered(e){if(e.type==="open"){await this.open(e);return}if(this.isCurrent(e)){if(e.type==="publish"){if(!this.active||!["owner","publisher","processor"].includes(this.active.role))throw new Error("broadcast role cannot publish");let t=await this.duplex(e.sourceSlot,true),r=this.active.writers.get(e.sourceSlot);r||(r=t.writable.getWriter(),this.active.writers.set(e.sourceSlot,r)),await b(r.write(e.object),6e4,"broadcast object write");return}if(e.type==="subscribe"){if(!this.active||!["owner","subscriber","processor"].includes(this.active.role))throw new Error("broadcast role cannot subscribe");await Promise.all(e.sourceSlots.map(async t=>{let r=await this.duplex(t,false),a=this.active;this.readObjects(a,t,r.readable).catch(async()=>{if(!(this.active!==a||a.closed))try{await this.deps.observe({type:"failed",broadcastGeneration:a.broadcastGeneration,grantGeneration:a.grantGeneration,retryable:!1,code:"relay-object-rejected"});}catch{}});}));return}this.retire(),await this.deps.observe({type:"closed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,code:e.reason});}}async open(e){this.retire(),this.opening=e;try{if(e.relay.kind==="sfu")throw new Error("SFU relay passed to MoQ adapter");let t=this.deps.openSession?await this.deps.openSession(e.relay.relayUrl,e.relay.token):await E(e.relay.relayUrl,e.relay.token,e.relay.serverCertificateHash),r={broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,role:e.role,namespace:e.relay.namespace,controlNamespace:`${e.relay.namespace}/control/${crypto.randomUUID()}`,session:t,duplexes:new Map,writers:new Map,closed:!1};if(this.active=r,t.onClose(()=>{this.active!==r||r.closed||this.deps.observe({type:"failed",broadcastGeneration:r.broadcastGeneration,grantGeneration:r.grantGeneration,retryable:!0,code:"relay-session-closed"});}),await b(t.init(),1e4,"broadcast MoQ Draft 14 setup"),await b(t.waitForSetup(),5e3,"broadcast MoQ Draft 14 setup"),this.active!==r||this.opening!==e)return;await this.deps.observe({type:"opened",broadcastGeneration:r.broadcastGeneration,grantGeneration:r.grantGeneration});}catch{this.opening===e&&(this.retire(),await this.deps.observe({type:"failed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,retryable:true,code:"relay-open-failed"}));}finally{this.opening===e&&(this.opening=null);}}async duplex(e,t){let r=this.active;if(!r)throw new Error("broadcast session is unavailable");let a=`${t?"pub":"sub"}:${e}`,o=r.duplexes.get(a);if(o)return o;let n=`${r.namespace}/source/${e}`,c=`${r.controlNamespace}/${e}`,i=await b(r.session.openObjectStreamDuplex(t?n:c,t?c:n,"openrtc-broadcast-1"),12e3,"broadcast MoQ Draft 14 object stream");if(this.active!==r)throw i.close(),new Error("broadcast generation retired during setup");return r.duplexes.set(a,i),i}async readObjects(e,t,r){let a=r.getReader();try{for(;this.active===e;){let o=await a.read();if(o.done)break;await this.deps.onObject({broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,sourceSlot:t,object:o.value})&&await this.deps.observe({type:"usage",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,deliveredBytes:o.value.byteLength});}}finally{a.releaseLock();}}isCurrent(e){return this.matches(e)&&this.active?.closed===false}matches(e){return this.active?.broadcastGeneration===e.broadcastGeneration&&this.active.grantGeneration===e.grantGeneration}retire(){let e=this.active;if(this.active=null,!!e){e.closed=true;for(let t of e.writers.values())try{t.releaseLock();}catch{}for(let t of e.duplexes.values())try{t.close();}catch{}e.session.close();}}};async function E(b$1,e,t){let r=new URL(b$1);if(r.protocol!=="https:"||r.search||r.hash||!/^[A-Za-z0-9._-]{16,16384}$/.test(e))throw new Error("broadcast relay access is invalid");let a=new URL(r.toString());if(a.pathname=`${a.pathname.replace(/\/+$/,"")}/${encodeURIComponent(e)}`,t&&t.byteLength!==32)throw new Error("broadcast relay certificate hash is invalid");let o=new WebTransport(a.toString(),t?{serverCertificateHashes:[{algorithm:"sha-256",value:t}]}:void 0);return await b(o.ready,15e3,"broadcast relay connection"),new a$2(o,r)}var y=class{constructor(e){this.deps=e;this.active=null;this.commands=Promise.resolve();}apply(e){let t=this.commands.then(()=>this.applyOrdered(e));return this.commands=t.catch(()=>{}),t}dispose(){this.retire();}async call(e,t,r={}){let a=await fetch(`${e.controlUrl}/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant:e.grant,bindingPublicJwk:e.bindingPublicJwk,publicationVerifyingKey:e.publicationVerifyingKey,...r})}),o=await a.json();if(!a.ok)throw new Error(o.error||`SFU ${t} failed (${a.status})`);return o}async applyOrdered(e){if(e.type==="open"){await this.open(e);return}let t=this.active;if(!(!t||t.closed||t.broadcastGeneration!==e.broadcastGeneration||t.grantGeneration!==e.grantGeneration))if(e.type==="publish"){if(!["owner","publisher","processor"].includes(t.role))throw new Error("SFU role cannot publish");let r=await this.channel(t,e.sourceSlot);await this.send(r,t,e.object);}else if(e.type==="subscribe"){if(!["owner","subscriber","processor"].includes(t.role))throw new Error("SFU role cannot subscribe");for(let r of e.sourceSlots)await this.channel(t,r);}else await this.retire(),await this.deps.observe({type:"closed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,code:e.reason});}async open(e){if(await this.retire(),e.relay.kind!=="sfu")throw new Error("MoQ relay passed to SFU adapter");let t=null,r=null;try{let a=e.relay;if({sessionId:r}=await this.call(a,"session"),!r)throw new Error("SFU session is missing");t=new RTCPeerConnection,t.addEventListener("datachannel",c=>{c.channel.label!=="server-events"&&c.channel.close();});let o=await this.call(a,"establish",{sessionId:r});await t.setRemoteDescription(o.sessionDescription),await t.setLocalDescription(await t.createAnswer()),await this.waitIce(t),await this.call(a,"answer",{sessionId:r,sessionDescription:t.localDescription}),await this.waitConnected(t);let n={broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,role:e.role,access:a,sessionId:r,pc:t,channels:new Map,nextObjectId:0,receiving:Promise.resolve(),fragments:new Map,closed:!1};this.active=n,t.addEventListener("connectionstatechange",()=>{this.active!==n||n.closed||["failed","closed","disconnected"].includes(t.connectionState)&&this.deps.observe({type:"failed",broadcastGeneration:n.broadcastGeneration,grantGeneration:n.grantGeneration,retryable:!0,code:"sfu-connection-lost"});}),await this.deps.observe({type:"opened",broadcastGeneration:n.broadcastGeneration,grantGeneration:n.grantGeneration});}catch{t?.close(),r&&await this.call(e.relay,"close",{sessionId:r}).catch(()=>{}),await this.deps.observe({type:"failed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,retryable:true,code:"sfu-open-failed"});}}async channel(e,t){let r=e.channels.get(t);if(r)return r;let{channelId:a}=await this.call(e.access,"channel",{sessionId:e.sessionId,sourceSlot:t});if(!Number.isInteger(a))throw new Error("SFU channel ID is invalid");let o=e.pc.createDataChannel(`openrtc-${t}`,{negotiated:true,id:a});return o.binaryType="arraybuffer",["owner","subscriber","processor"].includes(e.role)&&o.addEventListener("message",n=>{this.active!==e||e.closed||!(n.data instanceof ArrayBuffer)||(e.receiving=e.receiving.then(()=>this.receive(e,t,new Uint8Array(n.data))).catch(()=>{this.deps.observe({type:"failed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,retryable:false,code:"sfu-object-rejected"});}));}),e.channels.set(t,o),await new Promise((n,c)=>{if(o.readyState==="open")return n();let i=setTimeout(()=>c(new Error("SFU channel timed out")),15e3);o.addEventListener("open",()=>{clearTimeout(i),n();},{once:true}),o.addEventListener("error",()=>{clearTimeout(i),c(new Error("SFU channel failed"));},{once:true});}),o}async send(e,t,r){let a=r instanceof Uint8Array?r:Uint8Array.from(r);if(!a.length||a.length>1e6)throw new Error("SFU object exceeds bound");let o=Math.ceil(a.length/8e3),n=t.nextObjectId++>>>0;for(let c=0;c<o;c++){let i=a.subarray(c*8e3,(c+1)*8e3),s=new Uint8Array(12+i.length),d=new DataView(s.buffer);d.setUint32(0,1330795587),d.setUint32(4,n),d.setUint16(8,c),d.setUint16(10,o),s.set(i,12);let p=Date.now()+1e4;for(;e.bufferedAmount>128e3;){if(Date.now()>p||e.readyState!=="open")throw new Error("SFU send stalled");await new Promise(u=>setTimeout(u,10));}e.send(s);}}async receive(e,t,r){if(r.length<=12||r.length>8012)throw new Error("SFU fragment bound");let a=new DataView(r.buffer,r.byteOffset,r.byteLength);if(a.getUint32(0)!==1330795587)throw new Error("SFU fragment magic");let o=a.getUint32(4),n=a.getUint16(8),c=a.getUint16(10);if(!c||c>Math.ceil(1e6/8e3)||n>=c)throw new Error("SFU fragment count");let i=e.fragments.get(t);if(n===0&&(i={id:o,count:c,parts:[],bytes:0,started:Date.now()},e.fragments.set(t,i)),!i||i.id!==o||i.count!==c||i.parts.length!==n||Date.now()-i.started>5e3){e.fragments.delete(t);return}let s=r.slice(12);if(i.bytes+=s.length,i.bytes>1e6)throw new Error("SFU object bound");if(i.parts.push(s),i.parts.length!==c)return;e.fragments.delete(t);let d=new Uint8Array(i.bytes),p=0;for(let m of i.parts)d.set(m,p),p+=m.length;await this.deps.onObject({broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,sourceSlot:t,object:d})&&await this.deps.observe({type:"usage",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,deliveredBytes:d.length});}async retire(){let e=this.active;if(this.active=null,!!e){e.closed=true;for(let t of e.channels.values())t.close();e.pc.close(),await this.call(e.access,"close",{sessionId:e.sessionId}).catch(()=>{});}}async waitIce(e){e.iceGatheringState!=="complete"&&await new Promise((t,r)=>{let a=setTimeout(()=>r(new Error("SFU ICE gathering timed out")),15e3);e.addEventListener("icegatheringstatechange",()=>{e.iceGatheringState==="complete"&&(clearTimeout(a),t());});});}async waitConnected(e){e.connectionState!=="connected"&&await new Promise((t,r)=>{let a=setTimeout(()=>r(new Error("SFU connection timed out")),15e3);e.addEventListener("connectionstatechange",()=>{e.connectionState==="connected"&&(clearTimeout(a),t()),e.connectionState==="failed"&&(clearTimeout(a),r(new Error("SFU connection failed")));});});}};var f=class{constructor(e,t,r,a,o){this.wasm=e;this.handleId=t;this.drain=o;this.incoming=null;this.incomingWriters=new Map;this.sources=new Map;this.closed=false;let n=a[0]??"",c={beginOpenRtcMediaPublication:async s=>{let d=this.wasm.__beginOpenRtcBroadcastPublication(this.handleId,n,s.publicationId||void 0,s.kind,s.codec,s.clockRate,s.codedWidth,s.codedHeight,s.channels);return await this.drain(),{...d,control:new Uint8Array(d.control??[])}},encodeOpenRtcMediaSample:async s=>(this.wasm.__publishOpenRtcBroadcastSample(this.handleId,s.publicationId,s.timestampUs,s.durationUs,s.keyframe,s.discardable,s.payload),await this.drain(),new Uint8Array),pauseOpenRtcMediaPublication:async s=>{this.wasm.__pauseOpenRtcBroadcastPublication(this.handleId,s);},retireOpenRtcMediaPublication:async s=>{this.wasm.__retireOpenRtcBroadcastPublication(this.handleId,s);},retireOpenRtcMediaReceiver:async(s,d)=>{this.wasm.__retireOpenRtcMediaReceiver(s,d);},decodeOpenRtcMediaControl:async s=>this.wasm.__decodeOpenRtcMediaControl(s),decodeOpenRtcMediaChunk:async s=>{let d=this.wasm.__decodeOpenRtcMediaChunk(s);return {...d,payload:new Uint8Array(d.payload)}}},i={createBidirectionalStream:async()=>({protocol:"openrtc-media/1",readable:new ReadableStream({start(s){s.close();}}),writable:new WritableStream})};if(this.media=new b$1(i,c,(s,d)=>(this.incoming=d,()=>{this.incoming=null;})),["owner","publisher","processor"].includes(r)&&!n)throw new Error("[OpenRTC] Broadcast publisher grant has no source slot.")}addTrack(e,t){return this.media.addTrack(e,t)}removeTrack(e){return this.media.removeTrack(e)}onTrack(e){return this.media.onTrack(t=>e({...t,source:{id:this.sources.get(t.receiver.id)??"unknown"}}))}senders(){return this.media.senders()}receivers(){return this.media.receivers()}async accept(e,t){if(this.closed)return false;let r=this.wasm.__acceptOpenRtcBroadcastObject(this.handleId,e,t);if(!r)return false;let a=r.publicationId;if(this.sources.set(a,r.sourceSlot),r.control){let n=this.incomingWriters.get(a);if(r.controlType==="stop")return n?.generation===r.mediaGeneration&&(this.incomingWriters.delete(a),await n.writer.close().catch(()=>{})),this.sources.delete(a),true;if(r.controlType!=="publish"||n&&n.generation>=r.mediaGeneration)return true;n&&await n.writer.close().catch(()=>{});let c=new TransformStream,i=c.writable.getWriter();return this.incomingWriters.set(a,{generation:r.mediaGeneration,writer:i}),this.incoming?.({peerId:r.sourceSlot,protocol:"openrtc-media/1",readable:c.readable,writable:new WritableStream}),await i.write(a$1(new Uint8Array(r.control))),true}if(!r.media)return true;let o=this.incomingWriters.get(a);return !o||o.generation!==r.mediaGeneration||await o.writer.write(a$1(new Uint8Array(r.media))),true}async close(){this.closed||(this.closed=true,await Promise.all([...this.incomingWriters.values()].map(({writer:e})=>e.close().catch(()=>{}))),this.incomingWriters.clear(),this.sources.clear(),await this.media.close());}};var _=class{constructor(e){this.deps=e;this.wasmPromise=null;this.sessions=new Set;this.publishers=new Set;}async open(e){return this.openResolved(e)}async create(e){let t=e.auth??this.deps.defaultAuth;if(!t||!this.deps.manage||!this.deps.deviceId)throw new Error("Managed broadcast creation requires authenticated control-plane access.");let r=await this.deps.manage({action:"create",deviceId:await this.deps.deviceId(),auth:t,create:e});if(!r)throw new Error("Managed broadcast creation returned no grant.");return r}async renew(e,t){let r=await this.manageGrant("renew",e,t);if(!r)throw new Error("Managed broadcast renewal returned no grant.");return r}async invite(e,t,r){let a=await this.manage("invite",r,{grant:e,invitation:t});if(!a)throw new Error("Managed broadcast invitation returned no token.");return a}async accept(e,t){let r=await this.manage("accept",t,{invite:e});if(!r)throw new Error("Managed broadcast invitation acceptance returned no grant.");return r}async revoke(e,t,r){await this.manage("revoke",r,{grant:e,invite:t});}async leave(e,t){await this.manageGrant("leave",e,t);}async closeGrant(e,t){await this.manageGrant("close",e,t);}async preparePublisher(){let e=await this.wasm(),t=a.create(e);this.publishers.add(t);let r=false;return {verificationKey:t.verificationKey.slice(),open:a=>{if(r)throw new Error("broadcast publisher signer is closed");return this.openResolved(a,t)},close:async()=>{r||(r=true,t.close(),this.publishers.delete(t));}}}async close(){await Promise.all([...this.sessions].map(e=>e.close()));for(let e of this.publishers)e.close();this.publishers.clear();}wasm(){return this.wasmPromise??(this.wasmPromise=this.deps.loadWasm())}async manageGrant(e,t,r){return this.manage(e,r,{grant:t})}async manage(e,t,r){let a=t??this.deps.defaultAuth;if(!a||!this.deps.manage||!this.deps.deviceId)throw new Error(`Managed broadcast ${e} requires authenticated control-plane access.`);return this.deps.manage({action:e,deviceId:await this.deps.deviceId(),auth:a,...r})}async openResolved(e,t){let[r,a]=await Promise.all([this.wasm(),this.deps.resolve(e,t?.verificationKey)]),o=Date.now(),n;if(t)n=await t.open(a,o);else {let l=r.__prepareOpenRtcBroadcastGrant(a.token,a.issuerPublicKey,o),B=await a.signBindingChallenge(l.signingBytes);n=r.__openOpenRtcBroadcast(a.token,a.issuerPublicKey,l.handle,B,void 0,o);}let c={...a.relay},i=n.state,s=false,d=false,p=false,u=null,m={openSession:this.deps.openSession,observe:async l=>{if(!s){l.type==="opened"&&(i="live"),l.type==="failed"&&(i="retrying"),l.type==="closed"&&(i="closed");try{r.__observeOpenRtcBroadcastAdapter(n.handleId,l);}finally{await v();}}},onObject:async l=>s||!u?false:u.accept(l.sourceSlot,l.object)},S=c.kind==="sfu"?new y(m):new g(m),v=async()=>{if(!s){if(d){p=true;return}d=true;try{do{p=!1;let l=r.__takeOpenRtcBroadcastActions(n.handleId,32);for(let B of l)await S.apply(this.adapterAction(B,c));l.length===32&&(p=!0);}while(p)}finally{d=false;}}};u=new f(r,n.handleId,n.role,n.sourceSlots??[],v);let w={id:n.id,role:n.role,get state(){return i},media:u,getStats:async()=>({...r.__getOpenRtcBroadcastStats(n.handleId)}),close:async()=>{s||(s=true,S.dispose(),await u?.close(),r.__closeOpenRtcBroadcast(n.handleId),this.sessions.delete(w));}};this.sessions.add(w);try{return await v(),w}catch(l){throw await w.close(),l}}adapterAction(e,t){let r={broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration};if(e.type==="open"&&e.role)return {type:"open",role:e.role,relay:t,...r};if(e.type==="publish"&&e.sourceSlot&&e.object)return {type:"publish",sourceSlot:e.sourceSlot,object:e.object,discardable:e.discardable===true,control:e.control===true,...r};if(e.type==="subscribe"&&e.sourceSlots)return {type:"subscribe",sourceSlots:e.sourceSlots,...r};if(e.type==="close"&&e.reason)return {type:"close",reason:e.reason,...r};throw new Error("Rust returned an invalid broadcast adapter action")}};export{_ as a};
@@ -0,0 +1,2 @@
1
+ var o={CREDIT_EXHAUSTED:"credit-exhausted",APP_BUDGET_EXHAUSTED:"app-budget-exhausted",PRINCIPAL_BUDGET_EXHAUSTED:"principal-budget-exhausted",APP_RATE_LIMITED:"app-rate-limited",PRINCIPAL_RATE_LIMITED:"principal-rate-limited",EDGE_RATE_LIMITED:"edge-rate-limited",PROVIDER_SAFETY_PAUSED:"provider-safety-paused",USAGE_PRICE_STALE:"usage-price-stale",RELAY_BUDGET_EXHAUSTED:"relay-budget-exhausted",ROOM_CAPACITY_EXCEEDED:"room-capacity-exceeded"},a={"edge-rate-exceeded":{code:o.EDGE_RATE_LIMITED,scope:"ip"},"route-rate-exceeded":{code:o.EDGE_RATE_LIMITED,scope:"avenue"}};function n(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();return Object.prototype.hasOwnProperty.call(a,e)?a[e]:void 0}function d(t){return c(t)?{code:t}:n(t)}var s=new Set(Object.values(o));function c(t){return typeof t=="string"&&s.has(t)}var p="https://openrtc-docs.web.app/openrtc/api/errors";function u(t){let e=t,r={documentationUrl:p};typeof e.scope=="string"&&["account","app","principal","ip","avenue","platform"].includes(e.scope)&&(r.scope=e.scope),typeof e.operation=="string"&&/^[a-z0-9.-]{1,100}$/.test(e.operation)&&(r.operation=e.operation),typeof e.requestId=="string"&&/^[A-Za-z0-9_.:-]{1,160}$/.test(e.requestId)&&(r.requestId=e.requestId);for(let i of ["retryAfterMs","resetAt"])Number.isSafeInteger(e[i])&&Number(e[i])>=0&&(r[i]=Number(e[i]));return r}
2
+ export{o as a,n as b,d as c,c as d,u as e};
@@ -0,0 +1,2 @@
1
+ import*as c from'@moq/net';var j=class{constructor(e,t=new URL("https://localhost/")){this.transport=e;this.relayUrl=t;this.setupComplete=false;this.connection=null;this.closeListeners=[];this.closed=false;this.closeEmitted=false;this.setupResolve=null;this.setupPromise=new Promise(n=>{this.setupResolve=n;});}requireConnection(){if(this.closed||!this.connection||!this.setupComplete)throw new Error("MoQ Draft 14 session is not ready");return this.connection}async openObjectStreamDuplex(e,t,n){let l=e.trim(),a=t.trim(),i=n.trim();if(!l||!a||!i)throw new Error("MoQ carrier namespaces and track name must be non-empty");let p=this.requireConnection();if(typeof p.openObjectStreamDuplex!="function")throw new Error("MoQ Draft 14 reliable object streams are unavailable in this build");let u=await p.openObjectStreamDuplex(c.Path.from(l),c.Path.from(a),i),o={acceptedWriteObjects:0,acceptedWriteBytes:0,completedReceivedObjects:0,completedReceivedBytes:0},b=false,h=(r,s)=>{if(!o)return;let y=s?"acceptedWriteObjects":"completedReceivedObjects",v=s?"acceptedWriteBytes":"completedReceivedBytes",w=o[y]+1,S=o[v]+r;if(!Number.isSafeInteger(w)||!Number.isSafeInteger(S)){o=null;return}o[y]=w,o[v]=S;},f=u.readable.getReader(),m=u.writable.getWriter();return {maxObjectSize:u.maxObjectSize,getObjectQuantities:()=>b||!o?null:Object.freeze({...o}),readable:new ReadableStream({async pull(r){let s=await f.read();if(s.done){r.close();return}h(s.value.byteLength,false),r.enqueue(s.value);},cancel:r=>f.cancel(r)},{highWaterMark:0}),writable:new WritableStream({async write(r){let s=r.byteLength;await m.write(r),h(s,true);},close:()=>m.close(),abort:r=>m.abort(r)}),close(){b=true,u.close();}}}async init(){if(this.closed)throw new Error("MoQ session closed");if(this.connection)return;await this.transport.ready;let e=await c.Connection.connect(this.relayUrl,{transport:this.transport,websocket:{enabled:false}});if(e.version!=="moq-transport-14"&&e.version!=="moq-transport-16")throw e.close(),new Error(`MoQ relay negotiated unsupported protocol ${e.version}`);if(this.closed){e.close();return}this.connection=e,this.setupComplete=true,this.setupResolve?.(),this.setupResolve=null,e.closed.then(()=>this.emitClose("relay-session-closed"),t=>this.emitClose(t));}waitForSetup(){return this.setupPromise}onClose(e){return this.closeListeners.push(e),()=>{this.closeListeners=this.closeListeners.filter(t=>t!==e);}}close(){if(!this.closed){this.closed=true;try{this.connection?.close();}catch{}this.connection=null;try{this.transport.close();}catch{}this.emitClose("local-close");}}emitClose(e){if(!this.closeEmitted){this.closeEmitted=true,this.closed=true,this.setupComplete=false,this.connection=null;for(let t of [...this.closeListeners])try{t(e);}catch{}}}};function O(d,e,t){let n;return new Promise((l,a)=>{n=setTimeout(()=>{if(n=void 0,typeof t=="function"){a(t());return}let i=t?`${t} timed out`:"timeout";a(new Error(`${i} after ${e}ms`));},e),d.then(i=>{n!==void 0&&clearTimeout(n),l(i);},i=>{n!==void 0&&clearTimeout(n),a(i);});})}
2
+ export{j as a,O as b};
@@ -1,2 +1,2 @@
1
- import {d}from'./chunk-OWKAJPOI.js';import {a as a$1,d as d$1,c}from'./chunk-2GX6GB6L.js';var v=new Set;function p(e,t){v.has(e)||(v.add(e),console.warn(t));}function x(e){return /^pk_(live|test)_[0-9a-f]{40}$/.test(e)}async function F(e,t){let r=`${e}:${t}`,o=new TextEncoder().encode(r),s=await crypto.subtle.digest("SHA-256",o);return Array.from(new Uint8Array(s)).map(R=>R.toString(16).padStart(2,"0")).join("")}function u(e){let t=typeof e.apiKey=="string"?e.apiKey.trim():"";if(t)return x(t)||p(`invalid-api-key:${t.slice(0,10)}`,"[pluto-rtc] The provided `apiKey` does not match the expected format (pk_live_... or pk_test_...). Create an app at https://api.openrtc.app/developer."),`app_${t.slice(-16)}`;throw new Error("[openrtc] `apiKey` is required. Create an app at https://api.openrtc.app/developer.")}function a(e){return e.authMode?e.authMode:("apiKey"in e&&typeof e.apiKey=="string"&&e.apiKey.trim().length>0&&typeof(e.spaceKey??e.space)=="string"&&(e.spaceKey??e.space).trim().length>0||p("default-auth-mode","[pluto-rtc] `authMode` is not set; defaulting to `anonymous` for compatibility."),"anonymous")}function K(e){let t=typeof e.projectId=="string"?e.projectId.trim():"";return t||(p("default-project-id","[pluto-rtc] `projectId` is not set; defaulting to the built-in PlutoRTC Firebase project."),i)}function P(e){return e.trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}function j(e){let t="storagePrefix"in e&&typeof e.storagePrefix=="string"?P(e.storagePrefix):"";return t||P(u(e))||"default"}var M={devicesPerUser:100,maxRooms:1e4,maxMembersPerRoom:50,maxPersonalDevices:25e3},G=M;var T=[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun.cloudflare.com:3478"}],f={iceServers:T};var A=/^[A-Za-z0-9._-]+$/,O="[redacted]";function I(e){let t;try{t=new URL(e);}catch{throw new Error("[OpenRTC] transports.moq.relayUrl must be a valid HTTPS URL.")}if(t.protocol!=="https:")throw new Error("[OpenRTC] transports.moq.relayUrl must use HTTPS/WebTransport.");if(t.hash)throw new Error("[OpenRTC] transports.moq.relayUrl must not contain a fragment.");if(t.searchParams.has("jwt"))throw new Error("[OpenRTC] transports.moq.relayUrl must not contain a jwt query parameter; use transports.moq.accessToken.");return t}function m(e){return I(e.trim()).toString()}function z(e,t){let r=I(e.trim());if(t!==void 0){let n=t.trim();if(!n)throw new Error("[OpenRTC] transports.moq.accessToken must not be empty when provided.");if(new TextEncoder().encode(n).byteLength>16384)throw new Error("[OpenRTC] transports.moq.accessToken exceeds the maximum supported size.");if(!A.test(n))throw new Error("[OpenRTC] transports.moq.accessToken must be a URL-safe JWT.");r.searchParams.append("jwt",n);}return r.toString()}function W(e,t){let r=e instanceof Error?`${e.name}: ${e.message}`:String(e),n=t?.trim();return n?r.split(n).join(O):r}var h=[...d];function g(e){let t=e.spaceKey??e.space;return {...e,...t!==void 0?{spaceKey:t}:{}}}function S(e){return {...e,iceServers:e.iceServers?e.iceServers.map(t=>({...t})):e.iceServers}}function D(e){return {...e}}function w(e){return {...e}}function k(e){if(e)return {iroh:typeof e.iroh=="object"?w(e.iroh):e.iroh,webrtc:typeof e.webrtc=="object"?S(e.webrtc):e.webrtc,ble:typeof e.ble=="object"?{...e.ble}:e.ble,moq:typeof e.moq=="object"?D(e.moq):e.moq,privacy:e.privacy,optimizeFor:e.optimizeFor,priority:a$1(e.priority)}}function N(e){if(e.strictMode&&!e.transports&&(e.transports={iroh:{relayOnly:true}}),!!e.transports){if(e.transports.webrtc===true?e.transports.webrtc=S(f):e.transports.webrtc===false&&(e.transports.webrtc=void 0),e.transports.moq===true)throw new Error("[OpenRTC] transports.moq=true is ambiguous because no anonymous MoQ relay is available; provide transports.moq.relayUrl explicitly.");if(e.transports.moq===false)e.transports.moq=void 0;else if(e.transports.moq&&typeof e.transports.moq=="object"){let t=e.transports.moq,r=t.relayUrl?.trim(),n=t.accessToken;if(n!==void 0&&!n.trim())throw new Error("[OpenRTC] transports.moq.accessToken must not be empty when provided.");e.transports.moq={...t,...r?{relayUrl:m(r)}:{},...n!==void 0?{accessToken:n.trim()}:{}};}if(e.transports.iroh===true?e.transports.iroh={}:e.transports.iroh===false&&(e.transports.iroh=void 0),e.transports.privacy==="relay-only"){let t=e.transports.iroh&&typeof e.transports.iroh=="object"?e.transports.iroh:{};e.transports.iroh={...t,relayOnly:true,localDiscovery:false,localDiscoveryMode:void 0},e.transports.ble=void 0;let r=e.transports.webrtc;r&&typeof r=="object"&&(e.transports.webrtc={...r,privacyMode:true,lanMode:false,iceServers:c(r.iceServers)??[],iceTransportPolicy:"relay"}),e.transports.priority=d$1(e.transports.priority,!!e.transports.webrtc);}}}function E(e){if(!e.strictMode||!e.transports)return;let t=e.transports.iroh&&typeof e.transports.iroh=="object"?e.transports.iroh:{};e.transports.iroh={...t,relayOnly:true,relayTransportPolicy:t.relayTransportPolicy??"websocketRequired",localDiscovery:false,localDiscoveryMode:void 0},e.transports.privacy="relay-only",e.transports.ble=void 0;let r=e.transports.webrtc;r&&typeof r=="object"&&(e.transports.webrtc={...r,privacyMode:true,lanMode:false,iceServers:c(r.iceServers)??[],iceTransportPolicy:"relay"});let n=e.transports.moq;if(n&&typeof n=="object"){let o=n.relayUrl?.trim();if(!o)throw new Error("[OpenRTC] strictMode requires an explicit transports.moq.relayUrl.");e.transports.moq={...n,relayUrl:m(o)};}}function Z(e){let t=g(e),r=u(t),n=a(t),o={strictMode:false,disableIrohFallback:false,transportPriority:[...h],...t,authMode:n,transports:k(t.transports)};N(o),E(o),o.transportPriority=a$1(t.transportPriority??o.transports?.priority)??[...h],(o.strictMode||o.transports?.privacy==="relay-only")&&(o.transportPriority=d$1(t.transportPriority??o.transports?.priority,!!o.transports?.webrtc));let s=C(o),y=(o.discoveryMode??"space")==="space"?"client-open":"client-auth";return {appTag:r,authMode:n,configuredPersistenceMode:s,options:o,roomCreationMode:y}}function C(e){let t=e.transports?.iroh;return e.endpointIdPersistence??e.nodeIdPersistence??(typeof t=="object"?t.persistenceMode:void 0)??"ephemeral"}function ee(e){return "options"in e&&"configuredPersistenceMode"in e?{apiKey:e.options.apiKey,authMode:a(e.options),projectId:e.options.projectId,storagePrefix:e.options.storagePrefix,nodeIdPersistence:e.configuredPersistenceMode}:{apiKey:e.apiKey,authMode:a(e),projectId:e.projectId,storagePrefix:e.storagePrefix,nodeIdPersistence:C(e)}}function te(e,t){t&&(e.transports={...e.transports||{},...t});}var i="pluto-rtc-prod",U="https://api.openrtc.app",_="https://gateway.openrtc.app";function oe(e){let t=g(e),n=(typeof t.projectId=="string"&&t.projectId.trim()?t.projectId.trim():void 0)??i,o=n===i;return {...t,projectId:n,coordinationGateway:t.coordinationGateway??(o?{endpoint:_,controlPlaneEndpoint:U,environment:"production"}:void 0)}}
2
- export{oe as a,F as b,u as c,a as d,K as e,j as f,G as g,T as h,f as i,z as j,W as k,g as l,Z as m,ee as n,te as o};
1
+ import {d}from'./chunk-OWKAJPOI.js';import {a as a$1,d as d$1,c}from'./chunk-2GX6GB6L.js';var P=new Set;function p(e,t){P.has(e)||(P.add(e),console.warn(t));}function T(e){return /^pk_(live|test)_[0-9a-f]{40}$/.test(e)}async function F(e,t){let r=`${e}:${t}`,o=new TextEncoder().encode(r),s=await crypto.subtle.digest("SHA-256",o);return Array.from(new Uint8Array(s)).map(R=>R.toString(16).padStart(2,"0")).join("")}function u(e){let t=typeof e.apiKey=="string"?e.apiKey.trim():"";if(t)return T(t)||p(`invalid-api-key:${t.slice(0,10)}`,"[pluto-rtc] The provided `apiKey` does not match the expected format (pk_live_... or pk_test_...). Create an app at https://api.openrtc.app/developer."),`app_${t.slice(-16)}`;throw new Error("[openrtc] `apiKey` is required. Create an app at https://api.openrtc.app/developer.")}function a(e){return e.authMode?e.authMode:("apiKey"in e&&typeof e.apiKey=="string"&&e.apiKey.trim().length>0&&typeof(e.spaceKey??e.space)=="string"&&(e.spaceKey??e.space).trim().length>0||p("default-auth-mode","[pluto-rtc] `authMode` is not set; defaulting to `anonymous` for compatibility."),"anonymous")}function K(e){let t=typeof e.projectId=="string"?e.projectId.trim():"";return t||(p("default-project-id","[pluto-rtc] `projectId` is not set; defaulting to the built-in PlutoRTC Firebase project."),i)}function v(e){return e.trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}function j(e){let t="storagePrefix"in e&&typeof e.storagePrefix=="string"?v(e.storagePrefix):"";return t||v(u(e))||"default"}var x={devicesPerUser:100,maxRooms:1e4,maxMembersPerRoom:50,maxPersonalDevices:25e3},G=x;var M=[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun.cloudflare.com:3478"}],f={iceServers:M};var A=/^[A-Za-z0-9._-]+$/,D="[redacted]";function I(e){let t;try{t=new URL(e);}catch{throw new Error("[OpenRTC] transports.moq.relayUrl must be a valid HTTPS URL.")}if(t.protocol!=="https:")throw new Error("[OpenRTC] transports.moq.relayUrl must use HTTPS/WebTransport.");if(t.hash)throw new Error("[OpenRTC] transports.moq.relayUrl must not contain a fragment.");if(t.searchParams.has("jwt"))throw new Error("[OpenRTC] transports.moq.relayUrl must not contain a jwt query parameter; use transports.moq.accessToken.");return t}function m(e){return I(e.trim()).toString()}function Q(e,t){let r=I(e.trim());if(t!==void 0){let n=t.trim();if(!n)throw new Error("[OpenRTC] transports.moq.accessToken must not be empty when provided.");if(new TextEncoder().encode(n).byteLength>16384)throw new Error("[OpenRTC] transports.moq.accessToken exceeds the maximum supported size.");if(!A.test(n))throw new Error("[OpenRTC] transports.moq.accessToken must be a URL-safe JWT.");r.searchParams.append("jwt",n);}return r.toString()}function z(e,t){let r=e instanceof Error?`${e.name}: ${e.message}`:String(e),n=t?.trim();return n?r.split(n).join(D):r}var h=[...d];function g(e){let t=e.spaceKey??e.space;return {...e,...t!==void 0?{spaceKey:t}:{}}}function S(e){return {...e,iceServers:e.iceServers?e.iceServers.map(t=>({...t})):e.iceServers}}function O(e){return {...e}}function w(e){return {...e}}function k(e){if(e)return {iroh:typeof e.iroh=="object"?w(e.iroh):e.iroh,webrtc:typeof e.webrtc=="object"?S(e.webrtc):e.webrtc,ble:typeof e.ble=="object"?{...e.ble}:e.ble,moq:typeof e.moq=="object"?O(e.moq):e.moq,privacy:e.privacy,optimizeFor:e.optimizeFor,priority:a$1(e.priority)}}function N(e){if(e.strictMode&&!e.transports&&(e.transports={iroh:{relayOnly:true}}),!!e.transports){if(e.transports.webrtc===true?e.transports.webrtc=S(f):e.transports.webrtc===false&&(e.transports.webrtc=void 0),e.transports.moq===true)throw new Error("[OpenRTC] transports.moq=true is ambiguous because no anonymous MoQ relay is available; provide transports.moq.relayUrl explicitly.");if(e.transports.moq===false)e.transports.moq=void 0;else if(e.transports.moq&&typeof e.transports.moq=="object"){let t=e.transports.moq,r=t.relayUrl?.trim(),n=t.accessToken;if(n!==void 0&&!n.trim())throw new Error("[OpenRTC] transports.moq.accessToken must not be empty when provided.");e.transports.moq={...t,...r?{relayUrl:m(r)}:{},...n!==void 0?{accessToken:n.trim()}:{}};}if(e.transports.iroh===true?e.transports.iroh={}:e.transports.iroh===false&&(e.transports.iroh=void 0),e.transports.privacy==="relay-only"){let t=e.transports.iroh&&typeof e.transports.iroh=="object"?e.transports.iroh:{};e.transports.iroh={...t,relayOnly:true,localDiscovery:false,localDiscoveryMode:void 0},e.transports.ble=void 0;let r=e.transports.webrtc;r&&typeof r=="object"&&(e.transports.webrtc={...r,privacyMode:true,lanMode:false,iceServers:c(r.iceServers)??[],iceTransportPolicy:"relay"}),e.transports.priority=d$1(e.transports.priority,!!e.transports.webrtc);}}}function E(e){if(!e.strictMode||!e.transports)return;let t=e.transports.iroh&&typeof e.transports.iroh=="object"?e.transports.iroh:{};e.transports.iroh={...t,relayOnly:true,relayTransportPolicy:t.relayTransportPolicy??"websocketRequired",localDiscovery:false,localDiscoveryMode:void 0},e.transports.privacy="relay-only",e.transports.ble=void 0;let r=e.transports.webrtc;r&&typeof r=="object"&&(e.transports.webrtc={...r,privacyMode:true,lanMode:false,iceServers:c(r.iceServers)??[],iceTransportPolicy:"relay"});let n=e.transports.moq;if(n&&typeof n=="object"){let o=n.relayUrl?.trim();if(!o)throw new Error("[OpenRTC] strictMode requires an explicit transports.moq.relayUrl.");e.transports.moq={...n,relayUrl:m(o)};}}function Z(e){let t=g(e),r=u(t),n=a(t),o={strictMode:false,disableIrohFallback:false,transportPriority:[...h],...t,authMode:n,transports:k(t.transports)};N(o),E(o),o.transportPriority=a$1(t.transportPriority??o.transports?.priority)??[...h],(o.strictMode||o.transports?.privacy==="relay-only")&&(o.transportPriority=d$1(t.transportPriority??o.transports?.priority,!!o.transports?.webrtc));let s=C(o),y=(o.discoveryMode??"space")==="space"?"client-open":"client-auth";return {appTag:r,authMode:n,configuredPersistenceMode:s,options:o,roomCreationMode:y}}function C(e){let t=e.transports?.iroh;return e.endpointIdPersistence??e.nodeIdPersistence??(typeof t=="object"?t.persistenceMode:void 0)??"ephemeral"}function ee(e){return "options"in e&&"configuredPersistenceMode"in e?{apiKey:e.options.apiKey,authMode:a(e.options),projectId:e.options.projectId,storagePrefix:e.options.storagePrefix,nodeIdPersistence:e.configuredPersistenceMode}:{apiKey:e.apiKey,authMode:a(e),projectId:e.projectId,storagePrefix:e.storagePrefix,nodeIdPersistence:C(e)}}function te(e,t){t&&(e.transports={...e.transports||{},...t});}var i="pluto-rtc-prod",U="https://api.openrtc.app",_="https://gateway.openrtc.app";function oe(e){let t=g(e),n=(typeof t.projectId=="string"&&t.projectId.trim()?t.projectId.trim():void 0)??i,o=n===i;return {...t,projectId:n,coordinationGateway:t.coordinationGateway??(o?{endpoint:_,controlPlaneEndpoint:U,environment:"production"}:void 0)}}
2
+ export{oe as a,F as b,u as c,a as d,K as e,j as f,G as g,M as h,f as i,Q as j,z as k,g as l,Z as m,ee as n,te as o};
@@ -1 +1 @@
1
- import {a as a$1,d as d$1,e,c}from'./chunk-WALOTASO.js';var i={...a$1,AUTH_NOT_READY:"auth/not-ready",AUTH_DENIED:"auth/denied",AUTH_EXPIRED:"auth/expired",AUTH_DEVICE_REENROLLMENT_REQUIRED:"auth/device-reenrollment-required",AUTH_DEVICE_KEY_RECOVERY_REQUIRED:"auth/device-key-recovery-required",ADMISSION_DENIED:"admission/denied",ADMISSION_SCOPE_MISMATCH:"admission/scope-mismatch",TICKET_INVITE_INVALID:"admission/ticket-invite-invalid",TICKET_MESH_INVALID_OPTIONS:"admission/ticket-mesh-invalid-options",TICKET_MESH_CAPACITY_EXCEEDED:"admission/ticket-mesh-capacity-exceeded",TICKET_MESH_ALREADY_ACTIVE:"admission/ticket-mesh-already-active",ROOM_ARCHITECTURE_UNAVAILABLE:"room-architecture-unavailable",BUDGET_EXCEEDED:"budget/exceeded",BUDGET_STALE:"budget/stale",BUDGET_RENEWAL_REQUIRED:"budget/renewal-required",COORDINATION_DISCONNECTED:"coordination/disconnected",COORDINATION_PROTOCOL:"coordination/protocol",COORDINATION_RATE_LIMITED:"coordination/rate-limited",COORDINATION_SERVICE_UNAVAILABLE:"coordination/service-unavailable",TICKET_MESH_UNAVAILABLE:"coordination/ticket-mesh-unavailable",TRANSPORT_DIAL_EXHAUSTED:"transport/dial-exhausted",TRANSPORT_UNAVAILABLE:"transport/unavailable",TRANSPORT_TICKET_MISSING:"transport/ticket-missing",DELIVERY_NOT_READY:"delivery/not-ready",DELIVERY_UNCONFIRMED:"delivery/unconfirmed",INTERNAL:"internal/error"},a=class e$1 extends Error{constructor(r){super(r.message);this.name="RTCError";r.cause!==void 0&&(this.cause=r.cause),this.code=r.code,this.retryable=r.retryable,this.plane=r.plane,this.generation=r.generation,this.transportGeneration=r.transportGeneration,this.routeGeneration=r.routeGeneration,this.revision=r.revision,d$1(r.code)&&Object.assign(this,e(r));}static is(r){return r instanceof e$1||typeof r=="object"&&r!==null&&r.name==="RTCError"&&typeof r.code=="string"&&typeof r.retryable=="boolean"&&typeof r.plane=="string"}static shouldAppRetry(r){let t=D(r);return t.retryable?t.plane==="coordination"||t.plane==="transport"||t.plane==="auth":false}toJSON(){return {name:this.name,code:this.code,message:this.message,retryable:this.retryable,plane:this.plane,generation:this.generation??null,transportGeneration:this.transportGeneration??null,routeGeneration:this.routeGeneration??null,revision:this.revision??null,...d$1(this.code)?e(this):{}}}};function S(e$1){let n=D(e$1);return {errorCode:n.code,retryable:n.retryable,errorPlane:n.plane,...d$1(n.code)?e(n):{}}}function d(e$1,n,r){let t=I(e$1);return new a({code:e$1,message:n,retryable:r.retryable??t.retryable,plane:r.plane??t.plane,cause:r.cause,generation:r.generation,transportGeneration:r.transportGeneration,routeGeneration:r.routeGeneration,revision:r.revision,...e(r)})}function I(e){if(String(e).endsWith("-rate-limited"))return {retryable:true,plane:"coordination"};if(e===i.ROOM_CAPACITY_EXCEEDED||e===i.ROOM_ARCHITECTURE_UNAVAILABLE)return {retryable:false,plane:"admission"};let n=String(e).split("/",1)[0],r=d$1(e)?"budget":["auth","admission","budget","coordination","transport","delivery"].includes(n)?n:"internal";return {retryable:r==="transport"||r==="delivery"||r==="auth"&&e!==i.AUTH_DENIED&&e!==i.AUTH_DEVICE_KEY_RECOVERY_REQUIRED||r==="coordination"&&e!==i.COORDINATION_PROTOCOL||r==="budget"&&[i.USAGE_PRICE_STALE,i.BUDGET_STALE,i.BUDGET_RENEWAL_REQUIRED].includes(e),plane:r}}function o(e,n,r){return new a({code:e,message:n,...I(e),cause:r})}function D(e$1){if(a.is(e$1))return e$1 instanceof a?e$1:new a({code:e$1.code,message:e$1.message||String(e$1),retryable:e$1.retryable,plane:e$1.plane,cause:e$1,generation:e$1.generation,transportGeneration:e$1.transportGeneration,routeGeneration:e$1.routeGeneration,revision:e$1.revision,...e(e$1)});if(typeof e$1=="object"&&e$1!==null){let r=e$1,t=typeof r.code=="string"?r.code:"",l=typeof r.message=="string"?r.message:typeof r.error=="string"?r.error:e$1 instanceof Error?e$1.message:String(e$1),R=typeof r.retryable=="boolean"?r.retryable:void 0,T=r.details&&typeof r.details=="object"&&!Array.isArray(r.details)?r.details:null,_=T&&c(T.code),C=c(t),c$1=_?T:C?e$1:null,E=_||C;if(c$1&&E)return new a({...I(E.code),code:E.code,message:l,cause:e$1,retryable:typeof c$1.retryable=="boolean"?c$1.retryable:!!E.scope,...e(c$1),...E.scope?{scope:E.scope}:{}});if(t){let b=O(t,l,R);if(b)return b}return typeof r.name=="string"&&r.name==="CoordinationConnectError"?d(i.COORDINATION_DISCONNECTED,l,{retryable:R??true,plane:"coordination",cause:e$1}):typeof r.name=="string"&&r.name==="CoordinationGatewayProtocolError"?d(t||i.COORDINATION_PROTOCOL,l,{retryable:R??false,plane:A(t),cause:e$1}):f(l,e$1)}let n=e$1 instanceof Error?e$1.message:String(e$1??"unknown error");return f(n,e$1)}function O(e,n,r){let t=e.trim().toLowerCase();return t===i.ROOM_ARCHITECTURE_UNAVAILABLE?o(i.ROOM_ARCHITECTURE_UNAVAILABLE,n):t==="unauthenticated"||t==="functions/unauthenticated"||t==="auth/unauthorized"||t.includes("permission-denied")?o(i.AUTH_DENIED,n):t==="budget-renewal-required"||t==="budget/renewal-required"?d(i.BUDGET_RENEWAL_REQUIRED,n,{retryable:r??true,plane:"budget"}):t.includes("resource-exhausted")||t.includes("budget")||t==="budget-exceeded"||t==="insufficient-budget"?t.includes("stale")||/stale-budget/i.test(n)?d(i.BUDGET_STALE,n,{retryable:r??true,plane:"budget"}):o(i.BUDGET_EXCEEDED,n):t.includes("rate-limit")||t==="rate_limited"||t==="too-many-requests"?d(i.COORDINATION_RATE_LIMITED,n,{retryable:r??true,plane:"coordination"}):t.includes("admission")||t==="permission-denied"||t==="session-token-denied"?o(i.ADMISSION_DENIED,n):t.includes("scope")?o(i.ADMISSION_SCOPE_MISMATCH,n):t.includes("disconnect")||t.includes("unavailable")||t==="aborted"?d(i.COORDINATION_DISCONNECTED,n,{retryable:r??true,plane:"coordination"}):t.startsWith("coordination/")||t.includes("protocol")?d(e,n,{retryable:r??false,plane:A(e)}):null}function A(e){let n=e.trim().toLowerCase();return n.includes("budget")?"budget":n.includes("auth")?"auth":n.includes("admission")||n.includes("scope")?"admission":"coordination"}function f(e,n){if(/^peer \S+ has no active transport for protocol traffic$/i.test(e.trim()))return o(i.DELIVERY_NOT_READY,e,n);if(/(?:session[- ]token|auth(?:entication)?|credential|bearer).*expired/i.test(e))return o(i.AUTH_EXPIRED,e,n);if(/(?:admission|session[- ]token|permission|scope).*(?:denied|rejected|revoked|mismatch)/i.test(e))return o(i.ADMISSION_DENIED,e,n);let r=/denied|rejected|revoked|expired|mismatch|invalid|crypto.*fail/i.test(e);return !r&&/^timed out waiting for peer acknowledgement$/i.test(e.trim())?o(i.DELIVERY_UNCONFIRMED,e,n):!r&&(/\bnative-main-route-pending\b|\bpeer-stream-route-pending\b/i.test(e)||/is not settled for protocol traffic: status=(?:Connecting|Connected|Online|Disconnected|Closed) readiness=(?:Connecting|TransportOnly|Settling|AwaitingReplacement|Closed)\b/i.test(e)||/\b(?:connection|writer|channel) (?:is )?closed\b|\bconnection lost\b/i.test(e)||/\bsend_peer_over_iroh: no connection record for id=/i.test(e))?o(i.DELIVERY_NOT_READY,e,n):/auth(?:entication)?\s*(?:not ready|pending|missing)/i.test(e)||/token\s*(?:not ready|pending|missing)/i.test(e)||/awaiting[- ]auth/i.test(e)?o(i.AUTH_NOT_READY,e,n):/missing endpoint ticket|ticket missing/i.test(e)?o(i.TRANSPORT_TICKET_MISSING,e,n):/dial.*(exhaust|budget)|retry budget|connection.*did not become application-routable/i.test(e)?o(i.TRANSPORT_DIAL_EXHAUSTED,e,n):/stale[- ]budget/i.test(e)?o(i.BUDGET_STALE,e,n):/budget|credit|quota|limit\s*exceeded/i.test(e)?o(i.BUDGET_EXCEEDED,e,n):/admission|session[- ]token.*(deny|reject)|permission[- ]denied/i.test(e)?o(i.ADMISSION_DENIED,e,n):r?o(i.INTERNAL,e,n):/not\s+application-routable|not[- ]ready|settledReady/i.test(e)?o(i.DELIVERY_NOT_READY,e,n):/gateway|coordination|websocket|signaling/i.test(e)?o(i.COORDINATION_DISCONNECTED,e,n):o(i.INTERNAL,e,n)}export{i as a,a as b,S as c,d,D as e};
1
+ import {a as a$1,d as d$1,e,c}from'./chunk-72MN7BNQ.js';var i={...a$1,AUTH_NOT_READY:"auth/not-ready",AUTH_DENIED:"auth/denied",AUTH_EXPIRED:"auth/expired",AUTH_DEVICE_REENROLLMENT_REQUIRED:"auth/device-reenrollment-required",AUTH_DEVICE_KEY_RECOVERY_REQUIRED:"auth/device-key-recovery-required",ADMISSION_DENIED:"admission/denied",ADMISSION_SCOPE_MISMATCH:"admission/scope-mismatch",TICKET_INVITE_INVALID:"admission/ticket-invite-invalid",TICKET_MESH_INVALID_OPTIONS:"admission/ticket-mesh-invalid-options",TICKET_MESH_CAPACITY_EXCEEDED:"admission/ticket-mesh-capacity-exceeded",TICKET_MESH_ALREADY_ACTIVE:"admission/ticket-mesh-already-active",ROOM_ARCHITECTURE_UNAVAILABLE:"room-architecture-unavailable",BUDGET_EXCEEDED:"budget/exceeded",BUDGET_STALE:"budget/stale",BUDGET_RENEWAL_REQUIRED:"budget/renewal-required",COORDINATION_DISCONNECTED:"coordination/disconnected",COORDINATION_PROTOCOL:"coordination/protocol",COORDINATION_RATE_LIMITED:"coordination/rate-limited",COORDINATION_SERVICE_UNAVAILABLE:"coordination/service-unavailable",TICKET_MESH_UNAVAILABLE:"coordination/ticket-mesh-unavailable",TRANSPORT_DIAL_EXHAUSTED:"transport/dial-exhausted",TRANSPORT_UNAVAILABLE:"transport/unavailable",TRANSPORT_TICKET_MISSING:"transport/ticket-missing",DELIVERY_NOT_READY:"delivery/not-ready",DELIVERY_UNCONFIRMED:"delivery/unconfirmed",INTERNAL:"internal/error"},a=class e$1 extends Error{constructor(r){super(r.message);this.name="RTCError";r.cause!==void 0&&(this.cause=r.cause),this.code=r.code,this.retryable=r.retryable,this.plane=r.plane,this.generation=r.generation,this.transportGeneration=r.transportGeneration,this.routeGeneration=r.routeGeneration,this.revision=r.revision,d$1(r.code)&&Object.assign(this,e(r));}static is(r){return r instanceof e$1||typeof r=="object"&&r!==null&&r.name==="RTCError"&&typeof r.code=="string"&&typeof r.retryable=="boolean"&&typeof r.plane=="string"}static shouldAppRetry(r){let t=D(r);return t.retryable?t.plane==="coordination"||t.plane==="transport"||t.plane==="auth":false}toJSON(){return {name:this.name,code:this.code,message:this.message,retryable:this.retryable,plane:this.plane,generation:this.generation??null,transportGeneration:this.transportGeneration??null,routeGeneration:this.routeGeneration??null,revision:this.revision??null,...d$1(this.code)?e(this):{}}}};function S(e$1){let n=D(e$1);return {errorCode:n.code,retryable:n.retryable,errorPlane:n.plane,...d$1(n.code)?e(n):{}}}function d(e$1,n,r){let t=I(e$1);return new a({code:e$1,message:n,retryable:r.retryable??t.retryable,plane:r.plane??t.plane,cause:r.cause,generation:r.generation,transportGeneration:r.transportGeneration,routeGeneration:r.routeGeneration,revision:r.revision,...e(r)})}function I(e){if(String(e).endsWith("-rate-limited"))return {retryable:true,plane:"coordination"};if(e===i.ROOM_CAPACITY_EXCEEDED||e===i.ROOM_ARCHITECTURE_UNAVAILABLE)return {retryable:false,plane:"admission"};let n=String(e).split("/",1)[0],r=d$1(e)?"budget":["auth","admission","budget","coordination","transport","delivery"].includes(n)?n:"internal";return {retryable:r==="transport"||r==="delivery"||r==="auth"&&e!==i.AUTH_DENIED&&e!==i.AUTH_DEVICE_KEY_RECOVERY_REQUIRED||r==="coordination"&&e!==i.COORDINATION_PROTOCOL||r==="budget"&&[i.USAGE_PRICE_STALE,i.BUDGET_STALE,i.BUDGET_RENEWAL_REQUIRED].includes(e),plane:r}}function o(e,n,r){return new a({code:e,message:n,...I(e),cause:r})}function D(e$1){if(a.is(e$1))return e$1 instanceof a?e$1:new a({code:e$1.code,message:e$1.message||String(e$1),retryable:e$1.retryable,plane:e$1.plane,cause:e$1,generation:e$1.generation,transportGeneration:e$1.transportGeneration,routeGeneration:e$1.routeGeneration,revision:e$1.revision,...e(e$1)});if(typeof e$1=="object"&&e$1!==null){let r=e$1,t=typeof r.code=="string"?r.code:"",l=typeof r.message=="string"?r.message:typeof r.error=="string"?r.error:e$1 instanceof Error?e$1.message:String(e$1),R=typeof r.retryable=="boolean"?r.retryable:void 0,T=r.details&&typeof r.details=="object"&&!Array.isArray(r.details)?r.details:null,_=T&&c(T.code),C=c(t),c$1=_?T:C?e$1:null,E=_||C;if(c$1&&E)return new a({...I(E.code),code:E.code,message:l,cause:e$1,retryable:typeof c$1.retryable=="boolean"?c$1.retryable:!!E.scope,...e(c$1),...E.scope?{scope:E.scope}:{}});if(t){let b=O(t,l,R);if(b)return b}return typeof r.name=="string"&&r.name==="CoordinationConnectError"?d(i.COORDINATION_DISCONNECTED,l,{retryable:R??true,plane:"coordination",cause:e$1}):typeof r.name=="string"&&r.name==="CoordinationGatewayProtocolError"?d(t||i.COORDINATION_PROTOCOL,l,{retryable:R??false,plane:A(t),cause:e$1}):f(l,e$1)}let n=e$1 instanceof Error?e$1.message:String(e$1??"unknown error");return f(n,e$1)}function O(e,n,r){let t=e.trim().toLowerCase();return t===i.ROOM_ARCHITECTURE_UNAVAILABLE?o(i.ROOM_ARCHITECTURE_UNAVAILABLE,n):t==="unauthenticated"||t==="functions/unauthenticated"||t==="auth/unauthorized"||t.includes("permission-denied")?o(i.AUTH_DENIED,n):t==="budget-renewal-required"||t==="budget/renewal-required"?d(i.BUDGET_RENEWAL_REQUIRED,n,{retryable:r??true,plane:"budget"}):t.includes("resource-exhausted")||t.includes("budget")||t==="budget-exceeded"||t==="insufficient-budget"?t.includes("stale")||/stale-budget/i.test(n)?d(i.BUDGET_STALE,n,{retryable:r??true,plane:"budget"}):o(i.BUDGET_EXCEEDED,n):t.includes("rate-limit")||t==="rate_limited"||t==="too-many-requests"?d(i.COORDINATION_RATE_LIMITED,n,{retryable:r??true,plane:"coordination"}):t.includes("admission")||t==="permission-denied"||t==="session-token-denied"?o(i.ADMISSION_DENIED,n):t.includes("scope")?o(i.ADMISSION_SCOPE_MISMATCH,n):t.includes("disconnect")||t.includes("unavailable")||t==="aborted"?d(i.COORDINATION_DISCONNECTED,n,{retryable:r??true,plane:"coordination"}):t.startsWith("coordination/")||t.includes("protocol")?d(e,n,{retryable:r??false,plane:A(e)}):null}function A(e){let n=e.trim().toLowerCase();return n.includes("budget")?"budget":n.includes("auth")?"auth":n.includes("admission")||n.includes("scope")?"admission":"coordination"}function f(e,n){if(/^peer \S+ has no active transport for protocol traffic$/i.test(e.trim()))return o(i.DELIVERY_NOT_READY,e,n);if(/(?:session[- ]token|auth(?:entication)?|credential|bearer).*expired/i.test(e))return o(i.AUTH_EXPIRED,e,n);if(/(?:admission|session[- ]token|permission|scope).*(?:denied|rejected|revoked|mismatch)/i.test(e))return o(i.ADMISSION_DENIED,e,n);let r=/denied|rejected|revoked|expired|mismatch|invalid|crypto.*fail/i.test(e);return !r&&/^timed out waiting for peer acknowledgement$/i.test(e.trim())?o(i.DELIVERY_UNCONFIRMED,e,n):!r&&(/\bnative-main-route-pending\b|\bpeer-stream-route-pending\b/i.test(e)||/is not settled for protocol traffic: status=(?:Connecting|Connected|Online|Disconnected|Closed) readiness=(?:Connecting|TransportOnly|Settling|AwaitingReplacement|Closed)\b/i.test(e)||/\b(?:connection|writer|channel) (?:is )?closed\b|\bconnection lost\b/i.test(e)||/\bsend_peer_over_iroh: no connection record for id=/i.test(e))?o(i.DELIVERY_NOT_READY,e,n):/auth(?:entication)?\s*(?:not ready|pending|missing)/i.test(e)||/token\s*(?:not ready|pending|missing)/i.test(e)||/awaiting[- ]auth/i.test(e)?o(i.AUTH_NOT_READY,e,n):/missing endpoint ticket|ticket missing/i.test(e)?o(i.TRANSPORT_TICKET_MISSING,e,n):/dial.*(exhaust|budget)|retry budget|connection.*did not become application-routable/i.test(e)?o(i.TRANSPORT_DIAL_EXHAUSTED,e,n):/stale[- ]budget/i.test(e)?o(i.BUDGET_STALE,e,n):/budget|credit|quota|limit\s*exceeded/i.test(e)?o(i.BUDGET_EXCEEDED,e,n):/admission|session[- ]token.*(deny|reject)|permission[- ]denied/i.test(e)?o(i.ADMISSION_DENIED,e,n):r?o(i.INTERNAL,e,n):/not\s+application-routable|not[- ]ready|settledReady/i.test(e)?o(i.DELIVERY_NOT_READY,e,n):/gateway|coordination|websocket|signaling/i.test(e)?o(i.COORDINATION_DISCONNECTED,e,n):o(i.INTERNAL,e,n)}export{i as a,a as b,S as c,d,D as e};