import { R as RuntimePeerState, g as ConnectionState, b as PeerReadiness, P as PeerConnectOptions, a as Connection, I as IncomingStream, o as RuntimeClientOptions, r as RuntimeAuthIdentity, A as AuthContext, L as LocalDeviceInfo, l as DeviceProfile, B as BrowserProtocolStore, N as NamespaceDescriptor, p as IrohMutationReceipt, q as IrohDocEntry, e as RuntimeDevice, M as ManagedOptions, j as ManagedSession, D as DeviceStatus, k as DeviceConnectOptions, s as RuntimeSession, J as JoinRoomOptions, n as RuntimeRoomMember, t as ConnectionTarget, S as ScopedChannelOptions, f as ScopedLogicalChannel, d as PeerStreamOptions, m as RawConnection, C as ChannelDescriptor, u as PresenceLoopOptions, c as RuntimePeerHealth, h as ReadinessOptions, i as ConnectionEvent } from './types-D67HlF0p.js'; import { G as GrantScope, I as ISignalingBackend, f as ConnectDeviceHooks, g as ConnectDeviceOptions, C as ConnectDeviceResult, M as ManagedConnectionRecord, d as PeerSessionSnapshot, e as ResolvedPeerIdentity, a6 as AppLimits, N as NativeConnectParams, t as NativeConnectResult, E as ExplicitFileDataSendParams } from './ITransport-yaruAmx3.js'; import { R as RuntimeCapabilities, C as CapabilityProfile } from './capabilities-BwzPe51I.js'; /** * Coalesced peer reconciliation scheduler and full reconcile orchestration. * * Internal `Client` triggers schedule through `schedulePeerReconciliation()` so * concurrent refresh requests share one in-flight `runPeerReconciliation` pass. */ type PeerReconciliationStats = { scheduled: number; coalesced: number; ran: number; orphanTsConnection: number; orphanRustRecord: number; orphanTsConnectionHealed: number; }; interface SessionOptions { /** * Logical purpose of this session. Used as a peer-scope tag on all * outbound connections. Incoming events are filtered to peers carrying * this scope (or all peers when `allowAllPeers` is true). */ scope: string; /** * When true, watchPeerStates / onStateChange deliver events for * ALL peers, not just those scoped to this session. Useful for the default * 'user-device' session that legitimately needs the full peer picture. * Default: false. */ allowAllPeers?: boolean; /** * Additional peer IDs (node IDs, device IDs, connection IDs) that this * session is permitted to observe, independent of their scope tags. * Useful for magic-link sessions that know the host's node ID from the * ticket before a connection exists. */ allowPeers?: ReadonlyArray; } /** Disposable scope-filtered view over a shared RuntimeClient. */ interface Session { readonly scope: string; readonly disposed: boolean; /** * Subscribe to peer-state snapshots filtered to this session's scope. * The callback fires once immediately with the current filtered snapshot, * then again whenever relevant peer state changes. */ watchPeerStates(callback: (peers: RuntimePeerState[]) => void): () => void; /** * Subscribe to connection-state events filtered to this session's scope. * Returns the unsubscribe function (may be async for WASM bridge compat). */ onStateChange(callback: (state: ConnectionState) => void): (() => void) | Promise<() => void>; /** Async snapshot of peers matching this session's scope. */ listConnectedPeers(): RuntimePeerState[]; /** Peer readiness for a specific peer ID (scope-filtered). */ getPeerReadiness(peerId: string): Promise; /** * Connect to a peer via ticket or device ID, tagging the connection with * this session's scope. */ connectPeer(options: PeerConnectOptions): Promise; /** Disconnect a peer within this session's scope only. */ disconnectPeer(peerId: string): Promise; /** * Subscribe to incoming streams from peers whose scope matches this * session. Streams from other scopes are not delivered. */ onIncomingStream(callback: (stream: IncomingStream) => void): () => void; /** Tear down all subscriptions and disconnect scope-tagged connections. */ dispose(): void; } /** * Phase 4 of the OpenRTC auth + connection remediation plan * (`docs/plans/openrtc-auth-connection-remediation-plan.md`). * * `DriveGrantActorHandle` is the historical implementation behind the public * `ConnectionActor` alias. It is a TypeScript observer-side dial * coalescer for scoped protocol routes such as drive-grant guests and * trusted-device drive-view. It mirrors the intended Rust actor shape but is * not backed by the Rust actor today. With one handle per `(scope, peerNodeId)` * key, participating callers coalesce `ensureReady()` onto one underlying * `connectPeer` call. It is not a general peer lifecycle authority. * * ## Scope * * The handle is not wired into the underlying Rust dial path; it delegates to * the existing `connectPeer` path. It remains a transitional compatibility * layer until the runtime chooses one actor implementation and wires it * end-to-end. What it does today: * * - `DriveGrantConnectionPipeline` and trusted-device drive-view acquisition call * `runtimeClient.connectionActor(scope, peerNodeId).ensureReady()`, * then perform their existing `connectPeer` call inside the handle-owned * `dial` function. Multiple concurrent observers for the same key thus * coalesce to one `connectPeer` call. * - `DeviceContext` for the managed `app-user-device` session remains * separate. It owns app presence/auto-connect and must not call this * observer coalescer directly. * * ## Coalescing semantics * * `ensureReady()` is the canonical "is the connection up?" call: * * - If the underlying dial is in flight, all callers await the same * promise. * - If the underlying dial succeeded, callers resolve immediately. * - If the underlying dial failed, the handle stays "not ready" and the * next caller may try again. * - If `shutdown()` was called, every caller (current + future) rejects * with `ActorError.Shutdown`. * * The only state machine transitions are: * * `idle` --(ensureReady)--> `dialing` --(success)--> `ready` * | --(failure)--> `idle` * `` --(shutdown)--> `closed` * * WebRTC upgrade/readiness is intentionally absent from this actor. The * runtime `Connection`/peer lifecycle owns transport promotion. Actor callers * may observe that lifecycle separately, but this handle must not become a * second WebRTC-ready emitter. * * The Rust actor has a similar shape but is inactive scaffolding in the current * workspace. Treat the two implementations as migration debt, not redundant * production authorities. */ type DriveGrantActorErrorKind = 'shutdown' | 'dial-failed' | 'not-ready' | 'logical-channel-not-implemented'; declare class DriveGrantActorError extends Error { readonly kind: DriveGrantActorErrorKind; constructor(kind: DriveGrantActorErrorKind, message: string); } type DriveGrantActorState = 'idle' | 'dialing' | 'base-ready' | 'protocol-ready' | 'degraded' | 'closed'; type DriveGrantPreferredTransport = 'webrtc' | 'base' | 'none'; interface DriveGrantConnectionKey { scope: string; peerNodeId: string; } declare function driveGrantConnectionKey(scope: string, peerNodeId: string): DriveGrantConnectionKey; declare function driveGrantConnectionKeyToString(key: DriveGrantConnectionKey): string; /** * The dial function the handle calls when no connection has yet * resolved. Must be idempotent: returning when a healthy transport * exists, throwing only on transient failure (caller retries) or * permanent failure (caller surfaces). */ type DriveGrantDial = (key: DriveGrantConnectionKey) => Promise; /** * Optional teardown hook invoked on `shutdown()`. Default is a no-op. */ type DriveGrantClose = (key: DriveGrantConnectionKey) => Promise; interface DriveGrantActorHandleOptions { key: DriveGrantConnectionKey; dial: DriveGrantDial; close?: DriveGrantClose; } interface DriveGrantLogicalChannelHandle { label: string; } declare class DriveGrantActorHandle { readonly key: DriveGrantConnectionKey; private readonly dial; private readonly close; private state; private inFlight; constructor(options: DriveGrantActorHandleOptions); /** Returns true if the actor has resolved a successful dial and is not shut down. */ isReady(): boolean; /** Returns true after `shutdown()` has been called. */ isClosed(): boolean; getState(): DriveGrantActorState; getPreferredTransport(): DriveGrantPreferredTransport; markProtocolReady(): void; markDegraded(): void; /** * Correlation context. Always populated with * `sessionKind=drive-grant-guest`, `scope`, `peerNodeId`, and * (when the scope encodes one) `grantId`. */ private correlation; /** * Coalesce-and-dial. N concurrent callers resolve via a single * underlying dial. After the first success this is a fast no-op until * `shutdown()` flips state to `closed`. */ ensureReady(): Promise; /** * Phase 6: returns a logical channel handle backed by the base iroh * transport. The host-side `DriveViewBaseIrohHandler` dispatches * drive-view frames arriving on a bi-stream with label `"drive-view"`, * so logical channels are implicitly multiplexed by the underlying * QUIC stream layer. */ openLogicalChannel(label: string): Promise; /** * Idempotent shutdown. Subsequent `ensureReady()` rejects with * `shutdown`; subsequent `shutdown()` is a no-op. */ shutdown(): Promise; } /** * Registry that hands out one shared `DriveGrantActorHandle` per * `DriveGrantConnectionKey`. `getOrSpawn` is idempotent. */ declare class DriveGrantActorRegistry { private actors; private readonly factory; constructor(factory: (key: DriveGrantConnectionKey) => DriveGrantActorHandle); getOrSpawn(key: DriveGrantConnectionKey, factoryOverride?: (key: DriveGrantConnectionKey) => DriveGrantActorHandle): DriveGrantActorHandle; get(key: DriveGrantConnectionKey): DriveGrantActorHandle | null; /** Tear down every actor; clears the registry. */ shutdownAll(): Promise; size(): number; } interface PolicySnapshot { managedSession: { nativeStartRetryWindowMs: number; nativeStartRetryMinDelayMs: number; nativeStartRetryMaxDelayMs: number; deviceStatusRefreshDebounceMs: number; }; browserAutoConnect: { scanDebounceMs: number; retryCooldownMs: number; settleGuardMs: number; retryMaxMs: number; nonInitiatorBaseGraceMs: number; nonInitiatorMaxGraceMs: number; }; nativeIpc: { authRequiredWaitMs: number; defaultBoundedCommandTimeoutMs: number; connectionEventSubscribeWindowMs: number; connectionEventRetryMinDelayMs: number; connectionEventRetryMaxDelayMs: number; tauriIpcNegativeCacheMs: number; }; browserIdentity: { ephemeralDeviceIdTtlMs: number; }; } declare const RUNTIME_POLICY: PolicySnapshot; declare function getRuntimePolicy(): PolicySnapshot; /** * RuntimeClient is the primary application-facing API. * It owns host/runtime orchestration on top of the Rust core and should be the * only high-level surface consumed by product code. App code should not rebuild * lifecycle, discovery, or transfer-readiness policy above this layer. * * Allowed: * - app-facing session startup/shutdown * - typed device, peer, room, and transfer APIs * - thin host/runtime coordination * * Not allowed: * - teaching app code to depend on `advanced.unwrap*()` * - treating `nodeId` as high-level peer identity * - reimplementing Rust-owned lifecycle policy in product code * * Source of truth: * - Rust core owns transport lifecycle, connection health, and native signaling surfaces * - Browser discovery/presence/signaling are host-owned by the scoped TypeScript gateway adapter * - RuntimeClient should converge toward thin wrappers over those runtime/backing surfaces */ declare class RuntimeClient { private static readonly NATIVE_START_RETRY_WINDOW_MS; private static readonly NATIVE_START_RETRY_MIN_DELAY_MS; private static readonly NATIVE_START_RETRY_MAX_DELAY_MS; private static readonly DEVICE_STATUS_REFRESH_DEBOUNCE_MS; private static readonly MANAGED_USER_DEVICE_SCOPE; static readonly MANAGED_FRIEND_SCOPE: GrantScope; private readonly client; private readonly backend; private readonly deviceManager; private readonly peerManager; private readonly connectionController; private readonly nativeStreamConsumer; private managedSessionKey; private managedSessionUserId; private managedSessionOptions; private managedSessionTransition; private managedSessionStartInFlight; private terminalShutdown; private readonly managedReconciliationTasks; private readonly managedReconciliationFollowupTimers; /** * The one per-`{scope, peerNodeId}` observer-side dial coalescer. It is * intentionally separate from the peer lifecycle read model: it requests a * scoped route through `connectPeer`, while `Client` owns connection state. * * Persistent same-account auto-connect (`app-user-device`) and anonymous * share flows (`share-anonymous`) do not use this grant-guest coalescer. */ private scopedConnectionActorRegistry; private static describeTicketForLogs; private serializeManagedSessionOperation; constructor(options: RuntimeClientOptions, backend?: ISignalingBackend | null); get identity(): RuntimeAuthIdentity | null; private resolveManagedSessionUserId; private resolveManagedAutoConnectEnabled; private resolveManagedPresenceEnabled; private getEffectiveRuntimeUserId; private fetchAndApplyAppLimits; private resolvePeerStreamTarget; private compatPeerConnectionFromTarget; private isTransportOnlyStreamChannel; private nextNativeStartRetryDelayMs; private hasManagedSession; private usesNativeIpcBackend; private startManagedReconciliation; private scheduleManagedReconciliationFollowups; private stopManagedReconciliation; private notifyManagedReconciliation; syncNativeSession(reason?: string): Promise; notifyNetworkChange(reason?: string): Promise; private connectionStateSnapshotKey; private runNativeStartLoop; private isUnsupportedRuntimeAdapterError; onIdentityChange(callback: (identity: RuntimeAuthIdentity | null) => void): () => void; signInAnonymously(): Promise; signInWithPluto(): Promise; setAuthContext(context: AuthContext | null): Promise; signOut(): Promise; initialize(): Promise; getRuntimeStatus(): Promise<{ runtime: 'tauri' | 'browser' | 'unknown'; wasmLoaded: boolean; localNodeId?: string; userId?: string; }>; reconciliationStats(): Readonly; getRuntimePolicy(): PolicySnapshot; capabilities(): RuntimeCapabilities; getCapabilityProfile(): CapabilityProfile; start(options?: { clearSessionTokens?: boolean; }): Promise; stop(): void; getNodeId(): Promise; getNodeIdFromTicket(ticket: string): Promise; getLocalDeviceId(): Promise; getLocalDeviceInfo(): Promise; localDeviceProfile(options?: { deviceName?: string; localDeviceId?: string | null; platform?: 'native' | 'web'; userId?: string | null; }): Promise; updateDeviceName(deviceName: string): Promise; getManagedNodeId(options?: { initializeIfMissing?: boolean; }): Promise; /** * Enable upstream Iroh docs, blobs, and gossip on this runtime's existing * browser endpoint. The host store supplies durable IndexedDB operations; * no second endpoint, router, presence loop, or reconnect owner is created. */ initIrohProtocols(store: BrowserProtocolStore): Promise; createIrohNamespace(options?: { generation?: number; shareRevision?: number; }): Promise; importIrohTicket(ticket: string, options?: { generation?: number; shareRevision?: number; }): Promise; shareIrohNamespace(namespaceId: string, options?: { writable?: boolean; }): Promise; removeIrohNamespace(namespaceId: string, options?: { generation?: number; shareRevision?: number; }): Promise; putIrohBytes(namespaceId: string, key: Uint8Array, value: Uint8Array): Promise; setIrohHash(namespaceId: string, key: Uint8Array, contentHash: string, contentLength: number): Promise; deleteIrohPrefix(namespaceId: string, prefix: Uint8Array): Promise<{ removed: number; operationId: string; }>; queryIrohNamespace(namespaceId: string, keyPrefix?: Uint8Array): Promise; hydrateIrohBlob(contentHash: string): Promise; acknowledgeOutbox(operationId: string): Promise; flushIrohProtocols(): Promise; private persistentIrohProtocolBackend; private assertProtocolCounter; getTicket(): Promise; /** * Generate a session-scoped endpoint ticket with an embedded random token. * The token gates incoming connections: only clients that present the token * in their handshake are accepted while the registry is non-empty. * * @param grantScope Admission-grant label for bulk revoke (e.g. "share"). * This is distinct from `PeerScope`, which only labels peer lifecycle. * @param maxConnections 0 = unlimited. */ getTicketWithToken(grantScope: GrantScope, maxConnections?: number): Promise; /** * Register a product-issued admission token with the active runtime. * * Product code supplies the durable authorization decision, while OpenRTC * remains the sole owner of the native/WASM admission registry. Restricted * grants should always include their server-issued expiry. */ registerToken(input: { token: string; scope: GrantScope; maxConnections?: number; expiresAtMs?: number; }): Promise; /** Revoke all session tokens that match the given scope. */ revokeTokensByScope(grantScope: GrantScope): Promise; private revokeTokensByScopeInternal; /** Revoke a single session token by its raw value. */ revokeSessionToken(token: string): void; /** * Watch devices belonging to friend users via the active coordination * provider. Sets up one provider subscription per friend UID. * * Only works when the signaling backend supports `watchFriendDevices`. * For native backends, friend device discovery should be handled * at the application layer (e.g., FriendDeviceContext). * * @param friendUserIds - Array of friend user IDs to watch * @param callback - Called with the merged map of friend devices * @returns Cleanup function */ watchFriendDevices(friendUserIds: string[], callback: (friendDevices: Map) => void): () => void; /** * Get a compound ticket with a friend-scoped grant token. * Friends connecting with this ticket are admitted with `friend` scope. */ getFriendTicket(maxConnections?: number): Promise; /** * Revoke all friend-scoped tokens and disconnect affected connections. */ revokeFriendTokens(): Promise; /** * Update the friend ticket on the current device's presence doc. * Call this after minting a friend ticket so that friends watching * the device doc can see and use the friend-scoped ticket. */ updateFriendTicket(friendTicket: string | null): Promise; getEndpointTicket(): Promise; startManagedSession(options: ManagedOptions): Promise; stopManagedSession(options?: { preserveBackendSession?: boolean; }): Promise; private stopManagedSessionInternal; private rotateManagedUserDeviceGrant; listDevices(): Promise; listDeviceStatus(): Promise; updateDevice(deviceId: string, updates: { deviceName?: string; capabilities?: RuntimeDevice['capabilities']; metadata?: string; }): Promise; deleteDevice(deviceId: string): Promise; watchDevices(callback: (devices: RuntimeDevice[]) => void): () => void; watchDeviceStatus(callback: (devices: DeviceStatus[]) => void): () => void; connectWithRetry(device: RuntimeDevice, hooks: ConnectDeviceHooks, options: ConnectDeviceOptions): Promise; /** * Runtime-owned device connect flow used by product code. * Rust owns the actual managed dial policy. This wrapper only: * - validates the app-facing device/ticket input * - forwards the request to the active runtime adapter * - refreshes peer state and invokes optional app callbacks */ connectDevice(device: RuntimeDevice, options: DeviceConnectOptions): Promise; watchPeerStates(callback: (peers: RuntimePeerState[]) => void): () => void; watchPeerLifecycle(callback: (peers: RuntimePeerState[]) => void): () => void; getPeerState(id: string): RuntimePeerState | undefined; resolvePeerRecords(id: string): Promise; getPeerSession(id: string): Promise; listPeerSessions(): Promise; waitForConnectedPeer(id: string, timeoutMs?: number): Promise; getPeerReadiness(id: string, timeoutMs?: number): Promise; resolvePeerIdentity(id: string): Promise; resolveStreamPeer(remoteNodeId: string): Promise; listConnectedPeers(): RuntimePeerState[]; addPeerScope(id: string, scope?: string): RuntimePeerState | undefined; releasePeerScope(id: string, scope?: string): RuntimePeerState | undefined; getPeerScopes(id: string): string[]; isSamePeer(a: string, b: string): boolean; refreshPeerSnapshot(): Promise; subscribeSessions(localDeviceId: string, callback: (session: RuntimeSession) => void | Promise): Promise<() => void>; getAppLimits(): AppLimits; createRoom(roomId?: string): Promise; joinRoom(roomId: string, options?: JoinRoomOptions): Promise; leaveRoom(roomId: string): Promise; getRoomMembers(roomId: string): Promise; watchRoom(roomId: string, callback: (members: RuntimeRoomMember[]) => void): () => void; /** @deprecated Use connect() (no-arg) for lifecycle, or connectTo() for peer connections */ connectByTicket(target: ConnectionTarget): Promise; connectPeer(options: PeerConnectOptions): Promise; connectScopedChannel(options: ScopedChannelOptions): Promise; /** * Returns the per-`{scope, peerNodeId}` observer-side coalescer that * participating scoped guest callers (such as DriveViewClient) use. The * first call for a given key spawns the handle; subsequent calls return the same * handle so concurrent observers share a single underlying dial. * * The handle's `dial` function delegates to this RuntimeClient's existing * `connectPeer` API. It is a compatibility coalescer, not an independent * transport owner, and the Rust registry is not enabled by workspace * production startup. * * Managed `app-user-device` startup/presence/auto-connect must not call * this observer coalescer directly. Scoped protocol observers may use it * only with a narrow `dial` callback that delegates back through * `connectPeer`; the runtime `Client` remains the peer lifecycle owner. */ connectionActor(key: DriveGrantConnectionKey | { scope: string; peerNodeId: string; }, options?: { /** * Compound ticket to dial when the actor's `dial` runs. Used by * the default dial that calls `connectPeer` for callers that * don't supply a custom `dial`. */ ticket?: string; timeoutMs?: number; channelId?: string; /** * Phase 4 escape hatch: callers that need to capture the * resolved `Connection` (e.g. `DriveViewClient` wires its * router/disconnect handler to the connection object) can * supply their own `dial` here. The actor's coalescer still * ensures only one `dial(key)` runs even with N concurrent * `connectionActor(...).ensureReady()` callers — this just * lets the caller decide what "dial" means. */ dial?: (key: DriveGrantConnectionKey) => Promise; }): DriveGrantActorHandle; private assertScopedDialAllowed; private scopedDialCandidateIds; private hasManualDisconnectSuppression; /** Shuts down every scoped observer handle during managed-session teardown. */ shutdownActors(): Promise; openPeerBi(id: string, options?: PeerStreamOptions): Promise<{ connection: Connection; readable: ReadableStream; writable: WritableStream; }>; openPeerNativeBi(id: string, label: string, options?: PeerStreamOptions): Promise<{ connection: Connection; readable: ReadableStream; writable: WritableStream; }>; /** Like openPeerBi but skips the settled_ready requirement — usable for latency probes. */ openPeerBiRaw(id: string, options?: PeerStreamOptions): Promise<{ connection: Connection; readable: ReadableStream; writable: WritableStream; }>; openPeerUni(id: string, options?: PeerStreamOptions): Promise<{ connection: Connection; writable: WritableStream; }>; private waitForBrowserApplicationCrypto; connectToDevice(params: NativeConnectParams): Promise; connectRaw(target: ConnectionTarget): Promise; openBi(nodeId: string): Promise<{ readable: ReadableStream; writable: WritableStream; }>; openUni(nodeId: string): Promise>; onIncomingStream(callback: (stream: IncomingStream) => boolean | void): () => void; registerChannel(descriptor: ChannelDescriptor): void; unregisterChannel(channelId: string): void; listChannels(): ChannelDescriptor[]; onChannelStream(channelId: string, callback: (stream: IncomingStream) => boolean | void): () => void; /** @deprecated Use named channels or the optional `openrtc-file-transfer` package. */ sendExplicitFilePath(connectionId: string, filePath: string, transferId?: string): Promise; /** @deprecated Use named channels or the optional `openrtc-file-transfer` package. */ sendExplicitFileData(params: ExplicitFileDataSendParams): Promise; /** @deprecated Transfer history belongs to the consumer application. */ getTransferHistory(limit?: number): Promise>; /** @deprecated Transfer history belongs to the consumer application. */ deleteTransferJob(jobId: string): Promise; startPresenceLoop(options?: PresenceLoopOptions): Promise; updatePresence(options?: { isOnline?: boolean; ttlMs?: number; metadata?: string; ticket?: string; }): Promise; refreshLivePresence(options?: { metadata?: string; ticket?: string; }): Promise; setOffline(): Promise; cleanupStaleDevices(): Promise; startAutoConnect(localDeviceId?: string): Promise; isConnected(nodeId: string): Promise; disconnectNode(nodeId: string): Promise; disconnectDevice(deviceId: string): Promise; excludeAutoConnect(deviceId: string, excluded: boolean): Promise; disconnectPeer(id: string, scope?: string): Promise; forceDisconnectPeer(id: string): Promise; getPeerHealth(id: string): Promise; getConnectionStates(): Promise; /** * Subscribe to raw backend connection diagnostics. * * This compatibility surface intentionally does not drive peer lifecycle or * UI readiness; use watchPeerStates() for the reducer-owned lifecycle view. */ onStateChange(callback: (state: ConnectionState) => void): Promise<() => void> | (() => void); getConnections(): Connection[]; readyConnections(options?: ReadinessOptions): Connection[]; onConnection(callback: (connection: Connection) => void): () => void; onDisconnection(callback: (connection: Connection) => void): () => void; /** * Observe protected application payloads after the active transport has * normalized them through Connection. Protocol packages use this boundary * so Iroh, WebRTC, and MoQ share one intake path. */ onMessage(callback: (connection: Connection, message: unknown) => void): () => void; onConnectionEvent(callback: (event: ConnectionEvent) => void): () => void; forceReconnect(): void; /** Single-call lifecycle: combines initialize() + start() */ connect(): Promise; /** Disconnect from the runtime (alias for stop()) */ disconnect(): void; /** * Await the provider-neutral terminal lifecycle before destroying this * runtime instance. Consumers that may create a replacement runtime in the * same page should use this instead of composing setOffline(), stop(), and * destroy() themselves: the active adapter owns presence, coordination * sockets, session readers, and scoped connection actors. */ shutdown(): Promise; /** * Terminal teardown of the runtime instance. Unlike stop()/disconnect() * (which only stop the listen loop and are used during normal operation), * destroy() tears down the underlying Client's coordinated dispose path — * document/window listeners, auth token-change subscriptions, and signaling * subscriptions (audit V2). Call this only when the runtime singleton is truly * going away (app shutdown, HMR dispose), never on a routine disconnect. */ destroy(): void; /** Alias for destroy(); supports callers that expect a `dispose()` contract. */ dispose(): void; /** Alias for onIdentityChange */ onAuthChange(callback: (identity: RuntimeAuthIdentity | null) => void): () => void; /** Alias for setAuthContext */ setAuth(context: AuthContext | null): Promise; /** Alias for signInWithPluto */ signIn(): Promise; /** Alias for listDevices */ getDevices(): Promise; /** Device subscription with optional status enrichment */ onDevices(callback: (devices: RuntimeDevice[]) => void): () => void; onDevices(callback: (devices: DeviceStatus[]) => void, options: { status: true; }): () => void; /** Alias for getTicket — returns an invite/ticket string */ getInvite(): Promise; /** Connect to a peer by device ID or options */ connectTo(options: PeerConnectOptions): Promise; /** Alias for waitForConnectedPeer */ waitFor(id: string, timeoutMs?: number): Promise; /** Open a stream to a peer (default: bidirectional) */ openStream(id: string, options?: PeerStreamOptions & { direction?: 'bi' | 'send'; }): Promise<{ connection: Connection; readable?: ReadableStream; writable: WritableStream; }>; openChannelStream(channelId: string, id: string, options?: PeerStreamOptions & { direction?: 'bi' | 'send'; }): Promise<{ connection: Connection; readable?: ReadableStream; writable: WritableStream; }>; /** Alias for onIncomingStream */ onStream(callback: (stream: IncomingStream) => boolean | void): () => void; /** Alias for watchRoom */ onRoomChange(roomId: string, callback: (members: RuntimeRoomMember[]) => void): () => void; /** * Create a scope-filtered session backed by this runtime. * * The session filters all peer-state and connection-state emissions to * peers whose scope tags include `options.scope`, and tags outbound * connections with the same scope for the remote side's ACL layer. * * Disposing the session removes only its own subscriptions and * scope-tagged connections — other sessions on this runtime are unaffected. * * @example * // Guest magic-link viewer — sees only the ticket endpoint, never device peers * const session = runtime.createSession({ scope: 'magic-link', allowPeers: [ticketNodeId] }); * session.watchPeerStates(peers => { ... }); * // On unmount: * session.dispose(); */ createSession(options: SessionOptions): Session; } type RuntimeAdapterWithAuth = ISignalingBackend & { setAuthContext?: (context: AuthContext | null) => Promise | void; }; type RuntimeFactoryOptions = RuntimeClientOptions; interface PlutoRuntimeAssembly { runtime: RuntimeClient; identity: any; setAuthContext(context: AuthContext | null): Promise; syncPlutoAuth(options?: { userId?: string | null; forceRefresh?: boolean; }): Promise; bindPlutoAuthHost(): () => void; signInWithPluto(): Promise; signOut(): Promise; stopManagedSession(): Promise; startManagedSession(options: any): Promise; onAuthChange(callback: (identity: any) => void): () => void; getManagedNodeId(options?: { initializeIfMissing?: boolean; }): Promise; getRuntimeStatus(): Promise; listDeviceStatus(): Promise; watchDeviceStatus(callback: (devices: any[]) => void): () => void; connectDevice(device: any, options: any): Promise; excludeAutoConnect(deviceId: string, excluded: boolean): Promise; } export { DriveGrantActorHandle as D, type PolicySnapshot as P, RuntimeClient as R, type PeerReconciliationStats as a, type PlutoRuntimeAssembly as b, type RuntimeFactoryOptions as c, DriveGrantActorError as d, type DriveGrantActorErrorKind as e, type DriveGrantConnectionKey as f, type DriveGrantActorHandleOptions as g, type DriveGrantActorState as h, DriveGrantActorRegistry as i, type DriveGrantClose as j, type DriveGrantDial as k, type DriveGrantLogicalChannelHandle as l, type DriveGrantPreferredTransport as m, RUNTIME_POLICY as n, driveGrantConnectionKey as o, driveGrantConnectionKeyToString as p, getRuntimePolicy as q };