openrtc 0.1.2 → 0.2.0
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.
- package/README.md +26 -3
- package/dist/DelegatingRuntimeAdapter-CjHzBEBA.d.ts +180 -0
- package/dist/{IpcRuntimeAdapter-CT-W0Mtp.d.ts → IpcRuntimeAdapter-CtckyMol.d.ts} +2 -1
- package/dist/auth/index.js +1 -1
- package/dist/auth/internal.js +1 -1
- package/dist/chunk-3VTF5RKW.js +1 -0
- package/dist/chunk-JXGKO7SX.js +1 -0
- package/dist/chunk-MFT6SOZ6.js +3 -0
- package/dist/chunk-SGZWR63E.js +1 -0
- package/dist/chunk-VARALO7G.js +1 -0
- package/dist/chunk-WOHFM6DI.js +2 -0
- package/dist/chunk-YHJOXD46.js +2 -0
- package/dist/{factories-0TxDPMeu.d.ts → factories-CwZiIRg1.d.ts} +412 -226
- package/dist/index.d.ts +100 -6
- package/dist/index.js +2 -1
- package/dist/openrtc_bg.wasm +0 -0
- package/dist/runtime/WasmRuntimeAdapter.d.ts +2 -1
- package/dist/runtime/WasmRuntimeAdapter.js +1 -1
- package/dist/runtime/index.d.ts +205 -391
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/tauri.d.ts +5 -6
- package/dist/runtime/tauri.js +1 -1
- package/dist/transport/index.d.ts +11 -0
- package/dist/transport/index.js +1 -0
- package/dist/{DelegatingRuntimeAdapter-CW8d78dZ.d.ts → types-DyCGvj9l.d.ts} +200 -170
- package/package.json +12 -10
- package/dist/chunk-4MH42GUI.js +0 -2
- package/dist/chunk-CQAKCS2S.js +0 -4
- package/dist/chunk-D54VGRRH.js +0 -1
- package/dist/chunk-DIQYFAGL.js +0 -2
- package/dist/chunk-PZ25OCVG.js +0 -2
- package/dist/chunk-UVASANPG.js +0 -1
- package/wasm/README.md +0 -64
- package/wasm/openrtc.d.ts +0 -320
- package/wasm/openrtc.js +0 -2290
- package/wasm/openrtc_bg.wasm +0 -0
- package/wasm/openrtc_bg.wasm.d.ts +0 -113
- package/wasm/package.json +0 -16
|
@@ -1,145 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { P as
|
|
1
|
+
import { A as AuthContext, R as RuntimeCapabilities, a as RuntimeCapabilityProfile } from './DelegatingRuntimeAdapter-CjHzBEBA.js';
|
|
2
|
+
import { J as ConnectionOptions, q as ApplicationPayloadCrypto, v as ApplicationPayloadReadinessOptions, w as ApplicationPayloadRouteOptions, n as ProtocolName, x as ApplicationPayloadSendOptions, K as ChannelDescriptor$1, L as LocalDeviceInfo, O as IncomingStreamChannelMetadata, C as ClientOptions, a as Device, f as SignalingSession, R as RuntimeIdentity, b as DeviceStatusSnapshot, Q as ManagedDeviceConnectOptions, T as PeerState, U as PeerHealth, V as JoinRoomOptions, W as RoomMember, X as PeerScope, j as BackendConnectionState, Y as PeerLifecycleStatus, P as PeerSessionSnapshot, G as GrantScope, I as ISignalingBackend, l as ConnectDeviceHooks, m as ConnectDeviceOptions, k as ConnectDeviceResult, M as ManagedConnectionRecord, c as ResolvedPeerIdentity, t as AppLimits, i as NativeConnectResult, E as ExplicitFileDataSendParams } from './types-DyCGvj9l.js';
|
|
3
|
+
import { P as PlutoIpcBridge, I as IpcRuntimeAdapter } from './IpcRuntimeAdapter-CtckyMol.js';
|
|
3
4
|
import { WasmRuntimeAdapter } from './runtime/WasmRuntimeAdapter.js';
|
|
4
5
|
|
|
5
|
-
/**
|
|
6
|
-
* App-facing options intentionally hide transport node identifiers from callbacks.
|
|
7
|
-
*/
|
|
8
|
-
type RuntimeClientOptions = Omit<ClientOptions, 'onDevices' | 'onAutoConnect' | 'onIncomingSession'> & {
|
|
9
|
-
onDevices?: (devices: RuntimeDevice[]) => void;
|
|
10
|
-
onAutoConnect?: (devices: RuntimeDevice[]) => void;
|
|
11
|
-
onIncomingSession?: (session: RuntimeSession) => Promise<void>;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* App-facing device model. Runtime transport identifiers stay internal.
|
|
15
|
-
*/
|
|
16
|
-
type RuntimeDevice = Omit<Device, 'nodeId'>;
|
|
17
|
-
/**
|
|
18
|
-
* App-facing session model. Node identifiers are runtime-internal metadata.
|
|
19
|
-
*/
|
|
20
|
-
type RuntimeSession = Omit<SignalingSession, 'initiatorNodeId' | 'targetNodeId' | 'appTag'>;
|
|
21
|
-
type RuntimeAuthIdentity = RuntimeIdentity;
|
|
22
|
-
type RuntimeAuthContext = AuthContext;
|
|
23
|
-
/**
|
|
24
|
-
* App-facing peer state model. Runtime transport identifiers stay internal.
|
|
25
|
-
*/
|
|
26
|
-
type RuntimePeerState = Omit<PeerState, 'nodeId'>;
|
|
27
|
-
type RuntimePeerHealth = PeerHealth;
|
|
28
|
-
type RuntimePeerLifecycleStatus = PeerLifecycleStatus;
|
|
29
|
-
type RuntimePeerScope = PeerScope;
|
|
30
|
-
/**
|
|
31
|
-
* App-facing peer session snapshot model. Runtime transport identifiers stay internal.
|
|
32
|
-
*/
|
|
33
|
-
type RuntimePeerSessionSnapshot = Omit<PeerSessionSnapshot, 'nodeId'>;
|
|
34
|
-
type RuntimeLocalDeviceInfo = LocalDeviceInfo;
|
|
35
|
-
type RuntimeRoomMember = RoomMember;
|
|
36
|
-
type RuntimeDeviceConnectOptions = ManagedDeviceConnectOptions;
|
|
37
|
-
type RuntimeJoinRoomOptions = JoinRoomOptions;
|
|
38
|
-
type RuntimeChannelDescriptor = ChannelDescriptor$1;
|
|
39
|
-
interface RuntimeConnectionTarget {
|
|
40
|
-
ticket: string;
|
|
41
|
-
timeoutMs?: number;
|
|
42
|
-
}
|
|
43
|
-
interface RuntimePeerConnectOptions {
|
|
44
|
-
deviceId?: string;
|
|
45
|
-
ticket?: string;
|
|
46
|
-
scope?: RuntimePeerScope;
|
|
47
|
-
channelId?: string;
|
|
48
|
-
}
|
|
49
|
-
interface RuntimePeerStreamOptions {
|
|
50
|
-
ticket?: string;
|
|
51
|
-
scope?: RuntimePeerScope;
|
|
52
|
-
channelId?: string;
|
|
53
|
-
timeoutMs?: number;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* App-facing device status snapshot model. Runtime transport identifiers stay internal.
|
|
57
|
-
*/
|
|
58
|
-
type RuntimeDeviceStatusSnapshot = Omit<DeviceStatusSnapshot, 'nodeId'>;
|
|
59
|
-
type RuntimeDeviceStatus = RuntimeDeviceStatusSnapshot;
|
|
60
|
-
type RuntimeIncomingStream = {
|
|
61
|
-
type: 'bi' | 'uni';
|
|
62
|
-
stream: any;
|
|
63
|
-
remoteNodeId: string;
|
|
64
|
-
protocolHint?: 'control' | 'explicit' | 'native-main' | 'unknown';
|
|
65
|
-
channel?: IncomingStreamChannelMetadata | null;
|
|
66
|
-
};
|
|
67
|
-
type RuntimeConnectionEvent = {
|
|
68
|
-
type: 'connected' | 'disconnected';
|
|
69
|
-
connectionId: string;
|
|
70
|
-
localNodeId: string;
|
|
71
|
-
remoteNodeId: string;
|
|
72
|
-
transport: ProtocolName;
|
|
73
|
-
};
|
|
74
|
-
type RuntimeRawConnection = {
|
|
75
|
-
connectionId: string;
|
|
76
|
-
localNodeId: string;
|
|
77
|
-
remoteNodeId: string;
|
|
78
|
-
};
|
|
79
|
-
type RuntimePresenceLoopOptions = {
|
|
80
|
-
deviceName?: string;
|
|
81
|
-
ticket?: string;
|
|
82
|
-
metadata?: string;
|
|
83
|
-
};
|
|
84
|
-
type RuntimeManagedSessionPlatform = 'native' | 'web';
|
|
85
|
-
type RuntimeManagedSessionKind = 'app-user-device' | 'share-anonymous' | 'drive-grant-guest' | 'scoped-guest' | (string & {});
|
|
86
|
-
type RuntimeAutoConnectPolicy = 'enabled' | 'disabled' | 'scoped-only';
|
|
87
|
-
type RuntimePresencePolicy = 'online' | 'disabled';
|
|
88
|
-
type RuntimeConnectionStateSnapshot = BackendConnectionState;
|
|
89
|
-
type RuntimeUiConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'failed';
|
|
90
|
-
interface RuntimePeerReadinessSnapshot {
|
|
91
|
-
requestedId: string;
|
|
92
|
-
connected: boolean;
|
|
93
|
-
settledReady: boolean;
|
|
94
|
-
status: RuntimeUiConnectionStatus;
|
|
95
|
-
health: RuntimePeerHealth | 'unknown';
|
|
96
|
-
deviceId?: string | null;
|
|
97
|
-
deviceIdHint?: string | null;
|
|
98
|
-
activeConnectionId?: string | null;
|
|
99
|
-
readinessState?: string;
|
|
100
|
-
readinessReason?: string;
|
|
101
|
-
scopes: string[];
|
|
102
|
-
}
|
|
103
|
-
interface RuntimeLocalDeviceProfile {
|
|
104
|
-
deviceId: string | null;
|
|
105
|
-
deviceName: string;
|
|
106
|
-
platformType: string;
|
|
107
|
-
userId: string | null;
|
|
108
|
-
capabilities: NonNullable<RuntimeLocalDeviceInfo['capabilities']>;
|
|
109
|
-
lastSeenAt: string;
|
|
110
|
-
localNodeId?: string | null;
|
|
111
|
-
}
|
|
112
|
-
interface RuntimeManagedSessionOptions {
|
|
113
|
-
platform: RuntimeManagedSessionPlatform;
|
|
114
|
-
sessionKind?: RuntimeManagedSessionKind;
|
|
115
|
-
scope?: string | null;
|
|
116
|
-
autoConnectPolicy?: RuntimeAutoConnectPolicy;
|
|
117
|
-
presencePolicy?: RuntimePresencePolicy;
|
|
118
|
-
userId?: string | null;
|
|
119
|
-
deviceName?: string;
|
|
120
|
-
localDeviceId?: string | null;
|
|
121
|
-
metadata?: string;
|
|
122
|
-
autoConnect?: boolean;
|
|
123
|
-
presence?: boolean;
|
|
124
|
-
}
|
|
125
|
-
interface RuntimeManagedSession {
|
|
126
|
-
mode: RuntimeManagedSessionPlatform;
|
|
127
|
-
device: RuntimeLocalDeviceProfile;
|
|
128
|
-
stop: () => Promise<void>;
|
|
129
|
-
}
|
|
130
|
-
type ConnectionTarget = RuntimeConnectionTarget;
|
|
131
|
-
type PeerConnectOptions = RuntimePeerConnectOptions;
|
|
132
|
-
type PeerStreamOptions = RuntimePeerStreamOptions;
|
|
133
|
-
type IncomingStream = RuntimeIncomingStream;
|
|
134
|
-
type ConnectionEvent = RuntimeConnectionEvent;
|
|
135
|
-
type RawConnection = RuntimeRawConnection;
|
|
136
|
-
type PresenceLoopOptions = RuntimePresenceLoopOptions;
|
|
137
|
-
type PeerReadiness = RuntimePeerReadinessSnapshot;
|
|
138
|
-
type DeviceProfile = RuntimeLocalDeviceProfile;
|
|
139
|
-
type SessionOptions$1 = RuntimeManagedSessionOptions;
|
|
140
|
-
type Session$1 = RuntimeManagedSession;
|
|
141
|
-
type ChannelDescriptor = RuntimeChannelDescriptor;
|
|
142
|
-
|
|
143
6
|
interface ITransport {
|
|
144
7
|
readonly name: string;
|
|
145
8
|
readonly isReady: boolean;
|
|
@@ -163,16 +26,21 @@ declare class Connection {
|
|
|
163
26
|
private static readonly textEncoder;
|
|
164
27
|
private static readonly UPGRADE_RETRY_DELAY_MS;
|
|
165
28
|
private static readonly MAX_UPGRADE_RETRIES;
|
|
29
|
+
private static readonly MAX_UPGRADE_REDRIVES;
|
|
30
|
+
private static readonly UPGRADE_REDRIVE_DELAY_MS;
|
|
166
31
|
private static readonly WEBRTC_DISCONNECTED_GRACE_MS;
|
|
167
32
|
private static readonly MAX_PENDING_MESSAGES;
|
|
33
|
+
private static readonly DEFAULT_APPLICATION_CRYPTO_WAIT_MS;
|
|
168
34
|
/**
|
|
169
35
|
* Must exceed `WEBRTC_ICE_CONNECT_TIMEOUT_MS` in `WebRTCTransport`: the transport
|
|
170
36
|
* waits that long for ICE + DataChannel before `failed`. A shorter watchdog here
|
|
171
37
|
* tears the PC down early, burns `MAX_UPGRADE_RETRIES`, and stretches upgrades to ~60s+ under load.
|
|
172
38
|
*/
|
|
173
39
|
private static readonly WEBRTC_UPGRADE_ATTEMPT_TIMEOUT_MS;
|
|
40
|
+
private static readonly MAX_PENDING_ENCRYPTED_APPLICATION_PAYLOADS;
|
|
174
41
|
private listeners;
|
|
175
42
|
private pendingMessages;
|
|
43
|
+
private pendingEncryptedApplicationPayloads;
|
|
176
44
|
private webrtcBinaryHandlers;
|
|
177
45
|
private closeListeners;
|
|
178
46
|
private upgradeStateListeners;
|
|
@@ -188,34 +56,61 @@ declare class Connection {
|
|
|
188
56
|
readonly localNodeId: string;
|
|
189
57
|
private options;
|
|
190
58
|
private writeMutex;
|
|
59
|
+
private applicationCryptoWaiters;
|
|
191
60
|
private nativeSignalSender;
|
|
192
61
|
private webrtcTransport;
|
|
62
|
+
private webRtcApplicationRouteReadyTransport;
|
|
63
|
+
private webRtcApplicationRouteReadyNegotiationId;
|
|
193
64
|
private upgradeState;
|
|
194
65
|
private upgradeRequested;
|
|
66
|
+
private negotiationSwitchCount;
|
|
195
67
|
private upgradeAttemptActive;
|
|
196
68
|
private upgradeRetryCount;
|
|
69
|
+
private upgradeReDriveCount;
|
|
70
|
+
private upgradeReDriveTimer;
|
|
197
71
|
private upgradeRetryTimer;
|
|
198
72
|
private upgradeAttemptTimeoutTimer;
|
|
199
73
|
private lastReportedTransportStatus;
|
|
74
|
+
private applicationRouteMissingNotified;
|
|
200
75
|
private upgradeTerminalFailure;
|
|
201
76
|
private pendingSignals;
|
|
202
77
|
private activeNegotiationId;
|
|
203
78
|
private webrtcHeartbeat;
|
|
204
79
|
private webRtcHeartbeatProbeInFlight;
|
|
80
|
+
private webRtcApplicationRouteProbeInFlight;
|
|
205
81
|
private webRtcHeartbeatConsecutiveProbeFailures;
|
|
206
82
|
private irohHealthListeners;
|
|
207
83
|
private webrtcHealthListeners;
|
|
208
84
|
private lastWebRtcHeartbeatOkAt;
|
|
209
85
|
private lastWebRtcDataChannelOpenAt;
|
|
86
|
+
private static readonly WEBRTC_RENEGOTIATE_LIVENESS_WINDOW_MS;
|
|
87
|
+
private static readonly MAX_NEGOTIATION_SWITCHES;
|
|
210
88
|
private lastForegroundAt;
|
|
211
89
|
private webRtcDisconnectedGraceTimer;
|
|
212
90
|
private preferredWebRtcRole;
|
|
213
91
|
constructor(id: string, localNodeId: string, remoteNodeId: string, writer: WritableStreamDefaultWriter<Uint8Array>, reader: ReadableStreamDefaultReader<Uint8Array>, options?: ConnectionOptions);
|
|
92
|
+
setApplicationCrypto(applicationCrypto: ApplicationPayloadCrypto | undefined): void;
|
|
93
|
+
requireApplicationCrypto(): void;
|
|
94
|
+
isApplicationCryptoRequired(): boolean;
|
|
95
|
+
isReadyForApplicationPayload(options?: ApplicationPayloadReadinessOptions): boolean;
|
|
96
|
+
getApplicationPayloadTransports(options?: ApplicationPayloadRouteOptions): ProtocolName[];
|
|
97
|
+
private isTransportAvailableForApplicationPayload;
|
|
98
|
+
private resolveApplicationCryptoWaiters;
|
|
99
|
+
private rejectApplicationCryptoWaiters;
|
|
100
|
+
private waitForRequiredApplicationCrypto;
|
|
214
101
|
/**
|
|
215
102
|
* Starts WebRTC upgrade only when peer capability negotiation allows it.
|
|
216
103
|
* No-op when WebRTC is not configured or an upgrade already started.
|
|
217
104
|
*/
|
|
218
105
|
requestWebRTCUpgrade(reason?: string): void;
|
|
106
|
+
/**
|
|
107
|
+
* Whether the current WebRTC route is provably alive: an open data channel
|
|
108
|
+
* plus either a recent heartbeat round trip or a freshly opened channel. An
|
|
109
|
+
* `open` readyState alone is not proof — it lingers for many seconds after the
|
|
110
|
+
* remote vanishes (e.g. a page reload), so a dead-but-`open` channel reports
|
|
111
|
+
* not-live and can be replaced rather than trusted.
|
|
112
|
+
*/
|
|
113
|
+
private isWebRtcRouteHeartbeatLive;
|
|
219
114
|
requestTransportRecovery(reason: string, options?: {
|
|
220
115
|
forceRenegotiate?: boolean;
|
|
221
116
|
replaceExisting?: boolean;
|
|
@@ -248,6 +143,8 @@ declare class Connection {
|
|
|
248
143
|
candidateTypeSummary: string | null;
|
|
249
144
|
} | null;
|
|
250
145
|
}>;
|
|
146
|
+
private lastWebRtcLocalCandidateType;
|
|
147
|
+
private lastWebRtcRemoteCandidateType;
|
|
251
148
|
get transportType(): ProtocolName;
|
|
252
149
|
private _peerMoQReady;
|
|
253
150
|
get peerMoQReady(): boolean;
|
|
@@ -260,7 +157,7 @@ declare class Connection {
|
|
|
260
157
|
* Send a message to the other peer.
|
|
261
158
|
* Messages can be strings or objects (JSON stringified).
|
|
262
159
|
*/
|
|
263
|
-
send(message: string | object | ArrayBuffer | Uint8Array): Promise<void>;
|
|
160
|
+
send(message: string | object | ArrayBuffer | Uint8Array, options?: ApplicationPayloadSendOptions): Promise<void>;
|
|
264
161
|
/**
|
|
265
162
|
* Send media data (video/audio header + payload)
|
|
266
163
|
* Internal use for now.
|
|
@@ -271,24 +168,41 @@ declare class Connection {
|
|
|
271
168
|
* Throws when the requested transport is unavailable.
|
|
272
169
|
*/
|
|
273
170
|
sendOnTransport(transport: ProtocolName, message: string | object | ArrayBuffer | Uint8Array): Promise<void>;
|
|
171
|
+
/**
|
|
172
|
+
* Send plaintext control traffic that is required to bootstrap application
|
|
173
|
+
* key agreement. This is intentionally separate from public app-data sends.
|
|
174
|
+
*/
|
|
175
|
+
sendControl(message: string | object | ArrayBuffer | Uint8Array): Promise<void>;
|
|
274
176
|
/**
|
|
275
177
|
* Write an already-framed payload directly on the underlying iroh control stream.
|
|
276
178
|
* Used by native-main signaling paths that must preserve protocol framing.
|
|
277
179
|
*/
|
|
278
180
|
sendRawIrohFrame(frame: Uint8Array): Promise<void>;
|
|
279
181
|
/**
|
|
280
|
-
*
|
|
182
|
+
* Compatibility/diagnostic view of currently usable transports.
|
|
183
|
+
*
|
|
184
|
+
* Lifecycle projection and route selection must use getTransportStatus().
|
|
185
|
+
* This legacy list intentionally remains for older callers and tests that
|
|
186
|
+
* need a human-readable inventory, but it is not an authority for active
|
|
187
|
+
* versus fallback transport state.
|
|
281
188
|
*/
|
|
282
189
|
getAvailableTransports(): ProtocolName[];
|
|
283
190
|
onWebRTCBinaryMessage(handler: (data: Uint8Array) => boolean): void;
|
|
191
|
+
private dispatchWebRtcBinaryHandlers;
|
|
284
192
|
getWebRTCTransport(): ITransport | null;
|
|
285
193
|
sendOnWebRTC(data: Uint8Array): Promise<void>;
|
|
286
194
|
private encodePayload;
|
|
195
|
+
private protectApplicationPayload;
|
|
196
|
+
private openApplicationPayload;
|
|
197
|
+
private openUntypedApplicationPayload;
|
|
198
|
+
private queueEncryptedApplicationPayload;
|
|
199
|
+
private flushPendingEncryptedApplicationPayloads;
|
|
287
200
|
private buildFrame;
|
|
288
201
|
private sendOverIroh;
|
|
289
202
|
private sendUsingTransport;
|
|
290
203
|
private sendTypedOnTransport;
|
|
291
204
|
private sendTyped;
|
|
205
|
+
private getSendTransportPriorities;
|
|
292
206
|
/**
|
|
293
207
|
* Disconnect the connection
|
|
294
208
|
*/
|
|
@@ -310,6 +224,7 @@ declare class Connection {
|
|
|
310
224
|
private readLoop;
|
|
311
225
|
injectData(chunk: Uint8Array): void;
|
|
312
226
|
private handleData;
|
|
227
|
+
private tryHandlePlaintextNativeSignal;
|
|
313
228
|
private static isUntypedDataFrame;
|
|
314
229
|
private processDataPayload;
|
|
315
230
|
private isLikelyTextPayload;
|
|
@@ -318,6 +233,8 @@ declare class Connection {
|
|
|
318
233
|
receiveMessage(msg: any): void;
|
|
319
234
|
receiveDataPayload(messageData: Uint8Array): void;
|
|
320
235
|
private trackListeners;
|
|
236
|
+
private warnedSrtpApplicationCryptoBoundary;
|
|
237
|
+
private warnSrtpApplicationCryptoBoundary;
|
|
321
238
|
addTrack(track: MediaStreamTrack): RTCRtpSender | null;
|
|
322
239
|
addTransceiver(trackOrKind: MediaStreamTrack | string, init?: RTCRtpTransceiverInit): RTCRtpTransceiver | null;
|
|
323
240
|
onTrack(callback: (event: RTCTrackEvent) => void): void;
|
|
@@ -325,10 +242,12 @@ declare class Connection {
|
|
|
325
242
|
private isWebRtcDataChannelOpen;
|
|
326
243
|
private clearWebRtcDisconnectedGraceTimer;
|
|
327
244
|
private transportStillLikelyAlive;
|
|
328
|
-
private
|
|
245
|
+
private handleUnhealthyWebRtcTransportStateWithGrace;
|
|
329
246
|
private attemptUpgrade;
|
|
330
247
|
private setUpgradeState;
|
|
331
248
|
private handleUpgradeFailure;
|
|
249
|
+
private scheduleUpgradeReDrive;
|
|
250
|
+
private clearUpgradeReDriveTimer;
|
|
332
251
|
private shouldRetryUpgrade;
|
|
333
252
|
private scheduleUpgradeRetry;
|
|
334
253
|
private clearUpgradeRetryTimer;
|
|
@@ -337,14 +256,74 @@ declare class Connection {
|
|
|
337
256
|
private teardownWebRTCTransport;
|
|
338
257
|
private startWebRtcHeartbeat;
|
|
339
258
|
private stopWebRtcHeartbeat;
|
|
259
|
+
private notifyWebRtcApplicationRouteMissing;
|
|
260
|
+
private startWebRtcApplicationRouteProbe;
|
|
340
261
|
private sendIrohHeartbeatPong;
|
|
341
262
|
/** Register a listener for WebRTC heartbeat health changes. */
|
|
342
263
|
onWebRtcHeartbeatHealth(cb: (health: ConnectionHealth) => void): void;
|
|
343
264
|
/** Register a listener for iroh heartbeat health changes (WASM path). */
|
|
344
265
|
onIrohHeartbeatHealth(cb: (health: ConnectionHealth) => void): void;
|
|
345
266
|
reportTransportStatusIfChanged(): void;
|
|
267
|
+
/**
|
|
268
|
+
* Single connection-owned transport snapshot for status reporting,
|
|
269
|
+
* lifecycle projection, and diagnostics. The active route is application
|
|
270
|
+
* ready; the parallel route is its usable fallback or candidate.
|
|
271
|
+
*/
|
|
272
|
+
getTransportStatus(): {
|
|
273
|
+
activeTransport: ProtocolName;
|
|
274
|
+
parallelTransport: ProtocolName | null;
|
|
275
|
+
};
|
|
346
276
|
private resolveParallelTransport;
|
|
347
277
|
setNativeSignalSender(sender: (envelope: any) => Promise<void>): void;
|
|
278
|
+
/**
|
|
279
|
+
* Structured connection-lifecycle log. One event per meaningful transition
|
|
280
|
+
* (upgrade requested/started/failed, route promoted, app route ready, …) with
|
|
281
|
+
* the connection's current lifecycle snapshot, so the whole connection flow
|
|
282
|
+
* can be reconstructed from logs. Emits both a human line and a JSON line.
|
|
283
|
+
*/
|
|
284
|
+
private traceLifecycle;
|
|
285
|
+
getControlFrameMode(): NonNullable<ConnectionOptions['controlFrameMode']>;
|
|
286
|
+
/**
|
|
287
|
+
* Send a control envelope over the native-main signal route. Returns false
|
|
288
|
+
* (without sending) unless this connection is in `native-main` control-frame
|
|
289
|
+
* mode and has a native signal sender, so a typed connection never
|
|
290
|
+
* accidentally routes control through the native sender.
|
|
291
|
+
*/
|
|
292
|
+
sendNativeControlEnvelope(envelope: any): Promise<boolean>;
|
|
293
|
+
/**
|
|
294
|
+
* Promote a connection to the native-main control plane: switch its
|
|
295
|
+
* control-frame mode to `native-main` and attach the native signal sender.
|
|
296
|
+
* Used when native-main evidence arrives for a connection that bootstrapped
|
|
297
|
+
* on a typed stream, so subsequent control traffic flows over the durable
|
|
298
|
+
* native-main route even if the bootstrap stream later closes.
|
|
299
|
+
*/
|
|
300
|
+
promoteToNativeMainControlRoute(sender: (envelope: any) => Promise<void>): void;
|
|
301
|
+
private hasRequiredApplicationCrypto;
|
|
302
|
+
private clearWebRtcApplicationRouteReady;
|
|
303
|
+
private isCurrentWebRtcTransportApplicationRouteReady;
|
|
304
|
+
private isWebRtcApplicationRouteReadyForTransport;
|
|
305
|
+
/**
|
|
306
|
+
* Mark the upgraded WebRTC data plane as carrying a proven application route
|
|
307
|
+
* (data channel open + required crypto present). Idempotent. Promotes the
|
|
308
|
+
* active transport projection to `webrtc` via reportTransportStatusIfChanged.
|
|
309
|
+
*/
|
|
310
|
+
private markWebRtcApplicationRouteReady;
|
|
311
|
+
/**
|
|
312
|
+
* True only when the WebRTC transport is upgraded AND its application route
|
|
313
|
+
* is proven (crypto present). The active route must not advertise `webrtc`
|
|
314
|
+
* until this holds, so a half-open data channel never looks routable.
|
|
315
|
+
*/
|
|
316
|
+
isWebRtcApplicationRouteReady(): boolean;
|
|
317
|
+
/**
|
|
318
|
+
* MoQ has a different data-plane shape than WebRTC: it is a shared relay
|
|
319
|
+
* session on the Client plus a peer capability/subscription bit on this
|
|
320
|
+
* Connection. Even so, it follows the same lifecycle invariant as every
|
|
321
|
+
* custom transport: do not advertise it as the active application route until
|
|
322
|
+
* the local transport is ready, the peer route is enabled, and the required
|
|
323
|
+
* application crypto is available. Future MoQ route probes should tighten
|
|
324
|
+
* this predicate, not bypass it.
|
|
325
|
+
*/
|
|
326
|
+
isMoQApplicationRouteReady(): boolean;
|
|
348
327
|
private sendInternalSignal;
|
|
349
328
|
receiveInternalSignal(content: any): void;
|
|
350
329
|
private handleInternalSignal;
|
|
@@ -353,6 +332,202 @@ declare class Connection {
|
|
|
353
332
|
private normalizeNegotiationId;
|
|
354
333
|
}
|
|
355
334
|
|
|
335
|
+
/**
|
|
336
|
+
* Coalesced peer reconciliation scheduler and full reconcile orchestration.
|
|
337
|
+
*
|
|
338
|
+
* Internal `Client` triggers schedule through `schedulePeerReconciliation()` so
|
|
339
|
+
* concurrent refresh requests share one in-flight `runPeerReconciliation` pass.
|
|
340
|
+
*/
|
|
341
|
+
|
|
342
|
+
type PeerReconciliationStats = {
|
|
343
|
+
scheduled: number;
|
|
344
|
+
coalesced: number;
|
|
345
|
+
ran: number;
|
|
346
|
+
orphanTsConnection: number;
|
|
347
|
+
orphanRustRecord: number;
|
|
348
|
+
orphanTsConnectionHealed: number;
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* App-facing options intentionally hide transport node identifiers from callbacks.
|
|
353
|
+
*/
|
|
354
|
+
type RuntimeClientOptions = Omit<ClientOptions, 'onDevices' | 'onAutoConnect' | 'onIncomingSession'> & {
|
|
355
|
+
onDevices?: (devices: RuntimeDevice[]) => void;
|
|
356
|
+
onAutoConnect?: (devices: RuntimeDevice[]) => void;
|
|
357
|
+
onIncomingSession?: (session: RuntimeSession) => Promise<void>;
|
|
358
|
+
};
|
|
359
|
+
/**
|
|
360
|
+
* App-facing device model. Runtime transport identifiers stay internal.
|
|
361
|
+
*/
|
|
362
|
+
type RuntimeDevice = Omit<Device, 'nodeId'>;
|
|
363
|
+
/**
|
|
364
|
+
* App-facing session model. Node identifiers are runtime-internal metadata.
|
|
365
|
+
*/
|
|
366
|
+
type RuntimeSession = Omit<SignalingSession, 'initiatorNodeId' | 'targetNodeId' | 'appTag'>;
|
|
367
|
+
type RuntimeAuthIdentity = RuntimeIdentity;
|
|
368
|
+
type RuntimeAuthContext = AuthContext;
|
|
369
|
+
/**
|
|
370
|
+
* App-facing peer state model. Runtime transport identifiers stay internal.
|
|
371
|
+
*/
|
|
372
|
+
type RuntimePeerState = Omit<PeerState, 'nodeId'>;
|
|
373
|
+
type RuntimePeerHealth = PeerHealth;
|
|
374
|
+
type RuntimePeerLifecycleStatus = PeerLifecycleStatus;
|
|
375
|
+
type RuntimePeerScope = PeerScope;
|
|
376
|
+
/**
|
|
377
|
+
* App-facing peer session snapshot model. Runtime transport identifiers stay internal.
|
|
378
|
+
*/
|
|
379
|
+
type RuntimePeerSessionSnapshot = Omit<PeerSessionSnapshot, 'nodeId'>;
|
|
380
|
+
type RuntimeLocalDeviceInfo = LocalDeviceInfo;
|
|
381
|
+
type RuntimeRoomMember = RoomMember;
|
|
382
|
+
type RuntimeDeviceConnectOptions = ManagedDeviceConnectOptions;
|
|
383
|
+
type RuntimeJoinRoomOptions = JoinRoomOptions;
|
|
384
|
+
type RuntimeChannelDescriptor = ChannelDescriptor$1;
|
|
385
|
+
interface RuntimeConnectionTarget {
|
|
386
|
+
ticket: string;
|
|
387
|
+
timeoutMs?: number;
|
|
388
|
+
}
|
|
389
|
+
interface RuntimePeerConnectOptions {
|
|
390
|
+
deviceId?: string;
|
|
391
|
+
ticket?: string;
|
|
392
|
+
scope?: RuntimePeerScope;
|
|
393
|
+
channelId?: string;
|
|
394
|
+
/**
|
|
395
|
+
* When true, automatic/observer dials fail fast if the peer has a sticky
|
|
396
|
+
* manual-disconnect projection for this app session. User-initiated manual
|
|
397
|
+
* reconnects should leave this unset and clear the exclusion explicitly.
|
|
398
|
+
*/
|
|
399
|
+
respectManualDisconnect?: boolean;
|
|
400
|
+
}
|
|
401
|
+
interface RuntimePeerStreamOptions {
|
|
402
|
+
ticket?: string;
|
|
403
|
+
scope?: RuntimePeerScope;
|
|
404
|
+
channelId?: string;
|
|
405
|
+
timeoutMs?: number;
|
|
406
|
+
}
|
|
407
|
+
type RuntimeLogicalChannelFraming = 'raw' | 'u32be';
|
|
408
|
+
interface RuntimeScopedChannelOptions {
|
|
409
|
+
peerId?: string;
|
|
410
|
+
peerNodeId?: string;
|
|
411
|
+
deviceId?: string | null;
|
|
412
|
+
ticket?: string;
|
|
413
|
+
scope: RuntimePeerScope;
|
|
414
|
+
channelId: string;
|
|
415
|
+
timeoutMs?: number;
|
|
416
|
+
respectManualDisconnect?: boolean;
|
|
417
|
+
/**
|
|
418
|
+
* Native product protocols such as Plutonium drive-view expect a plaintext
|
|
419
|
+
* stream label before payload frames. OpenRTC owns that handshake here so
|
|
420
|
+
* apps do not need to choose raw transport APIs.
|
|
421
|
+
*/
|
|
422
|
+
nativeLabel?: boolean;
|
|
423
|
+
framing?: RuntimeLogicalChannelFraming;
|
|
424
|
+
}
|
|
425
|
+
interface RuntimeScopedLogicalChannel {
|
|
426
|
+
channelId: string;
|
|
427
|
+
peerId: string;
|
|
428
|
+
connection: Connection;
|
|
429
|
+
send(payload: Uint8Array): Promise<void>;
|
|
430
|
+
onMessage(callback: (payload: Uint8Array) => void): () => void;
|
|
431
|
+
close(): Promise<void>;
|
|
432
|
+
diagnostics(): {
|
|
433
|
+
connectionId: string | null;
|
|
434
|
+
remoteNodeId: string | null;
|
|
435
|
+
transports: string[];
|
|
436
|
+
framing: RuntimeLogicalChannelFraming;
|
|
437
|
+
nativeLabel: boolean;
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* App-facing device status snapshot model. Runtime transport identifiers stay internal.
|
|
442
|
+
*/
|
|
443
|
+
type RuntimeDeviceStatusSnapshot = Omit<DeviceStatusSnapshot, 'nodeId'>;
|
|
444
|
+
type RuntimeDeviceStatus = RuntimeDeviceStatusSnapshot;
|
|
445
|
+
type RuntimeIncomingStream = {
|
|
446
|
+
type: 'bi' | 'uni';
|
|
447
|
+
stream: any;
|
|
448
|
+
remoteNodeId: string;
|
|
449
|
+
protocolHint?: 'control' | 'explicit' | 'native-main' | 'unknown';
|
|
450
|
+
channel?: IncomingStreamChannelMetadata | null;
|
|
451
|
+
};
|
|
452
|
+
type RuntimeConnectionEvent = {
|
|
453
|
+
type: 'connected' | 'disconnected';
|
|
454
|
+
connectionId: string;
|
|
455
|
+
localNodeId: string;
|
|
456
|
+
remoteNodeId: string;
|
|
457
|
+
transport: ProtocolName;
|
|
458
|
+
};
|
|
459
|
+
type RuntimeRawConnection = {
|
|
460
|
+
connectionId: string;
|
|
461
|
+
localNodeId: string;
|
|
462
|
+
remoteNodeId: string;
|
|
463
|
+
};
|
|
464
|
+
type RuntimePresenceLoopOptions = {
|
|
465
|
+
deviceName?: string;
|
|
466
|
+
ticket?: string;
|
|
467
|
+
metadata?: string;
|
|
468
|
+
};
|
|
469
|
+
type RuntimeManagedSessionPlatform = 'native' | 'web';
|
|
470
|
+
type RuntimeManagedSessionKind = 'app-user-device' | 'share-anonymous' | 'drive-grant-guest' | 'scoped-guest' | (string & {});
|
|
471
|
+
type RuntimeAutoConnectPolicy = 'enabled' | 'disabled' | 'scoped-only';
|
|
472
|
+
type RuntimePresencePolicy = 'online' | 'disabled';
|
|
473
|
+
type RuntimeConnectionStateSnapshot = BackendConnectionState;
|
|
474
|
+
type RuntimeApplicationPayloadReadinessOptions = ApplicationPayloadReadinessOptions;
|
|
475
|
+
type RuntimeUiConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'failed';
|
|
476
|
+
interface RuntimePeerReadinessSnapshot {
|
|
477
|
+
requestedId: string;
|
|
478
|
+
connected: boolean;
|
|
479
|
+
settledReady: boolean;
|
|
480
|
+
status: RuntimeUiConnectionStatus;
|
|
481
|
+
health: RuntimePeerHealth | 'unknown';
|
|
482
|
+
deviceId?: string | null;
|
|
483
|
+
deviceIdHint?: string | null;
|
|
484
|
+
activeConnectionId?: string | null;
|
|
485
|
+
readinessState?: string;
|
|
486
|
+
readinessReason?: string;
|
|
487
|
+
scopes: string[];
|
|
488
|
+
}
|
|
489
|
+
interface RuntimeLocalDeviceProfile {
|
|
490
|
+
deviceId: string | null;
|
|
491
|
+
deviceName: string;
|
|
492
|
+
platformType: string;
|
|
493
|
+
userId: string | null;
|
|
494
|
+
capabilities: NonNullable<RuntimeLocalDeviceInfo['capabilities']>;
|
|
495
|
+
lastSeenAt: string;
|
|
496
|
+
localNodeId?: string | null;
|
|
497
|
+
}
|
|
498
|
+
interface RuntimeManagedSessionOptions {
|
|
499
|
+
platform: RuntimeManagedSessionPlatform;
|
|
500
|
+
sessionKind?: RuntimeManagedSessionKind;
|
|
501
|
+
scope?: string | null;
|
|
502
|
+
autoConnectPolicy?: RuntimeAutoConnectPolicy;
|
|
503
|
+
presencePolicy?: RuntimePresencePolicy;
|
|
504
|
+
userId?: string | null;
|
|
505
|
+
deviceName?: string;
|
|
506
|
+
localDeviceId?: string | null;
|
|
507
|
+
metadata?: string;
|
|
508
|
+
autoConnect?: boolean;
|
|
509
|
+
presence?: boolean;
|
|
510
|
+
}
|
|
511
|
+
interface RuntimeManagedSession {
|
|
512
|
+
mode: RuntimeManagedSessionPlatform;
|
|
513
|
+
device: RuntimeLocalDeviceProfile;
|
|
514
|
+
stop: () => Promise<void>;
|
|
515
|
+
}
|
|
516
|
+
type ConnectionTarget = RuntimeConnectionTarget;
|
|
517
|
+
type PeerConnectOptions = RuntimePeerConnectOptions;
|
|
518
|
+
type PeerStreamOptions = RuntimePeerStreamOptions;
|
|
519
|
+
type ScopedChannelOptions = RuntimeScopedChannelOptions;
|
|
520
|
+
type ScopedLogicalChannel = RuntimeScopedLogicalChannel;
|
|
521
|
+
type IncomingStream = RuntimeIncomingStream;
|
|
522
|
+
type ConnectionEvent = RuntimeConnectionEvent;
|
|
523
|
+
type RawConnection = RuntimeRawConnection;
|
|
524
|
+
type PresenceLoopOptions = RuntimePresenceLoopOptions;
|
|
525
|
+
type PeerReadiness = RuntimePeerReadinessSnapshot;
|
|
526
|
+
type DeviceProfile = RuntimeLocalDeviceProfile;
|
|
527
|
+
type SessionOptions$1 = RuntimeManagedSessionOptions;
|
|
528
|
+
type Session$1 = RuntimeManagedSession;
|
|
529
|
+
type ChannelDescriptor = RuntimeChannelDescriptor;
|
|
530
|
+
|
|
356
531
|
interface SessionOptions {
|
|
357
532
|
/**
|
|
358
533
|
* Logical purpose of this session. Used as a peer-scope tag on all
|
|
@@ -430,6 +605,7 @@ declare class ScopedSession implements Session {
|
|
|
430
605
|
disconnectPeer(peerId: string): Promise<void>;
|
|
431
606
|
onIncomingStream(callback: (stream: RuntimeIncomingStream) => void): () => void;
|
|
432
607
|
dispose(): void;
|
|
608
|
+
private releaseScopedPeersOnDispose;
|
|
433
609
|
private assertNotDisposed;
|
|
434
610
|
}
|
|
435
611
|
|
|
@@ -437,29 +613,29 @@ declare class ScopedSession implements Session {
|
|
|
437
613
|
* Phase 4 of the OpenRTC auth + connection remediation plan
|
|
438
614
|
* (`docs/plans/openrtc-auth-connection-remediation-plan.md`).
|
|
439
615
|
*
|
|
440
|
-
* `DriveGrantActorHandle` is the
|
|
441
|
-
* `
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
* removing the lifecycle-replacement race documented in `logs-desktop-A.md`.
|
|
616
|
+
* `DriveGrantActorHandle` is the historical implementation behind the public
|
|
617
|
+
* `ScopedConnectionActorHandle` alias. It is a TypeScript observer-side dial
|
|
618
|
+
* coalescer for scoped protocol routes such as drive-grant guests and
|
|
619
|
+
* trusted-device drive-view. It mirrors the intended Rust actor shape but is
|
|
620
|
+
* not backed by the Rust actor today. With one handle per `(scope, peerNodeId)`
|
|
621
|
+
* key, participating callers coalesce `ensureReady()` onto one underlying
|
|
622
|
+
* `connectPeer` call. It is not a general peer lifecycle authority.
|
|
448
623
|
*
|
|
449
624
|
* ## Scope
|
|
450
625
|
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
* to
|
|
626
|
+
* The handle is not wired into the underlying Rust dial path; it delegates to
|
|
627
|
+
* the existing `connectPeer` path. It remains a transitional compatibility
|
|
628
|
+
* layer until the runtime chooses one actor implementation and wires it
|
|
629
|
+
* end-to-end. What it does today:
|
|
455
630
|
*
|
|
456
|
-
* - `
|
|
457
|
-
* `runtimeClient.
|
|
458
|
-
* then
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
* - `DeviceContext` for `app-user-device`
|
|
462
|
-
*
|
|
631
|
+
* - `DriveGrantConnectionPipeline` and trusted-device drive-view acquisition call
|
|
632
|
+
* `runtimeClient.getScopedConnectionActor(scope, peerNodeId).ensureReady()`,
|
|
633
|
+
* then perform their existing `connectPeer` call inside the handle-owned
|
|
634
|
+
* `dial` function. Multiple concurrent observers for the same key thus
|
|
635
|
+
* coalesce to one `connectPeer` call.
|
|
636
|
+
* - `DeviceContext` for the managed `app-user-device` session remains
|
|
637
|
+
* separate. It owns app presence/auto-connect and must not call this
|
|
638
|
+
* observer coalescer directly.
|
|
463
639
|
*
|
|
464
640
|
* ## Coalescing semantics
|
|
465
641
|
*
|
|
@@ -479,16 +655,22 @@ declare class ScopedSession implements Session {
|
|
|
479
655
|
* | --(failure)--> `idle`
|
|
480
656
|
* `<any>` --(shutdown)--> `closed`
|
|
481
657
|
*
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
*
|
|
658
|
+
* WebRTC upgrade/readiness is intentionally absent from this actor. The
|
|
659
|
+
* runtime `Connection`/peer lifecycle owns transport promotion. Actor callers
|
|
660
|
+
* may observe that lifecycle separately, but this handle must not become a
|
|
661
|
+
* second WebRTC-ready emitter.
|
|
662
|
+
*
|
|
663
|
+
* The Rust actor has a similar shape but is inactive scaffolding in the current
|
|
664
|
+
* workspace. Treat the two implementations as migration debt, not redundant
|
|
665
|
+
* production authorities.
|
|
485
666
|
*/
|
|
486
667
|
type DriveGrantActorErrorKind = 'shutdown' | 'dial-failed' | 'not-ready' | 'logical-channel-not-implemented';
|
|
487
668
|
declare class DriveGrantActorError extends Error {
|
|
488
669
|
readonly kind: DriveGrantActorErrorKind;
|
|
489
670
|
constructor(kind: DriveGrantActorErrorKind, message: string);
|
|
490
671
|
}
|
|
491
|
-
type
|
|
672
|
+
type DriveGrantActorState = 'idle' | 'dialing' | 'base-ready' | 'protocol-ready' | 'degraded' | 'closed';
|
|
673
|
+
type DriveGrantPreferredTransport = 'webrtc' | 'base' | 'none';
|
|
492
674
|
interface DriveGrantConnectionKey {
|
|
493
675
|
scope: string;
|
|
494
676
|
peerNodeId: string;
|
|
@@ -514,22 +696,23 @@ interface DriveGrantActorHandleOptions {
|
|
|
514
696
|
interface DriveGrantLogicalChannelHandle {
|
|
515
697
|
label: string;
|
|
516
698
|
}
|
|
517
|
-
type WebRtcListener = (state: DriveGrantWebRtcState) => void;
|
|
518
699
|
declare class DriveGrantActorHandle {
|
|
519
700
|
readonly key: DriveGrantConnectionKey;
|
|
520
701
|
private readonly dial;
|
|
521
702
|
private readonly close;
|
|
522
703
|
private state;
|
|
523
704
|
private inFlight;
|
|
524
|
-
private webrtcState;
|
|
525
|
-
private webrtcListeners;
|
|
526
705
|
constructor(options: DriveGrantActorHandleOptions);
|
|
527
706
|
/** Returns true if the actor has resolved a successful dial and is not shut down. */
|
|
528
707
|
isReady(): boolean;
|
|
529
708
|
/** Returns true after `shutdown()` has been called. */
|
|
530
709
|
isClosed(): boolean;
|
|
710
|
+
getState(): DriveGrantActorState;
|
|
711
|
+
getPreferredTransport(): DriveGrantPreferredTransport;
|
|
712
|
+
markProtocolReady(): void;
|
|
713
|
+
markDegraded(): void;
|
|
531
714
|
/**
|
|
532
|
-
*
|
|
715
|
+
* Correlation context. Always populated with
|
|
533
716
|
* `sessionKind=drive-grant-guest`, `scope`, `peerNodeId`, and
|
|
534
717
|
* (when the scope encodes one) `grantId`.
|
|
535
718
|
*/
|
|
@@ -540,15 +723,6 @@ declare class DriveGrantActorHandle {
|
|
|
540
723
|
* `shutdown()` flips state to `closed`.
|
|
541
724
|
*/
|
|
542
725
|
ensureReady(): Promise<void>;
|
|
543
|
-
/** Subscribe to WebRTC adoption state. Returns an unsubscribe fn. */
|
|
544
|
-
observeWebRtc(listener: WebRtcListener): () => void;
|
|
545
|
-
/** Current WebRTC state without subscribing. */
|
|
546
|
-
getWebRtcState(): DriveGrantWebRtcState;
|
|
547
|
-
/**
|
|
548
|
-
* Test/Phase-7 hook: lifecycle code that learns of a WebRTC state
|
|
549
|
-
* transition pushes it via this method so observers see the change.
|
|
550
|
-
*/
|
|
551
|
-
setWebRtcState(state: DriveGrantWebRtcState): void;
|
|
552
726
|
/**
|
|
553
727
|
* Phase 6: returns a logical channel handle backed by the base iroh
|
|
554
728
|
* transport. The host-side `DriveViewBaseIrohHandler` dispatches
|
|
@@ -565,8 +739,7 @@ declare class DriveGrantActorHandle {
|
|
|
565
739
|
openLogicalChannelTestStub(label: string): Promise<DriveGrantLogicalChannelHandle>;
|
|
566
740
|
/**
|
|
567
741
|
* Idempotent shutdown. Subsequent `ensureReady()` rejects with
|
|
568
|
-
* `shutdown`; subsequent `shutdown()` is a no-op.
|
|
569
|
-
* a final `'failed'` state so they can wire teardown side-effects.
|
|
742
|
+
* `shutdown`; subsequent `shutdown()` is a no-op.
|
|
570
743
|
*/
|
|
571
744
|
shutdown(): Promise<void>;
|
|
572
745
|
}
|
|
@@ -657,15 +830,17 @@ declare class RuntimeClient {
|
|
|
657
830
|
private managedSessionTransition;
|
|
658
831
|
private managedSessionStartInFlight;
|
|
659
832
|
private readonly managedReconciliationTasks;
|
|
833
|
+
private managedReconciliationTimer;
|
|
834
|
+
private readonly managedReconciliationFollowupTimers;
|
|
660
835
|
/**
|
|
661
|
-
*
|
|
662
|
-
*
|
|
663
|
-
*
|
|
836
|
+
* The one per-`{scope, peerNodeId}` observer-side dial coalescer. It is
|
|
837
|
+
* intentionally separate from the peer lifecycle read model: it requests a
|
|
838
|
+
* scoped route through `connectPeer`, while `Client` owns connection state.
|
|
664
839
|
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
840
|
+
* Persistent same-account auto-connect (`app-user-device`) and anonymous
|
|
841
|
+
* share flows (`share-anonymous`) do not use this grant-guest coalescer.
|
|
667
842
|
*/
|
|
668
|
-
private
|
|
843
|
+
private scopedConnectionActorRegistry;
|
|
669
844
|
private static describeTicketForLogs;
|
|
670
845
|
private serializeManagedSessionOperation;
|
|
671
846
|
constructor(options: RuntimeClientOptions, backend?: ISignalingBackend | null);
|
|
@@ -674,7 +849,6 @@ declare class RuntimeClient {
|
|
|
674
849
|
private resolveManagedAutoConnectEnabled;
|
|
675
850
|
private resolveManagedPresenceEnabled;
|
|
676
851
|
private getEffectiveRuntimeUserId;
|
|
677
|
-
private sleep;
|
|
678
852
|
private fetchAndApplyAppLimits;
|
|
679
853
|
private resolvePeerStreamTarget;
|
|
680
854
|
private compatPeerConnectionFromTarget;
|
|
@@ -682,11 +856,14 @@ declare class RuntimeClient {
|
|
|
682
856
|
private hasManagedSession;
|
|
683
857
|
private usesNativeIpcBackend;
|
|
684
858
|
private startManagedReconciliation;
|
|
859
|
+
private scheduleManagedReconciliationFollowups;
|
|
860
|
+
private stopManagedReconciliation;
|
|
685
861
|
private notifyManagedReconciliation;
|
|
686
862
|
reconcileNativeManagedSession(reason?: string): Promise<void>;
|
|
687
863
|
private connectionStateSnapshotKey;
|
|
688
864
|
private runNativeStartLoop;
|
|
689
865
|
private isUnsupportedRuntimeAdapterError;
|
|
866
|
+
private isRecoverableNativeManagedSessionStartError;
|
|
690
867
|
onIdentityChange(callback: (identity: RuntimeAuthIdentity | null) => void): () => void;
|
|
691
868
|
signInAnonymously(): Promise<void>;
|
|
692
869
|
signInWithPluto(): Promise<void>;
|
|
@@ -699,8 +876,10 @@ declare class RuntimeClient {
|
|
|
699
876
|
localNodeId?: string;
|
|
700
877
|
userId?: string;
|
|
701
878
|
}>;
|
|
879
|
+
getPeerReconciliationStats(): Readonly<PeerReconciliationStats>;
|
|
702
880
|
getRuntimePolicy(): RuntimePolicySnapshot;
|
|
703
881
|
getRuntimeCapabilities(): RuntimeCapabilities;
|
|
882
|
+
getCapabilityProfile(): RuntimeCapabilityProfile;
|
|
704
883
|
start(options?: {
|
|
705
884
|
clearSessionTokens?: boolean;
|
|
706
885
|
}): Promise<void>;
|
|
@@ -790,6 +969,7 @@ declare class RuntimeClient {
|
|
|
790
969
|
*/
|
|
791
970
|
connectDevice(device: RuntimeDevice, options: RuntimeDeviceConnectOptions): Promise<ConnectDeviceResult>;
|
|
792
971
|
watchPeerStates(callback: (peers: RuntimePeerState[]) => void): () => void;
|
|
972
|
+
watchPeerLifecycle(callback: (peers: RuntimePeerState[]) => void): () => void;
|
|
793
973
|
getPeerState(id: string): RuntimePeerState | undefined;
|
|
794
974
|
resolvePeerConnectionRecords(id: string): Promise<ManagedConnectionRecord[]>;
|
|
795
975
|
getPeerSession(id: string): Promise<PeerSessionSnapshot | null>;
|
|
@@ -804,8 +984,9 @@ declare class RuntimeClient {
|
|
|
804
984
|
getPeerScopes(id: string): string[];
|
|
805
985
|
isSamePeer(a: string, b: string): boolean;
|
|
806
986
|
refreshPeerSnapshot(): Promise<RuntimePeerState[]>;
|
|
807
|
-
subscribeSessions(localDeviceId: string, callback: (session: RuntimeSession) => void): Promise<() => void>;
|
|
987
|
+
subscribeSessions(localDeviceId: string, callback: (session: RuntimeSession) => void | Promise<void>): Promise<() => void>;
|
|
808
988
|
getAppLimits(): AppLimits;
|
|
989
|
+
private syncRoomRtdbPresenceFromBackend;
|
|
809
990
|
createRoom(roomId?: string): Promise<string>;
|
|
810
991
|
joinRoom(roomId: string, options?: RuntimeJoinRoomOptions): Promise<Connection[]>;
|
|
811
992
|
leaveRoom(roomId: string): Promise<void>;
|
|
@@ -814,26 +995,24 @@ declare class RuntimeClient {
|
|
|
814
995
|
/** @deprecated Use connect() (no-arg) for lifecycle, or connectTo() for peer connections */
|
|
815
996
|
connectByTicket(target: RuntimeConnectionTarget): Promise<Connection>;
|
|
816
997
|
connectPeer(options: RuntimePeerConnectOptions): Promise<Connection>;
|
|
998
|
+
connectScopedChannel(options: RuntimeScopedChannelOptions): Promise<RuntimeScopedLogicalChannel>;
|
|
817
999
|
/**
|
|
818
|
-
*
|
|
819
|
-
*
|
|
820
|
-
*
|
|
821
|
-
* DriveShareRedeemPage) coalesce through. The first call for a
|
|
822
|
-
* given key spawns the handle; subsequent calls return the same
|
|
1000
|
+
* Returns the per-`{scope, peerNodeId}` observer-side coalescer that
|
|
1001
|
+
* participating scoped guest callers (such as DriveViewClient) use. The
|
|
1002
|
+
* first call for a given key spawns the handle; subsequent calls return the same
|
|
823
1003
|
* handle so concurrent observers share a single underlying dial.
|
|
824
1004
|
*
|
|
825
|
-
* The handle's `dial` function delegates to this RuntimeClient's
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
*
|
|
1005
|
+
* The handle's `dial` function delegates to this RuntimeClient's existing
|
|
1006
|
+
* `connectPeer` API. It is a compatibility coalescer, not an independent
|
|
1007
|
+
* transport owner, and the Rust registry is not enabled by workspace
|
|
1008
|
+
* production startup.
|
|
829
1009
|
*
|
|
830
|
-
*
|
|
831
|
-
*
|
|
832
|
-
*
|
|
833
|
-
*
|
|
834
|
-
* lifecycle).
|
|
1010
|
+
* Managed `app-user-device` startup/presence/auto-connect must not call
|
|
1011
|
+
* this observer coalescer directly. Scoped protocol observers may use it
|
|
1012
|
+
* only with a narrow `dial` callback that delegates back through
|
|
1013
|
+
* `connectPeer`; the runtime `Client` remains the peer lifecycle owner.
|
|
835
1014
|
*/
|
|
836
|
-
|
|
1015
|
+
getScopedConnectionActor(key: DriveGrantConnectionKey | {
|
|
837
1016
|
scope: string;
|
|
838
1017
|
peerNodeId: string;
|
|
839
1018
|
}, options?: {
|
|
@@ -851,37 +1030,26 @@ declare class RuntimeClient {
|
|
|
851
1030
|
* router/disconnect handler to the connection object) can
|
|
852
1031
|
* supply their own `dial` here. The actor's coalescer still
|
|
853
1032
|
* ensures only one `dial(key)` runs even with N concurrent
|
|
854
|
-
* `
|
|
1033
|
+
* `getScopedConnectionActor(...).ensureReady()` callers — this just
|
|
855
1034
|
* lets the caller decide what "dial" means.
|
|
856
1035
|
*/
|
|
857
1036
|
dial?: (key: DriveGrantConnectionKey) => Promise<void>;
|
|
858
1037
|
}): DriveGrantActorHandle;
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
* coalescer. Plutonium’s drive-grant flows were the first adopter, but other
|
|
864
|
-
* app protocols (magic-link, user-device, etc.) may also want the same shape.
|
|
865
|
-
*
|
|
866
|
-
* Backward-compat: this is a thin wrapper with identical behavior.
|
|
867
|
-
*/
|
|
868
|
-
getScopedConnectionActor(key: DriveGrantConnectionKey | {
|
|
869
|
-
scope: string;
|
|
870
|
-
peerNodeId: string;
|
|
871
|
-
}, options?: Parameters<RuntimeClient['getDriveGrantActor']>[1]): DriveGrantActorHandle;
|
|
872
|
-
/** Domain-agnostic alias for `shutdownDriveGrantActors`. */
|
|
1038
|
+
private assertScopedDialAllowed;
|
|
1039
|
+
private scopedDialCandidateIds;
|
|
1040
|
+
private hasManualDisconnectSuppression;
|
|
1041
|
+
/** Shuts down every scoped observer handle during managed-session teardown. */
|
|
873
1042
|
shutdownScopedConnectionActors(): Promise<void>;
|
|
874
|
-
/**
|
|
875
|
-
* Phase 4: tear down all live drive-grant actors. Called from
|
|
876
|
-
* managed-session teardown so a refresh between drive-grant guest
|
|
877
|
-
* routes does not leak observers across navigations.
|
|
878
|
-
*/
|
|
879
|
-
shutdownDriveGrantActors(): Promise<void>;
|
|
880
1043
|
openPeerBi(id: string, options?: RuntimePeerStreamOptions): Promise<{
|
|
881
1044
|
connection: Connection;
|
|
882
1045
|
readable: ReadableStream<Uint8Array>;
|
|
883
1046
|
writable: WritableStream<Uint8Array>;
|
|
884
1047
|
}>;
|
|
1048
|
+
openPeerNativeBi(id: string, label: string, options?: RuntimePeerStreamOptions): Promise<{
|
|
1049
|
+
connection: Connection;
|
|
1050
|
+
readable: ReadableStream<Uint8Array>;
|
|
1051
|
+
writable: WritableStream<Uint8Array>;
|
|
1052
|
+
}>;
|
|
885
1053
|
/** Like openPeerBi but skips the settled_ready requirement — usable for latency probes. */
|
|
886
1054
|
openPeerBiTransportOnly(id: string, options?: RuntimePeerStreamOptions): Promise<{
|
|
887
1055
|
connection: Connection;
|
|
@@ -929,8 +1097,15 @@ declare class RuntimeClient {
|
|
|
929
1097
|
forceDisconnectPeer(id: string): Promise<void>;
|
|
930
1098
|
getPeerHealth(id: string): Promise<RuntimePeerHealth>;
|
|
931
1099
|
getConnectionStates(): Promise<RuntimeConnectionStateSnapshot[]>;
|
|
1100
|
+
/**
|
|
1101
|
+
* Subscribe to raw backend connection diagnostics.
|
|
1102
|
+
*
|
|
1103
|
+
* This compatibility surface intentionally does not drive peer lifecycle or
|
|
1104
|
+
* UI readiness; use watchPeerStates() for the reducer-owned lifecycle view.
|
|
1105
|
+
*/
|
|
932
1106
|
onConnectionStateChange(callback: (state: RuntimeConnectionStateSnapshot) => void): Promise<() => void> | (() => void);
|
|
933
1107
|
getConnections(): Connection[];
|
|
1108
|
+
getApplicationReadyConnections(options?: RuntimeApplicationPayloadReadinessOptions): Connection[];
|
|
934
1109
|
onConnection(callback: (connection: Connection) => void): () => void;
|
|
935
1110
|
onDisconnection(callback: (connection: Connection) => void): () => void;
|
|
936
1111
|
onConnectionEvent(callback: (event: RuntimeConnectionEvent) => void): () => void;
|
|
@@ -939,6 +1114,17 @@ declare class RuntimeClient {
|
|
|
939
1114
|
connect(): Promise<void>;
|
|
940
1115
|
/** Disconnect from the runtime (alias for stop()) */
|
|
941
1116
|
disconnect(): void;
|
|
1117
|
+
/**
|
|
1118
|
+
* Terminal teardown of the runtime instance. Unlike stop()/disconnect()
|
|
1119
|
+
* (which only stop the listen loop and are used during normal operation),
|
|
1120
|
+
* destroy() tears down the underlying Client's coordinated dispose path —
|
|
1121
|
+
* document/window listeners, the periodic auth-refresh interval, and signaling
|
|
1122
|
+
* subscriptions (audit V2). Call this only when the runtime singleton is truly
|
|
1123
|
+
* going away (app shutdown, HMR dispose), never on a routine disconnect.
|
|
1124
|
+
*/
|
|
1125
|
+
destroy(): void;
|
|
1126
|
+
/** Alias for destroy(); supports callers that expect a `dispose()` contract. */
|
|
1127
|
+
dispose(): void;
|
|
942
1128
|
/** Alias for onIdentityChange */
|
|
943
1129
|
onAuthChange(callback: (identity: RuntimeAuthIdentity | null) => void): () => void;
|
|
944
1130
|
/** Alias for setAuthContext */
|
|
@@ -1038,4 +1224,4 @@ declare function createWasmClient(options: RuntimeFactoryOptions): PlutoRuntimeA
|
|
|
1038
1224
|
*/
|
|
1039
1225
|
declare function createIpcClient(options: RuntimeFactoryOptions, bridge: PlutoIpcBridge): PlutoRuntimeAssembly<IpcRuntimeAdapter>;
|
|
1040
1226
|
|
|
1041
|
-
export {
|
|
1227
|
+
export { type RuntimeSession as $, type PeerReadiness as A, type PeerStreamOptions as B, Connection as C, type DeviceProfile as D, type PresenceLoopOptions as E, type RawConnection as F, type RuntimeAuthContext as G, type RuntimeAuthIdentity as H, type ITransport as I, type RuntimeAutoConnectPolicy as J, type RuntimeConnectionTarget as K, type RuntimeDeviceStatus as L, type RuntimeJoinRoomOptions as M, type RuntimeLogicalChannelFraming as N, OPENRTC_RUNTIME_POLICY as O, type PeerReconciliationStats as P, type RuntimeManagedSession as Q, type RuntimeClientOptions as R, type RuntimeManagedSessionKind as S, type RuntimeManagedSessionOptions as T, type RuntimeManagedSessionPlatform as U, type RuntimePeerLifecycleStatus as V, type RuntimePeerScope as W, type RuntimePeerSessionSnapshot as X, type RuntimePresenceLoopOptions as Y, type RuntimePresencePolicy as Z, type RuntimeRoomMember as _, RuntimeClient as a, type RuntimeUiConnectionStatus as a0, type ScopedChannelOptions as a1, type ScopedLogicalChannel as a2, ScopedSession as a3, type Session as a4, type SessionOptions as a5, getRuntimePolicy as a6, type RuntimeFactoryOptions as a7, DriveGrantActorError as a8, type DriveGrantActorErrorKind as a9, DriveGrantActorHandle as aa, type DriveGrantActorHandleOptions as ab, DriveGrantActorRegistry as ac, type DriveGrantActorState as ad, type DriveGrantClose as ae, type DriveGrantDial as af, type DriveGrantConnectionKey as ag, type DriveGrantLogicalChannelHandle as ah, type DriveGrantPreferredTransport as ai, type Session$1 as aj, type SessionOptions$1 as ak, createIpcClient as al, createWasmClient as am, driveGrantConnectionKey as an, driveGrantConnectionKeyToString as ao, type RuntimeDevice as b, type RuntimeDeviceStatusSnapshot as c, type RuntimeDeviceConnectOptions as d, type RuntimeLocalDeviceInfo as e, type RuntimeLocalDeviceProfile as f, type RuntimePeerState as g, type RuntimePeerConnectOptions as h, type RuntimePeerReadinessSnapshot as i, type RuntimePeerHealth as j, type RuntimeChannelDescriptor as k, type RuntimePeerStreamOptions as l, type RuntimeIncomingStream as m, type RuntimeScopedChannelOptions as n, type RuntimeScopedLogicalChannel as o, type RuntimePolicySnapshot as p, type RuntimeConnectionStateSnapshot as q, type RuntimeApplicationPayloadReadinessOptions as r, type RuntimeConnectionEvent as s, type PlutoRuntimeAssembly as t, type RuntimeRawConnection as u, type ChannelDescriptor as v, type ConnectionEvent as w, type ConnectionTarget as x, type IncomingStream as y, type PeerConnectOptions as z };
|