@dxos/network-manager 0.8.3 → 0.8.4-main.28f8d3d
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/dist/lib/browser/{chunk-LFKR6BAF.mjs → chunk-JUVDHWW4.mjs} +351 -207
- package/dist/lib/browser/chunk-JUVDHWW4.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +37 -10
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/transport/tcp/index.mjs +4 -6
- package/dist/lib/browser/transport/tcp/index.mjs.map +1 -1
- package/dist/lib/node-esm/{chunk-QQY4BF6O.mjs → chunk-HUSU3OKQ.mjs} +351 -207
- package/dist/lib/node-esm/chunk-HUSU3OKQ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1 -1
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +37 -10
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/transport/tcp/index.mjs +10 -2
- package/dist/lib/node-esm/transport/tcp/index.mjs.map +3 -3
- package/dist/types/src/connection-log.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/network-manager.d.ts.map +1 -1
- package/dist/types/src/signal/index.d.ts +2 -2
- package/dist/types/src/signal/index.d.ts.map +1 -1
- package/dist/types/src/signal/swarm-messenger.d.ts +1 -1
- package/dist/types/src/signal/swarm-messenger.d.ts.map +1 -1
- package/dist/types/src/swarm/peer.d.ts +2 -2
- package/dist/types/src/swarm/peer.d.ts.map +1 -1
- package/dist/types/src/swarm/swarm.d.ts +3 -3
- package/dist/types/src/swarm/swarm.d.ts.map +1 -1
- package/dist/types/src/testing/test-builder.d.ts +1 -1
- package/dist/types/src/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/testing/test-wire-protocol.d.ts +1 -1
- package/dist/types/src/testing/test-wire-protocol.d.ts.map +1 -1
- package/dist/types/src/tests/basic-test-suite.d.ts.map +1 -1
- package/dist/types/src/topology/index.d.ts +1 -1
- package/dist/types/src/topology/index.d.ts.map +1 -1
- package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts +2 -2
- package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts.map +1 -1
- package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts +1 -1
- package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts.map +1 -1
- package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts.map +1 -1
- package/dist/types/src/transport/webrtc/rtc-transport-service.d.ts +1 -1
- package/dist/types/src/transport/webrtc/rtc-transport-service.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -20
- package/src/connection-log.ts +1 -1
- package/src/index.ts +1 -1
- package/src/network-manager.ts +1 -1
- package/src/signal/ice.test.ts +1 -1
- package/src/signal/index.ts +2 -2
- package/src/signal/integration.node.test.ts +2 -2
- package/src/signal/swarm-messenger.node.test.ts +1 -1
- package/src/signal/swarm-messenger.ts +1 -1
- package/src/swarm/connection.test.ts +2 -1
- package/src/swarm/connection.ts +4 -4
- package/src/swarm/peer.ts +3 -2
- package/src/swarm/swarm-mapper.ts +1 -1
- package/src/swarm/swarm.test.ts +5 -4
- package/src/swarm/swarm.ts +5 -4
- package/src/testing/test-builder.ts +12 -4
- package/src/testing/test-wire-protocol.ts +2 -2
- package/src/tests/basic-test-suite.ts +3 -2
- package/src/tests/memory-transport.test.ts +4 -2
- package/src/tests/tcp-transport.node.test.ts +4 -2
- package/src/tests/webrtc-transport.test.ts +2 -1
- package/src/topology/index.ts +1 -1
- package/src/transport/tcp/tcp-transport.ts +1 -1
- package/src/transport/webrtc/rtc-connection-factory.ts +1 -1
- package/src/transport/webrtc/rtc-peer-connection.ts +4 -3
- package/src/transport/webrtc/rtc-transport-channel.test.ts +3 -1
- package/src/transport/webrtc/rtc-transport-channel.ts +2 -1
- package/src/transport/webrtc/rtc-transport-factory.ts +3 -2
- package/src/transport/webrtc/rtc-transport-proxy.test.ts +5 -3
- package/src/transport/webrtc/rtc-transport-service.ts +6 -5
- package/src/transport/webrtc/rtc-transport.test.ts +4 -3
- package/dist/lib/browser/chunk-LFKR6BAF.mjs.map +0 -7
- package/dist/lib/node/chunk-2G6RZMS5.cjs +0 -4460
- package/dist/lib/node/chunk-2G6RZMS5.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -71
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/testing/index.cjs +0 -296
- package/dist/lib/node/testing/index.cjs.map +0 -7
- package/dist/lib/node/transport/tcp/index.cjs +0 -191
- package/dist/lib/node/transport/tcp/index.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-QQY4BF6O.mjs.map +0 -7
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/swarm/connection.ts", "../../../src/signal/ice.ts", "../../../src/signal/swarm-messenger.ts", "../../../src/swarm/swarm.ts", "../../../src/swarm/peer.ts", "../../../src/swarm/swarm-mapper.ts", "../../../src/swarm/connection-limiter.ts", "../../../src/connection-log.ts", "../../../src/network-manager.ts", "../../../src/topology/fully-connected-topology.ts", "../../../src/topology/mmst-topology.ts", "../../../src/topology/star-topology.ts", "../../../src/transport/memory-transport.ts", "../../../src/transport/transport.ts", "../../../src/transport/webrtc/rtc-connection-factory.ts", "../../../src/transport/webrtc/rtc-peer-connection.ts", "../../../src/transport/webrtc/rtc-transport-channel.ts", "../../../src/transport/webrtc/rtc-transport-stats.ts", "../../../src/transport/webrtc/utils.ts", "../../../src/transport/webrtc/rtc-transport-factory.ts", "../../../src/transport/webrtc/rtc-transport-proxy.ts", "../../../src/transport/webrtc/rtc-transport-service.ts", "../../../src/wire-protocol.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2021 DXOS.org\n//\n\nimport { DeferredTask, Event, Trigger, scheduleTask, scheduleTaskInterval, sleep, synchronized } from '@dxos/async';\nimport { Context, ContextDisposedError, cancelWithContext } from '@dxos/context';\nimport { ErrorStream } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { type PeerInfo } from '@dxos/messaging';\nimport {\n CancelledError,\n ConnectionResetError,\n ConnectivityError,\n ProtocolError,\n TimeoutError,\n trace,\n} from '@dxos/protocols';\nimport { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';\n\nimport { type SignalMessage, type SignalMessenger } from '../signal';\nimport { type Transport, type TransportFactory, type TransportStats } from '../transport';\nimport { type WireProtocol } from '../wire-protocol';\n\n/**\n * How long to wait before sending the signal in case we receive another signal.\n * This value is increased exponentially.\n */\nconst STARTING_SIGNALLING_DELAY = 10;\n\n/**\n * How long to wait for the transport to establish connectivity, i.e. for the connection to move between CONNECTING and CONNECTED.\n */\nconst TRANSPORT_CONNECTION_TIMEOUT = 10_000;\n\nconst TRANSPORT_STATS_INTERVAL = 5_000;\n\n/**\n * Maximum delay between signal batches.\n */\nconst MAX_SIGNALLING_DELAY = 300;\n\ninterface ConnectionCallbacks {\n /**\n * Connection opened.\n */\n onConnected?: () => void;\n\n /**\n * Connection closed.\n */\n onClosed?: (err?: Error) => void;\n}\n\n/**\n * State machine for each connection.\n */\nexport enum ConnectionState {\n /**\n * Connection is created, but not yet passed through the connection limiter.\n */\n CREATED = 'CREATED',\n\n /**\n * Initial state. Connection is registered but no attempt to connect to the remote peer has been performed.\n * Might mean that we are waiting for the answer signal from the remote peer.\n */\n INITIAL = 'INITIAL',\n\n /**\n * Trying to establish connection.\n */\n CONNECTING = 'CONNECTING',\n\n /**\n * Connection is established.\n */\n CONNECTED = 'CONNECTED',\n\n /**\n * Connection is being closed.\n */\n CLOSING = 'CLOSING',\n\n /**\n * Connection closed.\n */\n CLOSED = 'CLOSED',\n\n ABORTING = 'ABORTING',\n ABORTED = 'ABORTED',\n}\n\n/**\n * Represents a connection to a remote peer.\n * Owns a transport paired together with a wire-protocol.\n */\nexport class Connection {\n private readonly _ctx = new Context();\n private connectedTimeoutContext = new Context();\n\n private _protocolClosed = new Trigger();\n private _transportClosed = new Trigger();\n\n private _state: ConnectionState = ConnectionState.CREATED;\n private _transport: Transport | undefined;\n closeReason?: string;\n\n private _incomingSignalBuffer: Signal[] = [];\n private _outgoingSignalBuffer: Signal[] = [];\n\n readonly stateChanged = new Event<ConnectionState>();\n readonly errors = new ErrorStream();\n\n public _instanceId = PublicKey.random().toHex();\n\n public readonly transportStats = new Event<TransportStats>();\n\n private readonly _signalSendTask = new DeferredTask(this._ctx, async () => {\n await this._flushSignalBuffer();\n });\n\n private _signallingDelay = STARTING_SIGNALLING_DELAY;\n\n constructor(\n public readonly topic: PublicKey,\n public readonly localInfo: PeerInfo,\n public readonly remoteInfo: PeerInfo,\n public readonly sessionId: PublicKey,\n public readonly initiator: boolean,\n private readonly _signalMessaging: SignalMessenger,\n private readonly _protocol: WireProtocol,\n private readonly _transportFactory: TransportFactory,\n private readonly _callbacks?: ConnectionCallbacks,\n ) {\n log.trace('dxos.mesh.connection.construct', {\n sessionId: this.sessionId,\n topic: this.topic,\n localPeer: this.localInfo,\n remotePeer: this.remoteInfo,\n initiator: this.initiator,\n });\n }\n\n @logInfo\n get sessionIdString(): string {\n return this.sessionId.truncate();\n }\n\n get state() {\n return this._state;\n }\n\n get transport() {\n return this._transport;\n }\n\n get protocol() {\n return this._protocol;\n }\n\n /**\n * Create an underlying transport and prepares it for the connection.\n */\n async openConnection(): Promise<void> {\n invariant(this._state === ConnectionState.INITIAL, 'Invalid state.');\n log.trace('dxos.mesh.connection.open-connection', trace.begin({ id: this._instanceId }));\n log.trace('dxos.mesh.connection.open', {\n sessionId: this.sessionId,\n topic: this.topic,\n localPeerId: this.localInfo,\n remotePeerId: this.remoteInfo,\n initiator: this.initiator,\n });\n\n this._changeState(ConnectionState.CONNECTING);\n\n // TODO(dmaretskyi): Initialize only after the transport has established connection.\n this._protocol.open(this.sessionId).catch((err) => {\n this.errors.raise(err);\n });\n\n // TODO(dmaretskyi): Piped streams should do this automatically, but it break's without this code.\n this._protocol.stream.on('close', () => {\n log('protocol stream closed');\n this._protocolClosed.wake();\n this.close({ error: new ProtocolError('protocol stream closed') }).catch((err) => this.errors.raise(err));\n });\n\n scheduleTask(\n this.connectedTimeoutContext,\n async () => {\n log.info(`timeout waiting ${TRANSPORT_CONNECTION_TIMEOUT / 1000}s for transport to connect, aborting`);\n await this.abort(new TimeoutError(`${TRANSPORT_CONNECTION_TIMEOUT / 1000}s for transport to connect`)).catch(\n (err) => this.errors.raise(err),\n );\n },\n TRANSPORT_CONNECTION_TIMEOUT,\n );\n\n invariant(!this._transport);\n this._transport = this._transportFactory.createTransport({\n ownPeerKey: this.localInfo.peerKey,\n remotePeerKey: this.remoteInfo.peerKey,\n topic: this.topic.toHex(),\n initiator: this.initiator,\n stream: this._protocol.stream,\n sendSignal: async (signal) => this._sendSignal(signal),\n sessionId: this.sessionId,\n });\n\n this._transport.connected.once(async () => {\n this._changeState(ConnectionState.CONNECTED);\n await this.connectedTimeoutContext.dispose();\n this._callbacks?.onConnected?.();\n\n scheduleTaskInterval(this._ctx, async () => this._emitTransportStats(), TRANSPORT_STATS_INTERVAL);\n });\n\n this._transport.closed.once(() => {\n this._transport = undefined;\n this._transportClosed.wake();\n log('abort triggered by transport close');\n this.abort().catch((err) => this.errors.raise(err));\n });\n\n this._transport.errors.handle(async (err) => {\n log('transport error:', { err });\n if (!this.closeReason) {\n this.closeReason = err?.message;\n }\n\n // TODO(nf): fix ErrorStream so instanceof works here\n if (err instanceof ConnectionResetError) {\n log.info('aborting due to transport ConnectionResetError');\n this.abort(err).catch((err) => this.errors.raise(err));\n } else if (err instanceof ConnectivityError) {\n log.info('aborting due to transport ConnectivityError');\n this.abort(err).catch((err) => this.errors.raise(err));\n }\n\n if (this._state !== ConnectionState.CLOSED && this._state !== ConnectionState.CLOSING) {\n await this.connectedTimeoutContext.dispose();\n this.errors.raise(err);\n }\n });\n\n await this._transport.open();\n\n // Replay signals that were received before transport was created.\n for (const signal of this._incomingSignalBuffer) {\n void this._transport.onSignal(signal); // TODO(burdon): Remove async?\n }\n\n this._incomingSignalBuffer = [];\n\n log.trace('dxos.mesh.connection.open-connection', trace.end({ id: this._instanceId }));\n }\n\n @synchronized\n // TODO(nf): make the caller responsible for recording the reason and determining flow control.\n // TODO(nf): make abort cancel an existing close in progress.\n async abort(err?: Error): Promise<void> {\n log('abort', { err });\n if (this._state === ConnectionState.CLOSED || this._state === ConnectionState.ABORTED) {\n log(`abort ignored: already ${this._state}`, this.closeReason);\n return;\n }\n\n await this.connectedTimeoutContext.dispose();\n this._changeState(ConnectionState.ABORTING);\n if (!this.closeReason) {\n this.closeReason = err?.message;\n }\n\n await this._ctx.dispose();\n\n log('aborting...', { peerId: this.localInfo, err });\n\n try {\n // Forcefully close the stream flushing any unsent data packets.\n await this._closeProtocol({ abort: true });\n } catch (err: any) {\n log.catch(err);\n }\n\n try {\n // After the transport is closed streams are disconnected.\n await this._closeTransport();\n } catch (err: any) {\n log.catch(err);\n }\n\n try {\n this._callbacks?.onClosed?.(err);\n } catch (err) {\n log.catch(err);\n }\n this._changeState(ConnectionState.ABORTED);\n }\n\n @synchronized\n async close({ error, reason }: { error?: Error; reason?: string } = {}): Promise<void> {\n log('close', { error });\n if (!this.closeReason) {\n this.closeReason = reason ?? error?.message;\n } else {\n this.closeReason += `; ${reason ?? error?.message}`;\n }\n if (\n this._state === ConnectionState.CLOSED ||\n this._state === ConnectionState.ABORTING ||\n this._state === ConnectionState.ABORTED\n ) {\n log('close ignored: already in progress', { state: this._state, error });\n return;\n }\n const lastState = this._state;\n this._changeState(ConnectionState.CLOSING);\n\n await this.connectedTimeoutContext.dispose();\n await this._ctx.dispose();\n\n let abortProtocol = false;\n if (lastState !== ConnectionState.CONNECTED || error != null) {\n log(`graceful close requested when we were in ${lastState} state? aborting`);\n abortProtocol = true;\n }\n\n log('closing...', { peerId: this.localInfo, abortProtocol, error });\n\n try {\n await this._closeProtocol({ abort: abortProtocol });\n } catch (err: any) {\n log.catch(err);\n }\n try {\n // After the transport is closed streams are disconnected.\n await this._closeTransport();\n } catch (err: any) {\n log.catch(err);\n }\n\n log('closed', { peerId: this.localInfo });\n this._changeState(ConnectionState.CLOSED);\n this._callbacks?.onClosed?.(error);\n }\n\n private async _closeProtocol(options?: { abort: boolean }): Promise<void> {\n log('closing protocol', options);\n await Promise.race([options?.abort ? this._protocol.abort() : this._protocol.close(), this._protocolClosed.wait()]);\n log('protocol closed', options);\n }\n\n private async _closeTransport(): Promise<void> {\n log('closing transport');\n await Promise.race([this._transport?.close(), this._transportClosed.wait()]);\n log('transport closed');\n }\n\n private _sendSignal(signal: Signal): void {\n this._outgoingSignalBuffer.push(signal);\n this._signalSendTask.schedule();\n }\n\n private async _flushSignalBuffer(): Promise<void> {\n if (this._outgoingSignalBuffer.length === 0) {\n return;\n }\n\n try {\n if (process.env.NODE_ENV !== 'test') {\n await cancelWithContext(this._ctx, sleep(this._signallingDelay));\n this._signallingDelay = Math.min(this._signallingDelay * 2, MAX_SIGNALLING_DELAY);\n }\n\n const signals = [...this._outgoingSignalBuffer];\n this._outgoingSignalBuffer.length = 0;\n\n await this._signalMessaging.signal({\n author: this.localInfo,\n recipient: this.remoteInfo,\n sessionId: this.sessionId,\n topic: this.topic,\n data: { signalBatch: { signals } },\n });\n } catch (err) {\n // TODO(nf): determine why instanceof doesn't work here\n if (\n err instanceof CancelledError ||\n err instanceof ContextDisposedError ||\n (err instanceof Error && err.message?.includes('CANCELLED'))\n ) {\n return;\n }\n\n // If signal fails treat connection as failed\n log.info('signal message failed to deliver', { err });\n await this.close({ error: new ConnectivityError('signal message failed to deliver', err) });\n }\n }\n\n /**\n * Receive a signal from the remote peer.\n */\n async signal(msg: SignalMessage): Promise<void> {\n invariant(msg.sessionId);\n if (!msg.sessionId.equals(this.sessionId)) {\n log('dropping signal for incorrect session id');\n return;\n }\n invariant(msg.data.signal || msg.data.signalBatch);\n invariant(msg.author.peerKey === this.remoteInfo.peerKey);\n invariant(msg.recipient.peerKey === this.localInfo.peerKey);\n\n const signals = msg.data.signalBatch ? (msg.data.signalBatch.signals ?? []) : [msg.data.signal];\n for (const signal of signals) {\n if (!signal) {\n continue;\n }\n\n if ([ConnectionState.CREATED, ConnectionState.INITIAL].includes(this.state)) {\n log('buffered signal', { peerId: this.localInfo, remoteId: this.remoteInfo, msg: msg.data });\n this._incomingSignalBuffer.push(signal);\n } else {\n invariant(this._transport, 'Connection not ready to accept signals.');\n log('received signal', { peerId: this.localInfo, remoteId: this.remoteInfo, msg: msg.data });\n await this._transport.onSignal(signal);\n }\n }\n }\n\n initiate(): void {\n this._changeState(ConnectionState.INITIAL);\n }\n\n private _changeState(state: ConnectionState): void {\n log('stateChanged', { from: this._state, to: state, peerId: this.localInfo });\n invariant(state !== this._state, 'Already in this state.');\n this._state = state;\n this.stateChanged.emit(state);\n }\n\n private async _emitTransportStats(): Promise<void> {\n const stats = await this.transport?.getStats();\n if (stats) {\n this.transportStats.emit(stats);\n }\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { asyncTimeout } from '@dxos/async';\nimport { log } from '@dxos/log';\nimport { type Runtime } from '@dxos/protocols/proto/dxos/config';\nimport { isNonNullable } from '@dxos/util';\n\nexport interface IceProvider {\n getIceServers: () => Promise<RTCIceServer[]>;\n}\n\nexport const createIceProvider = (iceProviders: Runtime.Services.IceProvider[]): IceProvider => {\n let cachedIceServers: RTCIceServer[];\n return {\n getIceServers: async () => {\n if (cachedIceServers) {\n return cachedIceServers;\n }\n\n cachedIceServers = (\n await Promise.all(\n iceProviders.map(({ urls }) =>\n asyncTimeout(fetch(urls, { method: 'GET' }), 10_000)\n .then((response) => response.json())\n .catch((err) => {\n const isDev = typeof window !== 'undefined' && window.location.href.includes('localhost');\n if (!isDev) {\n log.error('Failed to fetch ICE servers from provider', { urls, err });\n }\n }),\n ),\n )\n )\n .filter(isNonNullable)\n .map(({ iceServers }: { iceServers: RTCIceServer[] }) => iceServers)\n .flat();\n\n return cachedIceServers;\n },\n };\n};\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { type Any } from '@dxos/codec-protobuf';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type Message, type PeerInfo } from '@dxos/messaging';\nimport { TimeoutError } from '@dxos/protocols';\nimport { schema } from '@dxos/protocols/proto';\nimport { type Answer, type SwarmMessage } from '@dxos/protocols/proto/dxos/mesh/swarm';\nimport { ComplexMap, type MakeOptional } from '@dxos/util';\n\nimport { type OfferMessage, type SignalMessage, type SignalMessenger } from './signal-messenger';\n\ninterface OfferRecord {\n resolve: (answer: Answer) => void;\n}\n\nexport type SwarmMessengerOptions = {\n sendMessage: (params: Message) => Promise<void>;\n onOffer: (message: OfferMessage) => Promise<Answer>;\n onSignal: (message: SignalMessage) => Promise<void>;\n topic: PublicKey;\n};\n\nconst SwarmMessage = schema.getCodecForType('dxos.mesh.swarm.SwarmMessage');\n\n/**\n * Adds offer/answer and signal interfaces.\n */\nexport class SwarmMessenger implements SignalMessenger {\n private readonly _ctx = new Context();\n\n private readonly _sendMessage: (msg: Message) => Promise<void>;\n private readonly _onSignal: (message: SignalMessage) => Promise<void>;\n private readonly _onOffer: (message: OfferMessage) => Promise<Answer>;\n private readonly _topic: PublicKey;\n\n private readonly _offerRecords: ComplexMap<PublicKey, OfferRecord> = new ComplexMap((key) => key.toHex());\n\n constructor({ sendMessage, onSignal, onOffer, topic }: SwarmMessengerOptions) {\n this._sendMessage = sendMessage;\n this._onSignal = onSignal;\n this._onOffer = onOffer;\n this._topic = topic;\n }\n\n async receiveMessage({\n author,\n recipient,\n payload,\n }: {\n author: PeerInfo;\n recipient: PeerInfo;\n payload: Any;\n }): Promise<void> {\n if (payload.type_url !== 'dxos.mesh.swarm.SwarmMessage') {\n // Ignore not swarm messages.\n return;\n }\n const message: SwarmMessage = SwarmMessage.decode(payload.value);\n\n if (!this._topic.equals(message.topic)) {\n // Ignore messages from wrong topics.\n return;\n }\n\n log('received', { from: author, to: recipient, msg: message });\n\n if (message.data?.offer) {\n await this._handleOffer({ author, recipient, message });\n } else if (message.data?.answer) {\n await this._resolveAnswers(message);\n } else if (message.data?.signal) {\n await this._handleSignal({ author, recipient, message });\n } else if (message.data?.signalBatch) {\n await this._handleSignal({ author, recipient, message });\n } else {\n log.warn('unknown message', { message });\n }\n }\n\n async signal(message: SignalMessage): Promise<void> {\n invariant(message.data?.signal || message.data?.signalBatch, 'Invalid message');\n await this._sendReliableMessage({\n author: message.author,\n recipient: message.recipient,\n message,\n });\n }\n\n async offer(message: OfferMessage): Promise<Answer> {\n const networkMessage: SwarmMessage = {\n ...message,\n messageId: PublicKey.random(),\n };\n return new Promise<Answer>((resolve, reject) => {\n this._offerRecords.set(networkMessage.messageId!, { resolve });\n this._sendReliableMessage({\n author: message.author,\n recipient: message.recipient,\n message: networkMessage,\n }).catch((err) => reject(err));\n });\n }\n\n private async _sendReliableMessage({\n author,\n recipient,\n message,\n }: {\n author: PeerInfo;\n recipient: PeerInfo;\n message: MakeOptional<SwarmMessage, 'messageId'>;\n }): Promise<void> {\n const networkMessage: SwarmMessage = {\n ...message,\n // Setting unique message_id if it not specified yet.\n messageId: message.messageId ?? PublicKey.random(),\n };\n\n log('sending', { from: author, to: recipient, msg: networkMessage });\n await this._sendMessage({\n author,\n recipient,\n payload: {\n type_url: 'dxos.mesh.swarm.SwarmMessage',\n value: SwarmMessage.encode(networkMessage),\n },\n });\n }\n\n private async _resolveAnswers(message: SwarmMessage): Promise<void> {\n invariant(message.data?.answer?.offerMessageId, 'No offerMessageId');\n const offerRecord = this._offerRecords.get(message.data.answer.offerMessageId);\n if (offerRecord) {\n this._offerRecords.delete(message.data.answer.offerMessageId);\n invariant(message.data?.answer, 'No answer');\n log('resolving', { answer: message.data.answer });\n offerRecord.resolve(message.data.answer);\n }\n }\n\n private async _handleOffer({\n author,\n recipient,\n message,\n }: {\n author: PeerInfo;\n recipient: PeerInfo;\n message: SwarmMessage;\n }): Promise<void> {\n invariant(message.data.offer, 'No offer');\n const offerMessage: OfferMessage = {\n author,\n recipient,\n ...message,\n data: { offer: message.data.offer },\n };\n const answer = await this._onOffer(offerMessage);\n answer.offerMessageId = message.messageId;\n try {\n await this._sendReliableMessage({\n author: recipient,\n recipient: author,\n message: {\n topic: message.topic,\n sessionId: message.sessionId,\n data: { answer },\n },\n });\n } catch (err) {\n if (err instanceof TimeoutError) {\n log.info('timeout sending answer to offer', { err });\n } else {\n log.info('error sending answer to offer', { err });\n }\n }\n }\n\n private async _handleSignal({\n author,\n recipient,\n message,\n }: {\n author: PeerInfo;\n recipient: PeerInfo;\n message: SwarmMessage;\n }): Promise<void> {\n invariant(message.messageId);\n invariant(message.data.signal || message.data.signalBatch, 'Invalid message');\n const signalMessage: SignalMessage = {\n author,\n recipient,\n ...message,\n data: {\n signal: message.data.signal,\n signalBatch: message.data.signalBatch,\n },\n };\n\n await this._onSignal(signalMessage);\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { Event, scheduleTask, sleep, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { ErrorStream } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { type ListeningHandle, type Messenger, type PeerInfo, PeerInfoHash, type SwarmEvent } from '@dxos/messaging';\nimport { trace } from '@dxos/protocols';\nimport { type Answer } from '@dxos/protocols/proto/dxos/mesh/swarm';\nimport { ComplexMap, isNonNullable } from '@dxos/util';\n\nimport { type OfferMessage, type SignalMessage, SwarmMessenger } from '../signal';\nimport { type SwarmController, type Topology } from '../topology';\nimport { type TransportFactory } from '../transport';\nimport { type Topic } from '../types';\nimport { type WireProtocolProvider } from '../wire-protocol';\n\nimport { type Connection, ConnectionState } from './connection';\nimport { type ConnectionLimiter } from './connection-limiter';\nimport { Peer } from './peer';\n\nconst INITIATION_DELAY = 100;\n\n// TODO(burdon): Factor out.\nconst getClassName = (obj: any) => Object.getPrototypeOf(obj).constructor.name;\n\n/**\n * A single peer's view of the swarm.\n * Manages a set of peers subscribed on the same topic.\n * Routes signal events and maintains swarm topology.\n */\nexport class Swarm {\n private readonly _swarmMessenger: SwarmMessenger;\n\n private _ctx = new Context();\n\n private _listeningHandle?: ListeningHandle = undefined;\n\n /**\n * PeerInfo -> Peer.\n * @internal\n */\n readonly _peers = new ComplexMap<PeerInfo, Peer>(PeerInfoHash);\n\n /**\n * Unique id of the swarm, local to the current peer, generated when swarm is joined.\n */\n @logInfo\n readonly _instanceId = PublicKey.random().toHex();\n\n /**\n * New connection to a peer is started.\n * @internal\n */\n readonly connectionAdded = new Event<Connection>();\n\n /**\n * Connection to a peer is dropped.\n * @internal\n */\n readonly disconnected = new Event<PeerInfo>();\n\n /**\n * Connection is established to a new peer.\n * @internal\n */\n readonly connected = new Event<PeerInfo>();\n\n readonly errors = new ErrorStream();\n\n // TODO(burdon): Swarm => Peer.create/destroy =< Connection.open/close\n\n // TODO(burdon): Pass in object.\n constructor(\n private readonly _topic: PublicKey,\n private readonly _ownPeer: PeerInfo,\n private _topology: Topology,\n private readonly _protocolProvider: WireProtocolProvider,\n private readonly _messenger: Messenger,\n private readonly _transportFactory: TransportFactory,\n private readonly _label: string | undefined,\n private readonly _connectionLimiter: ConnectionLimiter,\n private readonly _initiationDelay = INITIATION_DELAY,\n ) {\n log.trace(\n 'dxos.mesh.swarm.constructor',\n trace.begin({ id: this._instanceId, data: { topic: this._topic.toHex(), peer: this._ownPeer } }),\n );\n log('creating swarm', { peerId: _ownPeer });\n _topology.init(this._getSwarmController());\n\n this._swarmMessenger = new SwarmMessenger({\n sendMessage: async (msg) => await this._messenger.sendMessage(msg),\n onSignal: async (msg) => await this.onSignal(msg),\n onOffer: async (msg) => await this.onOffer(msg),\n topic: this._topic,\n });\n log.trace('dxos.mesh.swarm.constructor', trace.end({ id: this._instanceId }));\n }\n\n get connections() {\n return Array.from(this._peers.values())\n .map((peer) => peer.connection)\n .filter(isNonNullable);\n }\n\n get ownPeerId() {\n return PublicKey.from(this._ownPeer.peerKey);\n }\n\n @logInfo\n get ownPeer() {\n return this._ownPeer;\n }\n\n /**\n * Custom label assigned to this swarm. Used in devtools to display human-readable names for swarms.\n */\n get label(): string | undefined {\n return this._label;\n }\n\n @logInfo\n get topic(): Topic {\n return this._topic;\n }\n\n async open(): Promise<void> {\n invariant(!this._listeningHandle);\n this._listeningHandle = await this._messenger.listen({\n peer: this._ownPeer,\n payloadType: 'dxos.mesh.swarm.SwarmMessage',\n onMessage: async (message) => {\n await this._swarmMessenger\n .receiveMessage(message)\n // TODO(nf): discriminate between errors\n .catch((err) => log.info('Error while receiving message', { err }));\n },\n });\n }\n\n async destroy(): Promise<void> {\n log('destroying...');\n await this._listeningHandle?.unsubscribe();\n this._listeningHandle = undefined;\n\n await this._ctx.dispose();\n await this._topology.destroy();\n await Promise.all(Array.from(this._peers.keys()).map((key) => this._destroyPeer(key, 'swarm destroyed')));\n log('destroyed');\n }\n\n async setTopology(topology: Topology): Promise<void> {\n invariant(!this._ctx.disposed, 'Swarm is offline');\n if (topology === this._topology) {\n return;\n }\n log('setting topology', {\n previous: getClassName(this._topology),\n topology: getClassName(topology),\n });\n\n await this._topology.destroy();\n this._topology = topology;\n this._topology.init(this._getSwarmController());\n this._topology.update();\n }\n\n @synchronized\n async onSwarmEvent(swarmEvent: SwarmEvent): Promise<void> {\n log('swarm event', { swarmEvent }); // TODO(burdon): Stringify.\n\n if (this._ctx.disposed) {\n log('swarm event ignored for disposed swarm');\n return;\n }\n\n if (swarmEvent.peerAvailable) {\n const peerId = swarmEvent.peerAvailable.peer.peerKey;\n if (peerId !== this._ownPeer.peerKey) {\n log('new peer', { peerId });\n const peer = this._getOrCreatePeer(swarmEvent.peerAvailable.peer);\n peer.advertizing = true;\n }\n } else if (swarmEvent.peerLeft) {\n const peer = this._peers.get(swarmEvent.peerLeft.peer);\n if (peer) {\n peer.advertizing = false;\n // Destroy peer only if there is no p2p-connection established. Otherwise, let peers go through\n // the graceful shutdown protocol.\n if (this._isConnectionEstablishmentInProgress(peer)) {\n log(`destroying peer, state: ${peer.connection?.state}`);\n void this._destroyPeer(swarmEvent.peerLeft.peer, 'peer left').catch((err) => log.catch(err));\n }\n } else {\n log('received peerLeft but no peer found', { peer: swarmEvent.peerLeft.peer.peerKey });\n }\n }\n\n this._topology.update();\n }\n\n @synchronized\n async onOffer(message: OfferMessage): Promise<Answer> {\n log('offer', { message });\n if (this._ctx.disposed) {\n log('ignored for disposed swarm');\n return { accept: false };\n }\n\n // Id of the peer offering us the connection.\n invariant(message.author);\n if (message.recipient.peerKey !== this._ownPeer.peerKey) {\n log('rejecting offer with incorrect peerId', { message });\n return { accept: false };\n }\n if (!message.topic?.equals(this._topic)) {\n log('rejecting offer with incorrect topic', { message });\n return { accept: false };\n }\n\n const peer = this._getOfferSenderPeer(message.author);\n const answer = await peer.onOffer(message);\n this._topology.update();\n return answer;\n }\n\n private _getOfferSenderPeer(senderInfo: PeerInfo): Peer {\n const peer = this._getOrCreatePeer(senderInfo);\n\n // Handle fast peer reconnect (eg. tab reload)\n const connectionState = peer.connection?.state;\n if (connectionState === ConnectionState.CLOSING || connectionState === ConnectionState.ABORTING) {\n this._peers.delete(peer.remoteInfo);\n this.disconnected.emit(peer.remoteInfo);\n return this._getOrCreatePeer(peer.remoteInfo);\n }\n\n return peer;\n }\n\n async onSignal(message: SignalMessage): Promise<void> {\n log('signal', { message });\n if (this._ctx.disposed) {\n log.info('ignored for offline swarm');\n return;\n }\n invariant(\n message.recipient.peerKey === this._ownPeer.peerKey,\n `Invalid signal peer id expected=${this.ownPeerId}, actual=${message.recipient}`,\n );\n invariant(message.topic?.equals(this._topic));\n invariant(message.author);\n\n const peer = this._getOrCreatePeer(message.author);\n await peer.onSignal(message);\n }\n\n // For debug purposes\n @synchronized\n async goOffline(): Promise<void> {\n await this._ctx.dispose();\n await Promise.all([...this._peers.keys()].map((peerId) => this._destroyPeer(peerId, 'goOffline')));\n }\n\n // For debug purposes\n @synchronized\n async goOnline(): Promise<void> {\n this._ctx = new Context();\n }\n\n private _getOrCreatePeer(peerInfo: PeerInfo): Peer {\n invariant(peerInfo.peerKey, 'PeerInfo.peerKey is required');\n let peer = this._peers.get(peerInfo);\n if (!peer) {\n peer = new Peer(\n peerInfo,\n this._topic,\n this._ownPeer,\n this._swarmMessenger,\n this._protocolProvider,\n this._transportFactory,\n this._connectionLimiter,\n {\n onInitiated: (connection) => {\n this.connectionAdded.emit(connection);\n },\n onConnected: () => {\n this.connected.emit(peerInfo);\n },\n onDisconnected: async () => {\n if (this._isUnregistered(peer)) {\n log.verbose('ignored onDisconnected for unregistered peer');\n return;\n }\n if (!peer!.advertizing) {\n await this._destroyPeer(peerInfo, 'peer disconnected');\n }\n\n this.disconnected.emit(peerInfo);\n this._topology.update();\n },\n onRejected: () => {\n // If the peer rejected our connection remove it from the set of candidates.\n // TODO(dmaretskyi): Set flag instead.\n if (!this._isUnregistered(peer)) {\n log('peer rejected connection', { peerInfo });\n void this._destroyPeer(peerInfo, 'peer rejected connection');\n }\n },\n onAccepted: () => {\n this._topology.update();\n },\n onOffer: (remoteId) => {\n return this._topology.onOffer(PublicKey.from(remoteId.peerKey));\n },\n onPeerAvailable: () => {\n this._topology.update();\n },\n },\n );\n this._peers.set(peerInfo, peer);\n }\n\n return peer;\n }\n\n private async _destroyPeer(peerInfo: PeerInfo, reason?: string): Promise<void> {\n log('destroy peer', { peerKey: peerInfo.peerKey, reason });\n const peer = this._peers.get(peerInfo);\n invariant(peer);\n this._peers.delete(peerInfo);\n await peer.safeDestroy(reason);\n }\n\n private _getSwarmController(): SwarmController {\n return {\n getState: () => ({\n ownPeerId: PublicKey.from(this._ownPeer.peerKey),\n connected: Array.from(this._peers.entries())\n .filter(([_, peer]) => peer.connection)\n .map(([info]) => PublicKey.from(info.peerKey)),\n candidates: Array.from(this._peers.entries())\n .filter(([_, peer]) => !peer.connection && peer.advertizing && peer.availableToConnect)\n .map(([info]) => PublicKey.from(info.peerKey)),\n allPeers: Array.from(this._peers.keys()).map((info) => PublicKey.from(info.peerKey)),\n }),\n connect: (peer) => {\n if (this._ctx.disposed) {\n return;\n }\n\n // Run in a separate non-blocking task.\n scheduleTask(this._ctx, async () => {\n try {\n await this._initiateConnection({ peerKey: peer.toHex() });\n } catch (err: any) {\n log('initiation error', err);\n }\n });\n },\n disconnect: async (peer) => {\n if (this._ctx.disposed) {\n return;\n }\n\n // Run in a separate non-blocking task.\n scheduleTask(this._ctx, async () => {\n await this._closeConnection({ peerKey: peer.toHex() });\n this._topology.update();\n });\n },\n };\n }\n\n /**\n * Creates a connection then sends message over signal network.\n */\n private async _initiateConnection(remotePeer: PeerInfo): Promise<void> {\n const ctx = this._ctx; // Copy to avoid getting reset while sleeping.\n\n // It is likely that the other peer will also try to connect to us at the same time.\n // If our peerId is higher, we will wait for a bit so that other peer has a chance to connect first.\n const peer = this._getOrCreatePeer(remotePeer);\n if (remotePeer.peerKey < this._ownPeer.peerKey) {\n log('initiation delay', { remotePeer });\n await sleep(this._initiationDelay);\n }\n if (ctx.disposed) {\n return;\n }\n\n if (this._isUnregistered(peer)) {\n throw new Error('Peer left during initiation delay');\n }\n\n if (peer.connection) {\n // Do nothing if peer is already connected.\n return;\n }\n\n log('initiating connection...', { remotePeer });\n await peer.initiateConnection();\n this._topology.update();\n log('initiated', { remotePeer });\n }\n\n private async _closeConnection(peerInfo: PeerInfo): Promise<void> {\n const peer = this._peers.get(peerInfo);\n if (!peer) {\n return;\n }\n\n await peer.closeConnection();\n }\n\n private _isConnectionEstablishmentInProgress(peer: Peer): boolean {\n if (!peer.connection) {\n return true;\n }\n return [ConnectionState.INITIAL, ConnectionState.CREATED, ConnectionState.CONNECTING].includes(\n peer.connection.state,\n );\n }\n\n private _isUnregistered(peer?: Peer): boolean {\n return !peer || this._peers.get(peer.remoteInfo) !== peer;\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Event, scheduleTask, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type PeerInfo } from '@dxos/messaging';\nimport { CancelledError, SystemError } from '@dxos/protocols';\nimport { type Answer } from '@dxos/protocols/proto/dxos/mesh/swarm';\n\nimport { type OfferMessage, type SignalMessage, type SignalMessenger } from '../signal';\nimport { type TransportFactory } from '../transport';\nimport { type WireProtocolProvider } from '../wire-protocol';\n\nimport { Connection, ConnectionState } from './connection';\nimport { type ConnectionLimiter } from './connection-limiter';\n\nexport class ConnectionDisplacedError extends SystemError {\n constructor() {\n super('Connection displaced by remote initiator.');\n }\n}\n\ninterface PeerCallbacks {\n /**\n * Connection attempt initiated.\n */\n onInitiated: (connection: Connection) => void;\n\n /**\n * Connection opened.\n */\n onConnected: () => void;\n\n /**\n * Connection closed.\n */\n onDisconnected: () => void;\n\n /**\n * Peer accepted our offer to connect.\n */\n onAccepted: () => void;\n\n /**\n * Peer rejected our offer to connect.\n */\n onRejected: () => void;\n\n /**\n * Returns true if the remote peer's offer should be accepted.\n */\n onOffer: (remote: PeerInfo) => Promise<boolean>;\n\n /**\n * Peer is available to connect.\n */\n onPeerAvailable: () => void;\n}\n\n/**\n * Minimum time the connection needs to be open to not incur a cool-down timer for this peer after the connection closes.\n */\nconst CONNECTION_COUNTS_STABLE_AFTER = 5_000;\n\n/**\n * State of remote peer during the lifetime of a swarm connection.\n * Can open and close multiple connections to the remote peer.\n */\nexport class Peer {\n /**\n * Will be available to connect after this time.\n */\n private _availableAfter = 0;\n public availableToConnect = true;\n private _lastConnectionTime?: number;\n\n private readonly _ctx = new Context();\n private _connectionCtx?: Context;\n\n public connection?: Connection;\n\n /**\n * Whether the peer is currently advertizing itself on the signal-network.\n */\n public advertizing = false;\n\n public initiating = false;\n\n public readonly connectionDisplaced = new Event<Connection>();\n\n constructor(\n public readonly remoteInfo: PeerInfo,\n public readonly topic: PublicKey,\n public readonly localInfo: PeerInfo,\n private readonly _signalMessaging: SignalMessenger,\n private readonly _protocolProvider: WireProtocolProvider,\n private readonly _transportFactory: TransportFactory,\n private readonly _connectionLimiter: ConnectionLimiter,\n private readonly _callbacks: PeerCallbacks,\n ) {}\n\n /**\n * Respond to remote offer.\n */\n async onOffer(message: OfferMessage): Promise<Answer> {\n const remote = message.author;\n\n if (\n this.connection &&\n ![ConnectionState.CREATED, ConnectionState.INITIAL, ConnectionState.CONNECTING].includes(this.connection.state)\n ) {\n log.info(`received offer when connection already in ${this.connection.state} state`);\n return { accept: false };\n }\n // Check if we are already trying to connect to that peer.\n if (this.connection || this.initiating) {\n // Determine the \"polite\" peer (the one that will accept offers).\n // Peer with the highest Id closes its connection, and accepts remote peer's offer.\n if (remote.peerKey < this.localInfo.peerKey) {\n // TODO(nf): Gets stuck when remote connection is aborted (i.e. closed tab).\n log('close local connection', {\n localPeer: this.localInfo,\n topic: this.topic,\n remotePeer: this.remoteInfo,\n sessionId: this.connection?.sessionId,\n });\n\n if (this.connection) {\n // Close our connection and accept remote peer's connection.\n await this.closeConnection(new ConnectionDisplacedError());\n }\n } else {\n // Continue with our origination attempt, the remote peer will close its connection and accept ours.\n return { accept: false };\n }\n }\n\n if (await this._callbacks.onOffer(remote)) {\n if (!this.connection) {\n // Connection might have been already established.\n invariant(message.sessionId);\n const connection = this._createConnection(false, message.sessionId);\n\n try {\n await this._connectionLimiter.connecting(message.sessionId);\n connection.initiate();\n\n await connection.openConnection();\n } catch (err: any) {\n if (!(err instanceof CancelledError)) {\n log.info('connection error', { topic: this.topic, peerId: this.localInfo, remoteId: this.remoteInfo, err });\n }\n\n // Calls `onStateChange` with CLOSED state.\n await this.closeConnection(err);\n }\n\n return { accept: true };\n }\n }\n return { accept: false };\n }\n\n /**\n * Initiate a connection to the remote peer.\n */\n async initiateConnection(): Promise<void> {\n invariant(!this.initiating, 'Initiation in progress.');\n invariant(!this.connection, 'Already connected.');\n const sessionId = PublicKey.random();\n log('initiating...', { local: this.localInfo, topic: this.topic, remote: this.remoteInfo, sessionId });\n\n const connection = this._createConnection(true, sessionId);\n this.initiating = true;\n\n let answer: Answer;\n try {\n await this._connectionLimiter.connecting(sessionId);\n connection.initiate();\n\n answer = await this._signalMessaging.offer({\n author: this.localInfo,\n recipient: this.remoteInfo,\n sessionId,\n topic: this.topic,\n data: { offer: {} },\n });\n log('received', { answer, topic: this.topic, local: this.localInfo, remote: this.remoteInfo });\n if (connection.state !== ConnectionState.INITIAL) {\n log('ignoring response');\n return;\n }\n } catch (err: any) {\n log('initiation error: send offer', { err, topic: this.topic, local: this.localInfo, remote: this.remoteInfo });\n await connection.abort(err);\n throw err;\n } finally {\n this.initiating = false;\n }\n\n try {\n if (!answer.accept) {\n this._callbacks.onRejected();\n return;\n }\n } catch (err: any) {\n log('initiation error: accept answer', {\n err,\n topic: this.topic,\n local: this.localInfo,\n remote: this.remoteInfo,\n });\n await connection.abort(err);\n throw err;\n } finally {\n this.initiating = false;\n }\n\n try {\n log('opening connection as initiator');\n await connection.openConnection();\n this._callbacks.onAccepted();\n } catch (err: any) {\n log('initiation error: open connection', {\n err,\n topic: this.topic,\n local: this.localInfo,\n remote: this.remoteInfo,\n });\n // TODO(nf): unsure when this will be called and the connection won't abort itself. but if it does fall through we should probably abort and not close.\n log.warn('closing connection due to unhandled error on openConnection', { err });\n // Calls `onStateChange` with CLOSED state.\n await this.closeConnection(err);\n throw err;\n } finally {\n this.initiating = false;\n }\n }\n\n /**\n * Create new connection.\n * Either we're initiating a connection or creating one in response to an offer from the other peer.\n */\n private _createConnection(initiator: boolean, sessionId: PublicKey): Connection {\n log('creating connection', {\n topic: this.topic,\n peerId: this.localInfo,\n remoteId: this.remoteInfo,\n initiator,\n sessionId,\n });\n invariant(!this.connection, 'Already connected.');\n\n const connection = new Connection(\n this.topic,\n this.localInfo,\n this.remoteInfo,\n sessionId,\n initiator,\n this._signalMessaging,\n // TODO(dmaretskyi): Init only when connection is established.\n this._protocolProvider({\n initiator,\n localPeerId: PublicKey.from(this.localInfo.peerKey),\n remotePeerId: PublicKey.from(this.remoteInfo.peerKey),\n topic: this.topic,\n }),\n this._transportFactory,\n {\n onConnected: () => {\n this.availableToConnect = true;\n this._lastConnectionTime = Date.now();\n this._callbacks.onConnected();\n\n this._connectionLimiter.doneConnecting(sessionId);\n log.trace('dxos.mesh.connection.connected', {\n topic: this.topic,\n localPeerId: this.localInfo,\n remotePeerId: this.remoteInfo,\n sessionId,\n initiator,\n });\n },\n onClosed: (err) => {\n const logMeta = { topic: this.topic, peerId: this.localInfo, remoteId: this.remoteInfo, initiator };\n log('connection closed', logMeta);\n\n // Make sure none of the connections are stuck in the limiter.\n this._connectionLimiter.doneConnecting(sessionId);\n\n invariant(this.connection === connection, 'Connection mismatch (race condition).');\n\n log.trace('dxos.mesh.connection.closed', {\n topic: this.topic,\n localPeerId: this.localInfo,\n remotePeerId: this.remoteInfo,\n sessionId,\n initiator,\n });\n\n if (err instanceof ConnectionDisplacedError) {\n this.connectionDisplaced.emit(this.connection);\n } else {\n if (this._lastConnectionTime && this._lastConnectionTime + CONNECTION_COUNTS_STABLE_AFTER < Date.now()) {\n // If we're closing the connection, and it has been connected for a while, reset the backoff.\n this._availableAfter = 0;\n } else {\n this.availableToConnect = false;\n this._availableAfter = increaseInterval(this._availableAfter);\n }\n\n this._callbacks.onDisconnected();\n\n scheduleTask(\n this._connectionCtx!,\n () => {\n log('peer became available', logMeta);\n this.availableToConnect = true;\n this._callbacks.onPeerAvailable();\n },\n this._availableAfter,\n );\n }\n\n this.connection = undefined;\n },\n },\n );\n this._callbacks.onInitiated(connection);\n\n void this._connectionCtx?.dispose();\n this._connectionCtx = this._ctx.derive();\n\n connection.errors.handle((err) => {\n log.info('connection error, closing', {\n topic: this.topic,\n peerId: this.localInfo,\n remoteId: this.remoteInfo,\n initiator,\n err,\n });\n log.trace('dxos.mesh.connection.error', {\n topic: this.topic,\n localPeerId: this.localInfo,\n remotePeerId: this.remoteInfo,\n sessionId,\n initiator,\n err,\n });\n\n // Calls `onStateChange` with CLOSED state.\n void this.closeConnection(err);\n });\n\n this.connection = connection;\n\n return connection;\n }\n\n async closeConnection(err?: Error): Promise<void> {\n if (!this.connection) {\n return;\n }\n\n const connection = this.connection;\n\n log('closing...', { peerId: this.remoteInfo, sessionId: connection.sessionId });\n\n // Triggers `onStateChange` callback which will clean up the connection.\n // Won't throw.\n await connection.close({ error: err });\n\n log('closed', { peerId: this.remoteInfo, sessionId: connection.sessionId });\n }\n\n async onSignal(message: SignalMessage): Promise<void> {\n if (!this.connection) {\n log('dropping signal message for non-existent connection', { message });\n return;\n }\n\n await this.connection.signal(message);\n }\n\n @synchronized\n async safeDestroy(reason?: string): Promise<void> {\n await this._ctx.dispose();\n log('Destroying peer', { peerId: this.remoteInfo, topic: this.topic });\n\n // Won't throw.\n await this?.connection?.close({ reason });\n }\n}\n\nconst increaseInterval = (interval: number) => {\n if (interval === 0) {\n return 50;\n } else if (interval < 500) {\n return 500;\n } else if (interval < 1000) {\n return 1000;\n } else if (interval < 5_000) {\n return 5_000;\n }\n return 10_000;\n};\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { type CleanupFn, Event, SubscriptionList } from '@dxos/async';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { type PeerInfo as MessagingPeer, PeerInfoHash } from '@dxos/messaging';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type ConnectionState } from './connection';\nimport { type Swarm } from './swarm';\n\n/**\n * State of the connection to the remote peer with additional info derived from network mapping.\n */\nexport type PeerState = ConnectionState | 'INDIRECTLY_CONNECTED' | 'ME';\n\n/**\n * Information about remote peer, directly or indirectly connected.\n */\nexport interface PeerInfo {\n id: PublicKey;\n state: PeerState;\n connections: PublicKey[];\n}\n\nexport class SwarmMapper {\n private readonly _subscriptions = new SubscriptionList();\n private readonly _connectionSubscriptions = new ComplexMap<MessagingPeer, CleanupFn>(PeerInfoHash);\n private readonly _peers = new ComplexMap<MessagingPeer, PeerInfo>(PeerInfoHash);\n\n readonly mapUpdated = new Event<PeerInfo[]>();\n\n get peers(): PeerInfo[] {\n return Array.from(this._peers.values());\n }\n\n constructor(private readonly _swarm: Swarm) {\n this._subscriptions.add(\n _swarm.connectionAdded.on((connection) => {\n this._update();\n this._connectionSubscriptions.set(\n connection.remoteInfo,\n connection.stateChanged.on(() => {\n this._update();\n }),\n );\n }),\n );\n\n this._subscriptions.add(\n _swarm.disconnected.on((peerId) => {\n this._connectionSubscriptions.get(peerId)?.();\n this._connectionSubscriptions.delete(peerId);\n this._update();\n }),\n );\n\n // if (_presence) {\n // this._subscriptions.add(_presence.graphUpdated.on(() => {\n // this._update();\n // }));\n // }\n\n // TODO(burdon): Do not call from constructor.\n this._update();\n }\n\n private _update(): void {\n log('updating swarm');\n\n this._peers.clear();\n this._peers.set(this._swarm.ownPeer, {\n id: this._swarm.ownPeerId,\n state: 'ME', // TODO(burdon): Enum (rename \"local\").\n connections: [],\n });\n\n for (const connection of this._swarm.connections) {\n this._peers.set(connection.remoteInfo, {\n id: PublicKey.from(connection.remoteInfo.peerKey),\n state: connection.state,\n connections: [this._swarm.ownPeerId],\n });\n }\n\n // if (this._presence) {\n // this._presence.graph.forEachNode((node: any) => {\n // const id = PublicKey.fromHex(node.id);\n // if (this._peers.has(id)) {\n // return;\n // }\n\n // this._peers.set(id, {\n // id,\n // state: 'INDIRECTLY_CONNECTED',\n // connections: []\n // });\n // });\n\n // this._presence.graph.forEachLink((link: any) => {\n // const from = PublicKey.from(link.fromId);\n // const to = PublicKey.from(link.toId);\n // // Ignore connections to self, they are already handled.\n // if (!from.equals(this._swarm.ownPeerId) && !to.equals(this._swarm.ownPeerId)) {\n // this._peers.get(from)!.connections.push(to);\n // }\n // });\n // }\n\n log('graph changed', {\n directConnections: this._swarm.connections.length,\n totalPeersInSwarm: this._peers.size,\n });\n\n this.mapUpdated.emit(Array.from(this._peers.values()));\n }\n\n // TODO(burdon): Async open/close.\n destroy(): void {\n Array.from(this._connectionSubscriptions.values()).forEach((cb) => cb());\n this._connectionSubscriptions.clear();\n this._subscriptions.clear();\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { DeferredTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { CancelledError } from '@dxos/protocols';\nimport { ComplexMap } from '@dxos/util';\n\nexport const MAX_CONCURRENT_INITIATING_CONNECTIONS = 50;\n\nexport type ConnectionLimiterOptions = {\n maxConcurrentInitConnections?: number;\n};\n\n/**\n * Limits the amount of concurrent connections with 'CONNECTING' state.\n */\nexport class ConnectionLimiter {\n private readonly _ctx = new Context();\n private readonly _maxConcurrentInitConnections;\n /**\n * Queue of promises to resolve when initiating connections amount is below the limit.\n */\n private readonly _waitingPromises = new ComplexMap<PublicKey, { resolve: () => void; reject: (err: Error) => void }>(\n PublicKey.hash,\n );\n\n resolveWaitingPromises = new DeferredTask(this._ctx, async () => {\n Array.from(this._waitingPromises.values())\n .slice(0, this._maxConcurrentInitConnections)\n .forEach(({ resolve }) => {\n resolve();\n });\n });\n\n constructor({ maxConcurrentInitConnections = MAX_CONCURRENT_INITIATING_CONNECTIONS }: ConnectionLimiterOptions = {}) {\n this._maxConcurrentInitConnections = maxConcurrentInitConnections;\n }\n\n /**\n * @returns Promise that resolves in queue when connections amount with 'CONNECTING' state is below the limit.\n */\n async connecting(sessionId: PublicKey): Promise<void> {\n invariant(!this._waitingPromises.has(sessionId), 'Peer is already waiting for connection');\n log('waiting', { sessionId });\n await new Promise<void>((resolve, reject) => {\n this._waitingPromises.set(sessionId, {\n resolve,\n reject,\n });\n this.resolveWaitingPromises.schedule();\n });\n log('allow', { sessionId });\n }\n\n /**\n * Rejects promise returned by `connecting` method.\n */\n doneConnecting(sessionId: PublicKey): void {\n log('done', { sessionId });\n if (!this._waitingPromises.has(sessionId)) {\n return;\n }\n this._waitingPromises.get(sessionId)!.reject(new CancelledError());\n this._waitingPromises.delete(sessionId);\n this.resolveWaitingPromises.schedule();\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { raise } from '@dxos/debug';\nimport { PublicKey } from '@dxos/keys';\nimport { type ConnectionInfo, type SwarmInfo } from '@dxos/protocols/proto/dxos/devtools/swarm';\nimport { type MuxerStats } from '@dxos/teleport';\nimport { ComplexMap } from '@dxos/util';\n\nimport { ConnectionState, type Swarm } from './swarm';\nimport { type WireProtocol } from './wire-protocol';\n\nconst CONNECTION_GC_THRESHOLD = 1000 * 60 * 15;\n\nexport enum EventType {\n CONNECTION_STATE_CHANGED = 'CONNECTION_STATE_CHANGED',\n PROTOCOL_ERROR = 'PROTOCOL_ERROR',\n PROTOCOL_EXTENSIONS_INITIALIZED = 'PROTOCOL_EXTENSIONS_INITIALIZED',\n PROTOCOL_EXTENSIONS_HANDSHAKE = 'PROTOCOL_EXTENSIONS_HANDSHAKE',\n PROTOCOL_HANDSHAKE = 'PROTOCOL_HANDSHAKE',\n}\n\nexport class ConnectionLog {\n /**\n * SwarmId => info\n */\n private readonly _swarms = new ComplexMap<PublicKey, SwarmInfo>(PublicKey.hash);\n\n readonly update = new Event();\n\n getSwarmInfo(swarmId: PublicKey): SwarmInfo {\n return this._swarms.get(swarmId) ?? raise(new Error(`Swarm not found: ${swarmId}`));\n }\n\n get swarms(): SwarmInfo[] {\n return Array.from(this._swarms.values());\n }\n\n joinedSwarm(swarm: Swarm): void {\n const info: SwarmInfo = {\n id: PublicKey.from(swarm._instanceId),\n topic: swarm.topic,\n isActive: true,\n label: swarm.label,\n connections: [],\n };\n\n this._swarms.set(PublicKey.from(swarm._instanceId), info);\n this.update.emit();\n\n swarm.connectionAdded.on((connection) => {\n const connectionInfo: ConnectionInfo = {\n state: ConnectionState.CREATED,\n closeReason: connection.closeReason,\n remotePeerId: PublicKey.from(connection.remoteInfo.peerKey),\n sessionId: connection.sessionId,\n transport: connection.transport && Object.getPrototypeOf(connection.transport).constructor.name,\n protocolExtensions: [], // TODO(dmaretskyi): Fix.\n events: [],\n lastUpdate: new Date(),\n };\n info.connections!.push(connectionInfo);\n this.update.emit();\n\n connection.stateChanged.on(async (state) => {\n connectionInfo.state = state;\n connectionInfo.closeReason = connection.closeReason;\n connectionInfo.lastUpdate = new Date();\n connectionInfo.events!.push({\n type: EventType.CONNECTION_STATE_CHANGED,\n newState: state,\n });\n\n if (state === ConnectionState.CONNECTED) {\n const details = await connection.transport?.getDetails();\n connectionInfo.transportDetails = details;\n }\n\n this.update.emit();\n });\n\n (connection.protocol as WireProtocol & { stats: Event<MuxerStats> })?.stats?.on((stats) => {\n connectionInfo.readBufferSize = stats.readBufferSize;\n connectionInfo.writeBufferSize = stats.writeBufferSize;\n connectionInfo.streams = stats.channels;\n connectionInfo.lastUpdate = new Date();\n this.update.emit();\n });\n\n connection.transportStats?.on((stats) => {\n connectionInfo.transportBytesSent = stats.bytesSent;\n connectionInfo.transportBytesReceived = stats.bytesReceived;\n connectionInfo.transportPacketsSent = stats.packetsSent;\n connectionInfo.transportPacketsReceived = stats.packetsReceived;\n });\n\n gcSwarm(info);\n\n // connection.protocol.protocol?.error.on((error) => {\n // connectionInfo.events!.push({\n // type: EventType.PROTOCOL_ERROR,\n // error: error.stack ?? error.message\n // });\n // this.update.emit();\n // });\n // connection.protocol.protocol?.extensionsInitialized.on(() => {\n // connectionInfo.events!.push({\n // type: EventType.PROTOCOL_EXTENSIONS_INITIALIZED\n // });\n // this.update.emit();\n // });\n // connection.protocol.protocol?.extensionsHandshake.on(() => {\n // connectionInfo.events!.push({\n // type: EventType.PROTOCOL_EXTENSIONS_HANDSHAKE\n // });\n // this.update.emit();\n // });\n // connection.protocol.protocol?.handshake.on(() => {\n // connectionInfo.events!.push({\n // type: EventType.PROTOCOL_HANDSHAKE\n // });\n // this.update.emit();\n // });\n });\n }\n\n leftSwarm(swarm: Swarm): void {\n this.getSwarmInfo(PublicKey.from(swarm._instanceId)).isActive = false;\n this.update.emit();\n }\n}\n\nconst gcSwarm = (swarm: SwarmInfo) => {\n swarm.connections = swarm.connections?.filter((connection) => {\n return connection.lastUpdate ? Date.now() - connection.lastUpdate.getTime() < CONNECTION_GC_THRESHOLD : true;\n });\n};\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { Event, synchronized } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { Messenger, type PeerInfo, type SignalManager } from '@dxos/messaging';\nimport { trace } from '@dxos/protocols';\nimport { ConnectionState } from '@dxos/protocols/proto/dxos/client/services';\nimport { ComplexMap } from '@dxos/util';\n\nimport { ConnectionLog } from './connection-log';\nimport { type SignalConnection } from './signal';\nimport { ConnectionLimiter, Swarm, SwarmMapper } from './swarm';\nimport { type Topology } from './topology';\nimport { type TransportFactory } from './transport';\nimport { type WireProtocolProvider } from './wire-protocol';\n/**\n * Represents a single connection to a remote peer.\n */\nexport type SwarmConnection = {\n close(): Promise<void>;\n};\n\n// TODO(burdon): Add timeout.\nexport type SwarmOptions = {\n /**\n * Swarm topic.\n */\n topic: PublicKey;\n\n /**\n * This node's peer info.\n */\n peerInfo?: PeerInfo;\n\n /**\n * Protocol to use for every connection.\n */\n protocolProvider: WireProtocolProvider;\n\n /**\n * Requested topology. Must be a new instance for every swarm.\n */\n topology?: Topology;\n\n /**\n * Custom label assigned to this swarm.\n * Used in devtools to display human-readable names for swarms.\n */\n label?: string;\n};\n\nexport type SwarmNetworkManagerOptions = {\n transportFactory: TransportFactory;\n signalManager: SignalManager;\n enableDevtoolsLogging?: boolean; // Log to devtools.\n peerInfo?: PeerInfo;\n};\n\n/**\n * Manages p2p connection to the swarm.\n */\nexport class SwarmNetworkManager {\n /**\n * @internal\n */\n readonly _swarms = new ComplexMap<PublicKey, Swarm>(PublicKey.hash);\n private readonly _mappers = new ComplexMap<PublicKey, SwarmMapper>(PublicKey.hash);\n\n private readonly _transportFactory: TransportFactory;\n private readonly _signalManager: SignalManager;\n private readonly _messenger: Messenger;\n private readonly _signalConnection: SignalConnection;\n private readonly _connectionLimiter: ConnectionLimiter;\n private readonly _connectionLog?: ConnectionLog;\n private readonly _instanceId = PublicKey.random().toHex();\n private _peerInfo?: PeerInfo = undefined;\n\n private _connectionState = ConnectionState.ONLINE;\n public readonly connectionStateChanged = new Event<ConnectionState>();\n public readonly topicsUpdated = new Event<void>();\n\n constructor({ transportFactory, signalManager, enableDevtoolsLogging, peerInfo }: SwarmNetworkManagerOptions) {\n this._transportFactory = transportFactory;\n\n // Listen for signal manager events.\n this._signalManager = signalManager;\n this._signalManager.swarmEvent.on((event) => this._swarms.get(event.topic)?.onSwarmEvent(event));\n this._messenger = new Messenger({ signalManager: this._signalManager });\n this._signalConnection = {\n join: (opts) => this._signalManager.join(opts),\n leave: (opts) => this._signalManager.leave(opts),\n };\n this._peerInfo = peerInfo;\n\n this._connectionLimiter = new ConnectionLimiter();\n // TODO(burdon): Inject listener (generic pattern).\n if (enableDevtoolsLogging) {\n this._connectionLog = new ConnectionLog();\n }\n }\n\n // TODO(burdon): Remove access (Devtools only).\n get connectionLog() {\n return this._connectionLog;\n }\n\n get connectionState() {\n return this._connectionState;\n }\n\n // TODO(burdon): Reconcile with \"discovery_key\".\n get topics() {\n return Array.from(this._swarms.keys());\n }\n\n getSwarmMap(topic: PublicKey): SwarmMapper | undefined {\n return this._mappers.get(topic);\n }\n\n getSwarm(topic: PublicKey): Swarm | undefined {\n return this._swarms.get(topic);\n }\n\n setPeerInfo(peerInfo: PeerInfo): void {\n this._peerInfo = peerInfo;\n }\n\n async open(): Promise<void> {\n log.trace('dxos.mesh.network-manager.open', trace.begin({ id: this._instanceId }));\n await this._messenger.open();\n await this._signalManager.open();\n log.trace('dxos.mesh.network-manager.open', trace.end({ id: this._instanceId }));\n }\n\n async close(): Promise<void> {\n for (const topic of this._swarms.keys()) {\n await this.leaveSwarm(topic).catch((err) => {\n log(err);\n });\n }\n\n await this._messenger.close();\n await this._signalManager.close();\n }\n\n /**\n * Join the swarm.\n */\n @synchronized\n async joinSwarm({\n topic, //\n topology,\n protocolProvider: protocol,\n label,\n }: SwarmOptions): Promise<SwarmConnection> {\n invariant(PublicKey.isPublicKey(topic));\n invariant(topology);\n invariant(this._peerInfo);\n invariant(typeof protocol === 'function');\n if (this._swarms.has(topic)) {\n throw new Error(`Already connected to swarm: ${PublicKey.from(topic)}`);\n }\n\n log('joining', { topic: PublicKey.from(topic), peerInfo: this._peerInfo, topology: topology.toString() }); // TODO(burdon): Log peerId.\n const swarm = new Swarm(\n topic,\n this._peerInfo,\n topology,\n protocol,\n this._messenger,\n this._transportFactory,\n label,\n this._connectionLimiter,\n );\n\n swarm.errors.handle((error) => {\n log('swarm error', { error });\n });\n\n this._swarms.set(topic, swarm);\n this._mappers.set(topic, new SwarmMapper(swarm));\n\n // Open before joining.\n await swarm.open();\n\n this._signalConnection.join({ topic, peer: this._peerInfo }).catch((error) => log.catch(error));\n\n this.topicsUpdated.emit();\n this._connectionLog?.joinedSwarm(swarm);\n log('joined', { topic: PublicKey.from(topic), count: this._swarms.size });\n\n return {\n close: () => this.leaveSwarm(topic),\n };\n }\n\n /**\n * Close the connection.\n */\n @synchronized\n async leaveSwarm(topic: PublicKey): Promise<void> {\n if (!this._swarms.has(topic)) {\n // log.warn('swarm not open', { topic: PublicKey.from(topic).truncate() });\n return;\n }\n\n log('leaving', { topic: PublicKey.from(topic) });\n const swarm = this._swarms.get(topic)!;\n await this._signalConnection.leave({ topic, peer: swarm.ownPeer });\n\n const map = this._mappers.get(topic)!;\n map.destroy();\n this._mappers.delete(topic);\n\n this._connectionLog?.leftSwarm(swarm);\n\n await swarm.destroy();\n this._swarms.delete(topic);\n\n this.topicsUpdated.emit();\n log('left', { topic: PublicKey.from(topic), count: this._swarms.size });\n }\n\n async setConnectionState(state: ConnectionState): Promise<void> {\n if (state === this._connectionState) {\n return;\n }\n\n switch (state) {\n case ConnectionState.OFFLINE: {\n this._connectionState = state;\n // go offline\n await Promise.all([...this._swarms.values()].map((swarm) => swarm.goOffline()));\n await this._messenger.close();\n await this._signalManager.close();\n break;\n }\n case ConnectionState.ONLINE: {\n this._connectionState = state;\n // go online\n this._messenger.open();\n await Promise.all([...this._swarms.values()].map((swarm) => swarm.goOnline()));\n await this._signalManager.open();\n break;\n }\n }\n\n this.connectionStateChanged.emit(this._connectionState);\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\n\nimport { type SwarmController, type Topology } from './topology';\n\nexport class FullyConnectedTopology implements Topology {\n private _controller?: SwarmController;\n\n toString(): string {\n return 'FullyConnectedTopology';\n }\n\n init(controller: SwarmController): void {\n invariant(!this._controller, 'Already initialized');\n this._controller = controller;\n }\n\n update(): void {\n invariant(this._controller, 'Not initialized');\n const { candidates: discovered } = this._controller.getState();\n for (const peer of discovered) {\n // TODO(burdon): Back-off.\n this._controller.connect(peer);\n }\n }\n\n async onOffer(peer: PublicKey): Promise<boolean> {\n return true;\n }\n\n async destroy(): Promise<void> {\n // Nothing to do.\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { type SwarmController, type Topology } from './topology';\n\nconst MIN_UPDATE_INTERVAL = 1000 * 10;\nconst MAX_CHANGES_PER_UPDATE = 1;\n\nexport interface MMSTTopologyOptions {\n /**\n * Number of connections the peer will originate by itself.\n */\n originateConnections?: number;\n\n /**\n * Maximum number of connections allowed, all other connections will be dropped.\n */\n maxPeers?: number;\n\n /**\n * Size of random sample from which peer candidates are selected.\n */\n sampleSize?: number;\n}\n\nexport class MMSTTopology implements Topology {\n private readonly _originateConnections: number;\n private readonly _maxPeers: number;\n private readonly _sampleSize: number;\n\n private _controller?: SwarmController;\n\n private _sampleCollected = false;\n\n private _lastAction = new Date(0);\n\n constructor({ originateConnections = 2, maxPeers = 4, sampleSize = 10 }: MMSTTopologyOptions = {}) {\n this._originateConnections = originateConnections;\n this._maxPeers = maxPeers;\n this._sampleSize = sampleSize;\n }\n\n init(controller: SwarmController): void {\n invariant(!this._controller, 'Already initialized');\n this._controller = controller;\n }\n\n update(): void {\n invariant(this._controller, 'Not initialized');\n const { connected, candidates } = this._controller.getState();\n // Run the algorithms if we have first candidates, ran it before, or have more connections than needed.\n if (this._sampleCollected || connected.length > this._maxPeers || candidates.length > 0) {\n log('Running the algorithm.');\n this._sampleCollected = true;\n this._runAlgorithm();\n }\n }\n\n forceUpdate(): void {\n this._lastAction = new Date(0);\n this.update();\n }\n\n async onOffer(peer: PublicKey): Promise<boolean> {\n invariant(this._controller, 'Not initialized');\n const { connected } = this._controller.getState();\n const accept = connected.length < this._maxPeers;\n log(`Offer ${peer} accept=${accept}`);\n return accept;\n }\n\n async destroy(): Promise<void> {\n // Nothing to do.\n }\n\n private _runAlgorithm(): void {\n invariant(this._controller, 'Not initialized');\n const { connected, candidates, ownPeerId } = this._controller.getState();\n\n // TODO(nf): does this rate limiting/flap dampening logic belong here or in the SwarmController?\n if (connected.length > this._maxPeers) {\n // Disconnect extra peers.\n log(`disconnect ${connected.length - this._maxPeers} peers.`);\n const sorted = sortByXorDistance(connected, ownPeerId)\n .reverse()\n .slice(0, this._maxPeers - connected.length);\n invariant(sorted.length === 0);\n\n if (sorted.length > MAX_CHANGES_PER_UPDATE) {\n log(`want to disconnect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`);\n }\n\n if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {\n for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {\n log(`Disconnect ${peer}.`);\n this._controller.disconnect(peer);\n }\n this._lastAction = new Date();\n } else {\n log('rate limited disconnect');\n }\n } else if (connected.length < this._originateConnections) {\n // Connect new peers to reach desired quota.\n log(`connect ${this._originateConnections - connected.length} peers.`);\n const sample = candidates.sort(() => Math.random() - 0.5).slice(0, this._sampleSize);\n const sorted = sortByXorDistance(sample, ownPeerId).slice(0, this._originateConnections - connected.length);\n\n if (sorted.length > MAX_CHANGES_PER_UPDATE) {\n log(`want to connect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`);\n }\n if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {\n for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {\n log(`Connect ${peer}.`);\n this._controller.connect(peer);\n }\n this._lastAction = new Date();\n } else {\n log('rate limited connect');\n }\n }\n }\n\n toString(): string {\n return 'MMSTTopology';\n }\n}\n\nconst sortByXorDistance = (keys: PublicKey[], reference: PublicKey): PublicKey[] => {\n const sorted = keys.sort((a, b) => {\n return compareXor(distXor(a.asBuffer(), reference.asBuffer()), distXor(b.asBuffer(), reference.asBuffer()));\n });\n log('Sorted keys', { keys, reference, sorted });\n return sorted;\n};\n\nconst distXor = (a: Buffer, b: Buffer) => {\n const maxLength = Math.max(a.length, b.length);\n const result = Buffer.allocUnsafe(maxLength);\n for (let i = 0; i < maxLength; i++) {\n result[i] = (a[i] || 0) ^ (b[i] || 0);\n }\n return result;\n};\n\nconst compareXor = (a: Buffer, b: Buffer) => {\n const maxLength = Math.max(a.length, b.length);\n for (let i = 0; i < maxLength; i++) {\n if ((a[i] || 0) === (b[i] || 0)) {\n continue;\n }\n return (a[i] || 0) < (b[i] || 0) ? -1 : 1;\n }\n return 0;\n};\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { type SwarmController, type Topology } from './topology';\n\nexport class StarTopology implements Topology {\n private _controller?: SwarmController;\n\n constructor(private readonly _centralPeer: PublicKey) {}\n\n toString(): string {\n return `StarTopology(${this._centralPeer.truncate()})`;\n }\n\n init(controller: SwarmController): void {\n invariant(!this._controller, 'Already initialized.');\n this._controller = controller;\n }\n\n update(): void {\n invariant(this._controller, 'Not initialized.');\n const { candidates, connected, ownPeerId } = this._controller.getState();\n if (!ownPeerId.equals(this._centralPeer)) {\n log('leaf peer dropping all connections apart from central peer.');\n\n // Drop all connections other than central peer.\n for (const peer of connected) {\n if (!peer.equals(this._centralPeer)) {\n log('dropping connection', { peer });\n this._controller.disconnect(peer);\n }\n }\n }\n\n for (const peer of candidates) {\n // Connect to central peer.\n if (peer.equals(this._centralPeer) || ownPeerId.equals(this._centralPeer)) {\n log('connecting to peer', { peer });\n this._controller.connect(peer);\n }\n }\n }\n\n async onOffer(peer: PublicKey): Promise<boolean> {\n invariant(this._controller, 'Not initialized.');\n const { ownPeerId } = this._controller.getState();\n log('offer', {\n peer,\n isCentral: peer.equals(this._centralPeer),\n isSelfCentral: ownPeerId.equals(this._centralPeer),\n });\n return ownPeerId.equals(this._centralPeer) || peer.equals(this._centralPeer);\n }\n\n async destroy(): Promise<void> {\n // Nothing to do.\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { Transform } from 'node:stream';\n\nimport { Event, Trigger } from '@dxos/async';\nimport { ErrorStream } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type Transport, type TransportFactory, type TransportOptions } from './transport';\n\n// TODO(burdon): Make configurable.\n// Delay (in milliseconds) for data being sent through in-memory connections to simulate network latency.\nconst MEMORY_TRANSPORT_DELAY = 1;\n\n/**\n * Creates a binary stream that delays data being sent through the stream by the specified amount of time.\n */\nconst createStreamDelay = (delay: number): NodeJS.ReadWriteStream => {\n return new Transform({\n objectMode: true,\n transform: (chunk, _, cb) => {\n setTimeout(() => cb(null, chunk), delay); // TODO(burdon): Randomize.\n },\n });\n};\n\nexport const MemoryTransportFactory: TransportFactory = {\n createTransport: (options) => new MemoryTransport(options),\n};\n\n/**\n * Fake transport.\n */\nexport class MemoryTransport implements Transport {\n // TODO(burdon): Remove static properties (inject context into constructor).\n private static readonly _connections = new ComplexMap<PublicKey, MemoryTransport>(PublicKey.hash);\n\n @logInfo\n private readonly _instanceId = PublicKey.random(); // TODO(burdon): Rename peerId? (Use local/remote labels in logs).\n\n private readonly _remote = new Trigger<PublicKey>();\n\n private readonly _outgoingDelay = createStreamDelay(MEMORY_TRANSPORT_DELAY);\n private readonly _incomingDelay = createStreamDelay(MEMORY_TRANSPORT_DELAY);\n\n private _closed = false;\n\n @logInfo\n private _remoteInstanceId!: PublicKey;\n\n private _remoteConnection?: MemoryTransport;\n\n public readonly closed = new Event<void>();\n public readonly connected = new Event<void>();\n public readonly errors = new ErrorStream();\n\n constructor(private readonly _options: TransportOptions) {\n invariant(!MemoryTransport._connections.has(this._instanceId), 'Duplicate memory connection');\n MemoryTransport._connections.set(this._instanceId, this);\n }\n\n get isOpen() {\n // TODO(burdon): Open state?\n return !this._closed;\n }\n\n async open(): Promise<this> {\n log('opening...');\n\n // Initiator will send a signal, the receiver will receive the unique ID and connect the streams.\n if (this._options.initiator) {\n log('sending signal');\n try {\n await this._options.sendSignal({ payload: { transportId: this._instanceId.toHex() } });\n } catch (err) {\n if (!this._closed) {\n this.errors.raise(toError(err));\n }\n }\n } else {\n // Don't block the open method.\n this._remote\n .wait({ timeout: this._options.timeout ?? 1_000 })\n .then((remoteId) => {\n if (this._closed) {\n return;\n }\n\n this._remoteInstanceId = remoteId;\n this._remoteConnection = MemoryTransport._connections.get(this._remoteInstanceId);\n if (!this._remoteConnection) {\n // Remote connection was destroyed before we could connect.\n this._closed = true;\n this.closed.emit();\n return;\n }\n\n invariant(!this._remoteConnection._remoteConnection, `Remote already connected: ${this._remoteInstanceId}`);\n this._remoteConnection._remoteConnection = this;\n this._remoteConnection._remoteInstanceId = this._instanceId;\n\n log('connected');\n this._options.stream\n .pipe(this._outgoingDelay)\n .pipe(this._remoteConnection._options.stream)\n .pipe(this._incomingDelay)\n .pipe(this._options.stream);\n\n this.connected.emit();\n this._remoteConnection.connected.emit();\n })\n .catch((err) => {\n if (this._closed) {\n return;\n }\n\n this.errors.raise(err);\n });\n }\n return this;\n }\n\n async close(): Promise<this> {\n log('closing...');\n this._closed = true;\n\n MemoryTransport._connections.delete(this._instanceId);\n if (this._remoteConnection) {\n this._remoteConnection._closed = true;\n MemoryTransport._connections.delete(this._remoteInstanceId);\n\n // TODO(dmaretskyi): Hypercore streams do not seem to have the unpipe method.\n // NOTE(burdon): Using readable-stream.wrap() might help (see feed-store).\n // code this._stream\n // code .unpipe(this._outgoingDelay)\n // code .unpipe(this._remoteConnection._stream)\n // code .unpipe(this._incomingDelay)\n // code .unpipe(this._stream);\n\n this._options.stream.unpipe(this._incomingDelay);\n this._incomingDelay.unpipe(this._remoteConnection._options.stream);\n this._remoteConnection._options.stream.unpipe(this._outgoingDelay);\n this._outgoingDelay.unpipe(this._options.stream);\n this._options.stream.unpipe(this._outgoingDelay);\n\n this._remoteConnection.closed.emit();\n this._remoteConnection._remoteConnection = undefined;\n this._remoteConnection = undefined;\n }\n\n this.closed.emit();\n log('closed');\n return this;\n }\n\n async onSignal({ payload }: Signal): Promise<void> {\n log('received signal', { payload });\n if (!payload?.transportId) {\n return;\n }\n\n // TODO(burdon): Check open?\n const transportId = payload.transportId as string;\n if (transportId) {\n const remoteId = PublicKey.fromHex(transportId);\n this._remote.wake(remoteId);\n }\n }\n\n async getDetails(): Promise<string> {\n return this._instanceId.toHex();\n }\n\n async getStats(): Promise<{\n bytesSent: number;\n bytesReceived: number;\n packetsSent: number;\n packetsReceived: number;\n }> {\n return {\n bytesSent: 0,\n bytesReceived: 0,\n packetsSent: 0,\n packetsReceived: 0,\n };\n }\n}\n\n// TODO(burdon): Factor out.\nconst toError = (err: any): Error => (err instanceof Error ? err : new Error(String(err)));\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { type Event } from '@dxos/async';\nimport { type ErrorStream } from '@dxos/debug';\nimport { type PublicKey } from '@dxos/keys';\nimport { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';\n\nexport enum TransportKind {\n WEB_RTC = 'WEB-RTC',\n WEB_RTC_PROXY = 'WEB-RTC_PROXY',\n MEMORY = 'MEMORY',\n TCP = 'TCP',\n}\n\n/**\n * Abstraction over a P2P connection transport.\n * Currently, WebRTC or in-memory.\n */\n// TODO(burdon): Create abstract base class for common logging and error handling?\nexport interface Transport {\n closed: Event;\n connected: Event;\n errors: ErrorStream;\n\n open(): Promise<this>;\n close(): Promise<this>;\n\n /**\n * Handle message from signaling.\n */\n onSignal(signal: Signal): Promise<void>;\n\n /**\n * Transport-specific stats.\n */\n getStats(): Promise<TransportStats>;\n\n /**\n * Transport-specific connection details.\n */\n getDetails(): Promise<string>;\n}\n\n/**\n * Common options for all transports.\n */\nexport type TransportOptions = {\n ownPeerKey: string;\n remotePeerKey: string;\n\n topic: string;\n /**\n * Did local node initiate this connection.\n */\n initiator: boolean;\n\n /**\n * Wire protocol for data stream.\n */\n stream: NodeJS.ReadWriteStream;\n\n /**\n * Sends signal message to remote peer.\n */\n sendSignal: (signal: Signal) => Promise<void>;\n\n sessionId?: PublicKey;\n\n timeout?: number;\n};\n\nexport interface TransportFactory {\n createTransport(options: TransportOptions): Transport;\n}\n\nexport type TransportStats = {\n bytesSent: number;\n bytesReceived: number;\n packetsSent: number;\n packetsReceived: number;\n rawStats?: any;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Mutex } from '@dxos/async';\n\nexport type ConnectionInfo = {\n initiator: boolean;\n};\n\nexport interface RtcConnectionFactory {\n initialize(): Promise<void>;\n onConnectionDestroyed(): Promise<void>;\n createConnection(config: RTCConfiguration): Promise<RTCPeerConnection>;\n initConnection(connection: RTCPeerConnection, info: ConnectionInfo): Promise<void>;\n}\n\n/**\n * Use built-in browser RTCPeerConnection.\n */\nclass BrowserRtcConnectionFactory implements RtcConnectionFactory {\n async initialize(): Promise<void> {}\n async onConnectionDestroyed(): Promise<void> {}\n\n async createConnection(config: RTCConfiguration): Promise<RTCPeerConnection> {\n return new RTCPeerConnection(config);\n }\n\n async initConnection(connection: RTCPeerConnection, info: ConnectionInfo): Promise<void> {}\n}\n\n/**\n * Use `node-datachannel` polyfill.\n * https://github.com/paullouisageneau/libdatachannel\n */\nclass NodeRtcConnectionFactory implements RtcConnectionFactory {\n private static _createdConnections = 0;\n private static _cleanupMutex = new Mutex();\n\n // This should be inside the function to avoid triggering `eval` in the global scope.\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n\n // TODO(burdon): Do imports here?\n async initialize(): Promise<void> {}\n async onConnectionDestroyed(): Promise<void> {\n return NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {\n if (--NodeRtcConnectionFactory._createdConnections === 0) {\n (await import('#node-datachannel')).cleanup();\n }\n });\n }\n\n async createConnection(config: RTCConfiguration): Promise<RTCPeerConnection> {\n return NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {\n const { RTCPeerConnection } = await import('#node-datachannel/polyfill');\n NodeRtcConnectionFactory._createdConnections++;\n return new RTCPeerConnection(config);\n }) as any;\n }\n\n async initConnection(connection: RTCPeerConnection, info: ConnectionInfo): Promise<void> {\n // Initiator peer is responsible for data-channel creation. This triggers the callback in browsers.\n // In node-datachannel/polyfill createOffer() / setLocalDescription(offer) are no-ops, the process\n // is handled by c++ implementation when a data-channel gets created.\n // By calling the method here we'll start waiting for an offer promise that'll resolve on data-channel creation\n // at which point we'll need to send an SDP to a remote peer.\n // https://github.com/murat-dogan/node-datachannel/blob/master/polyfill/RTCPeerConnection.js#L452C1-L459C6\n //\n if (info.initiator) {\n connection.onnegotiationneeded?.(null as any);\n }\n }\n}\n\n/**\n * Create platform-specific connection factory.\n */\nexport const getRtcConnectionFactory = (): RtcConnectionFactory => {\n return typeof (globalThis as any).RTCPeerConnection === 'undefined'\n ? new NodeRtcConnectionFactory()\n : new BrowserRtcConnectionFactory();\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Mutex, Trigger, synchronized } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log, logInfo } from '@dxos/log';\nimport { ConnectivityError } from '@dxos/protocols';\nimport { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';\nimport { trace } from '@dxos/tracing';\n\nimport type { IceProvider } from '../../signal';\nimport { type TransportOptions } from '../transport';\n\nimport { type RtcConnectionFactory } from './rtc-connection-factory';\nimport { RtcTransportChannel } from './rtc-transport-channel';\nimport { areSdpEqual, chooseInitiatorPeer } from './utils';\n\nexport type RtcPeerChannelFactoryOptions = {\n ownPeerKey: string;\n remotePeerKey: string;\n /**\n * Sends signal message to remote peer.\n */\n sendSignal: (signal: Signal) => Promise<void>;\n\n // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#iceservers\n webrtcConfig?: RTCConfiguration;\n iceProvider?: IceProvider;\n\n /**\n * TODO: remove after the new rtc code rollout. Used for staging interop with older version running in prod.\n */\n legacyInitiator?: boolean;\n};\n\n/**\n * A factory for rtc Transport implementations for a particular peer.\n * Contains WebRTC connection establishment logic.\n * When the first Transport is opened a connection is established and kept until all the transports are closed.\n */\n@trace.resource()\nexport class RtcPeerConnection {\n // A peer who is not the initiator waits for another party to open a channel.\n private readonly _channelCreatedCallbacks = new Map<string, ChannelCreatedCallback>();\n // Channels indexed by topic.\n private readonly _transportChannels = new Map<string, RtcTransportChannel>();\n private readonly _dataChannels = new Map<string, RTCDataChannel>();\n // A peer is ready to receive ICE candidates when local and remote description were set.\n private readonly _readyForCandidates = new Trigger();\n\n private readonly _offerProcessingMutex = new Mutex();\n\n /**\n * Can't use peer.connection.initiator, because if two connections to the same peer are created in\n * different swarms, we might be the initiator of the first one, but not of the other one.\n * Use a stable peer keypair property (key ordering) to decide who's acting as the initiator of\n * transport connection establishment and data channel creation.\n */\n private readonly _initiator: boolean;\n\n private _connection?: RTCPeerConnection;\n\n constructor(\n private readonly _factory: RtcConnectionFactory,\n private readonly _options: RtcPeerChannelFactoryOptions,\n ) {\n this._initiator = chooseInitiatorPeer(_options.ownPeerKey, _options.remotePeerKey) === _options.ownPeerKey;\n }\n\n public get transportChannelCount() {\n return this._transportChannels.size;\n }\n\n public get currentConnection(): RTCPeerConnection | undefined {\n return this._connection;\n }\n\n public async createDataChannel(topic: string): Promise<RTCDataChannel> {\n const connection = await this._openConnection();\n if (!this._transportChannels.has(topic)) {\n if (!this._transportChannels.size) {\n void this._lockAndCloseConnection();\n }\n throw new Error('Transport closed while connection was being open');\n }\n if (this._initiator) {\n const channel = connection.createDataChannel(topic);\n this._dataChannels.set(topic, channel);\n return channel;\n } else {\n const existingChannel = this._dataChannels.get(topic);\n if (existingChannel) {\n return existingChannel;\n }\n log('waiting for initiator-peer to open a data channel');\n return new Promise((resolve, reject) => {\n this._channelCreatedCallbacks.set(topic, { resolve, reject });\n });\n }\n }\n\n public createTransportChannel(options: TransportOptions): RtcTransportChannel {\n const channel = new RtcTransportChannel(this, options);\n this._transportChannels.set(options.topic, channel);\n channel.closed.on(() => {\n this._transportChannels.delete(options.topic);\n if (this._transportChannels.size === 0) {\n void this._lockAndCloseConnection();\n }\n });\n return channel;\n }\n\n @synchronized\n private async _openConnection(): Promise<RTCPeerConnection> {\n if (this._connection) {\n return this._connection;\n }\n\n log('initializing connection...', () => ({ remotePeer: this._options.remotePeerKey }));\n\n const config = await this._loadConnectionConfig();\n\n //\n // Peer connection.\n // https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Connectivity\n // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection\n //\n const connection = await this._factory.createConnection(config);\n\n const iceCandidateErrors: IceCandidateErrorDetails[] = [];\n\n Object.assign<RTCPeerConnection, Partial<RTCPeerConnection>>(connection, {\n onnegotiationneeded: async () => {\n invariant(this._initiator);\n\n if (connection !== this._connection) {\n this._onConnectionCallbackAfterClose('onnegotiationneeded', connection);\n return;\n }\n\n log('onnegotiationneeded');\n try {\n const offer = await connection.createOffer();\n await connection.setLocalDescription(offer);\n await this._sendDescription(connection, offer);\n } catch (err: any) {\n void this._lockAndAbort(connection, err);\n }\n },\n\n // When ICE candidate identified (should be sent to remote peer) and when ICE gathering finalized.\n // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidate_event\n onicecandidate: async (event) => {\n if (connection !== this._connection) {\n this._onConnectionCallbackAfterClose('onicecandidate', connection);\n return;\n }\n\n if (event.candidate) {\n log('onicecandidate', { candidate: event.candidate.candidate });\n await this._sendIceCandidate(event.candidate);\n } else {\n log('onicecandidate gathering complete');\n }\n },\n\n // When error occurs while performing ICE negotiations through a STUN or TURN server.\n // It's ok for some candidates to fail if a working pair is eventually found.\n // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidateerror_event\n onicecandidateerror: (event: any) => {\n const { url, errorCode, errorText } = event as RTCPeerConnectionIceErrorEvent;\n iceCandidateErrors.push({ url, errorCode, errorText });\n },\n\n // When possible error during ICE gathering.\n // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceconnectionstatechange_event\n oniceconnectionstatechange: () => {\n if (connection !== this._connection) {\n this._onConnectionCallbackAfterClose('oniceconnectionstatechange', connection);\n return;\n }\n\n log('oniceconnectionstatechange', { state: connection.iceConnectionState });\n if (connection.iceConnectionState === 'failed') {\n void this._lockAndAbort(connection, createIceFailureError(iceCandidateErrors));\n }\n },\n\n // When new track (or channel) is added.\n // State: { new, connecting, connected, disconnected, failed, closed }\n // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionstatechange_event\n onconnectionstatechange: () => {\n if (connection !== this._connection) {\n if (connection.connectionState !== 'closed' && connection.connectionState !== 'failed') {\n this._onConnectionCallbackAfterClose('onconnectionstatechange', connection);\n }\n return;\n }\n\n log('onconnectionstatechange', { state: connection.connectionState });\n if (connection.connectionState === 'failed') {\n void this._lockAndAbort(connection, new Error('Connection failed.'));\n }\n },\n\n onsignalingstatechange: () => {\n log('onsignalingstatechange', { state: connection.signalingState });\n },\n\n // When channel is added to connection.\n // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/datachannel_event\n ondatachannel: (event) => {\n invariant(!this._initiator, 'Initiator is expected to create data channels.');\n\n if (connection !== this._connection) {\n this._onConnectionCallbackAfterClose('ondatachannel', connection);\n return;\n }\n\n log('ondatachannel', { label: event.channel.label });\n this._dataChannels.set(event.channel.label, event.channel);\n const pendingCallback = this._channelCreatedCallbacks.get(event.channel.label);\n if (pendingCallback) {\n this._channelCreatedCallbacks.delete(event.channel.label);\n pendingCallback.resolve(event.channel);\n }\n },\n });\n\n this._connection = connection;\n this._readyForCandidates.reset();\n\n await this._factory.initConnection(connection, { initiator: this._initiator });\n\n return this._connection;\n }\n\n @synchronized\n private async _lockAndAbort(connection: RTCPeerConnection, error: Error): Promise<void> {\n this._abortConnection(connection, error);\n }\n\n private _abortConnection(connection: RTCPeerConnection, error: Error): void {\n if (connection !== this._connection) {\n log.error('attempted to abort an inactive connection', { error });\n this._safeCloseConnection(connection);\n return;\n }\n for (const [topic, pendingCallback] of this._channelCreatedCallbacks.entries()) {\n pendingCallback.reject(error);\n this._transportChannels.delete(topic);\n }\n this._channelCreatedCallbacks.clear();\n for (const channel of this._transportChannels.values()) {\n channel.onConnectionError(error);\n }\n this._transportChannels.clear();\n this._safeCloseConnection();\n log('connection aborted', { reason: error.message });\n }\n\n @synchronized\n private async _lockAndCloseConnection(): Promise<void> {\n invariant(this._transportChannels.size === 0);\n if (this._connection) {\n this._safeCloseConnection();\n log('connection closed');\n }\n }\n\n @synchronized\n public async onSignal(signal: Signal): Promise<void> {\n const connection = this._connection;\n if (!connection) {\n log.warn('a signal ignored because the connection was closed', { type: signal.payload.data.type });\n return;\n }\n\n const data = signal.payload.data;\n switch (data.type) {\n case 'offer': {\n await this._offerProcessingMutex.executeSynchronized(async () => {\n if (isRemoteDescriptionSet(connection, data)) {\n return;\n }\n if (connection.connectionState !== 'new') {\n this._abortConnection(connection, new Error(`Received an offer in ${connection.connectionState}.`));\n return;\n }\n\n try {\n await connection.setRemoteDescription({ type: data.type, sdp: data.sdp });\n const answer = await connection.createAnswer();\n await connection.setLocalDescription(answer);\n await this._sendDescription(connection, answer);\n this._onSessionNegotiated(connection);\n } catch (err) {\n this._abortConnection(connection, new Error('Error handling a remote offer.', { cause: err }));\n }\n });\n break;\n }\n\n case 'answer':\n await this._offerProcessingMutex.executeSynchronized(async () => {\n try {\n if (isRemoteDescriptionSet(connection, data)) {\n return;\n }\n if (connection.signalingState !== 'have-local-offer') {\n this._abortConnection(\n connection,\n new Error(`Unexpected answer from remote peer, signalingState was ${connection.signalingState}.`),\n );\n return;\n }\n await connection.setRemoteDescription({ type: data.type, sdp: data.sdp });\n this._onSessionNegotiated(connection);\n } catch (err) {\n this._abortConnection(connection, new Error('Error handling a remote answer.', { cause: err }));\n }\n });\n break;\n\n case 'candidate':\n void this._processIceCandidate(connection, data.candidate);\n break;\n\n default:\n this._abortConnection(connection, new Error(`Unknown signal type ${data.type}.`));\n break;\n }\n\n log('signal processed', { type: data.type });\n }\n\n private async _processIceCandidate(connection: RTCPeerConnection, candidate: RTCIceCandidate): Promise<void> {\n try {\n // ICE candidates are associated with a session, so we need to wait for the remote description to be set.\n await this._readyForCandidates.wait();\n if (connection === this._connection) {\n log('adding ice candidate', { candidate });\n await connection.addIceCandidate(candidate);\n }\n } catch (err) {\n log.catch(err);\n }\n }\n\n private _onSessionNegotiated(connection: RTCPeerConnection): void {\n if (connection === this._connection) {\n log('ready to process ice candidates');\n this._readyForCandidates.wake();\n } else {\n log.warn('session was negotiated after connection became inactive');\n }\n }\n\n private _onConnectionCallbackAfterClose(callback: string, connection: RTCPeerConnection): void {\n log.warn('callback invoked after a connection was destroyed, this is probably a bug', {\n callback,\n state: connection.connectionState,\n });\n this._safeCloseConnection(connection);\n }\n\n private _safeCloseConnection(connection: RTCPeerConnection | undefined = this._connection): void {\n const resetFields = this._connection && connection === this._connection;\n try {\n connection?.close();\n } catch (err) {\n log.catch(err);\n }\n if (resetFields) {\n this._connection = undefined;\n this._dataChannels.clear();\n this._readyForCandidates.wake();\n void this._factory.onConnectionDestroyed().catch((err) => log.catch(err));\n for (const [_, pendingCallback] of this._channelCreatedCallbacks.entries()) {\n pendingCallback.reject('Connection closed.');\n }\n this._channelCreatedCallbacks.clear();\n }\n }\n\n private async _loadConnectionConfig() {\n const config = { ...this._options.webrtcConfig };\n try {\n const providedIceServers = (await this._options.iceProvider?.getIceServers()) ?? [];\n if (providedIceServers.length > 0) {\n config.iceServers = [...(config.iceServers ?? []), ...providedIceServers];\n }\n } catch (error) {\n log.catch(error);\n }\n return config;\n }\n\n private async _sendIceCandidate(candidate: RTCIceCandidate): Promise<void> {\n try {\n await this._options.sendSignal({\n payload: {\n data: {\n type: 'candidate',\n candidate: {\n candidate: candidate.candidate,\n // These fields never seem to be not null, but connecting to Chrome doesn't work if they are.\n sdpMLineIndex: candidate.sdpMLineIndex ?? '0',\n sdpMid: candidate.sdpMid ?? '0',\n },\n },\n },\n });\n } catch (err) {\n log.warn('signaling error', { err });\n }\n }\n\n private async _sendDescription(connection: RTCPeerConnection, description: RTCSessionDescriptionInit): Promise<void> {\n if (connection !== this._connection) {\n // Connection was closed while description was being created.\n return;\n }\n // Type is 'offer' | 'answer'.\n const data = { type: description.type, sdp: description.sdp };\n await this._options.sendSignal({ payload: { data } });\n }\n\n @trace.info()\n protected get _connectionInfo() {\n const connectionInfo = this._connection && {\n connectionState: this._connection.connectionState,\n iceConnectionState: this._connection.iceConnectionState,\n iceGatheringState: this._connection.iceGatheringState,\n signalingState: this._connection.signalingState,\n remoteDescription: this._connection.remoteDescription,\n localDescription: this._connection.localDescription,\n };\n return {\n ...connectionInfo,\n ts: Date.now(),\n remotePeerKey: this._options.remotePeerKey,\n channels: [...this._transportChannels.keys()].map((topic) => topic),\n config: this._connection?.getConfiguration(),\n };\n }\n\n @logInfo\n private get _loggerContext() {\n return {\n ownPeerKey: this._options.ownPeerKey,\n remotePeerKey: this._options.remotePeerKey,\n initiator: this._initiator,\n channels: this._transportChannels.size,\n };\n }\n}\n\nconst isRemoteDescriptionSet = (connection: RTCPeerConnection, data: { type: string; sdp: string }) => {\n if (!connection.remoteDescription?.type || connection.remoteDescription?.type !== data.type) {\n return false;\n }\n return areSdpEqual(connection.remoteDescription.sdp, data.sdp);\n};\n\ntype IceCandidateErrorDetails = { url: string; errorCode: number; errorText: string };\n\nconst createIceFailureError = (details: IceCandidateErrorDetails[]) => {\n const candidateErrors = details.map(({ url, errorCode, errorText }) => `${errorCode} ${url}: ${errorText}`);\n return new ConnectivityError(`ICE failed:\\n${candidateErrors.join('\\n')}`);\n};\n\ntype ChannelCreatedCallback = {\n resolve: (channel: RTCDataChannel) => void;\n reject: (reason?: any) => void;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\n\nimport { Event as AsyncEvent } from '@dxos/async';\nimport { Resource } from '@dxos/context';\nimport { ErrorStream } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { ConnectivityError } from '@dxos/protocols';\nimport { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';\n\nimport { type Transport, type TransportOptions, type TransportStats } from '../transport';\n\nimport { type RtcPeerConnection } from './rtc-peer-connection';\nimport { createRtcTransportStats, describeSelectedRemoteCandidate } from './rtc-transport-stats';\n\n// https://viblast.com/blog/2015/2/5/webrtc-data-channel-message-size\nconst MAX_MESSAGE_SIZE = 64 * 1024;\n// The default Readable stream buffer size: https://nodejs.org/api/stream.html#implementing-a-readable-stream\nconst MAX_BUFFERED_AMOUNT = 64 * 1024;\n\n/**\n * A WebRTC connection data channel.\n * Manages a WebRTC connection to a remote peer using an abstract signalling mechanism.\n */\nexport class RtcTransportChannel extends Resource implements Transport {\n public readonly closed = new AsyncEvent();\n public readonly connected = new AsyncEvent();\n public readonly errors = new ErrorStream();\n\n private _channel: RTCDataChannel | undefined;\n private _stream: Duplex | undefined;\n private _streamDataFlushedCallback: PendingStreamFlushedCallback | null = null;\n private _isChannelCreationInProgress = false;\n\n constructor(\n private readonly _connection: RtcPeerConnection,\n private readonly _options: TransportOptions,\n ) {\n super();\n }\n\n public get isRtcChannelCreationInProgress() {\n return this._isChannelCreationInProgress;\n }\n\n public onConnectionError(error: Error): void {\n if (this.isOpen) {\n this.errors.raise(error);\n }\n }\n\n protected override async _open(): Promise<void> {\n invariant(!this._isChannelCreationInProgress);\n this._isChannelCreationInProgress = true;\n this._connection\n .createDataChannel(this._options.topic)\n .then((channel) => {\n if (this.isOpen) {\n this._channel = channel;\n this._initChannel(this._channel);\n } else {\n this._safeCloseChannel(channel);\n }\n })\n .catch((err) => {\n if (this.isOpen) {\n const error =\n err instanceof Error\n ? err\n : new ConnectivityError(`Failed to create a channel: ${JSON.stringify(err?.message)}`);\n this.errors.raise(error);\n } else {\n log.verbose('connection establishment failed after transport was closed', { err });\n }\n })\n .finally(() => {\n this._isChannelCreationInProgress = false;\n });\n }\n\n protected override async _close(): Promise<void> {\n if (this._channel) {\n this._safeCloseChannel(this._channel);\n this._channel = undefined;\n this._stream = undefined;\n }\n this.closed.emit();\n\n log('closed');\n }\n\n private _initChannel(channel: RTCDataChannel): void {\n Object.assign<RTCDataChannel, Partial<RTCDataChannel>>(channel, {\n onopen: () => {\n if (!this.isOpen) {\n log.warn('channel opened in a closed transport', { topic: this._options.topic });\n this._safeCloseChannel(channel);\n return;\n }\n\n log('onopen');\n const duplex = new Duplex({\n read: () => {},\n write: (chunk, encoding, callback) => {\n return this._handleChannelWrite(chunk, callback);\n },\n });\n duplex.pipe(this._options.stream).pipe(duplex);\n this._stream = duplex;\n this.connected.emit();\n },\n\n onclose: async () => {\n log('onclose');\n await this.close();\n },\n\n onmessage: async (event: MessageEvent) => {\n if (!this._stream) {\n log.warn('ignoring message on a closed channel');\n return;\n }\n\n let data = event.data;\n if (data instanceof ArrayBuffer) {\n data = Buffer.from(data);\n } else if (data instanceof Blob) {\n data = Buffer.from(await data.arrayBuffer());\n }\n this._stream.push(data);\n },\n\n onerror: (event: Event & any) => {\n if (this.isOpen) {\n const err = event.error instanceof Error ? event.error : new Error(`Datachannel error: ${event.type}.`);\n this.errors.raise(err);\n }\n },\n\n onbufferedamountlow: () => {\n const cb = this._streamDataFlushedCallback;\n this._streamDataFlushedCallback = null;\n cb?.();\n },\n });\n }\n\n private async _handleChannelWrite(chunk: any, callback: PendingStreamFlushedCallback): Promise<void> {\n if (!this._channel) {\n log.warn('writing to a channel after a connection was closed');\n return;\n }\n\n if (chunk.length > MAX_MESSAGE_SIZE) {\n const error = new Error(`Message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}.`);\n this.errors.raise(error);\n callback();\n return;\n }\n\n try {\n this._channel.send(chunk);\n } catch (err: any) {\n this.errors.raise(err);\n callback();\n return;\n }\n\n if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {\n if (this._streamDataFlushedCallback !== null) {\n log.error('consumer trying to write before we are ready for more data');\n }\n this._streamDataFlushedCallback = callback;\n } else {\n callback();\n }\n }\n\n private _safeCloseChannel(channel: RTCDataChannel): void {\n try {\n channel.close();\n } catch (error: any) {\n log.catch(error);\n }\n }\n\n public onSignal(signal: Signal): Promise<void> {\n return this._connection.onSignal(signal);\n }\n\n async getDetails(): Promise<string> {\n return describeSelectedRemoteCandidate(this._connection.currentConnection);\n }\n\n async getStats(): Promise<TransportStats> {\n return createRtcTransportStats(this._connection.currentConnection, this._options.topic);\n }\n}\n\ntype PendingStreamFlushedCallback = () => void;\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { TransportStats } from '../transport';\n\nexport const describeSelectedRemoteCandidate = async (connection?: RTCPeerConnection): Promise<string> => {\n const stats = connection && (await getRtcConnectionStats(connection));\n const rc = stats?.remoteCandidate;\n if (!rc) {\n return 'unavailable';\n }\n\n if (rc.candidateType === 'relay') {\n return `${rc.ip}:${rc.port} relay for ${rc.relatedAddress}:${rc.relatedPort}`;\n }\n\n return `${rc.ip}:${rc.port} ${rc.candidateType}`;\n};\n\nexport const createRtcTransportStats = async (\n connection: RTCPeerConnection | undefined,\n topic: string,\n): Promise<TransportStats> => {\n const stats = connection && (await getRtcConnectionStats(connection, topic));\n if (!stats) {\n return {\n bytesSent: 0,\n bytesReceived: 0,\n packetsSent: 0,\n packetsReceived: 0,\n rawStats: {},\n };\n }\n\n return {\n bytesSent: stats.dataChannel?.bytesSent,\n bytesReceived: stats.dataChannel?.bytesReceived,\n packetsSent: 0,\n packetsReceived: 0,\n rawStats: stats.raw,\n };\n};\n\nconst getRtcConnectionStats = async (connection: RTCPeerConnection, channelTopic?: string): Promise<any> => {\n const stats = await connection.getStats();\n\n const statsEntries: [string, any][] = Array.from((stats as any).entries());\n const transport = statsEntries.find(([_, entry]) => entry.type === 'transport')?.[1];\n\n const selectedCandidatePair =\n transport && statsEntries.find(([entryId]) => entryId === transport.selectedCandidatePairId)?.[1];\n const remoteCandidate =\n selectedCandidatePair && statsEntries.find(([entryId]) => entryId === selectedCandidatePair.remoteCandidateId)?.[1];\n\n const dataChannel =\n channelTopic &&\n statsEntries.find(([_, entry]) => entry.type === 'data-channel' && entry.label === channelTopic)?.[1];\n\n return {\n transport,\n selectedCandidatePair,\n dataChannel,\n remoteCandidate,\n raw: Object.fromEntries(stats as any),\n };\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport const chooseInitiatorPeer = (peer1Key: string, peer2Key: string) => (peer1Key < peer2Key ? peer1Key : peer2Key);\n\nexport const areSdpEqual = (sdp1: string, sdp2: string) => {\n const sdp1Lines = deduplicatedSdpLines(sdp1);\n const sdp2Lines = deduplicatedSdpLines(sdp2);\n if (sdp1Lines.length !== sdp2Lines.length) {\n return false;\n }\n return sdp1Lines.every((line, idx) => line === sdp2Lines[idx]);\n};\n\n/**\n * For some reason libdatachannel duplicates some attributes after an sdp is set.\n * So the following test might fail:\n * conn.setRemoteDescription(sdp);\n * expect(conn.remoteDescription.sdp).toEqual(sdp);\n */\nconst deduplicatedSdpLines = (sdp: string) => {\n const deduplicatedLines: string[] = [];\n const seenLines: string[] = [];\n for (const line of sdp.split('\\r\\n')) {\n if (line.startsWith('m')) {\n seenLines.length = 0;\n }\n if (seenLines.includes(line)) {\n continue;\n }\n seenLines.push(line);\n deduplicatedLines.push(line);\n }\n return deduplicatedLines;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { IceProvider } from '../../signal';\nimport type { TransportFactory } from '../transport';\n\nimport { getRtcConnectionFactory } from './rtc-connection-factory';\nimport { RtcPeerConnection } from './rtc-peer-connection';\n\nexport const createRtcTransportFactory = (\n webrtcConfig?: RTCConfiguration,\n iceProvider?: IceProvider,\n): TransportFactory => {\n const connectionFactory = getRtcConnectionFactory();\n return {\n createTransport: (options) => {\n // TODO(yaroslav): sendSignal is scoped to a swarm, RtcConnections can be cached if it's scoped to a peer\n const connection = new RtcPeerConnection(connectionFactory, {\n ownPeerKey: options.ownPeerKey,\n remotePeerKey: options.remotePeerKey,\n sendSignal: options.sendSignal,\n legacyInitiator: options.initiator,\n webrtcConfig,\n iceProvider,\n });\n return connection.createTransportChannel(options);\n },\n };\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Writable } from 'node:stream';\n\nimport { Event, scheduleTask } from '@dxos/async';\nimport { type Stream } from '@dxos/codec-protobuf/stream';\nimport { Resource } from '@dxos/context';\nimport { ErrorStream } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { ConnectionResetError, ConnectivityError, TimeoutError } from '@dxos/protocols';\nimport { type BridgeEvent, type BridgeService, ConnectionState } from '@dxos/protocols/proto/dxos/mesh/bridge';\nimport { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';\nimport { arrayToBuffer } from '@dxos/util';\n\nimport { type Transport, type TransportFactory, type TransportOptions, type TransportStats } from '../transport';\n\nconst RPC_TIMEOUT = 10_000;\nconst CLOSE_RPC_TIMEOUT = 3000;\nconst RESP_MIN_THRESHOLD = 500;\n\nexport type RtcTransportProxyOptions = TransportOptions & {\n bridgeService: BridgeService;\n};\n\nexport class RtcTransportProxy extends Resource implements Transport {\n private readonly _proxyId = PublicKey.random();\n\n readonly closed = new Event();\n readonly connected = new Event();\n readonly errors = new ErrorStream();\n\n private _serviceStream: Stream<BridgeEvent> | undefined;\n\n constructor(private readonly _options: RtcTransportProxyOptions) {\n super();\n }\n\n protected override async _open(): Promise<void> {\n let stream: Stream<BridgeEvent>;\n try {\n stream = this._options.bridgeService.open(\n {\n proxyId: this._proxyId,\n remotePeerKey: this._options.remotePeerKey,\n ownPeerKey: this._options.ownPeerKey,\n topic: this._options.topic,\n initiator: this._options.initiator ?? false,\n },\n { timeout: RPC_TIMEOUT },\n );\n } catch (error: any) {\n this.errors.raise(error);\n return;\n }\n\n this._serviceStream = stream;\n\n stream.waitUntilReady().then(\n () => {\n stream.subscribe(\n async (event: BridgeEvent) => {\n log('rtc transport proxy event', event);\n if (event.connection) {\n await this._handleConnection(event.connection);\n } else if (event.data) {\n this._handleData(event.data);\n } else if (event.signal) {\n await this._handleSignal(event.signal);\n }\n },\n (err) => {\n log('rtc bridge stream closed', { err });\n if (err) {\n this._raiseIfOpen(err);\n } else {\n void this.close();\n }\n },\n );\n\n const connectorStream = new Writable({\n write: (chunk, _, callback) => {\n const sendStartMs = Date.now();\n this._options.bridgeService\n .sendData({ proxyId: this._proxyId, payload: chunk }, { timeout: RPC_TIMEOUT })\n .then(\n () => {\n if (Date.now() - sendStartMs > RESP_MIN_THRESHOLD) {\n log('slow response, delaying callback');\n scheduleTask(this._ctx, () => callback(), RESP_MIN_THRESHOLD);\n } else {\n callback();\n }\n },\n (err: any) => {\n callback();\n this._raiseIfOpen(err);\n },\n );\n },\n });\n\n connectorStream.on('error', (err) => {\n this._raiseIfOpen(err);\n });\n\n this._options.stream.pipe(connectorStream);\n },\n (error) => {\n if (error) {\n this._raiseIfOpen(error);\n } else {\n void this.close();\n }\n },\n );\n }\n\n protected override async _close(): Promise<void> {\n try {\n await this._serviceStream?.close();\n this._serviceStream = undefined;\n } catch (err: any) {\n log.catch(err);\n }\n\n try {\n await this._options.bridgeService.close({ proxyId: this._proxyId }, { timeout: CLOSE_RPC_TIMEOUT });\n } catch (err: any) {\n log.catch(err);\n }\n\n this.closed.emit();\n }\n\n async onSignal(signal: Signal): Promise<void> {\n this._options.bridgeService\n .sendSignal({ proxyId: this._proxyId, signal }, { timeout: RPC_TIMEOUT })\n .catch((err) => this._raiseIfOpen(decodeError(err)));\n }\n\n private async _handleConnection(connectionEvent: BridgeEvent.ConnectionEvent): Promise<void> {\n if (connectionEvent.error) {\n this.errors.raise(decodeError(connectionEvent.error));\n return;\n }\n\n switch (connectionEvent.state) {\n case ConnectionState.CONNECTED: {\n this.connected.emit();\n break;\n }\n case ConnectionState.CLOSED: {\n await this.close();\n break;\n }\n }\n }\n\n private _handleData(dataEvent: BridgeEvent.DataEvent): void {\n try {\n // NOTE: This must be a Buffer otherwise hypercore-protocol breaks.\n this._options.stream.write(arrayToBuffer(dataEvent.payload));\n } catch (error: any) {\n this._raiseIfOpen(error);\n }\n }\n\n private async _handleSignal(signalEvent: BridgeEvent.SignalEvent): Promise<void> {\n try {\n await this._options.sendSignal(signalEvent.payload);\n } catch (error) {\n const type = signalEvent.payload.payload.data?.type;\n if (type === 'offer' || type === 'answer') {\n this._raiseIfOpen(new ConnectivityError(`Session establishment failed: ${type} couldn't be sent.`));\n }\n }\n }\n\n async getDetails(): Promise<string> {\n try {\n const response = await this._options.bridgeService.getDetails(\n { proxyId: this._proxyId },\n { timeout: RPC_TIMEOUT },\n );\n return response.details;\n } catch (err) {\n return 'bridge-svc unreachable';\n }\n }\n\n async getStats(): Promise<TransportStats> {\n try {\n const response = await this._options.bridgeService.getStats({ proxyId: this._proxyId }, { timeout: RPC_TIMEOUT });\n return response.stats as TransportStats;\n } catch (err) {\n return {\n bytesSent: 0,\n bytesReceived: 0,\n packetsSent: 0,\n packetsReceived: 0,\n rawStats: 'bridge-svc unreachable',\n };\n }\n }\n\n private _raiseIfOpen(error: any): void {\n if (this.isOpen) {\n this.errors.raise(error);\n } else {\n log.info('error swallowed because transport was closed', { message: error.message });\n }\n }\n\n /**\n * Called when underlying proxy service becomes unavailable.\n */\n forceClose(): void {\n void this._serviceStream?.close();\n this.closed.emit();\n }\n}\n\nexport class RtcTransportProxyFactory implements TransportFactory {\n private _bridgeService: BridgeService | undefined;\n private _connections = new Set<RtcTransportProxy>();\n\n /**\n * Sets the current BridgeService to be used to open connections.\n * Calling this method will close any existing connections.\n */\n setBridgeService(bridgeService: BridgeService | undefined): this {\n this._bridgeService = bridgeService;\n for (const connection of this._connections) {\n connection.forceClose();\n }\n return this;\n }\n\n createTransport(options: TransportOptions): Transport {\n invariant(this._bridgeService, 'RtcTransportProxyFactory is not ready to open connections');\n const transport = new RtcTransportProxy({ ...options, bridgeService: this._bridgeService });\n this._connections.add(transport);\n transport.closed.on(() => {\n this._connections.delete(transport);\n });\n return transport;\n }\n}\n\nconst decodeError = (err: Error | string) => {\n const message = typeof err === 'string' ? err : err.message;\n if (message.includes('CONNECTION_RESET')) {\n return new ConnectionResetError(message);\n } else if (message.includes('TIMEOUT')) {\n return new TimeoutError(message);\n } else if (message.includes('CONNECTIVITY_ERROR')) {\n return new ConnectivityError(message);\n } else {\n return typeof err === 'string' ? new Error(err) : err;\n }\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\n\nimport { Stream } from '@dxos/codec-protobuf/stream';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n type BridgeEvent,\n type BridgeService,\n type CloseRequest,\n type ConnectionRequest,\n ConnectionState,\n type DataRequest,\n type DetailsRequest,\n type DetailsResponse,\n type SignalRequest,\n type StatsRequest,\n type StatsResponse,\n} from '@dxos/protocols/proto/dxos/mesh/bridge';\nimport { ComplexMap } from '@dxos/util';\n\nimport { type IceProvider } from '../../signal';\nimport { type Transport, type TransportFactory } from '../transport';\n\nimport { createRtcTransportFactory } from './rtc-transport-factory';\n\ntype TransportState = {\n proxyId: PublicKey;\n transport: Transport;\n connectorStream: Duplex;\n writeProcessedCallbacks: (() => void)[];\n};\n\nexport class RtcTransportService implements BridgeService {\n private readonly _openTransports = new ComplexMap<PublicKey, TransportState>(PublicKey.hash);\n\n constructor(\n webrtcConfig?: RTCConfiguration,\n iceProvider?: IceProvider,\n private readonly _transportFactory: TransportFactory = createRtcTransportFactory(webrtcConfig, iceProvider),\n ) {}\n\n public hasOpenTransports(): boolean {\n return this._openTransports.size > 0;\n }\n\n open(request: ConnectionRequest): Stream<BridgeEvent> {\n const existingTransport = this._openTransports.get(request.proxyId);\n if (existingTransport) {\n log.error('requesting a new transport bridge for an existing proxy');\n void this._safeCloseTransport(existingTransport);\n this._openTransports.delete(request.proxyId);\n }\n\n return new Stream<BridgeEvent>(({ ready, next, close }) => {\n const pushNewState = createStateUpdater(next);\n\n const transportStream: Duplex = new Duplex({\n read: () => {\n const callbacks = [...transportState.writeProcessedCallbacks];\n transportState.writeProcessedCallbacks.length = 0;\n callbacks.forEach((cb) => cb());\n },\n write: function (chunk, _, callback) {\n next({ data: { payload: chunk } });\n callback();\n },\n });\n\n const transport = this._transportFactory.createTransport({\n initiator: request.initiator,\n topic: request.topic,\n ownPeerKey: request.ownPeerKey,\n remotePeerKey: request.remotePeerKey,\n stream: transportStream,\n sendSignal: async (signal) => {\n next({ signal: { payload: signal } });\n },\n });\n\n const transportState: TransportState = {\n proxyId: request.proxyId,\n transport,\n connectorStream: transportStream,\n writeProcessedCallbacks: [],\n };\n\n transport.connected.on(() => pushNewState(ConnectionState.CONNECTED));\n\n transport.errors.handle(async (err) => {\n pushNewState(ConnectionState.CLOSED, err);\n void this._safeCloseTransport(transportState);\n close(err);\n });\n\n transport.closed.on(async () => {\n pushNewState(ConnectionState.CLOSED);\n void this._safeCloseTransport(transportState);\n close();\n });\n\n this._openTransports.set(request.proxyId, transportState);\n\n transport.open().catch(async (err) => {\n pushNewState(ConnectionState.CLOSED, err);\n void this._safeCloseTransport(transportState);\n close(err);\n });\n\n ready();\n\n log('stream ready');\n\n pushNewState(ConnectionState.CONNECTING);\n });\n }\n\n async sendSignal({ proxyId, signal }: SignalRequest): Promise<void> {\n const transport = this._openTransports.get(proxyId);\n invariant(transport);\n\n await transport.transport.onSignal(signal);\n }\n\n async getDetails({ proxyId }: DetailsRequest): Promise<DetailsResponse> {\n const transport = this._openTransports.get(proxyId);\n invariant(transport);\n\n return { details: await transport.transport.getDetails() };\n }\n\n async getStats({ proxyId }: StatsRequest): Promise<StatsResponse> {\n const transport = this._openTransports.get(proxyId);\n invariant(transport);\n\n return { stats: await transport.transport.getStats() };\n }\n\n async sendData({ proxyId, payload }: DataRequest): Promise<void> {\n const transport = this._openTransports.get(proxyId);\n invariant(transport);\n\n const bufferHasSpace = transport.connectorStream.push(payload);\n if (!bufferHasSpace) {\n await new Promise<void>((resolve) => {\n transport.writeProcessedCallbacks.push(resolve);\n });\n }\n }\n\n async close({ proxyId }: CloseRequest): Promise<void> {\n const transport = this._openTransports.get(proxyId);\n if (!transport) {\n return;\n }\n\n this._openTransports.delete(proxyId);\n await this._safeCloseTransport(transport);\n }\n\n private async _safeCloseTransport(transport: TransportState): Promise<void> {\n if (this._openTransports.get(transport.proxyId) === transport) {\n this._openTransports.delete(transport.proxyId);\n }\n\n transport.writeProcessedCallbacks.forEach((cb) => cb());\n\n try {\n await transport.transport.close();\n } catch (error: any) {\n log.warn('transport close error', { message: error?.message });\n }\n try {\n transport.connectorStream.end();\n } catch (error: any) {\n log.warn('connectorStream close error', { message: error?.message });\n }\n log('closed');\n }\n}\n\nconst createStateUpdater = (next: (event: BridgeEvent) => void) => {\n return (state: ConnectionState, err?: Error) => {\n next({\n connection: {\n state,\n ...(err ? { error: err.message } : undefined),\n },\n });\n };\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type Duplex } from 'node:stream';\n\nimport { type PublicKey } from '@dxos/keys';\nimport { Teleport, type TeleportParams } from '@dxos/teleport';\n\nexport type WireProtocolParams = {\n initiator: boolean;\n localPeerId: PublicKey;\n remotePeerId: PublicKey;\n topic: PublicKey;\n};\n\nexport type WireProtocolProvider = (params: WireProtocolParams) => WireProtocol;\n\n/**\n * Application-specific network protocol that is used when a connection to a peer is established.\n * Will implement high-level logic, like replication, authentication, etc.\n */\nexport interface WireProtocol {\n stream: Duplex;\n\n open(sessionId?: PublicKey): Promise<void>;\n close(): Promise<void>;\n abort(): Promise<void>;\n}\n\n/**\n * Create a wire-protocol provider backed by a teleport instance.\n * @param onConnection Called after teleport is initialized for the session. Protocol extensions could be attached here.\n * @param defaultParams Optionally provide default Teleport params that might be overridden by factory callers.\n * @returns\n */\nexport const createTeleportProtocolFactory = (\n onConnection: (teleport: Teleport) => Promise<void>,\n defaultParams?: Partial<TeleportParams>,\n): WireProtocolProvider => {\n return (params) => {\n const teleport = new Teleport({ ...defaultParams, ...params });\n return {\n stream: teleport.stream,\n open: async (sessionId?: PublicKey) => {\n await teleport.open(sessionId);\n await onConnection(teleport);\n },\n close: async () => {\n await teleport.close();\n },\n abort: async () => {\n await teleport.abort();\n },\n };\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["DeferredTask", "Event", "Trigger", "scheduleTask", "scheduleTaskInterval", "sleep", "synchronized", "Context", "ContextDisposedError", "cancelWithContext", "ErrorStream", "invariant", "PublicKey", "log", "logInfo", "CancelledError", "ConnectionResetError", "ConnectivityError", "ProtocolError", "TimeoutError", "trace", "STARTING_SIGNALLING_DELAY", "TRANSPORT_CONNECTION_TIMEOUT", "TRANSPORT_STATS_INTERVAL", "MAX_SIGNALLING_DELAY", "ConnectionState", "Connection", "_ctx", "connectedTimeoutContext", "_protocolClosed", "_transportClosed", "_state", "_transport", "closeReason", "_incomingSignalBuffer", "_outgoingSignalBuffer", "stateChanged", "errors", "_instanceId", "transportStats", "_signalSendTask", "_signallingDelay", "topic", "localInfo", "remoteInfo", "sessionId", "initiator", "_signalMessaging", "_protocol", "_transportFactory", "_callbacks", "random", "toHex", "_flushSignalBuffer", "localPeer", "remotePeer", "sessionIdString", "truncate", "state", "transport", "protocol", "openConnection", "begin", "id", "localPeerId", "remotePeerId", "_changeState", "open", "catch", "err", "raise", "stream", "on", "wake", "close", "error", "info", "abort", "createTransport", "ownPeerKey", "peerKey", "remotePeerKey", "sendSignal", "signal", "_sendSignal", "connected", "once", "dispose", "onConnected", "_emitTransportStats", "closed", "undefined", "handle", "message", "onSignal", "end", "peerId", "_closeProtocol", "_closeTransport", "onClosed", "reason", "lastState", "abortProtocol", "options", "Promise", "race", "wait", "push", "schedule", "length", "process", "Math", "min", "signals", "author", "recipient", "data", "signalBatch", "Error", "includes", "msg", "equals", "remoteId", "initiate", "from", "to", "emit", "stats", "getStats", "asyncTimeout", "log", "isNonNullable", "createIceProvider", "iceProviders", "cachedIceServers", "getIceServers", "Promise", "all", "map", "urls", "fetch", "method", "then", "response", "json", "catch", "err", "isDev", "window", "location", "href", "includes", "error", "filter", "iceServers", "flat", "Context", "invariant", "PublicKey", "log", "TimeoutError", "schema", "ComplexMap", "SwarmMessage", "getCodecForType", "SwarmMessenger", "_ctx", "_sendMessage", "_onSignal", "_onOffer", "_topic", "_offerRecords", "key", "toHex", "sendMessage", "onSignal", "onOffer", "topic", "receiveMessage", "author", "recipient", "payload", "type_url", "message", "decode", "value", "equals", "from", "to", "msg", "data", "offer", "_handleOffer", "answer", "_resolveAnswers", "signal", "_handleSignal", "signalBatch", "warn", "_sendReliableMessage", "networkMessage", "messageId", "random", "Promise", "resolve", "reject", "set", "catch", "err", "encode", "offerMessageId", "offerRecord", "get", "delete", "offerMessage", "sessionId", "info", "signalMessage", "Event", "scheduleTask", "sleep", "synchronized", "Context", "ErrorStream", "invariant", "PublicKey", "log", "logInfo", "PeerInfoHash", "trace", "ComplexMap", "isNonNullable", "Event", "scheduleTask", "synchronized", "Context", "invariant", "PublicKey", "log", "CancelledError", "SystemError", "ConnectionDisplacedError", "SystemError", "CONNECTION_COUNTS_STABLE_AFTER", "Peer", "_availableAfter", "availableToConnect", "_lastConnectionTime", "_ctx", "_connectionCtx", "connection", "advertizing", "initiating", "connectionDisplaced", "remoteInfo", "topic", "localInfo", "_signalMessaging", "_protocolProvider", "_transportFactory", "_connectionLimiter", "_callbacks", "Context", "Event", "onOffer", "message", "remote", "author", "ConnectionState", "CREATED", "INITIAL", "CONNECTING", "includes", "state", "log", "info", "accept", "peerKey", "localPeer", "remotePeer", "sessionId", "closeConnection", "invariant", "_createConnection", "connecting", "initiate", "openConnection", "err", "CancelledError", "peerId", "remoteId", "initiateConnection", "PublicKey", "random", "local", "answer", "offer", "recipient", "data", "abort", "onRejected", "onAccepted", "warn", "initiator", "Connection", "localPeerId", "from", "remotePeerId", "onConnected", "Date", "now", "doneConnecting", "trace", "onClosed", "logMeta", "emit", "increaseInterval", "onDisconnected", "scheduleTask", "onPeerAvailable", "undefined", "onInitiated", "dispose", "derive", "errors", "handle", "close", "error", "onSignal", "signal", "safeDestroy", "reason", "interval", "INITIATION_DELAY", "getClassName", "obj", "Object", "getPrototypeOf", "name", "Swarm", "_swarmMessenger", "_ctx", "_listeningHandle", "_peers", "_instanceId", "connectionAdded", "disconnected", "connected", "errors", "_topic", "_ownPeer", "_topology", "_protocolProvider", "_messenger", "_transportFactory", "_label", "_connectionLimiter", "_initiationDelay", "Context", "undefined", "ComplexMap", "PeerInfoHash", "PublicKey", "random", "toHex", "Event", "ErrorStream", "log", "trace", "begin", "id", "data", "topic", "peer", "peerId", "init", "_getSwarmController", "SwarmMessenger", "sendMessage", "msg", "onSignal", "onOffer", "end", "connections", "Array", "from", "values", "map", "connection", "filter", "isNonNullable", "ownPeerId", "peerKey", "ownPeer", "label", "open", "invariant", "listen", "payloadType", "onMessage", "message", "receiveMessage", "catch", "err", "info", "destroy", "unsubscribe", "dispose", "Promise", "all", "keys", "key", "_destroyPeer", "setTopology", "topology", "disposed", "previous", "update", "onSwarmEvent", "swarmEvent", "peerAvailable", "_getOrCreatePeer", "advertizing", "peerLeft", "get", "_isConnectionEstablishmentInProgress", "state", "accept", "author", "recipient", "equals", "_getOfferSenderPeer", "answer", "senderInfo", "connectionState", "ConnectionState", "CLOSING", "ABORTING", "delete", "remoteInfo", "emit", "goOffline", "goOnline", "peerInfo", "Peer", "onInitiated", "onConnected", "onDisconnected", "_isUnregistered", "verbose", "onRejected", "onAccepted", "remoteId", "onPeerAvailable", "set", "reason", "safeDestroy", "getState", "entries", "_", "candidates", "availableToConnect", "allPeers", "connect", "scheduleTask", "_initiateConnection", "disconnect", "_closeConnection", "remotePeer", "ctx", "sleep", "Error", "initiateConnection", "closeConnection", "INITIAL", "CREATED", "CONNECTING", "includes", "Event", "SubscriptionList", "PublicKey", "log", "PeerInfoHash", "ComplexMap", "SwarmMapper", "_subscriptions", "_connectionSubscriptions", "_peers", "mapUpdated", "peers", "Array", "from", "values", "_swarm", "add", "connectionAdded", "on", "connection", "_update", "set", "remoteInfo", "stateChanged", "disconnected", "peerId", "get", "delete", "clear", "ownPeer", "id", "ownPeerId", "state", "connections", "peerKey", "directConnections", "length", "totalPeersInSwarm", "size", "emit", "destroy", "forEach", "cb", "DeferredTask", "Context", "invariant", "PublicKey", "log", "CancelledError", "ComplexMap", "MAX_CONCURRENT_INITIATING_CONNECTIONS", "ConnectionLimiter", "_ctx", "_maxConcurrentInitConnections", "_waitingPromises", "hash", "resolveWaitingPromises", "Array", "from", "values", "slice", "forEach", "resolve", "maxConcurrentInitConnections", "connecting", "sessionId", "has", "Promise", "reject", "set", "schedule", "doneConnecting", "get", "delete", "Event", "raise", "PublicKey", "ComplexMap", "CONNECTION_GC_THRESHOLD", "EventType", "ConnectionLog", "_swarms", "ComplexMap", "PublicKey", "hash", "update", "Event", "getSwarmInfo", "swarmId", "get", "raise", "Error", "swarms", "Array", "from", "values", "joinedSwarm", "swarm", "info", "id", "_instanceId", "topic", "isActive", "label", "connections", "set", "emit", "connectionAdded", "on", "connection", "connectionInfo", "state", "ConnectionState", "CREATED", "closeReason", "remotePeerId", "remoteInfo", "peerKey", "sessionId", "transport", "Object", "getPrototypeOf", "name", "protocolExtensions", "events", "lastUpdate", "Date", "push", "stateChanged", "type", "newState", "CONNECTED", "details", "getDetails", "transportDetails", "protocol", "stats", "readBufferSize", "writeBufferSize", "streams", "channels", "transportStats", "transportBytesSent", "bytesSent", "transportBytesReceived", "bytesReceived", "transportPacketsSent", "packetsSent", "transportPacketsReceived", "packetsReceived", "gcSwarm", "leftSwarm", "filter", "now", "getTime", "Event", "synchronized", "invariant", "PublicKey", "log", "Messenger", "trace", "ConnectionState", "ComplexMap", "SwarmNetworkManager", "_swarms", "ComplexMap", "PublicKey", "hash", "_mappers", "_transportFactory", "_signalManager", "_messenger", "_signalConnection", "_connectionLimiter", "_connectionLog", "_instanceId", "random", "toHex", "_peerInfo", "undefined", "_connectionState", "ConnectionState", "ONLINE", "connectionStateChanged", "Event", "topicsUpdated", "transportFactory", "signalManager", "enableDevtoolsLogging", "peerInfo", "swarmEvent", "on", "event", "get", "topic", "onSwarmEvent", "Messenger", "join", "opts", "leave", "ConnectionLimiter", "ConnectionLog", "connectionLog", "connectionState", "topics", "Array", "from", "keys", "getSwarmMap", "getSwarm", "setPeerInfo", "open", "log", "trace", "begin", "id", "end", "close", "leaveSwarm", "catch", "err", "joinSwarm", "topology", "protocolProvider", "protocol", "label", "invariant", "isPublicKey", "has", "Error", "toString", "swarm", "Swarm", "errors", "handle", "error", "set", "SwarmMapper", "peer", "emit", "joinedSwarm", "count", "size", "ownPeer", "map", "destroy", "delete", "leftSwarm", "setConnectionState", "state", "OFFLINE", "Promise", "all", "values", "goOffline", "goOnline", "invariant", "FullyConnectedTopology", "_controller", "toString", "init", "controller", "update", "candidates", "discovered", "getState", "peer", "connect", "onOffer", "destroy", "invariant", "log", "MIN_UPDATE_INTERVAL", "MAX_CHANGES_PER_UPDATE", "MMSTTopology", "_originateConnections", "_maxPeers", "_sampleSize", "_controller", "_sampleCollected", "_lastAction", "Date", "originateConnections", "maxPeers", "sampleSize", "init", "controller", "update", "connected", "candidates", "getState", "length", "_runAlgorithm", "forceUpdate", "onOffer", "peer", "accept", "destroy", "ownPeerId", "sorted", "sortByXorDistance", "reverse", "slice", "now", "getTime", "disconnect", "sample", "sort", "Math", "random", "connect", "toString", "keys", "reference", "a", "b", "compareXor", "distXor", "asBuffer", "maxLength", "max", "result", "Buffer", "allocUnsafe", "i", "invariant", "log", "StarTopology", "_controller", "_centralPeer", "toString", "truncate", "init", "controller", "update", "candidates", "connected", "ownPeerId", "getState", "equals", "peer", "disconnect", "connect", "onOffer", "isCentral", "isSelfCentral", "destroy", "Transform", "Event", "Trigger", "ErrorStream", "invariant", "PublicKey", "log", "logInfo", "ComplexMap", "MEMORY_TRANSPORT_DELAY", "createStreamDelay", "delay", "objectMode", "transform", "chunk", "_", "cb", "setTimeout", "MemoryTransportFactory", "createTransport", "options", "MemoryTransport", "_connections", "hash", "_instanceId", "_remote", "_outgoingDelay", "_incomingDelay", "_closed", "_remoteInstanceId", "_remoteConnection", "closed", "connected", "errors", "_options", "random", "has", "set", "isOpen", "open", "initiator", "sendSignal", "payload", "transportId", "toHex", "err", "raise", "toError", "wait", "timeout", "then", "remoteId", "get", "emit", "stream", "pipe", "catch", "close", "delete", "unpipe", "undefined", "onSignal", "fromHex", "wake", "getDetails", "getStats", "bytesSent", "bytesReceived", "packetsSent", "packetsReceived", "Error", "String", "TransportKind", "Mutex", "BrowserRtcConnectionFactory", "initialize", "onConnectionDestroyed", "createConnection", "config", "RTCPeerConnection", "initConnection", "connection", "info", "NodeRtcConnectionFactory", "_createdConnections", "_cleanupMutex", "Mutex", "executeSynchronized", "cleanup", "initiator", "onnegotiationneeded", "getRtcConnectionFactory", "globalThis", "Mutex", "Trigger", "synchronized", "invariant", "log", "logInfo", "ConnectivityError", "trace", "Duplex", "Event", "AsyncEvent", "Resource", "ErrorStream", "invariant", "log", "ConnectivityError", "describeSelectedRemoteCandidate", "connection", "stats", "getRtcConnectionStats", "rc", "remoteCandidate", "candidateType", "ip", "port", "relatedAddress", "relatedPort", "createRtcTransportStats", "topic", "bytesSent", "bytesReceived", "packetsSent", "packetsReceived", "rawStats", "dataChannel", "raw", "channelTopic", "getStats", "statsEntries", "Array", "from", "entries", "transport", "find", "_", "entry", "type", "selectedCandidatePair", "entryId", "selectedCandidatePairId", "remoteCandidateId", "label", "Object", "fromEntries", "MAX_MESSAGE_SIZE", "MAX_BUFFERED_AMOUNT", "RtcTransportChannel", "Resource", "closed", "connected", "errors", "_channel", "_stream", "_streamDataFlushedCallback", "_isChannelCreationInProgress", "_connection", "_options", "AsyncEvent", "ErrorStream", "isRtcChannelCreationInProgress", "onConnectionError", "error", "isOpen", "raise", "_open", "invariant", "createDataChannel", "topic", "then", "channel", "_initChannel", "_safeCloseChannel", "catch", "err", "Error", "ConnectivityError", "JSON", "stringify", "message", "log", "verbose", "finally", "_close", "undefined", "emit", "Object", "assign", "onopen", "warn", "duplex", "Duplex", "read", "write", "chunk", "encoding", "callback", "_handleChannelWrite", "pipe", "stream", "onclose", "close", "onmessage", "event", "data", "ArrayBuffer", "Buffer", "from", "Blob", "arrayBuffer", "push", "onerror", "type", "onbufferedamountlow", "cb", "length", "send", "bufferedAmount", "onSignal", "signal", "getDetails", "describeSelectedRemoteCandidate", "currentConnection", "getStats", "createRtcTransportStats", "chooseInitiatorPeer", "peer1Key", "peer2Key", "areSdpEqual", "sdp1", "sdp2", "sdp1Lines", "deduplicatedSdpLines", "sdp2Lines", "length", "every", "line", "idx", "sdp", "deduplicatedLines", "seenLines", "split", "startsWith", "includes", "push", "RtcPeerConnection", "_channelCreatedCallbacks", "_transportChannels", "_dataChannels", "_readyForCandidates", "_offerProcessingMutex", "_initiator", "_connection", "_factory", "_options", "Map", "Trigger", "Mutex", "chooseInitiatorPeer", "ownPeerKey", "remotePeerKey", "transportChannelCount", "size", "currentConnection", "createDataChannel", "topic", "connection", "_openConnection", "has", "_lockAndCloseConnection", "Error", "channel", "set", "existingChannel", "get", "log", "Promise", "resolve", "reject", "createTransportChannel", "options", "RtcTransportChannel", "closed", "on", "delete", "remotePeer", "config", "_loadConnectionConfig", "createConnection", "iceCandidateErrors", "Object", "assign", "onnegotiationneeded", "invariant", "_onConnectionCallbackAfterClose", "offer", "createOffer", "setLocalDescription", "_sendDescription", "err", "_lockAndAbort", "onicecandidate", "event", "candidate", "_sendIceCandidate", "onicecandidateerror", "url", "errorCode", "errorText", "push", "oniceconnectionstatechange", "state", "iceConnectionState", "createIceFailureError", "onconnectionstatechange", "connectionState", "onsignalingstatechange", "signalingState", "ondatachannel", "label", "pendingCallback", "reset", "initConnection", "initiator", "error", "_abortConnection", "_safeCloseConnection", "entries", "clear", "values", "onConnectionError", "reason", "message", "onSignal", "signal", "warn", "type", "payload", "data", "executeSynchronized", "isRemoteDescriptionSet", "setRemoteDescription", "sdp", "answer", "createAnswer", "_onSessionNegotiated", "cause", "_processIceCandidate", "wait", "addIceCandidate", "catch", "wake", "callback", "resetFields", "close", "undefined", "onConnectionDestroyed", "_", "webrtcConfig", "providedIceServers", "iceProvider", "getIceServers", "length", "iceServers", "sendSignal", "sdpMLineIndex", "sdpMid", "description", "_connectionInfo", "connectionInfo", "iceGatheringState", "remoteDescription", "localDescription", "ts", "Date", "now", "channels", "keys", "map", "getConfiguration", "_loggerContext", "info", "resource", "areSdpEqual", "details", "candidateErrors", "ConnectivityError", "join", "createRtcTransportFactory", "webrtcConfig", "iceProvider", "connectionFactory", "getRtcConnectionFactory", "createTransport", "options", "connection", "RtcPeerConnection", "ownPeerKey", "remotePeerKey", "sendSignal", "legacyInitiator", "initiator", "createTransportChannel", "Writable", "Event", "scheduleTask", "Resource", "ErrorStream", "invariant", "PublicKey", "log", "ConnectionResetError", "ConnectivityError", "TimeoutError", "ConnectionState", "arrayToBuffer", "RPC_TIMEOUT", "CLOSE_RPC_TIMEOUT", "RESP_MIN_THRESHOLD", "RtcTransportProxy", "_proxyId", "closed", "connected", "errors", "_serviceStream", "_options", "random", "_open", "stream", "bridgeService", "open", "proxyId", "remotePeerKey", "ownPeerKey", "topic", "initiator", "timeout", "error", "raise", "waitUntilReady", "then", "subscribe", "event", "connection", "_handleConnection", "data", "_handleData", "signal", "_handleSignal", "err", "_raiseIfOpen", "close", "connectorStream", "write", "chunk", "_", "callback", "sendStartMs", "Date", "now", "sendData", "payload", "_ctx", "on", "pipe", "_close", "undefined", "catch", "emit", "onSignal", "sendSignal", "decodeError", "connectionEvent", "state", "CONNECTED", "CLOSED", "dataEvent", "signalEvent", "type", "getDetails", "response", "details", "getStats", "stats", "bytesSent", "bytesReceived", "packetsSent", "packetsReceived", "rawStats", "isOpen", "info", "message", "forceClose", "RtcTransportProxyFactory", "_bridgeService", "_connections", "Set", "setBridgeService", "createTransport", "options", "transport", "add", "delete", "includes", "Error", "Duplex", "Stream", "invariant", "PublicKey", "log", "ConnectionState", "ComplexMap", "RtcTransportService", "_openTransports", "webrtcConfig", "iceProvider", "_transportFactory", "createRtcTransportFactory", "ComplexMap", "PublicKey", "hash", "hasOpenTransports", "size", "open", "request", "existingTransport", "get", "proxyId", "log", "error", "_safeCloseTransport", "delete", "Stream", "ready", "next", "close", "pushNewState", "createStateUpdater", "transportStream", "Duplex", "read", "callbacks", "transportState", "writeProcessedCallbacks", "length", "forEach", "cb", "write", "chunk", "_", "callback", "data", "payload", "transport", "createTransport", "initiator", "topic", "ownPeerKey", "remotePeerKey", "stream", "sendSignal", "signal", "connectorStream", "connected", "on", "ConnectionState", "CONNECTED", "errors", "handle", "err", "CLOSED", "closed", "set", "catch", "CONNECTING", "invariant", "onSignal", "getDetails", "details", "getStats", "stats", "sendData", "bufferHasSpace", "push", "Promise", "resolve", "warn", "message", "end", "state", "connection", "undefined", "Teleport", "createTeleportProtocolFactory", "onConnection", "defaultParams", "params", "teleport", "Teleport", "stream", "open", "sessionId", "close", "abort"]
|
|
7
|
+
}
|