openrtc 2.4.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +77 -5
  2. package/dist/BrowserManagedBroadcastHost-ARCP5MGJ.js +1 -0
  3. package/dist/{Connection-DZ5eP5hL.d.ts → Connection-CTpuImO-.d.ts} +168 -4
  4. package/dist/{DelegatingRuntimeAdapter-4cgiIWMN.d.ts → DelegatingRuntimeAdapter-D67Ozqo3.d.ts} +7 -3
  5. package/dist/{IpcRuntimeAdapter-Dduaxscj.d.ts → IpcRuntimeAdapter-Ddx0MtSI.d.ts} +8 -2
  6. package/dist/WasmBridge-ZXBCXBBM.js +1 -0
  7. package/dist/{assembly-By3UBQsE.d.ts → assembly-DvfsYFCL.d.ts} +7 -2
  8. package/dist/{capabilities-B2mHv_H7.d.ts → capabilities-CmzzxSvW.d.ts} +13 -2
  9. package/dist/chunk-2K47N3QP.js +2 -0
  10. package/dist/chunk-AYHD4X2R.js +1 -0
  11. package/dist/chunk-BFN3AVHA.js +2 -0
  12. package/dist/chunk-BGWJHPBC.js +2 -0
  13. package/dist/chunk-CCCYE3XN.js +1 -0
  14. package/dist/chunk-DUY34MGT.js +1 -0
  15. package/dist/chunk-EIJNERKZ.js +1 -0
  16. package/dist/chunk-FEF3DPPB.js +1 -0
  17. package/dist/chunk-GHAJW6SZ.js +2 -0
  18. package/dist/chunk-GTHSRQ7Y.js +2 -0
  19. package/dist/chunk-LLZT3MR6.js +118 -0
  20. package/dist/chunk-N6LGTNUI.js +1 -0
  21. package/dist/{chunk-4MLJXEVV.js → chunk-NDR2ANQB.js} +1 -1
  22. package/dist/chunk-VFDCIEP6.js +2 -0
  23. package/dist/{chunk-P2SHJMS3.js → chunk-VTYVIKTM.js} +1 -1
  24. package/dist/chunk-XTYALGJN.js +2 -0
  25. package/dist/{chunk-5XOLKH66.js → chunk-Z4KJHIV5.js} +1 -1
  26. package/dist/chunk-Z54XUIKZ.js +1 -0
  27. package/dist/{controlPlane-7E6KGQPP.js → controlPlane-IIPEJ77Q.js} +1 -1
  28. package/dist/coreClient.d.ts +3 -3
  29. package/dist/coreClient.js +1 -1
  30. package/dist/{deviceEnrollment-CBJYXZ43.js → deviceEnrollment-ZQZ2WP5H.js} +1 -1
  31. package/dist/{deviceKey-Y35WSEQQ.js → deviceKey-EIMDBAQS.js} +1 -1
  32. package/dist/{dist-FIVA6EPA.js → dist-XO466BRG.js} +18 -0
  33. package/dist/index.d.ts +6 -5
  34. package/dist/index.js +1 -1
  35. package/dist/ipcFactory-PRAJ7JP7.js +1 -0
  36. package/dist/native.d.ts +5 -5
  37. package/dist/native.js +1 -1
  38. package/dist/node-browser.d.ts +8 -0
  39. package/dist/node-browser.js +1 -0
  40. package/dist/node.d.ts +87 -0
  41. package/dist/node.js +2 -0
  42. package/dist/openrtc-VCS6V3AN.js +2 -0
  43. package/dist/openrtc_bg.wasm +0 -0
  44. package/dist/room-ULZ2FGWV.js +1 -0
  45. package/dist/runtime/WasmRuntimeAdapter.d.ts +3 -3
  46. package/dist/runtime/WasmRuntimeAdapter.js +1 -1
  47. package/dist/runtime/device-status.d.ts +1 -1
  48. package/dist/runtime/factories.d.ts +75 -6
  49. package/dist/runtime/factories.js +1 -1
  50. package/dist/runtime/index.d.ts +11 -10
  51. package/dist/runtime/index.js +1 -1
  52. package/dist/server-browser.d.ts +14 -0
  53. package/dist/server-browser.js +1 -0
  54. package/dist/server.d.ts +44 -0
  55. package/dist/server.js +2 -0
  56. package/dist/service-node.d.ts +155 -0
  57. package/dist/service-node.js +1 -0
  58. package/dist/testing/native.d.ts +4 -4
  59. package/dist/testing/native.js +1 -1
  60. package/dist/testing.d.ts +38 -5
  61. package/dist/testing.js +1 -1
  62. package/dist/transport/index.d.ts +2 -2
  63. package/dist/{types-BArEthJr.d.ts → types-Cyc-mPjk.d.ts} +189 -2
  64. package/package.json +26 -3
  65. package/dist/WasmBridge-3W2HHADU.js +0 -1
  66. package/dist/chunk-2LATKLCC.js +0 -118
  67. package/dist/chunk-6OFAKLDB.js +0 -2
  68. package/dist/chunk-AJQVMVYW.js +0 -1
  69. package/dist/chunk-BCGCJGIV.js +0 -2
  70. package/dist/chunk-BOS554IK.js +0 -2
  71. package/dist/chunk-GNW63SM6.js +0 -2
  72. package/dist/chunk-MI3ZMVPK.js +0 -2
  73. package/dist/chunk-WB66633N.js +0 -1
  74. package/dist/chunk-XEHBTMJQ.js +0 -1
  75. package/dist/chunk-YYI6AY6W.js +0 -2
  76. package/dist/ipcFactory-4PCGKZIN.js +0 -1
  77. package/dist/openrtc-5HAYVDHT.js +0 -2
package/README.md CHANGED
@@ -100,6 +100,75 @@ const team = await rtc.rooms.join('team', {
100
100
  Every long-lived capability has `close()`; spaces and rooms also have
101
101
  `leave()`. One handle activates exactly one avenue.
102
102
 
103
+ ## Developer service nodes
104
+
105
+ `openrtc/service-node` exposes a preview WebSocket-server-like application
106
+ surface for browser/WASM. Browser code supplies a callback
107
+ that obtains a short-lived authority grant from the developer backend; it must
108
+ never receive a developer `sk_*` key. Trusted Node/server code can mint that
109
+ grant with `openrtc/server`.
110
+
111
+ ```ts
112
+ import { ServiceNode } from 'openrtc/service-node';
113
+
114
+ const service = new ServiceNode({
115
+ client: rtc,
116
+ apiKey,
117
+ serviceId: 'world-simulation',
118
+ generation: 1,
119
+ shardIds: ['zone-a'],
120
+ deviceId: await rtc.devices.localId(),
121
+ deviceSigner,
122
+ assignmentSigner,
123
+ grantIssuer: (request) => fetch('/api/openrtc/authority-grant', {
124
+ method: 'POST',
125
+ body: JSON.stringify(request),
126
+ }).then((response) => response.json()),
127
+ });
128
+
129
+ service.onConnection(({ connection }) => console.log(connection.id));
130
+ await service.listen('world-42');
131
+ ```
132
+
133
+ Trusted Node.js authorities use the dedicated Rust host through `openrtc/node`;
134
+ no application IPC bridge or native addon is required:
135
+
136
+ ```ts
137
+ import { ServiceNode } from 'openrtc/node';
138
+
139
+ const service = new ServiceNode({
140
+ apiKey: process.env.OPENRTC_API_KEY!,
141
+ secretKey: process.env.OPENRTC_SECRET_KEY!,
142
+ serviceId: 'world-simulation',
143
+ generation: 1,
144
+ shardIds: ['zone-a'],
145
+ deviceId: 'world-simulation-1',
146
+ stateDirectory: '/var/lib/world-simulation/openrtc', // private and persistent
147
+ });
148
+
149
+ service.onConnection(({ connection }) => {
150
+ connection.onMessage((message) => console.log(connection.peerId, message));
151
+ });
152
+ await service.listen('world-42');
153
+ ```
154
+
155
+ The released package must contain the signed native artifact for the current
156
+ `process.platform`/`process.arch`; a missing artifact fails closed. A reviewed
157
+ source checkout can instead opt into `buildFromSource: true` with an absolute
158
+ `sourceRoot`. The developer secret is sent only over the child's stdin, and
159
+ the Node layer only demultiplexes bounded application messages and authority
160
+ assignments. The Rust peer-session actor remains the sole lifecycle owner.
161
+ This preview Node facade intentionally owns one room and exposes only
162
+ message-oriented `send`/`onMessage`/`onClose` plus assignment publication; it
163
+ does not yet claim the browser facade's streams, media, or full Room
164
+ namespaces. Browser resolution of `openrtc/node` fails closed; browser code
165
+ uses WASM plus delegated grants through `openrtc/service-node`. Native Rust
166
+ uses `ControlPlane::join_authority_room` directly and does not require
167
+ JavaScript.
168
+
169
+ The authority surface remains preview-only until signed prebuilt artifacts and
170
+ source-bound browser, Node, and native Rust authority E2E lanes pass.
171
+
103
172
  ## Optional trust adapters
104
173
 
105
174
  Attestation is evaluated at device enrollment, key rotation, recovery, or risk
@@ -166,8 +235,11 @@ overrides live only in `openrtc/testing`.
166
235
 
167
236
  Relay, durable membership, managed attestation, MoQ, and BLE require both
168
237
  portal enablement and explicit runtime opt-in. Avenues default to 8 peers.
169
- Reviewed non-room avenues may request 9-12 peers. Reviewed rooms may request up
170
- to 99 peers with `advancedFanout: true`; OpenRTC then maintains a symmetric
171
- four-neighbor overlay and forwards named-channel messages with bounded hops and
172
- duplicate suppression. `state()` is intentionally unavailable in sparse rooms;
173
- use a named channel with application-owned latest-state revisions.
238
+ Reviewed non-room avenues may request 9-12 peers. Rooms default to
239
+ `architecture: 'auto'` and `payload: 'reliable'`. Small rooms use a direct
240
+ mesh. A room may declare `payload: 'latest-state'` so auto can use the reviewed
241
+ four-neighbor sparse graph through 50 members. Reliable rooms above the safe
242
+ mesh limit require
243
+ the explicitly enabled, content-blind managed path. `advancedFanout: true` is a
244
+ one-release alias for fixed sparse latest-state delivery. `state()` remains
245
+ unavailable in sparse rooms; use a named channel with application revisions.
@@ -0,0 +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-LLZT3MR6.js';import'./chunk-JPBW67B3.js';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 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),2e3,"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();try{let t=this.deps.openSession?await this.deps.openSession(e.relay.relayUrl,e.relay.token):await A(e.relay.relayUrl,e.relay.token),r={broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,role:e.role,namespace:e.relay.namespace,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)return;await this.deps.observe({type:"opened",broadcastGeneration:r.broadcastGeneration,grantGeneration:r.grantGeneration});}catch{this.matches(e)&&(this.retire(),await this.deps.observe({type:"failed",broadcastGeneration:e.broadcastGeneration,grantGeneration:e.grantGeneration,retryable:true,code:"relay-open-failed"}));}}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}`,l=`${r.namespace}/control/${r.grantGeneration}/${e}`,c=await b(r.session.openObjectStreamDuplex(t?n:l,t?l:n,"openrtc-broadcast-1"),12e3,"broadcast MoQ Draft 14 object stream");if(this.active!==r)throw c.close(),new Error("broadcast generation retired during setup");return r.duplexes.set(a,c),c}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 A(m,e){let t=new URL(m);if(t.protocol!=="https:"||t.search||t.hash||!/^[A-Za-z0-9._-]{16,16384}$/.test(e))throw new Error("broadcast relay access is invalid");let r=new URL(t.toString());r.pathname=`${r.pathname.replace(/\/+$/,"")}/${encodeURIComponent(e)}`;let a=new WebTransport(r.toString());return await b(a.ready,15e3,"broadcast relay connection"),new a$2(a,t)}var g=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]??"",l={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)}}},c={createBidirectionalStream:async()=>({protocol:"openrtc-media/1",readable:new ReadableStream({start(s){s.close();}}),writable:new WritableStream})};if(this.media=new b$1(c,l,(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 l=new TransformStream,c=l.writable.getWriter();return this.incomingWriters.set(a,{generation:r.mediaGeneration,writer:c}),this.incoming?.({peerId:r.sourceSlot,protocol:"openrtc-media/1",readable:l.readable,writable:new WritableStream}),await c.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 M=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 i=r.__prepareOpenRtcBroadcastGrant(a.token,a.issuerPublicKey,o),v=await a.signBindingChallenge(i.signingBytes);n=r.__openOpenRtcBroadcast(a.token,a.issuerPublicKey,i.handle,v,void 0,o);}let l={...a.relay},c=n.state,s=false,d=false,h=false,u=null,f=new y({openSession:this.deps.openSession,observe:async i=>{if(!s){i.type==="opened"&&(c="live"),i.type==="failed"&&(c="retrying"),i.type==="closed"&&(c="closed");try{r.__observeOpenRtcBroadcastAdapter(n.handleId,i);}finally{await w();}}},onObject:async i=>s||!u?false:u.accept(i.sourceSlot,i.object)}),w=async()=>{if(!s){if(d){h=true;return}d=true;try{do{h=!1;let i=r.__takeOpenRtcBroadcastActions(n.handleId,32);for(let v of i)await f.apply(this.adapterAction(v,l));i.length===32&&(h=!0);}while(h)}finally{d=false;}}};u=new g(r,n.handleId,n.role,n.sourceSlots??[],w);let b={id:n.id,role:n.role,get state(){return c},media:u,getStats:async()=>({...r.__getOpenRtcBroadcastStats(n.handleId)}),close:async()=>{s||(s=true,f.dispose(),await u?.close(),r.__closeOpenRtcBroadcast(n.handleId),this.sessions.delete(b));}};this.sessions.add(b);try{return await w(),b}catch(i){throw await b.close(),i}}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{M as BrowserManagedBroadcastHost};
@@ -17,7 +17,7 @@ type AuthContext = {
17
17
  /**
18
18
  * App-facing options intentionally hide transport node identifiers from callbacks.
19
19
  */
20
- type RuntimeClientOptions = Omit<ClientOptions, 'onDevices' | 'onAutoConnect' | 'onIncomingSession' | 'coordinationAvenueOverride' | 'coordinationRoomGossipFanout' | 'coordinationPlatformType'> & {
20
+ type RuntimeClientOptions = Omit<ClientOptions, 'onDevices' | 'onAutoConnect' | 'onIncomingSession' | 'coordinationAvenueOverride' | 'coordinationRoomGossipFanout' | 'coordinationRoomArchitecture' | 'coordinationDevicePublicKeyX' | 'coordinationDeviceSign' | 'coordinationPlatformType'> & {
21
21
  onDevices?: (devices: RuntimeDevice[]) => void;
22
22
  onAutoConnect?: (devices: RuntimeDevice[]) => void;
23
23
  onIncomingSession?: (session: RuntimeSession) => Promise<void>;
@@ -294,6 +294,79 @@ interface ManagedSession {
294
294
  stop: () => Promise<void>;
295
295
  }
296
296
 
297
+ /**
298
+ * Provider-neutral hot coordination contract.
299
+ *
300
+ * Implementations deliver authenticated roster, presence, and signaling facts.
301
+ * They do not decide peer identity, admission, transport dialing, retries,
302
+ * replacement, or settlement; those remain Rust/OpenRTC lifecycle concerns.
303
+ */
304
+ interface CoordinationSignalingStore {
305
+ updatePresence(localNodeId: string, ticket: string, online: boolean, ttlMs: number, metadata?: string, deviceNameOverride?: string): Promise<void>;
306
+ setOffline(localNodeId: string): Promise<void>;
307
+ updateDevice(deviceId: string, updates: {
308
+ deviceName?: string;
309
+ capabilities?: Device['capabilities'];
310
+ metadata?: string;
311
+ excludedPeers?: string[];
312
+ }): Promise<void>;
313
+ /**
314
+ * Publish the complete session-scoped peer-exclusion set for this runtime.
315
+ *
316
+ * The coordination provider owns delivery and persistence. Rust/WASM owns
317
+ * the local desired-peer decision and consumes remote exclusion snapshots.
318
+ */
319
+ setExcludedPeers?(excludedPeers: string[]): Promise<void>;
320
+ deleteDevice(deviceId: string): Promise<void>;
321
+ cleanupStaleDevices(): Promise<void>;
322
+ searchDevices(excludeNodeId?: string): Promise<Device[]>;
323
+ listDevices(excludeNodeId?: string): Promise<Device[]>;
324
+ subscribeDevices(): Promise<ReadableStream<DeviceEvent[]>>;
325
+ onDevicesChange(callback: (devices: Device[]) => void, excludeNodeId?: string): () => void;
326
+ onRoomArchitectureChange?(callback: (snapshot: RoomArchitectureSnapshot) => void): () => void;
327
+ onRoomAuthorityAssignmentChange?(callback: (assignment: RoomAuthorityAssignment | null) => void): () => void;
328
+ publishAuthorityAssignment?(input: {
329
+ assignment: {
330
+ policyVersion: 'room-authority-assignment-v1';
331
+ serviceId: string;
332
+ generation: number;
333
+ revision: number;
334
+ subjectDeviceId: string;
335
+ shardId: string;
336
+ priorityDeviceIds: string[];
337
+ relevantEntityIds: string[];
338
+ issuedAtMs: number;
339
+ expiresAtMs: number;
340
+ };
341
+ signature: string;
342
+ }): Promise<void>;
343
+ publishManagedRoomMessage?(input: {
344
+ messageId: string;
345
+ channel: string;
346
+ priority: 0 | 1 | 2 | 3;
347
+ zoneId?: string;
348
+ payload: Uint8Array;
349
+ }): Promise<void>;
350
+ onManagedRoomMessage?(callback: (message: ManagedRoomMessage) => void): () => void;
351
+ createSession(session: SignalingSession): Promise<void>;
352
+ updateSession(sessionId: string, updateData: Record<string, unknown>): Promise<void>;
353
+ subscribeSessions(localDeviceId: string): Promise<ReadableStream<SessionEvent[]>>;
354
+ sendMessage(targetId: string, payload: string, state?: string, replyPayload?: string): Promise<string>;
355
+ pollMessages(targetId: string): Promise<SignalingEnvelope[]>;
356
+ watchFriendDevices(friendUserIds: string[], callback: (devices: Map<string, Device[]>) => void): () => void;
357
+ updateFriendTicket(friendTicket: string | null): Promise<void>;
358
+ handleScopeChange(): Promise<void>;
359
+ setHostAvailability?(input: {
360
+ available: boolean;
361
+ reason: string;
362
+ }): void;
363
+ stopAuthActivity(): void;
364
+ usesCoordinationGateway?(): boolean;
365
+ joinCoordinationRoom?(roomId: string, nodeId: string, ticket: string): Promise<void>;
366
+ leaveCoordinationRoom?(roomId: string): Promise<void>;
367
+ getCoordinationRoomMembers?(roomId: string): Promise<RoomMember[]>;
368
+ watchCoordinationRoomMembers?(roomId: string, callback: (members: RoomMember[]) => void): () => void;
369
+ }
297
370
  interface CoordinationGatewayOptions {
298
371
  /**
299
372
  * Provider-neutral coordination gateway endpoint.
@@ -644,6 +717,8 @@ interface Device {
644
717
  connectable?: boolean;
645
718
  kind?: EndpointKind | string;
646
719
  nodeId?: string;
720
+ /** Gateway-verified public half of the non-exportable device signing key. */
721
+ devicePublicKeyJwk?: JsonWebKey;
647
722
  platformType?: string;
648
723
  capabilities?: {
649
724
  canHost?: boolean;
@@ -665,6 +740,8 @@ interface Device {
665
740
  transports?: ProtocolName[];
666
741
  }
667
742
  interface PeerState {
743
+ /** Rust's current-record terminal verdict; absent on older runtimes. */
744
+ logicalSessionTerminal?: boolean;
668
745
  peerId: string;
669
746
  deviceId?: string;
670
747
  deviceIdHint?: string;
@@ -709,6 +786,7 @@ interface PeerState {
709
786
  errorPlane?: string;
710
787
  }
711
788
  interface BackendConnectionState {
789
+ logicalSessionTerminal?: boolean;
712
790
  connectionId: string;
713
791
  deviceId?: string | null;
714
792
  deviceIdHint?: string | null;
@@ -977,6 +1055,7 @@ interface ResolvedPeerIdentity {
977
1055
  nodeId?: string | null;
978
1056
  }
979
1057
  interface PeerSessionSnapshot {
1058
+ logicalSessionTerminal?: boolean;
980
1059
  peerId: string;
981
1060
  deviceId?: string | null;
982
1061
  deviceIdHint?: string | null;
@@ -1082,6 +1161,53 @@ interface DesiredPeerProjection {
1082
1161
  online?: boolean;
1083
1162
  sessionId?: string | null;
1084
1163
  excludedPeers?: string[];
1164
+ devicePublicKeyJwk?: JsonWebKey;
1165
+ topologyRole?: 'active' | 'backup';
1166
+ topologyRevision?: number;
1167
+ }
1168
+ /**
1169
+ * Room-wide routing intent. Physical Iroh carrier selection remains private.
1170
+ * `managed` is reserved but unavailable in 2.5; selecting it fails explicitly.
1171
+ */
1172
+ type RoomArchitectureMode = 'auto' | 'mesh' | 'sparse' | 'managed' | 'authority';
1173
+ type EffectiveRoomArchitecture = Exclude<RoomArchitectureMode, 'auto'>;
1174
+ type RoomArchitectureReason = 'size' | 'traffic' | 'latency' | 'cost' | 'capacity' | 'manual' | 'recovery';
1175
+ /**
1176
+ * Customer-safe room policy projection delivered by the authenticated gateway.
1177
+ * Provider rates, margins, reserves, and invoice allocation stay server-side.
1178
+ */
1179
+ interface RoomArchitectureSnapshot {
1180
+ requested: RoomArchitectureMode;
1181
+ effective: EffectiveRoomArchitecture;
1182
+ epoch: number;
1183
+ phase: 'settled' | 'preparing';
1184
+ reason: RoomArchitectureReason;
1185
+ heldCreditsUsd: number;
1186
+ quoteExpiresAtMs: number;
1187
+ }
1188
+ /**
1189
+ * Read-only application-interest projection signed by the room's registered
1190
+ * authority and admitted by the gateway. It suggests what the application
1191
+ * should render or simulate; it never grants transport or room permissions.
1192
+ */
1193
+ interface RoomAuthorityAssignment {
1194
+ serviceId: string;
1195
+ generation: number;
1196
+ revision: number;
1197
+ shardId: string;
1198
+ priorityDeviceIds: readonly string[];
1199
+ relevantEntityIds: readonly string[];
1200
+ issuedAtMs: number;
1201
+ expiresAtMs: number;
1202
+ }
1203
+ /** Internal decrypted delivery from the Rust-owned managed-room group. */
1204
+ interface ManagedRoomMessage {
1205
+ senderId: string;
1206
+ messageId: string;
1207
+ channel: string;
1208
+ priority: 0 | 1 | 2 | 3;
1209
+ zoneId?: string;
1210
+ payload: Uint8Array;
1085
1211
  }
1086
1212
  /** Browser-only Rust/WASM module supplied by the browser signaling adapter. */
1087
1213
  interface BrowserWasmRuntimeModule {
@@ -1124,6 +1250,31 @@ interface ISignalingBackend {
1124
1250
  }): Promise<void>;
1125
1251
  deleteDevice(deviceId: string): Promise<void>;
1126
1252
  onDevicesChange(callback: (devices: Device[]) => void, excludeNodeId?: string): () => void;
1253
+ onRoomArchitectureChange?(callback: (snapshot: RoomArchitectureSnapshot) => void): () => void;
1254
+ onRoomAuthorityAssignmentChange?(callback: (assignment: RoomAuthorityAssignment | null) => void): () => void;
1255
+ publishAuthorityAssignment?(input: {
1256
+ assignment: {
1257
+ policyVersion: 'room-authority-assignment-v1';
1258
+ serviceId: string;
1259
+ generation: number;
1260
+ revision: number;
1261
+ subjectDeviceId: string;
1262
+ shardId: string;
1263
+ priorityDeviceIds: string[];
1264
+ relevantEntityIds: string[];
1265
+ issuedAtMs: number;
1266
+ expiresAtMs: number;
1267
+ };
1268
+ signature: string;
1269
+ }): Promise<void>;
1270
+ publishManagedRoomMessage?(input: {
1271
+ messageId: string;
1272
+ channel: string;
1273
+ priority: 0 | 1 | 2 | 3;
1274
+ zoneId?: string;
1275
+ payload: Uint8Array;
1276
+ }): Promise<void>;
1277
+ onManagedRoomMessage?(callback: (message: ManagedRoomMessage) => void): () => void;
1127
1278
  onAuthChange(callback: (user: RuntimeIdentity | null) => void): () => void;
1128
1279
  checkForSSOToken(): Promise<void>;
1129
1280
  waitForAuth(): Promise<void>;
@@ -1135,7 +1286,7 @@ interface ISignalingBackend {
1135
1286
  submitDesiredPeerProjection?(revision: number, peers: DesiredPeerProjection[]): Promise<void>;
1136
1287
  notifyDisconnectRequested?(remoteNodeId: string): void;
1137
1288
  startPresence?(userId: string, localNodeId: string, deviceName: string, ticket: string, metadata?: string): Promise<void>;
1138
- startPresenceLoop(userId: string, localNodeId: string, deviceName: string, ticket: string, metadata?: string): void;
1289
+ startPresenceLoop(userId: string, localNodeId: string, deviceName: string, ticket: string, metadata?: string): Promise<void>;
1139
1290
  createSession(session: SignalingSession): Promise<void>;
1140
1291
  updateSession(sessionId: string, updateData: any): Promise<void>;
1141
1292
  subscribeSessions(localDeviceId: string): Promise<ReadableStream<SessionEvent[]>>;
@@ -1188,6 +1339,19 @@ interface ISignalingBackend {
1188
1339
  onStateChange?(callback: (state: BackendConnectionState) => void): Promise<() => void> | (() => void);
1189
1340
  /** Native-only protected logical message surface; browser uses its WASM connection. */
1190
1341
  sendPeerMessage?(id: string, payload: Uint8Array): Promise<void>;
1342
+ encodeSparseFanoutMessage?(capability: string, payload: Uint8Array): Promise<Uint8Array>;
1343
+ acceptSparseFanoutMessage?(capability: string, sourcePeerId: string, payload: Uint8Array): Promise<{
1344
+ payload: Uint8Array;
1345
+ authorDeviceId: string;
1346
+ authorPeerId: string;
1347
+ topologyRevision: number;
1348
+ hop: number;
1349
+ forwardPeerIds: string[];
1350
+ forwardPeerLimit: number;
1351
+ forwardQueueCapacity: number;
1352
+ forward?: Uint8Array;
1353
+ }>;
1354
+ recordSparseFanoutForwardQueueDrop?(capability: string, count: number): Promise<void>;
1191
1355
  /** Native-only generation-fenced logical message projection. */
1192
1356
  onPeerMessage?(callback: (event: NativePeerDataEvent) => void): Promise<() => void> | (() => void);
1193
1357
  /** @deprecated Implement file protocols over named channels, or use `openrtc-file-transfer`. */
@@ -1383,7 +1547,7 @@ declare class Connection {
1383
1547
  transportState?: string | null;
1384
1548
  transportGeneration?: number | null;
1385
1549
  transportStableId?: number | null;
1386
- }): void;
1550
+ }): boolean;
1387
1551
  getTransportDiagnostics(): Promise<any>;
1388
1552
  send(message: Message, options?: ApplicationPayloadSendOptions): Promise<void>;
1389
1553
  lastPayloadTransport(): ProtocolName | null;
@@ -1433,4 +1597,4 @@ declare class Connection {
1433
1597
  private close;
1434
1598
  }
1435
1599
 
1436
- export { type NativeManagedSessionStartResult as $, type AuthContext as A, type AuthMode as B, type ChannelDescriptor$1 as C, type DeviceStatus as D, type SignalingMode as E, type ClientOptions as F, type GrantScope as G, type ExplicitFileDataSendParams as H, type IncomingStream as I, type JoinRoomOptions$1 as J, type ISignalingBackend as K, type LocalDeviceInfo$1 as L, type ManagedOptions as M, type RuntimeIdentity as N, type RoomMember as O, type PlutoIrohConfiguration as P, type Device as Q, type RouteOptimization as R, type ScopedChannelOptions as S, type DeviceStatusSnapshot as T, type ManagedConnectionRecord as U, type SignalingEnvelope as V, type DeviceEvent as W, type DesiredPeerProjection as X, type SignalingSession as Y, type SessionEvent as Z, type LocalDeviceInfo as _, type PlutoRTCConfiguration as a, type BackendPeerBiStream as a0, type BackendPeerUniStream as a1, type PortableMediaPublish as a2, type PortableMediaPublicationStart as a3, type PortableMediaSample as a4, type PortableMediaChunk as a5, type PortableMediaControl as a6, type NativeConnectParams as a7, type NativeConnectResult as a8, type BackendConnectionState as a9, type ScanningLoopHandle as aA, type RuntimeBootstrapOptions as aB, type RuntimeBootstrapResult as aC, type ApplicationPayloadReadinessOptions as aD, type ManagedApplicationRouteOptions as aE, type PeerState as aF, type PeerScope as aG, type PeerHealth as aH, type ChannelDescriptor as aI, type JoinRequest as aJ, type AutoConnectPolicy as aK, type ChannelFraming as aL, type ConnectionStatus as aM, type DevicePresence as aN, type PayloadRouteOptions as aO, type PeerLifecycleStatus$1 as aP, type PeerSessionSnapshot$1 as aQ, type PresencePolicy as aR, type RuntimeAuthContext as aS, type RuntimePeerScope as aT, type SessionKind as aU, type SessionPlatform as aV, type NativePeerDataEvent as aa, type CoordinationGatewayGrantRequest as ab, type CoordinationGatewayGrant as ac, type BrowserWasmRuntimeModule as ad, type BrowserProtocolStore as ae, type NamespaceDescriptor as af, type IrohMutationReceipt as ag, type IrohDocEntry as ah, type CoreClientBridgeHost as ai, type RouteDescriptor as aj, type PayloadCrypto as ak, type CryptoStreams as al, type CryptoBiStream as am, type RouteFamily as an, type RouteKind as ao, type RuntimeAuthIdentity as ap, type RuntimeSession as aq, type AppLimits as ar, type ConnectionTarget as as, type PresenceLoopOptions as at, type SignalingOptions as au, type JoinRoomOptions as av, type ChannelMetadata as aw, type RoomCreationMode as ax, type ProtocolCapabilityMap as ay, type ScanningLoopOptions as az, type PlutoMoQConfiguration as b, type ProtocolName as c, type RuntimePeerState as d, type PeerConnectOptions as e, Connection as f, type PeerSessionSnapshot as g, type PeerReadiness as h, type RuntimePeerHealth as i, type ResolvedPeerIdentity as j, type PeerStreamOptions as k, type RuntimeDevice as l, type ScopedLogicalChannel as m, type ConnectionState as n, type ReadinessOptions as o, type ConnectionEvent as p, type ManagedSession as q, type DeviceConnectOptions as r, type ConnectDeviceResult as s, type ConnectDeviceHooks as t, type ConnectDeviceOptions as u, type DeviceProfile as v, type RawConnection as w, type RuntimeRoomMember as x, type RuntimeClientOptions as y, type DiscoveryMode as z };
1600
+ export { type DeviceEvent as $, type RawConnection as A, type RuntimeRoomMember as B, type ChannelDescriptor$1 as C, type DeviceStatus as D, type EffectiveRoomArchitecture as E, type AuthContext as F, type GrantScope as G, type RuntimeClientOptions as H, type IncomingStream as I, type JoinRoomOptions$1 as J, type DiscoveryMode as K, type LocalDeviceInfo$1 as L, type ManagedOptions as M, type AuthMode as N, type SignalingMode as O, type PlutoIrohConfiguration as P, type ClientOptions as Q, type RoomArchitectureMode as R, type ScopedChannelOptions as S, type ExplicitFileDataSendParams as T, type ISignalingBackend as U, type RuntimeIdentity as V, type RoomMember as W, type Device as X, type DeviceStatusSnapshot as Y, type ManagedConnectionRecord as Z, type SignalingEnvelope as _, type RoomArchitectureReason as a, type SessionKind as a$, type DesiredPeerProjection as a0, type SignalingSession as a1, type SessionEvent as a2, type LocalDeviceInfo as a3, type NativeManagedSessionStartResult as a4, type BackendPeerBiStream as a5, type BackendPeerUniStream as a6, type PortableMediaPublish as a7, type PortableMediaPublicationStart as a8, type PortableMediaSample as a9, type PresenceLoopOptions as aA, type SignalingOptions as aB, type JoinRoomOptions as aC, type ChannelMetadata as aD, type RoomCreationMode as aE, type ProtocolCapabilityMap as aF, type ScanningLoopOptions as aG, type ScanningLoopHandle as aH, type RuntimeBootstrapOptions as aI, type RuntimeBootstrapResult as aJ, type ApplicationPayloadReadinessOptions as aK, type ManagedApplicationRouteOptions as aL, type PeerState as aM, type PeerScope as aN, type PeerHealth as aO, type ChannelDescriptor as aP, type JoinRequest as aQ, type AutoConnectPolicy as aR, type ChannelFraming as aS, type ConnectionStatus as aT, type DevicePresence as aU, type PayloadRouteOptions as aV, type PeerLifecycleStatus$1 as aW, type PeerSessionSnapshot$1 as aX, type PresencePolicy as aY, type RuntimeAuthContext as aZ, type RuntimePeerScope as a_, type PortableMediaChunk as aa, type PortableMediaControl as ab, type NativeConnectParams as ac, type NativeConnectResult as ad, type BackendConnectionState as ae, type NativePeerDataEvent as af, type CoordinationGatewayGrantRequest as ag, type CoordinationGatewayGrant as ah, type BrowserWasmRuntimeModule as ai, type BrowserProtocolStore as aj, type NamespaceDescriptor as ak, type IrohMutationReceipt as al, type IrohDocEntry as am, type CoordinationSignalingStore as an, type ManagedRoomMessage as ao, type CoreClientBridgeHost as ap, type RouteDescriptor as aq, type PayloadCrypto as ar, type CryptoStreams as as, type CryptoBiStream as at, type RouteFamily as au, type RouteKind as av, type RuntimeAuthIdentity as aw, type RuntimeSession as ax, type AppLimits as ay, type ConnectionTarget as az, type RoomArchitectureSnapshot as b, type SessionPlatform as b0, 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 RuntimeDevice as p, type ScopedLogicalChannel as q, type ConnectionState as r, type ReadinessOptions as s, type ConnectionEvent as t, type ManagedSession as u, type DeviceConnectOptions as v, type ConnectDeviceResult as w, type ConnectDeviceHooks as x, type ConnectDeviceOptions as y, type DeviceProfile as z };
@@ -1,5 +1,5 @@
1
- import { z as DiscoveryMode, B as AuthMode, E as SignalingMode, F as ClientOptions, H as ExplicitFileDataSendParams, K as ISignalingBackend, N as RuntimeIdentity, A as AuthContext, O as RoomMember, Q as Device, T as DeviceStatusSnapshot, g as PeerSessionSnapshot, j as ResolvedPeerIdentity, U as ManagedConnectionRecord, V as SignalingEnvelope, W as DeviceEvent, X as DesiredPeerProjection, Y as SignalingSession, Z as SessionEvent, _ as LocalDeviceInfo, $ as NativeManagedSessionStartResult, c as ProtocolName, G as GrantScope, a0 as BackendPeerBiStream, a1 as BackendPeerUniStream, a2 as PortableMediaPublish, a3 as PortableMediaPublicationStart, a4 as PortableMediaSample, a5 as PortableMediaChunk, a6 as PortableMediaControl, a7 as NativeConnectParams, a8 as NativeConnectResult, a9 as BackendConnectionState, aa as NativePeerDataEvent } from './Connection-DZ5eP5hL.js';
2
- import { R as RuntimeCapabilities } from './capabilities-B2mHv_H7.js';
1
+ import { K as DiscoveryMode, N as AuthMode, O as SignalingMode, Q as ClientOptions, T as ExplicitFileDataSendParams, U as ISignalingBackend, V as RuntimeIdentity, F as AuthContext, W as RoomMember, X as Device, Y as DeviceStatusSnapshot, k as PeerSessionSnapshot, n as ResolvedPeerIdentity, Z as ManagedConnectionRecord, _ as SignalingEnvelope, $ as DeviceEvent, a0 as DesiredPeerProjection, a1 as SignalingSession, a2 as SessionEvent, a3 as LocalDeviceInfo, a4 as NativeManagedSessionStartResult, g as ProtocolName, G as GrantScope, a5 as BackendPeerBiStream, a6 as BackendPeerUniStream, a7 as PortableMediaPublish, a8 as PortableMediaPublicationStart, a9 as PortableMediaSample, aa as PortableMediaChunk, ab as PortableMediaControl, ac as NativeConnectParams, ad as NativeConnectResult, ae as BackendConnectionState, af as NativePeerDataEvent } from './Connection-CTpuImO-.js';
2
+ import { R as RuntimeCapabilities } from './capabilities-CmzzxSvW.js';
3
3
 
4
4
  /** Host-neutral configuration shared by browser/WASM and native/IPC adapters. */
5
5
  interface RuntimeBridgeOptions {
@@ -13,6 +13,10 @@ interface RuntimeBridgeOptions {
13
13
  coordinationGateway?: ClientOptions['coordinationGateway'];
14
14
  coordinationAvenueOverride?: ClientOptions['coordinationAvenueOverride'];
15
15
  coordinationRoomGossipFanout?: ClientOptions['coordinationRoomGossipFanout'];
16
+ coordinationRoomArchitecture?: ClientOptions['coordinationRoomArchitecture'];
17
+ coordinationDevicePublicKeyX?: ClientOptions['coordinationDevicePublicKeyX'];
18
+ coordinationDeviceSign?: ClientOptions['coordinationDeviceSign'];
19
+ initialAutoConnectExcludedDeviceIds?: ClientOptions['initialAutoConnectExcludedDeviceIds'];
16
20
  attestationTokenProvider?: ClientOptions['attestationTokenProvider'];
17
21
  /** Internal host hint used by the provider-neutral gateway projection. */
18
22
  coordinationPlatformType?: string;
@@ -73,7 +77,7 @@ declare abstract class DelegatingRuntimeAdapter implements ISignalingBackend {
73
77
  subscribeDevices(userId: string): Promise<ReadableStream<DeviceEvent[]>>;
74
78
  startAutoConnect(userId: string, localDeviceId: string): void;
75
79
  submitDesiredPeerProjection(revision: number, peers: DesiredPeerProjection[]): Promise<void>;
76
- startPresenceLoop(userId: string, localNodeId: string, deviceName: string, ticket: string, metadata?: string): void;
80
+ startPresenceLoop(userId: string, localNodeId: string, deviceName: string, ticket: string, metadata?: string): Promise<void>;
77
81
  createSession(session: SignalingSession): Promise<void>;
78
82
  updateSession(sessionId: string, updateData: any): Promise<void>;
79
83
  subscribeSessions(localDeviceId: string): Promise<ReadableStream<SessionEvent[]>>;
@@ -1,6 +1,6 @@
1
- import { R as RuntimeBridgeOptions, D as DelegatingRuntimeAdapter } from './DelegatingRuntimeAdapter-4cgiIWMN.js';
1
+ import { R as RuntimeBridgeOptions, D as DelegatingRuntimeAdapter } from './DelegatingRuntimeAdapter-D67Ozqo3.js';
2
2
  import { P as PlutoIpcBridge } from './ipc-DgzKqHH3.js';
3
- import { a9 as BackendConnectionState, aa as NativePeerDataEvent } from './Connection-DZ5eP5hL.js';
3
+ import { ae as BackendConnectionState, af as NativePeerDataEvent } from './Connection-CTpuImO-.js';
4
4
 
5
5
  interface NativeIpcBridgeOptions extends RuntimeBridgeOptions {
6
6
  ipcBridge?: PlutoIpcBridge;
@@ -21,6 +21,12 @@ interface NativeIpcBridgeOptions extends RuntimeBridgeOptions {
21
21
  interface NativeProjectionHost {
22
22
  incoming_projected_streams(): Promise<ReadableStream<NativeRootProjectionEvent>>;
23
23
  isCurrentTransport(endpointId: string, transportStableId: bigint): Promise<boolean>;
24
+ /**
25
+ * Drop the process-owned Tauri projection Channel. Required because an
26
+ * errored ReadableStream does not run its cancel algorithm, so listen-loop
27
+ * or pump faults would otherwise leave Rust claiming the sole owner slot.
28
+ */
29
+ releaseNativeProjectionSubscription?(): Promise<void>;
24
30
  }
25
31
  interface NativeProjectedStreamSource {
26
32
  readonly __openrtcNativeCapabilityProjection: true;
@@ -0,0 +1 @@
1
+ export{b as WasmBridge,a as loadBrowserWasmRuntimeModule}from'./chunk-EIJNERKZ.js';import'./chunk-AYHD4X2R.js';import'./chunk-GTHSRQ7Y.js';import'./chunk-XTYALGJN.js';import'./chunk-OT7IPLZE.js';import'./chunk-OWKAJPOI.js';import'./chunk-CCCYE3XN.js';import'./chunk-N6LGTNUI.js';import'./chunk-JPBW67B3.js';import'./chunk-2GX6GB6L.js';
@@ -1,5 +1,5 @@
1
- import { d as RuntimePeerState, n as ConnectionState, h as PeerReadiness, e as PeerConnectOptions, f as Connection, I as IncomingStream, G as GrantScope, y as RuntimeClientOptions, K as ISignalingBackend, ap as RuntimeAuthIdentity, A as AuthContext, c as ProtocolName, L as LocalDeviceInfo, v as DeviceProfile, ae as BrowserProtocolStore, af as NamespaceDescriptor, ag as IrohMutationReceipt, ah as IrohDocEntry, l as RuntimeDevice, M as ManagedOptions, q as ManagedSession, D as DeviceStatus, t as ConnectDeviceHooks, u as ConnectDeviceOptions, s as ConnectDeviceResult, r as DeviceConnectOptions, U as ManagedConnectionRecord, g as PeerSessionSnapshot, j as ResolvedPeerIdentity, aq as RuntimeSession, ar as AppLimits, J as JoinRoomOptions, x as RuntimeRoomMember, as as ConnectionTarget, S as ScopedChannelOptions, m as ScopedLogicalChannel, k as PeerStreamOptions, a7 as NativeConnectParams, a8 as NativeConnectResult, w as RawConnection, C as ChannelDescriptor, H as ExplicitFileDataSendParams, at as PresenceLoopOptions, i as RuntimePeerHealth, o as ReadinessOptions, p as ConnectionEvent } from './Connection-DZ5eP5hL.js';
2
- import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-B2mHv_H7.js';
1
+ import { h as RuntimePeerState, r as ConnectionState, l as PeerReadiness, i as PeerConnectOptions, j as Connection, I as IncomingStream, G as GrantScope, H as RuntimeClientOptions, U as ISignalingBackend, aw as RuntimeAuthIdentity, F as AuthContext, g as ProtocolName, L as LocalDeviceInfo, z as DeviceProfile, aj as BrowserProtocolStore, ak as NamespaceDescriptor, al as IrohMutationReceipt, am as IrohDocEntry, p as RuntimeDevice, M as ManagedOptions, u as ManagedSession, D as DeviceStatus, x as ConnectDeviceHooks, y as ConnectDeviceOptions, w as ConnectDeviceResult, v as DeviceConnectOptions, Z as ManagedConnectionRecord, k as PeerSessionSnapshot, n as ResolvedPeerIdentity, ax as RuntimeSession, ay as AppLimits, J as JoinRoomOptions, B as RuntimeRoomMember, az as ConnectionTarget, S as ScopedChannelOptions, q as ScopedLogicalChannel, o as PeerStreamOptions, ac as NativeConnectParams, ad as NativeConnectResult, A as RawConnection, C as ChannelDescriptor, T as ExplicitFileDataSendParams, aA as PresenceLoopOptions, b as RoomArchitectureSnapshot, c as RoomAuthorityAssignment, m as RuntimePeerHealth, s as ReadinessOptions, t as ConnectionEvent } from './Connection-CTpuImO-.js';
2
+ import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-CmzzxSvW.js';
3
3
 
4
4
  /**
5
5
  * Coalesced peer reconciliation scheduler and full reconcile orchestration.
@@ -618,7 +618,12 @@ declare class RuntimeClient {
618
618
  startAutoConnect(localDeviceId?: string): Promise<void>;
619
619
  isConnected(nodeId: string): Promise<boolean>;
620
620
  disconnectNode(nodeId: string): Promise<void>;
621
+ recordSparseFanoutForwardQueueDrop(capability: string, count: number): Promise<void>;
621
622
  disconnectDevice(deviceId: string): Promise<void>;
623
+ /** Observe the gateway-owned room policy without taking topology ownership. */
624
+ onRoomArchitectureChange(callback: (snapshot: RoomArchitectureSnapshot) => void): () => void;
625
+ /** Observe signed authority interest without taking routing ownership. */
626
+ onRoomAuthorityAssignmentChange(callback: (assignment: RoomAuthorityAssignment | null) => void): () => void;
622
627
  excludeAutoConnect(deviceId: string, excluded: boolean): Promise<void>;
623
628
  disconnectPeer(id: string, scope?: string): Promise<void>;
624
629
  forceDisconnectPeer(id: string): Promise<void>;
@@ -1,8 +1,17 @@
1
- import { c as ProtocolName, R as RouteOptimization } from './Connection-DZ5eP5hL.js';
1
+ import { g as ProtocolName, f as RouteOptimization } from './Connection-CTpuImO-.js';
2
2
 
3
3
  type RuntimeAdapterKind = 'browser-wasm' | 'native-ipc' | 'tauri-ipc' | 'unknown';
4
+ type CapabilityMaturity = 'stable' | 'preview' | 'support-only' | 'unavailable';
5
+ interface ProductCapabilityMaturity {
6
+ boundedRooms: CapabilityMaturity;
7
+ serviceNodes: CapabilityMaturity;
8
+ offlineEdge: CapabilityMaturity;
9
+ broadcast: CapabilityMaturity;
10
+ }
4
11
  interface RuntimeCapabilities {
5
12
  adapter: RuntimeAdapterKind;
13
+ /** Product support facts reported by the runtime owner. */
14
+ productMaturity?: ProductCapabilityMaturity;
6
15
  signaling: {
7
16
  coordinationGateway: boolean;
8
17
  nativeIpc: boolean;
@@ -40,6 +49,7 @@ interface RuntimeCapabilities {
40
49
  }
41
50
  interface CapabilityProfile {
42
51
  environment: 'web' | 'native' | 'unknown';
52
+ productMaturity?: ProductCapabilityMaturity;
43
53
  transports: {
44
54
  quic: boolean;
45
55
  irohRelay: boolean;
@@ -63,6 +73,7 @@ interface NativeRuntimeStatus {
63
73
  ready?: boolean;
64
74
  nodeId?: string | null;
65
75
  node_id?: string | null;
76
+ productMaturity?: Partial<ProductCapabilityMaturity>;
66
77
  transport?: {
67
78
  irohQuic?: TransportStatus;
68
79
  irohLan?: TransportStatus;
@@ -98,4 +109,4 @@ declare function browserCapabilities(host?: CapabilityHost | null | undefined):
98
109
  declare function statusCapabilities(status: NativeRuntimeStatus | null | undefined, allowWasmFallback?: boolean): RuntimeCapabilities;
99
110
  declare function capabilityProfile(capabilities: RuntimeCapabilities): CapabilityProfile;
100
111
 
101
- export { BROWSER_CAPABILITIES as B, type CapabilityProfile as C, NATIVE_CAPABILITIES as N, type RuntimeCapabilities as R, type TransportStatus as T, type CapabilityHost as a, type NativeRuntimeStatus as b, type RuntimeAdapterKind as c, browserCapabilities as d, capabilityProfile as e, cloneCapabilities as f, statusCapabilities as s };
112
+ export { BROWSER_CAPABILITIES as B, type CapabilityProfile as C, NATIVE_CAPABILITIES as N, type ProductCapabilityMaturity as P, type RuntimeCapabilities as R, type TransportStatus as T, type CapabilityHost as a, type CapabilityMaturity as b, type NativeRuntimeStatus as c, type RuntimeAdapterKind as d, browserCapabilities as e, capabilityProfile as f, cloneCapabilities as g, statusCapabilities as s };