@dxos/network-manager 0.1.22 → 0.1.24-next.6b1f434

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../../src/testing/test-builder.ts", "../../../../src/network-manager.ts", "../../../../src/connection-log.ts", "../../../../src/swarm/connection.ts", "../../../../src/swarm/swarm.ts", "../../../../src/signal/message-router.ts", "../../../../src/swarm/peer.ts", "../../../../src/swarm/swarm-mapper.ts", "../../../../src/topology/fully-connected-topology.ts", "../../../../src/topology/mmst-topology.ts", "../../../../src/topology/star-topology.ts", "../../../../src/transport/memory-transport.ts", "../../../../src/transport/webrtc-transport.ts", "../../../../src/transport/webrtc.ts", "../../../../src/transport/webrtc-transport-service.ts", "../../../../src/transport/webrtc-transport-proxy.ts", "../../../../src/testing/test-wire-protocol.ts", "../../../../src/wire-protocol.ts"],
4
- "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { PublicKey } from '@dxos/keys';\nimport { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';\nimport { schema } from '@dxos/protocols';\nimport { ConnectionState } from '@dxos/protocols/proto/dxos/client/services';\nimport { createLinkedPorts, createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';\nimport { ComplexMap } from '@dxos/util';\n\nimport { NetworkManager } from '../network-manager';\nimport { FullyConnectedTopology } from '../topology';\nimport {\n MemoryTransportFactory,\n TransportFactory,\n WebRTCTransport,\n WebRTCTransportProxyFactory,\n WebRTCTransportService\n} from '../transport';\nimport { TestWireProtocol } from './test-wire-protocol';\n\n// Signal server will be started by the setup script.\nexport const TEST_SIGNAL_URL = 'ws://localhost:4000/.well-known/dx/signal';\n\nexport type TestBuilderOptions = {\n signalHosts?: string[];\n bridge?: boolean;\n};\n\n/**\n * Builder used to construct networks and peers.\n */\nexport class TestBuilder {\n private _signalContext = new MemorySignalManagerContext();\n\n constructor(public readonly options: TestBuilderOptions = {}) {}\n\n createSignalManager() {\n if (this.options.signalHosts) {\n return new WebsocketSignalManager(this.options.signalHosts);\n }\n\n return new MemorySignalManager(this._signalContext);\n }\n\n createPeer() {\n return new TestPeer(this);\n }\n}\n\n/**\n * Testing network peer.\n */\nexport class TestPeer {\n readonly peerId = PublicKey.random();\n\n private readonly _swarms = new ComplexMap<PublicKey, TestSwarmConnection>(PublicKey.hash);\n\n /**\n * @internal\n */\n readonly _networkManager: NetworkManager;\n\n private _proxy?: ProtoRpcPeer<any>;\n private _service?: ProtoRpcPeer<any>;\n\n constructor(private readonly testBuilder: TestBuilder) {\n this._networkManager = this.createNetworkManager();\n }\n\n // TODO(burdon): Move to TestBuilder.\n createNetworkManager() {\n let transportFactory: TransportFactory = MemoryTransportFactory;\n\n if (this.testBuilder.options.signalHosts) {\n if (this.testBuilder.options.bridge) {\n // Simulates bridge to shared worker.\n const [proxyPort, servicePort] = createLinkedPorts();\n\n this._proxy = createProtoRpcPeer({\n port: proxyPort,\n requested: {\n BridgeService: schema.getService('dxos.mesh.bridge.BridgeService')\n },\n noHandshake: true,\n encodingOptions: {\n preserveAny: true\n }\n });\n\n this._service = createProtoRpcPeer({\n port: servicePort,\n exposed: {\n BridgeService: schema.getService('dxos.mesh.bridge.BridgeService')\n },\n handlers: { BridgeService: new WebRTCTransportService() },\n noHandshake: true,\n encodingOptions: {\n preserveAny: true\n }\n });\n\n transportFactory = new WebRTCTransportProxyFactory().setBridgeService(this._proxy.rpc.BridgeService);\n } else {\n transportFactory = {\n createTransport: (params) => new WebRTCTransport(params)\n };\n }\n }\n\n return new NetworkManager({\n signalManager: this.testBuilder.createSignalManager(),\n transportFactory\n });\n }\n\n async open() {\n await this._proxy?.open();\n await this._service?.open();\n }\n\n async close() {\n await Promise.all(Array.from(this._swarms.values()).map((swarm) => swarm.leave()));\n this._swarms.clear();\n\n await this._proxy?.close();\n await this._service?.close();\n await this._networkManager.close();\n }\n\n getSwarm(topic: PublicKey): TestSwarmConnection {\n const swarm = this._swarms.get(topic);\n if (!swarm) {\n throw new Error(`Swarm not found for topic: ${topic}`);\n }\n\n return swarm;\n }\n\n createSwarm(topic: PublicKey): TestSwarmConnection {\n // TODO(burdon): Multiple.\n // if (this._swarms.get(topic)) {\n // throw new Error(`Swarm already exists for topic: ${topic.truncate()}`);\n // }\n\n const swarm = new TestSwarmConnection(this, topic);\n this._swarms.set(topic, swarm);\n return swarm;\n }\n\n async goOffline() {\n await this._networkManager.setConnectionState(ConnectionState.OFFLINE);\n }\n\n async goOnline() {\n await this._networkManager.setConnectionState(ConnectionState.ONLINE);\n }\n}\n\n// TODO(burdon): Reconcile with new Swarm concept.\nexport class TestSwarmConnection {\n protocol: TestWireProtocol;\n\n constructor(readonly peer: TestPeer, readonly topic: PublicKey) {\n // TODO(burdon): Configure plugins.\n // TODO(burdon): Prevent reuse?\n this.protocol = new TestWireProtocol(this.peer.peerId);\n }\n\n // TODO(burdon): Need to create new plugin instance per swarm?\n // If so, then perhaps joinSwarm should return swarm object with access to plugins.\n async join(topology = new FullyConnectedTopology()) {\n await this.peer._networkManager.joinSwarm({\n topic: this.topic,\n peerId: this.peer.peerId,\n protocolProvider: this.protocol.factory,\n topology\n });\n\n return this;\n }\n\n async leave() {\n await this.peer._networkManager.leaveSwarm(this.topic);\n return this;\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport assert from 'node:assert';\n\nimport { Event } from '@dxos/async';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { Messenger, SignalManager } from '@dxos/messaging';\nimport { ConnectionState } from '@dxos/protocols/proto/dxos/client/services';\nimport { ComplexMap } from '@dxos/util';\n\nimport { ConnectionLog } from './connection-log';\nimport { SignalConnection } from './signal';\nimport { Swarm, SwarmMapper } from './swarm';\nimport { Topology } from './topology';\nimport { TransportFactory } from './transport';\nimport { WireProtocolProvider } from './wire-protocol';\n\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 id.\n */\n peerId: PublicKey;\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 NetworkManagerOptions = {\n transportFactory: TransportFactory;\n signalManager: SignalManager;\n log?: boolean; // Log to devtools.\n};\n\n/**\n * Manages connection to the swarm.\n */\n// TODO(dmaretskyi): Rename SwarmManager.\nexport class NetworkManager {\n private 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\n private _connectionState = ConnectionState.ONLINE;\n public readonly connectionStateChanged = new Event<ConnectionState>();\n\n private readonly _connectionLog?: ConnectionLog;\n\n public readonly topicsUpdated = new Event<void>();\n\n constructor({ transportFactory, signalManager, log }: NetworkManagerOptions) {\n this._transportFactory = transportFactory;\n\n // Listen for signal manager events.\n this._signalManager = signalManager;\n this._signalManager.swarmEvent.on(({ topic, swarmEvent: event }) => this._swarms.get(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\n // TODO(burdon): Inject listener (generic pattern).\n if (log) {\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 // TODO(burdon): Remove access (Devtools only).\n get signalManager() {\n return this._signalManager;\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 async open() {\n await this._messenger.open();\n await this._signalManager.open();\n }\n\n async close() {\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 async joinSwarm({\n topic,\n peerId,\n topology,\n protocolProvider: protocol,\n label\n }: SwarmOptions): Promise<SwarmConnection> {\n assert(PublicKey.isPublicKey(topic));\n assert(PublicKey.isPublicKey(peerId));\n assert(topology);\n assert(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), peerId, topology: topology.toString() }); // TODO(burdon): Log peerId.\n const swarm = new Swarm(topic, peerId, topology, protocol, this._messenger, this._transportFactory, label);\n swarm.errors.handle((error) => {\n log('swarm error', { error });\n });\n\n this._swarms.set(topic, swarm);\n this._signalConnection.join({ topic, peerId }).catch((error) => log.catch(error));\n this._mappers.set(topic, new SwarmMapper(swarm));\n\n this.topicsUpdated.emit();\n this._connectionLog?.swarmJoined(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 async leaveSwarm(topic: PublicKey) {\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, peerId: swarm.ownPeerId });\n\n const map = this._mappers.get(topic)!;\n map.destroy();\n this._mappers.delete(topic);\n\n this._connectionLog?.swarmLeft(swarm);\n\n await swarm.destroy();\n this._swarms.delete(topic);\n\n await this.topicsUpdated.emit();\n log('left', { topic: PublicKey.from(topic), count: this._swarms.size });\n }\n\n async setConnectionState(state: ConnectionState) {\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 this._messenger.close();\n await this._signalManager.close();\n await Promise.all([...this._swarms.values()].map((swarm) => swarm.goOffline()));\n break;\n }\n case ConnectionState.ONLINE: {\n this._connectionState = state;\n // go online\n this._messenger.open();\n await this._signalManager.open();\n await Promise.all([...this._swarms.values()].map((swarm) => swarm.goOnline()));\n break;\n }\n }\n\n this.connectionStateChanged.emit(this._connectionState);\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 { SwarmInfo, ConnectionInfo } from '@dxos/protocols/proto/dxos/devtools/swarm';\nimport { ComplexMap } from '@dxos/util';\n\nimport { ConnectionState, Swarm } from './swarm';\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) {\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 swarmJoined(swarm: Swarm) {\n const info: SwarmInfo = {\n id: swarm.instanceId,\n topic: swarm.topic,\n isActive: true,\n label: swarm.label,\n connections: []\n };\n\n this._swarms.set(swarm.instanceId, info);\n this.update.emit();\n\n swarm.connectionAdded.on((connection) => {\n const connectionInfo: ConnectionInfo = {\n state: ConnectionState.INITIAL,\n remotePeerId: connection.remoteId,\n sessionId: connection.sessionId,\n transport: connection.transport && Object.getPrototypeOf(connection.transport).constructor.name,\n protocolExtensions: [], // TODO(dmaretskyi): Fix.\n events: []\n };\n info.connections!.push(connectionInfo);\n this.update.emit();\n\n connection.stateChanged.on((state) => {\n connectionInfo.state = state;\n connectionInfo.events!.push({\n type: EventType.CONNECTION_STATE_CHANGED,\n newState: state\n });\n this.update.emit();\n });\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 swarmLeft(swarm: Swarm) {\n this.getSwarmInfo(swarm.instanceId).isActive = false;\n this.update.emit();\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport assert from 'node:assert';\n\nimport { Event, synchronized } from '@dxos/async';\nimport { ErrorStream } from '@dxos/debug';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';\n\nimport { SignalMessage, SignalMessenger } from '../signal';\nimport { Transport, TransportFactory } from '../transport';\nimport { WireProtocol } from '../wire-protocol';\n\n/**\n * State machine for each connection.\n */\nexport enum ConnectionState {\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\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 _state: ConnectionState = ConnectionState.INITIAL;\n private _transport: Transport | undefined;\n private _bufferedSignals: Signal[] = [];\n\n readonly stateChanged = new Event<ConnectionState>();\n readonly errors = new ErrorStream();\n\n constructor(\n public readonly topic: PublicKey,\n public readonly ownId: PublicKey, // TODO(burdon): peerID?\n public readonly remoteId: PublicKey,\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 ) {}\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 // TODO(burdon): Make async?\n openConnection() {\n assert(this._state === ConnectionState.INITIAL, 'Invalid state.');\n this._changeState(ConnectionState.CONNECTING);\n\n // TODO(dmaretskyi): Initialize only after the transport has established connection.\n this._protocol.initialize().catch((err) => {\n this.errors.raise(err);\n });\n\n assert(!this._transport);\n this._transport = this._transportFactory.createTransport({\n initiator: this.initiator,\n stream: this._protocol.stream,\n sendSignal: async (signal) => {\n await this._signalMessaging.signal({\n author: this.ownId,\n recipient: this.remoteId,\n sessionId: this.sessionId,\n topic: this.topic,\n data: { signal }\n });\n }\n });\n\n this._transport.connected.once(() => {\n this._changeState(ConnectionState.CONNECTED);\n });\n\n this._transport.closed.once(() => {\n this._transport = undefined;\n this.close().catch((err) => this.errors.raise(err));\n });\n\n this._transport.errors.handle((err) => {\n if (this._state !== ConnectionState.CLOSED && this._state !== ConnectionState.CLOSING) {\n this.errors.raise(err);\n }\n });\n\n // Replay signals that were received before transport was created.\n for (const signal of this._bufferedSignals) {\n void this._transport.signal(signal); // TODO(burdon): Remove async?\n }\n\n this._bufferedSignals = [];\n }\n\n @synchronized\n async close() {\n if (this._state === ConnectionState.CLOSED) {\n return;\n }\n\n this._changeState(ConnectionState.CLOSING);\n\n log('closing...', { peerId: this.ownId });\n\n try {\n // Gracefully close the stream flushing any unsent data packets.\n await this._protocol.destroy();\n } catch (err: any) {\n log.catch(err);\n }\n\n try {\n // After the transport is closed streams are disconnected.\n await this._transport?.destroy();\n } catch (err: any) {\n log.catch(err);\n }\n\n log('closed', { peerId: this.ownId });\n this._changeState(ConnectionState.CLOSED);\n }\n\n async signal(msg: SignalMessage) {\n assert(msg.sessionId);\n if (!msg.sessionId.equals(this.sessionId)) {\n log('dropping signal for incorrect session id');\n return;\n }\n assert(msg.data.signal);\n assert(msg.author?.equals(this.remoteId));\n assert(msg.recipient?.equals(this.ownId));\n\n if (this._state === ConnectionState.INITIAL) {\n log('buffered signal', { peerId: this.ownId, remoteId: this.remoteId, msg: msg.data });\n this._bufferedSignals.push(msg.data.signal);\n return;\n }\n\n assert(this._transport, 'Connection not ready to accept signals.');\n log('received signal', { peerId: this.ownId, remoteId: this.remoteId, msg: msg.data });\n await this._transport.signal(msg.data.signal);\n }\n\n private _changeState(state: ConnectionState): void {\n assert(state !== this._state, 'Already in this state.');\n this._state = state;\n this.stateChanged.emit(state);\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport assert from 'node:assert';\n\nimport { Event, scheduleTask, sleep, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { ErrorStream } from '@dxos/debug';\nimport { PublicKey } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { Messenger } from '@dxos/messaging';\nimport { SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';\nimport { Answer } from '@dxos/protocols/proto/dxos/mesh/swarm';\nimport { ComplexMap, isNotNullOrUndefined } from '@dxos/util';\n\nimport { MessageRouter, OfferMessage, SignalMessage } from '../signal';\nimport { SwarmController, Topology } from '../topology';\nimport { TransportFactory } from '../transport';\nimport { Topic } from '../types';\nimport { WireProtocolProvider } from '../wire-protocol';\nimport { Connection, ConnectionState } from './connection';\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 connections implemented by simple-peer instances.\n * Routes signal events and maintains swarm topology.\n */\nexport class Swarm {\n private readonly _peers = new ComplexMap<PublicKey, Peer>(PublicKey.hash);\n\n private readonly _swarmMessenger: MessageRouter;\n\n private _ctx = new Context();\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();\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<PublicKey>();\n\n /**\n * Connection is established to a new peer.\n * @internal\n */\n readonly connected = new Event<PublicKey>();\n\n readonly errors = new ErrorStream();\n\n // TODO(burdon): Swarm => Peer.create/destroy =< Connection.open/close\n\n // TODO(burdon): Split up properties.\n constructor(\n private readonly _topic: PublicKey,\n private readonly _ownPeerId: PublicKey,\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 ) {\n log('creating swarm', { peerId: _ownPeerId });\n _topology.init(this._getSwarmController());\n\n this._swarmMessenger = new MessageRouter({\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\n this._messenger\n .listen({\n peerId: this._ownPeerId,\n payloadType: 'dxos.mesh.swarm.SwarmMessage',\n onMessage: async (message) => await this._swarmMessenger.receiveMessage(message)\n })\n .catch((error) => log.catch(error));\n }\n\n get connections() {\n return Array.from(this._peers.values())\n .map((peer) => peer.connection)\n .filter(isNotNullOrUndefined);\n }\n\n @logInfo\n get ownPeerId() {\n return this._ownPeerId;\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 // TODO(burdon): async open?\n async destroy() {\n log('destroying...');\n await this._ctx.dispose();\n await this._topology.destroy();\n await Promise.all(Array.from(this._peers.keys()).map((key) => this._destroyPeer(key)));\n log('destroyed');\n }\n\n async setTopology(topology: Topology) {\n assert(!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 onSwarmEvent(swarmEvent: SwarmEvent) {\n log('swarm event', { swarmEvent }); // TODO(burdon): Stringify.\n\n if (swarmEvent.peerAvailable) {\n if (this._ctx.disposed) {\n log.warn('ignored for offline swarm');\n return;\n }\n const peerId = PublicKey.from(swarmEvent.peerAvailable.peer);\n log('new peer', { peerId });\n if (!peerId.equals(this._ownPeerId)) {\n const peer = this._getOrCreatePeer(peerId);\n peer.advertizing = true;\n }\n } else if (swarmEvent.peerLeft) {\n const peer = this._peers.get(PublicKey.from(swarmEvent.peerLeft.peer));\n if (peer) {\n peer.advertizing = false;\n if (!peer.connection || peer.connection.state !== ConnectionState.CONNECTED) {\n // Destroy peer only if there is no p2p-connection established\n void this._destroyPeer(peer.id).catch((err) => log.catch(err));\n }\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.info('ignored for offline swarm');\n return { accept: false };\n }\n\n // Id of the peer offering us the connection.\n assert(message.author);\n if (!message.recipient?.equals(this._ownPeerId)) {\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._getOrCreatePeer(message.author);\n const answer = await peer.onOffer(message);\n this._topology.update();\n return answer;\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 assert(\n message.recipient?.equals(this._ownPeerId),\n `Invalid signal peer id expected=${this.ownPeerId}, actual=${message.recipient}`\n );\n assert(message.topic?.equals(this._topic));\n assert(message.author);\n\n const peer = this._getOrCreatePeer(message.author);\n await peer.onSignal(message);\n }\n\n // For debug purposes\n async goOffline() {\n await this._ctx.dispose();\n [...this._peers.values()].forEach((peer) => {\n peer.advertizing = false;\n });\n await Promise.all([...this._peers.keys()].map((peerId) => this._closeConnection(peerId)));\n }\n\n // For debug purposes\n @synchronized\n async goOnline() {\n this._ctx = new Context();\n\n [...this._peers.values()].forEach((peer) => {\n peer.advertizing = true;\n });\n this._topology.update();\n }\n\n private _getOrCreatePeer(peerId: PublicKey): Peer {\n let peer = this._peers.get(peerId);\n if (!peer) {\n peer = new Peer(\n peerId,\n this._topic,\n this._ownPeerId,\n this._swarmMessenger,\n this._protocolProvider,\n this._transportFactory,\n {\n onInitiated: (connection) => {\n this.connectionAdded.emit(connection);\n },\n onConnected: () => {\n this.connected.emit(peerId);\n },\n onDisconnected: async () => {\n if (!peer!.advertizing) {\n await this._destroyPeer(peer!.id);\n }\n\n this.disconnected.emit(peerId);\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._peers.has(peerId)) {\n void this._destroyPeer(peerId);\n }\n },\n onAccepted: () => {\n this._topology.update();\n },\n onOffer: (remoteId) => {\n return this._topology.onOffer(remoteId);\n }\n }\n );\n this._peers.set(peerId, peer);\n }\n\n return peer;\n }\n\n private async _destroyPeer(peerId: PublicKey) {\n assert(this._peers.has(peerId));\n await this._peers.get(peerId)!.destroy();\n this._peers.delete(peerId);\n }\n\n private _getSwarmController(): SwarmController {\n return {\n getState: () => ({\n ownPeerId: this._ownPeerId,\n connected: Array.from(this._peers.values())\n .filter((peer) => peer.connection)\n .map((peer) => peer.id),\n candidates: Array.from(this._peers.values())\n .filter((peer) => !peer.connection && peer.advertizing)\n .map((peer) => peer.id)\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(peer);\n } catch (err: any) {\n log.warn('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(peer);\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(remoteId: PublicKey) {\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 if (remoteId.toHex() < this._ownPeerId.toHex()) {\n log('initiation delay', { remoteId });\n await sleep(INITIATION_DELAY);\n }\n if (this._ctx.disposed) {\n return;\n }\n\n const peer = this._getOrCreatePeer(remoteId);\n\n if (peer.connection) {\n // Do nothing if peer is already connected.\n return;\n }\n\n log('initiating connection...', { remoteId });\n await peer.initiateConnection();\n this._topology.update();\n log('initiated', { remoteId });\n }\n\n private async _closeConnection(peerId: PublicKey) {\n const peer = this._peers.get(peerId);\n if (!peer) {\n return;\n }\n\n await peer.closeConnection();\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport assert from 'node:assert';\n\nimport { Any } from '@dxos/codec-protobuf';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { Answer, SwarmMessage } from '@dxos/protocols/proto/dxos/mesh/swarm';\nimport { ComplexMap, MakeOptional } from '@dxos/util';\n\nimport { OfferMessage, SignalMessage, SignalMessenger } from './signal-messenger';\n\ninterface OfferRecord {\n resolve: (answer: Answer) => void;\n reject: (error?: Error) => void;\n}\n\ninterface MessageRouterOptions {\n sendMessage: (params: { author: PublicKey; recipient: PublicKey; payload: Any }) => Promise<void>;\n onOffer: (message: OfferMessage) => Promise<Answer>;\n onSignal: (message: SignalMessage) => Promise<void>;\n topic: PublicKey;\n}\n\n/**\n * Adds offer/answer and signal interfaces.\n */\nexport class MessageRouter implements SignalMessenger {\n private readonly _onSignal: (message: SignalMessage) => Promise<void>;\n private readonly _sendMessage: (msg: { author: PublicKey; recipient: PublicKey; payload: Any }) => Promise<void>;\n\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 }: MessageRouterOptions) {\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: PublicKey;\n recipient: PublicKey;\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 = schema.getCodecForType('dxos.mesh.swarm.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 }\n }\n\n async signal(message: SignalMessage): Promise<void> {\n assert(message.data?.signal);\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, reject });\n return this._sendReliableMessage({\n author: message.author,\n recipient: message.recipient,\n message: networkMessage\n });\n });\n }\n\n private async _sendReliableMessage({\n author,\n recipient,\n message\n }: {\n author: PublicKey;\n recipient: PublicKey;\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._encodeAndSend({ author, recipient, message: networkMessage });\n }\n\n private async _encodeAndSend({\n author,\n recipient,\n message\n }: {\n author: PublicKey;\n recipient: PublicKey;\n message: SwarmMessage;\n }) {\n await this._sendMessage({\n author,\n recipient,\n payload: {\n type_url: 'dxos.mesh.swarm.SwarmMessage',\n value: schema.getCodecForType('dxos.mesh.swarm.SwarmMessage').encode(message)\n }\n });\n }\n\n private async _resolveAnswers(message: SwarmMessage): Promise<void> {\n assert(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 assert(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: PublicKey;\n recipient: PublicKey;\n message: SwarmMessage;\n }): Promise<void> {\n assert(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 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 }\n\n private async _handleSignal({\n author,\n recipient,\n message\n }: {\n author: PublicKey;\n recipient: PublicKey;\n message: SwarmMessage;\n }): Promise<void> {\n assert(message.messageId);\n assert(message.data.signal, 'No Signal');\n const signalMessage: SignalMessage = {\n author,\n recipient,\n ...message,\n data: { signal: message.data.signal }\n };\n\n await this._onSignal(signalMessage);\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\n\nimport { synchronized } from '@dxos/async';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { Answer } from '@dxos/protocols/proto/dxos/mesh/swarm';\n\nimport { OfferMessage, SignalMessage, SignalMessenger } from '../signal';\nimport { TransportFactory } from '../transport';\nimport { WireProtocolProvider } from '../wire-protocol';\nimport { Connection, ConnectionState } from './connection';\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: (remoteId: PublicKey) => Promise<boolean>;\n}\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 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 constructor(\n public readonly id: PublicKey,\n public readonly topic: PublicKey,\n public readonly localPeerId: PublicKey,\n private readonly _signalMessaging: SignalMessenger,\n private readonly _protocolProvider: WireProtocolProvider,\n private readonly _transportFactory: TransportFactory,\n private readonly _callbacks: PeerCallbacks\n ) {}\n\n /**\n * Respond to remote offer.\n */\n async onOffer(message: OfferMessage): Promise<Answer> {\n const remoteId = message.author;\n\n // Check if we are already trying to connect to that peer.\n if (this.connection || this.initiating) {\n // Peer with the highest Id closes its connection, and accepts remote peer's offer.\n if (remoteId.toHex() < this.localPeerId.toHex()) {\n // TODO(burdon): Too verbose.\n log(\"closing local connection and accepting remote peer's offer\", {\n id: this.id,\n topic: this.topic,\n peerId: this.localPeerId\n });\n\n if (this.connection) {\n // Close our connection and accept remote peer's connection.\n await this.closeConnection();\n }\n } else {\n // Continue with our origination attempt, the remote peer will close it's connection and accept ours.\n return { accept: false };\n }\n }\n\n if (await this._callbacks.onOffer(remoteId)) {\n if (!this.connection) {\n // Connection might have been already established.\n assert(message.sessionId);\n const connection = this._createConnection(false, message.sessionId);\n try {\n connection.openConnection();\n } catch (err: any) {\n log.warn('connection error', { topic: this.topic, peerId: this.localPeerId, remoteId: this.id, err });\n // Calls `onStateChange` with CLOSED state.\n await this.closeConnection();\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() {\n assert(!this.initiating, 'Initiation in progress.');\n assert(!this.connection, 'Already connected.');\n const sessionId = PublicKey.random();\n log('initiating...', { id: this.id, topic: this.topic, peerId: this.id, sessionId });\n const connection = this._createConnection(true, sessionId);\n this.initiating = true;\n\n try {\n const answer = await this._signalMessaging.offer({\n author: this.localPeerId,\n recipient: this.id,\n sessionId,\n topic: this.topic,\n data: { offer: {} }\n });\n log('received', { answer, topic: this.topic, ownId: this.localPeerId, remoteId: this.id });\n if (connection.state !== ConnectionState.INITIAL) {\n log('ignoring response');\n return;\n }\n\n if (!answer.accept) {\n this._callbacks.onRejected();\n return;\n }\n connection.openConnection();\n this._callbacks.onAccepted();\n } catch (err: any) {\n log.warn('initiation error', { topic: this.topic, peerId: this.localPeerId, remoteId: this.id, err });\n // Calls `onStateChange` with CLOSED state.\n await this.closeConnection();\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) {\n log('creating connection', {\n topic: this.topic,\n peerId: this.localPeerId,\n remoteId: this.id,\n initiator,\n sessionId\n });\n assert(!this.connection, 'Already connected.');\n\n const connection = new Connection(\n this.topic,\n this.localPeerId,\n this.id,\n sessionId,\n initiator,\n this._signalMessaging,\n // TODO(dmaretskyi): Init only when connection is established.\n this._protocolProvider({ initiator, localPeerId: this.localPeerId, remotePeerId: this.id, topic: this.topic }),\n this._transportFactory\n );\n this._callbacks.onInitiated(connection);\n connection.stateChanged.on((state) => {\n switch (state) {\n case ConnectionState.CONNECTED: {\n this._callbacks.onConnected();\n break;\n }\n\n case ConnectionState.CLOSED: {\n log('connection closed', { topic: this.topic, peerId: this.localPeerId, remoteId: this.id, initiator });\n assert(this.connection === connection, 'Connection mismatch (race condition).');\n\n this.connection = undefined;\n this._callbacks.onDisconnected();\n break;\n }\n }\n });\n connection.errors.handle((err) => {\n log.warn('connection error', { topic: this.topic, peerId: this.localPeerId, remoteId: this.id, initiator, err });\n\n // Calls `onStateChange` with CLOSED state.\n void this.closeConnection();\n });\n\n this.connection = connection;\n\n return connection;\n }\n\n async closeConnection() {\n if (!this.connection) {\n return;\n }\n const connection = this.connection;\n log('closing...', { peerId: this.id, sessionId: connection.sessionId });\n\n // Triggers `onStateChange` callback which will clean up the connection.\n // Won't throw.\n await connection.close();\n\n log('closed', { peerId: this.id, sessionId: connection.sessionId });\n }\n\n async onSignal(message: SignalMessage) {\n if (!this.connection) {\n log('dropping signal message for non-existent connection', { message });\n return;\n }\n await this.connection.signal(message);\n }\n\n @synchronized\n async destroy() {\n log('Destroying peer', { peerId: this.id, topic: this.topic });\n\n // Won't throw.\n await this?.connection?.close();\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { Event, EventSubscriptions } from '@dxos/async';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { ComplexMap } from '@dxos/util';\n\nimport { ConnectionState } from './connection';\nimport { 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\ntype Unsubscribe = () => void;\n\nexport class SwarmMapper {\n private readonly _subscriptions = new EventSubscriptions();\n private readonly _connectionSubscriptions = new ComplexMap<PublicKey, Unsubscribe>(PublicKey.hash);\n private readonly _peers = new ComplexMap<PublicKey, PeerInfo>(PublicKey.hash);\n\n readonly mapUpdated = new Event<PeerInfo[]>();\n\n get peers(): PeerInfo[] {\n return Array.from(this._peers.values());\n }\n\n // prettier-ignore\n constructor(\n private readonly _swarm: Swarm\n ) {\n this._subscriptions.add(\n _swarm.connectionAdded.on((connection) => {\n this._update();\n this._connectionSubscriptions.set(\n connection.remoteId,\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() {\n log('updating swarm');\n\n this._peers.clear();\n this._peers.set(this._swarm.ownPeerId, {\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.remoteId, {\n id: connection.remoteId,\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() {\n Array.from(this._connectionSubscriptions.values()).forEach((cb) => cb());\n this._subscriptions.clear();\n }\n}\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport assert from 'node:assert';\n\nimport { PublicKey } from '@dxos/keys';\n\nimport { SwarmController, Topology } from './topology';\n\nexport class FullyConnectedTopology implements Topology {\n private _controller?: SwarmController;\n\n toString() {\n return 'FullyConnectedTopology';\n }\n\n init(controller: SwarmController): void {\n assert(!this._controller, 'Already initialized');\n this._controller = controller;\n }\n\n update(): void {\n assert(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 assert from 'node:assert';\nimport distance from 'xor-distance';\n\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { SwarmController, Topology } from './topology';\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 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 assert(!this._controller, 'Already initialized');\n this._controller = controller;\n }\n\n update(): void {\n assert(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 async onOffer(peer: PublicKey): Promise<boolean> {\n assert(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() {\n assert(this._controller, 'Not initialized');\n const { connected, candidates, ownPeerId } = this._controller.getState();\n\n if (connected.length > this._maxPeers) {\n // Disconnect extra peers.\n const sorted = sortByXorDistance(connected, ownPeerId)\n .reverse()\n .slice(0, this._maxPeers - connected.length);\n for (const peer of sorted) {\n log(`Disconnect ${peer}.`);\n this._controller.disconnect(peer);\n }\n } else if (connected.length < this._originateConnections) {\n // Connect new peers to reach desired quota.\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 for (const peer of sorted) {\n log(`Connect ${peer}.`);\n this._controller.connect(peer);\n }\n }\n }\n\n toString() {\n return 'MMSTTopology';\n }\n}\n\nconst sortByXorDistance = (keys: PublicKey[], reference: PublicKey): PublicKey[] =>\n keys.sort((a, b) =>\n distance.gt(distance(a.asBuffer(), reference.asBuffer()), distance(b.asBuffer(), reference.asBuffer()))\n );\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport assert from 'node:assert';\n\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { SwarmController, Topology } from './topology';\n\nexport class StarTopology implements Topology {\n private _controller?: SwarmController;\n\n // prettier-ignore\n constructor(\n private readonly _centralPeer: PublicKey\n ) {}\n\n toString() {\n return `StarTopology(${this._centralPeer.truncate()})`;\n }\n\n init(controller: SwarmController): void {\n assert(!this._controller, 'Already initialized.');\n this._controller = controller;\n }\n\n update(): void {\n assert(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 assert(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 assert from 'node:assert';\nimport { Transform } from 'node:stream';\n\nimport { Event, Trigger } from '@dxos/async';\nimport { ErrorStream } from '@dxos/debug';\nimport { PublicKey } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';\nimport { ComplexMap } from '@dxos/util';\n\nimport { Transport, TransportFactory, 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: (params) => new MemoryTransport(params)\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 public readonly closed = new Event<void>();\n public readonly connected = new Event<void>();\n public readonly errors = new ErrorStream();\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 _destroyed = false;\n\n @logInfo\n private _remoteInstanceId!: PublicKey;\n\n private _remoteConnection?: MemoryTransport;\n\n constructor(private readonly options: TransportOptions) {\n log('creating');\n\n assert(!MemoryTransport._connections.has(this._instanceId), 'Duplicate memory connection');\n MemoryTransport._connections.set(this._instanceId, this);\n\n // Initiator will send a signal, the receiver will receive the unique ID and connect the streams.\n if (this.options.initiator) {\n // prettier-ignore\n setTimeout(async () => {\n log('sending signal');\n void this.options.sendSignal({\n payload: { transportId: this._instanceId.toHex() }\n });\n });\n } else {\n this._remote\n .wait({ timeout: this.options.timeout ?? 1000 })\n .then((remoteId) => {\n if (this._destroyed) {\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._destroyed = true;\n this.closed.emit();\n return;\n }\n\n assert(\n !this._remoteConnection._remoteConnection,\n new Error(`Remote already connected: ${this._remoteInstanceId}`)\n );\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._destroyed) {\n return;\n }\n\n this.errors.raise(err);\n });\n }\n }\n\n async destroy(): Promise<void> {\n log('closing');\n this._destroyed = true;\n\n MemoryTransport._connections.delete(this._instanceId);\n if (this._remoteConnection) {\n log('closing');\n this._remoteConnection._destroyed = 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._outgoingDelay.unpipe();\n this._incomingDelay.unpipe();\n\n this._remoteConnection.closed.emit();\n this._remoteConnection._remoteConnection = undefined;\n this._remoteConnection = undefined;\n log('closed');\n }\n\n this.closed.emit();\n log('closed');\n }\n\n signal({ payload }: Signal) {\n log('received signal', { payload });\n if (!payload?.transportId) {\n return;\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", "//\n// Copyright 2020 DXOS.org\n//\n\nimport assert from 'node:assert';\nimport SimplePeerConstructor, { Instance as SimplePeer } from 'simple-peer';\n\nimport { Event } from '@dxos/async';\nimport { ErrorStream, raise } from '@dxos/debug';\nimport { log } from '@dxos/log';\nimport { Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';\n\nimport { Transport, TransportFactory } from './transport';\nimport { wrtc } from './webrtc';\n\nexport type WebRTCTransportParams = {\n initiator: boolean;\n stream: NodeJS.ReadWriteStream;\n webrtcConfig?: any;\n sendSignal: (signal: Signal) => Promise<void>;\n};\n\n/**\n * Implements Transport for WebRTC. Uses simple-peer under the hood.\n */\nexport class WebRTCTransport implements Transport {\n private readonly _peer: SimplePeer;\n private _closed = false;\n\n readonly closed = new Event();\n readonly connected = new Event();\n readonly errors = new ErrorStream();\n\n constructor(private readonly params: WebRTCTransportParams) {\n log('created connection', params);\n this._peer = new SimplePeerConstructor({\n initiator: this.params.initiator,\n wrtc: SimplePeerConstructor.WEBRTC_SUPPORT ? undefined : wrtc ?? raise(new Error('wrtc not available')),\n config: this.params.webrtcConfig\n });\n\n this._peer.on('signal', async (data) => {\n log('signal', data);\n await this.params.sendSignal({ payload: { data } });\n });\n\n this._peer.on('connect', () => {\n log('connected');\n this.params.stream.pipe(this._peer!).pipe(this.params.stream);\n this.connected.emit();\n });\n\n this._peer.on('close', async () => {\n log('closed');\n await this._disconnectStreams();\n this.closed.emit();\n });\n\n this._peer.on('error', async (err) => {\n this.errors.raise(err);\n await this.destroy();\n });\n }\n\n async destroy() {\n log('closing...');\n this._closed = true;\n await this._disconnectStreams();\n this._peer!.destroy();\n this.closed.emit();\n log('closed');\n }\n\n signal(signal: Signal) {\n if (this._closed) {\n return; // Ignore signals after close.\n }\n\n assert(signal.payload.data, 'Signal message must contain signal data.');\n this._peer.signal(signal.payload.data);\n }\n\n private async _disconnectStreams() {\n // TODO(rzadp): Find a way of unpiping this?\n this.params.stream.unpipe?.(this._peer)?.unpipe?.(this.params.stream);\n }\n}\n\n// TODO(dmaretskyi): Convert to class.\nexport const createWebRTCTransportFactory = (webrtcConfig?: any): TransportFactory => ({\n createTransport: (params) =>\n new WebRTCTransport({\n ...params,\n webrtcConfig\n })\n});\n", "//\n// Copyright 2022 DXOS.org\n//\n\n/**\n * Will be null if WebRTC is not available in this environment.\n */\nlet wrtc: any = null;\n\n// Try to load WebRTC if available. This will fail in the shared-worker context.\ntry {\n wrtc = require('@koush/wrtc');\n} catch {}\n\nexport { wrtc };\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\nimport { Duplex } from 'node:stream';\n\nimport { Stream } from '@dxos/codec-protobuf';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n BridgeService,\n ConnectionRequest,\n SignalRequest,\n DataRequest,\n BridgeEvent,\n ConnectionState,\n CloseRequest\n} from '@dxos/protocols/proto/dxos/mesh/bridge';\nimport { ComplexMap } from '@dxos/util';\n\nimport { WebRTCTransport } from './webrtc-transport';\n\nexport class WebRTCTransportService implements BridgeService {\n private readonly transports = new ComplexMap<PublicKey, { transport: WebRTCTransport; stream: Duplex }>(\n PublicKey.hash\n );\n\n // prettier-ignore\n constructor(\n private readonly _webrtcConfig?: any\n ) {}\n\n open(request: ConnectionRequest): Stream<BridgeEvent> {\n const rpcStream: Stream<BridgeEvent> = new Stream(({ ready, next, close }) => {\n const duplex: Duplex = new Duplex({\n read: () => {},\n write: function (chunk, _, callback) {\n next({ data: { payload: chunk } });\n callback();\n }\n });\n\n const transport = new WebRTCTransport({\n initiator: request.initiator,\n stream: duplex,\n sendSignal: async (signal) => {\n next({\n signal: { payload: signal }\n });\n }\n });\n\n next({\n connection: {\n state: ConnectionState.CONNECTING\n }\n });\n\n transport.connected.on(() => {\n next({\n connection: {\n state: ConnectionState.CONNECTED\n }\n });\n });\n\n transport.errors.handle((err) => {\n next({\n connection: {\n state: ConnectionState.CLOSED,\n error: err.toString()\n }\n });\n close(err);\n });\n\n transport.closed.on(() => {\n next({\n connection: {\n state: ConnectionState.CLOSED\n }\n });\n close();\n });\n\n ready();\n this.transports.set(request.proxyId, { transport, stream: duplex });\n });\n\n return rpcStream;\n }\n\n async sendSignal({ proxyId, signal }: SignalRequest): Promise<void> {\n assert(this.transports.has(proxyId));\n await this.transports.get(proxyId)!.transport.signal(signal);\n }\n\n async sendData({ proxyId, payload }: DataRequest): Promise<void> {\n assert(this.transports.has(proxyId));\n await this.transports.get(proxyId)!.stream.push(payload);\n }\n\n async close({ proxyId }: CloseRequest) {\n await this.transports.get(proxyId)?.transport.destroy();\n await this.transports.get(proxyId)?.stream.end();\n this.transports.delete(proxyId);\n log('Closed.');\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\n\nimport { Event } from '@dxos/async';\nimport { Stream } from '@dxos/codec-protobuf';\nimport { Context } from '@dxos/context';\nimport { ErrorStream } from '@dxos/debug';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { ConnectionState, BridgeEvent, BridgeService } from '@dxos/protocols/proto/dxos/mesh/bridge';\nimport { Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';\n\nimport { Transport, TransportFactory, TransportOptions } from './transport';\n\nexport type WebRTCTransportProxyParams = {\n initiator: boolean;\n stream: NodeJS.ReadWriteStream;\n bridgeService: BridgeService;\n sendSignal: (signal: Signal) => Promise<void>;\n};\n\nexport class WebRTCTransportProxy implements Transport {\n private readonly _proxyId = PublicKey.random();\n private readonly _ctx = new Context();\n\n readonly closed = new Event();\n private _closed = false;\n readonly connected = new Event();\n\n readonly errors = new ErrorStream();\n\n private _serviceStream!: Stream<BridgeEvent>;\n\n // prettier-ignore\n constructor(\n private readonly _params: WebRTCTransportProxyParams\n ) {\n this._serviceStream = this._params.bridgeService.open({\n proxyId: this._proxyId,\n initiator: this._params.initiator\n });\n\n this._serviceStream.waitUntilReady().then(\n () => {\n this._serviceStream.subscribe(async (event: BridgeEvent) => {\n log('WebRTCTransportProxy: 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\n const dataListener = async (data: Uint8Array) => {\n try {\n await this._params.bridgeService.sendData({\n proxyId: this._proxyId,\n payload: data\n });\n } catch (err: any) {\n log.catch(err);\n }\n };\n this._params.stream.on('data', dataListener);\n this._ctx.onDispose(() => { this._params.stream.off('data', dataListener); });\n },\n (error) => log.catch(error)\n );\n }\n\n private async _handleConnection(connectionEvent: BridgeEvent.ConnectionEvent): Promise<void> {\n if (connectionEvent.error) {\n this.errors.raise(new Error(connectionEvent.error));\n }\n\n switch (connectionEvent.state) {\n case ConnectionState.CONNECTED: {\n this.connected.emit();\n break;\n }\n case ConnectionState.CLOSED: {\n await this.destroy();\n break;\n }\n }\n }\n\n private _handleData(dataEvent: BridgeEvent.DataEvent) {\n // NOTE: This must be a Buffer otherwise hypercore-protocol breaks.\n this._params.stream.write(Buffer.from(dataEvent.payload));\n }\n\n private async _handleSignal(signalEvent: BridgeEvent.SignalEvent) {\n await this._params.sendSignal(signalEvent.payload);\n }\n\n signal(signal: Signal): void {\n this._params.bridgeService\n .sendSignal({\n proxyId: this._proxyId,\n signal\n })\n .catch((err) => this.errors.raise(err));\n }\n\n // TODO(burdon): Move open from constructor.\n async destroy(): Promise<void> {\n await this._ctx.dispose();\n if (this._closed) {\n return;\n }\n\n this._serviceStream.close();\n\n try {\n await this._params.bridgeService.close({ proxyId: this._proxyId });\n } catch (err: any) {\n log.catch(err);\n }\n\n this.closed.emit();\n this._closed = true;\n }\n\n /**\n * Called when underlying proxy service becomes unavailable.\n */\n // TODO(burdon): Option on close method.\n forceClose() {\n this._serviceStream.close();\n this.closed.emit();\n this._closed = true;\n }\n}\n\n// TODO(burdon): Why is this named Proxy?\nexport class WebRTCTransportProxyFactory implements TransportFactory {\n private _bridgeService: BridgeService | undefined;\n private _connections = new Set<WebRTCTransportProxy>();\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\n return this;\n }\n\n createTransport(options: TransportOptions): Transport {\n assert(this._bridgeService, 'WebRTCTransportProxyFactory is not ready to open connections');\n\n const transport = new WebRTCTransportProxy({\n ...options,\n bridgeService: this._bridgeService\n });\n\n this._connections.add(transport);\n transport.closed.on(() => this._connections.delete(transport));\n\n return transport;\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { TestExtension } from '@dxos/teleport';\nimport { ComplexMap } from '@dxos/util';\n\nimport { createTeleportProtocolFactory } from '../wire-protocol';\n\nexport class TestWireProtocol {\n public readonly connections = new ComplexMap<PublicKey, TestExtension>(PublicKey.hash);\n public readonly connected = new Event<PublicKey>();\n\n constructor(public readonly peerId: PublicKey) {}\n\n readonly factory = createTeleportProtocolFactory(async (teleport) => {\n log('create', { remotePeerId: teleport.remotePeerId });\n const extension = new TestExtension({\n onClose: async () => {\n this.connections.delete(teleport.remotePeerId);\n }\n });\n this.connections.set(teleport.remotePeerId, extension);\n teleport.addExtension('test', extension);\n this.connected.emit(teleport.remotePeerId);\n });\n\n async waitForConnection(peerId: PublicKey) {\n if (this.connections.has(peerId)) {\n return this.connections.get(peerId)!;\n }\n log('waitForConnection', { peerId });\n await this.connected.waitFor((connectedId) => connectedId.equals(peerId));\n return this.connections.get(peerId)!;\n }\n\n async testConnection(peerId: PublicKey) {\n const connection = await this.waitForConnection(peerId);\n await connection.test();\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\n\nimport { PublicKey } from '@dxos/keys';\nimport { Teleport } 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 initialize(): Promise<void>;\n destroy(): 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 * @returns\n */\nexport const createTeleportProtocolFactory = (\n onConnection: (teleport: Teleport) => Promise<void>\n): WireProtocolProvider => {\n return (params) => {\n const teleport = new Teleport(params);\n return {\n stream: teleport.stream,\n initialize: async () => {\n await teleport.open();\n await onConnection(teleport);\n },\n destroy: async () => {\n await teleport.close();\n }\n };\n };\n};\n"],
5
- "mappings": "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",
6
- "names": ["PublicKey", "MemorySignalManager", "MemorySignalManagerContext", "WebsocketSignalManager", "schema", "ConnectionState", "createLinkedPorts", "createProtoRpcPeer", "ComplexMap", "assert", "Event", "PublicKey", "log", "Messenger", "ConnectionState", "ComplexMap", "Event", "raise", "PublicKey", "ComplexMap", "assert", "Event", "synchronized", "ErrorStream", "log", "ConnectionState", "INITIAL", "CONNECTING", "CONNECTED", "CLOSING", "CLOSED", "Connection", "constructor", "topic", "ownId", "remoteId", "sessionId", "initiator", "_signalMessaging", "_protocol", "_transportFactory", "_state", "_bufferedSignals", "stateChanged", "errors", "state", "transport", "_transport", "protocol", "openConnection", "_changeState", "initialize", "catch", "err", "raise", "createTransport", "stream", "sendSignal", "signal", "author", "recipient", "data", "connected", "once", "closed", "undefined", "close", "handle", "peerId", "destroy", "msg", "equals", "push", "emit", "assert", "Event", "scheduleTask", "sleep", "synchronized", "Context", "ErrorStream", "PublicKey", "log", "logInfo", "ComplexMap", "isNotNullOrUndefined", "assert", "PublicKey", "log", "schema", "ComplexMap", "MessageRouter", "constructor", "sendMessage", "onSignal", "onOffer", "topic", "_offerRecords", "key", "toHex", "_sendMessage", "_onSignal", "_onOffer", "_topic", "receiveMessage", "author", "recipient", "payload", "type_url", "message", "getCodecForType", "decode", "value", "equals", "from", "to", "msg", "data", "offer", "_handleOffer", "answer", "_resolveAnswers", "signal", "_handleSignal", "_sendReliableMessage", "networkMessage", "messageId", "random", "Promise", "resolve", "reject", "set", "_encodeAndSend", "encode", "offerMessageId", "offerRecord", "get", "delete", "offerMessage", "sessionId", "signalMessage", "assert", "synchronized", "PublicKey", "log", "__decorate", "Peer", "constructor", "id", "topic", "localPeerId", "_signalMessaging", "_protocolProvider", "_transportFactory", "_callbacks", "advertizing", "initiating", "onOffer", "message", "remoteId", "author", "connection", "toHex", "log", "peerId", "closeConnection", "accept", "assert", "sessionId", "_createConnection", "openConnection", "err", "warn", "initiateConnection", "PublicKey", "random", "answer", "offer", "recipient", "data", "ownId", "state", "ConnectionState", "INITIAL", "onRejected", "onAccepted", "initiator", "Connection", "remotePeerId", "onInitiated", "stateChanged", "on", "CONNECTED", "onConnected", "CLOSED", "undefined", "onDisconnected", "errors", "handle", "close", "onSignal", "signal", "destroy", "synchronized", "__decorate", "INITIATION_DELAY", "getClassName", "obj", "Object", "getPrototypeOf", "constructor", "name", "Swarm", "_topic", "_ownPeerId", "_topology", "_protocolProvider", "_messenger", "_transportFactory", "_label", "_peers", "ComplexMap", "PublicKey", "hash", "_ctx", "Context", "connectionAdded", "Event", "disconnected", "connected", "errors", "ErrorStream", "instanceId", "random", "log", "peerId", "init", "_getSwarmController", "_swarmMessenger", "MessageRouter", "sendMessage", "msg", "onSignal", "onOffer", "topic", "listen", "payloadType", "onMessage", "message", "receiveMessage", "catch", "error", "connections", "Array", "from", "values", "map", "peer", "connection", "filter", "isNotNullOrUndefined", "ownPeerId", "label", "destroy", "dispose", "Promise", "all", "keys", "key", "_destroyPeer", "setTopology", "topology", "assert", "disposed", "previous", "update", "onSwarmEvent", "swarmEvent", "peerAvailable", "warn", "equals", "_getOrCreatePeer", "advertizing", "peerLeft", "get", "state", "ConnectionState", "CONNECTED", "id", "err", "info", "accept", "author", "recipient", "answer", "goOffline", "forEach", "_closeConnection", "goOnline", "Peer", "onInitiated", "emit", "onConnected", "onDisconnected", "onRejected", "has", "onAccepted", "remoteId", "set", "delete", "getState", "candidates", "connect", "scheduleTask", "_initiateConnection", "disconnect", "toHex", "sleep", "initiateConnection", "closeConnection", "logInfo", "synchronized", "Event", "EventSubscriptions", "PublicKey", "log", "ComplexMap", "SwarmMapper", "peers", "Array", "from", "_peers", "values", "constructor", "_swarm", "_subscriptions", "_connectionSubscriptions", "hash", "mapUpdated", "add", "connectionAdded", "on", "connection", "_update", "set", "remoteId", "stateChanged", "disconnected", "peerId", "get", "delete", "clear", "ownPeerId", "id", "state", "connections", "directConnections", "length", "totalPeersInSwarm", "size", "emit", "destroy", "forEach", "cb", "EventType", "CONNECTION_STATE_CHANGED", "PROTOCOL_ERROR", "PROTOCOL_EXTENSIONS_INITIALIZED", "PROTOCOL_EXTENSIONS_HANDSHAKE", "PROTOCOL_HANDSHAKE", "ConnectionLog", "_swarms", "ComplexMap", "PublicKey", "hash", "update", "Event", "getSwarmInfo", "swarmId", "get", "raise", "Error", "swarms", "Array", "from", "values", "swarmJoined", "swarm", "info", "id", "instanceId", "topic", "isActive", "label", "connections", "set", "emit", "connectionAdded", "on", "connection", "connectionInfo", "state", "ConnectionState", "INITIAL", "remotePeerId", "remoteId", "sessionId", "transport", "Object", "getPrototypeOf", "constructor", "name", "protocolExtensions", "events", "push", "stateChanged", "type", "newState", "swarmLeft", "NetworkManager", "constructor", "transportFactory", "signalManager", "log", "_swarms", "ComplexMap", "PublicKey", "hash", "_mappers", "_connectionState", "ConnectionState", "ONLINE", "connectionStateChanged", "Event", "topicsUpdated", "_transportFactory", "_signalManager", "swarmEvent", "on", "topic", "event", "get", "onSwarmEvent", "_messenger", "Messenger", "_signalConnection", "join", "opts", "leave", "_connectionLog", "ConnectionLog", "connectionLog", "connectionState", "topics", "Array", "from", "keys", "getSwarmMap", "getSwarm", "open", "close", "leaveSwarm", "catch", "err", "joinSwarm", "peerId", "topology", "protocolProvider", "protocol", "label", "assert", "isPublicKey", "has", "Error", "toString", "swarm", "Swarm", "errors", "handle", "error", "set", "SwarmMapper", "emit", "swarmJoined", "count", "size", "warn", "truncate", "ownPeerId", "map", "destroy", "delete", "swarmLeft", "setConnectionState", "state", "OFFLINE", "Promise", "all", "values", "goOffline", "goOnline", "assert", "FullyConnectedTopology", "toString", "init", "controller", "_controller", "update", "candidates", "discovered", "getState", "peer", "connect", "onOffer", "destroy", "assert", "distance", "log", "assert", "log", "assert", "Transform", "Event", "Trigger", "ErrorStream", "PublicKey", "log", "logInfo", "ComplexMap", "__decorate", "MEMORY_TRANSPORT_DELAY", "createStreamDelay", "delay", "objectMode", "transform", "chunk", "_", "cb", "setTimeout", "MemoryTransportFactory", "createTransport", "params", "MemoryTransport", "constructor", "options", "closed", "connected", "errors", "_remote", "_outgoingDelay", "_incomingDelay", "_destroyed", "_instanceId", "random", "_connections", "has", "set", "initiator", "sendSignal", "payload", "transportId", "toHex", "wait", "timeout", "then", "remoteId", "_remoteInstanceId", "_remoteConnection", "get", "emit", "Error", "stream", "pipe", "catch", "err", "raise", "destroy", "delete", "unpipe", "undefined", "signal", "fromHex", "wake", "hash", "assert", "SimplePeerConstructor", "Event", "ErrorStream", "raise", "log", "wrtc", "require", "WebRTCTransport", "constructor", "params", "_closed", "closed", "Event", "connected", "errors", "ErrorStream", "log", "_peer", "SimplePeerConstructor", "initiator", "wrtc", "WEBRTC_SUPPORT", "undefined", "raise", "Error", "config", "webrtcConfig", "on", "data", "sendSignal", "payload", "stream", "pipe", "emit", "_disconnectStreams", "err", "destroy", "signal", "assert", "unpipe", "assert", "Duplex", "Stream", "PublicKey", "log", "ConnectionState", "ComplexMap", "WebRTCTransportService", "constructor", "_webrtcConfig", "transports", "ComplexMap", "PublicKey", "hash", "open", "request", "rpcStream", "Stream", "ready", "next", "close", "duplex", "Duplex", "read", "write", "chunk", "_", "callback", "data", "payload", "transport", "WebRTCTransport", "initiator", "stream", "sendSignal", "signal", "connection", "state", "ConnectionState", "CONNECTING", "connected", "on", "CONNECTED", "errors", "handle", "err", "CLOSED", "error", "toString", "closed", "set", "proxyId", "assert", "has", "get", "sendData", "push", "destroy", "end", "delete", "log", "assert", "Event", "Context", "ErrorStream", "PublicKey", "log", "ConnectionState", "WebRTCTransportProxy", "constructor", "_params", "_proxyId", "random", "_ctx", "closed", "_closed", "connected", "errors", "_serviceStream", "bridgeService", "open", "proxyId", "initiator", "waitUntilReady", "then", "subscribe", "event", "connection", "_handleConnection", "data", "_handleData", "signal", "_handleSignal", "dataListener", "sendData", "payload", "err", "catch", "stream", "on", "onDispose", "off", "error", "connectionEvent", "raise", "Error", "state", "CONNECTED", "emit", "CLOSED", "destroy", "dataEvent", "write", "Buffer", "from", "signalEvent", "sendSignal", "dispose", "close", "forceClose", "WebRTCTransportProxyFactory", "_connections", "Set", "setBridgeService", "_bridgeService", "createTransport", "options", "transport", "add", "delete", "Event", "PublicKey", "log", "TestExtension", "ComplexMap", "Teleport", "createTeleportProtocolFactory", "onConnection", "params", "teleport", "stream", "initialize", "open", "destroy", "close", "TestWireProtocol", "constructor", "peerId", "connections", "ComplexMap", "PublicKey", "hash", "connected", "Event", "factory", "createTeleportProtocolFactory", "teleport", "log", "remotePeerId", "extension", "TestExtension", "onClose", "delete", "set", "addExtension", "emit", "waitForConnection", "has", "get", "waitFor", "connectedId", "equals", "testConnection", "connection", "test", "TEST_SIGNAL_URL", "TestBuilder", "constructor", "options", "_signalContext", "MemorySignalManagerContext", "createSignalManager", "signalHosts", "WebsocketSignalManager", "MemorySignalManager", "createPeer", "TestPeer", "testBuilder", "peerId", "PublicKey", "random", "_swarms", "ComplexMap", "hash", "_networkManager", "createNetworkManager", "transportFactory", "MemoryTransportFactory", "bridge", "proxyPort", "servicePort", "createLinkedPorts", "_proxy", "createProtoRpcPeer", "port", "requested", "BridgeService", "schema", "getService", "noHandshake", "encodingOptions", "preserveAny", "_service", "exposed", "handlers", "WebRTCTransportService", "WebRTCTransportProxyFactory", "setBridgeService", "rpc", "createTransport", "params", "WebRTCTransport", "NetworkManager", "signalManager", "open", "close", "Promise", "all", "Array", "from", "values", "map", "swarm", "leave", "clear", "getSwarm", "topic", "get", "Error", "createSwarm", "TestSwarmConnection", "set", "goOffline", "setConnectionState", "ConnectionState", "OFFLINE", "goOnline", "ONLINE", "peer", "protocol", "TestWireProtocol", "join", "topology", "FullyConnectedTopology", "joinSwarm", "protocolProvider", "factory", "leaveSwarm"]
3
+ "sources": ["../../../../src/testing/test-builder.ts", "../../../../src/testing/test-wire-protocol.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { PublicKey } from '@dxos/keys';\nimport { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';\nimport { schema } from '@dxos/protocols';\nimport { ConnectionState } from '@dxos/protocols/proto/dxos/client/services';\nimport { createLinkedPorts, createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';\nimport { ComplexMap } from '@dxos/util';\n\nimport { NetworkManager } from '../network-manager';\nimport { FullyConnectedTopology } from '../topology';\nimport {\n MemoryTransportFactory,\n TransportFactory,\n WebRTCTransport,\n WebRTCTransportProxyFactory,\n WebRTCTransportService\n} from '../transport';\nimport { TestWireProtocol } from './test-wire-protocol';\n\n// Signal server will be started by the setup script.\nexport const TEST_SIGNAL_URL = 'ws://localhost:4000/.well-known/dx/signal';\n\nexport type TestBuilderOptions = {\n signalHosts?: string[];\n bridge?: boolean;\n};\n\n/**\n * Builder used to construct networks and peers.\n */\nexport class TestBuilder {\n private _signalContext = new MemorySignalManagerContext();\n\n constructor(public readonly options: TestBuilderOptions = {}) {}\n\n createSignalManager() {\n if (this.options.signalHosts) {\n return new WebsocketSignalManager(this.options.signalHosts);\n }\n\n return new MemorySignalManager(this._signalContext);\n }\n\n createPeer() {\n return new TestPeer(this);\n }\n}\n\n/**\n * Testing network peer.\n */\nexport class TestPeer {\n readonly peerId = PublicKey.random();\n\n private readonly _swarms = new ComplexMap<PublicKey, TestSwarmConnection>(PublicKey.hash);\n\n /**\n * @internal\n */\n readonly _networkManager: NetworkManager;\n\n private _proxy?: ProtoRpcPeer<any>;\n private _service?: ProtoRpcPeer<any>;\n\n constructor(private readonly testBuilder: TestBuilder) {\n this._networkManager = this.createNetworkManager();\n }\n\n // TODO(burdon): Move to TestBuilder.\n createNetworkManager() {\n let transportFactory: TransportFactory = MemoryTransportFactory;\n\n if (this.testBuilder.options.signalHosts) {\n if (this.testBuilder.options.bridge) {\n // Simulates bridge to shared worker.\n const [proxyPort, servicePort] = createLinkedPorts();\n\n this._proxy = createProtoRpcPeer({\n port: proxyPort,\n requested: {\n BridgeService: schema.getService('dxos.mesh.bridge.BridgeService')\n },\n noHandshake: true,\n encodingOptions: {\n preserveAny: true\n }\n });\n\n this._service = createProtoRpcPeer({\n port: servicePort,\n exposed: {\n BridgeService: schema.getService('dxos.mesh.bridge.BridgeService')\n },\n handlers: { BridgeService: new WebRTCTransportService() },\n noHandshake: true,\n encodingOptions: {\n preserveAny: true\n }\n });\n\n transportFactory = new WebRTCTransportProxyFactory().setBridgeService(this._proxy.rpc.BridgeService);\n } else {\n transportFactory = {\n createTransport: (params) => new WebRTCTransport(params)\n };\n }\n }\n\n return new NetworkManager({\n signalManager: this.testBuilder.createSignalManager(),\n transportFactory\n });\n }\n\n async open() {\n await this._proxy?.open();\n await this._service?.open();\n }\n\n async close() {\n await Promise.all(Array.from(this._swarms.values()).map((swarm) => swarm.leave()));\n this._swarms.clear();\n\n await this._proxy?.close();\n await this._service?.close();\n await this._networkManager.close();\n }\n\n getSwarm(topic: PublicKey): TestSwarmConnection {\n const swarm = this._swarms.get(topic);\n if (!swarm) {\n throw new Error(`Swarm not found for topic: ${topic}`);\n }\n\n return swarm;\n }\n\n createSwarm(topic: PublicKey): TestSwarmConnection {\n // TODO(burdon): Multiple.\n // if (this._swarms.get(topic)) {\n // throw new Error(`Swarm already exists for topic: ${topic.truncate()}`);\n // }\n\n const swarm = new TestSwarmConnection(this, topic);\n this._swarms.set(topic, swarm);\n return swarm;\n }\n\n async goOffline() {\n await this._networkManager.setConnectionState(ConnectionState.OFFLINE);\n }\n\n async goOnline() {\n await this._networkManager.setConnectionState(ConnectionState.ONLINE);\n }\n}\n\n// TODO(burdon): Reconcile with new Swarm concept.\nexport class TestSwarmConnection {\n protocol: TestWireProtocol;\n\n constructor(readonly peer: TestPeer, readonly topic: PublicKey) {\n // TODO(burdon): Configure plugins.\n // TODO(burdon): Prevent reuse?\n this.protocol = new TestWireProtocol(this.peer.peerId);\n }\n\n // TODO(burdon): Need to create new plugin instance per swarm?\n // If so, then perhaps joinSwarm should return swarm object with access to plugins.\n async join(topology = new FullyConnectedTopology()) {\n await this.peer._networkManager.joinSwarm({\n topic: this.topic,\n peerId: this.peer.peerId,\n protocolProvider: this.protocol.factory,\n topology\n });\n\n return this;\n }\n\n async leave() {\n await this.peer._networkManager.leaveSwarm(this.topic);\n return this;\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { asyncTimeout, Event } from '@dxos/async';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { TestExtension } from '@dxos/teleport';\nimport { ComplexMap } from '@dxos/util';\n\nimport { createTeleportProtocolFactory } from '../wire-protocol';\n\nexport class TestWireProtocol {\n public readonly connections = new ComplexMap<PublicKey, TestExtension>(PublicKey.hash);\n public readonly connected = new Event<PublicKey>();\n\n constructor(public readonly peerId: PublicKey) {}\n\n readonly factory = createTeleportProtocolFactory(async (teleport) => {\n log('create', { remotePeerId: teleport.remotePeerId });\n const extension = new TestExtension({\n onClose: async () => {\n this.connections.delete(teleport.remotePeerId);\n }\n });\n this.connections.set(teleport.remotePeerId, extension);\n teleport.addExtension('test', extension);\n this.connected.emit(teleport.remotePeerId);\n });\n\n async waitForConnection(peerId: PublicKey) {\n if (this.connections.has(peerId)) {\n return this.connections.get(peerId)!;\n }\n log('waitForConnection', { peerId });\n await asyncTimeout(\n this.connected.waitFor((connectedId) => connectedId.equals(peerId)),\n 1_000\n );\n return this.connections.get(peerId)!;\n }\n\n async testConnection(peerId: PublicKey) {\n const connection = await this.waitForConnection(peerId);\n await connection.test();\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["PublicKey", "MemorySignalManager", "MemorySignalManagerContext", "WebsocketSignalManager", "schema", "ConnectionState", "createLinkedPorts", "createProtoRpcPeer", "ComplexMap", "asyncTimeout", "Event", "PublicKey", "log", "TestExtension", "ComplexMap", "TestWireProtocol", "constructor", "peerId", "connections", "ComplexMap", "PublicKey", "hash", "connected", "Event", "factory", "createTeleportProtocolFactory", "teleport", "log", "remotePeerId", "extension", "TestExtension", "onClose", "delete", "set", "addExtension", "emit", "waitForConnection", "has", "get", "asyncTimeout", "waitFor", "connectedId", "equals", "testConnection", "connection", "test", "TEST_SIGNAL_URL", "TestBuilder", "constructor", "options", "_signalContext", "MemorySignalManagerContext", "createSignalManager", "signalHosts", "WebsocketSignalManager", "MemorySignalManager", "createPeer", "TestPeer", "testBuilder", "peerId", "PublicKey", "random", "_swarms", "ComplexMap", "hash", "_networkManager", "createNetworkManager", "transportFactory", "MemoryTransportFactory", "bridge", "proxyPort", "servicePort", "createLinkedPorts", "_proxy", "createProtoRpcPeer", "port", "requested", "BridgeService", "schema", "getService", "noHandshake", "encodingOptions", "preserveAny", "_service", "exposed", "handlers", "WebRTCTransportService", "WebRTCTransportProxyFactory", "setBridgeService", "rpc", "createTransport", "params", "WebRTCTransport", "NetworkManager", "signalManager", "open", "close", "Promise", "all", "Array", "from", "values", "map", "swarm", "leave", "clear", "getSwarm", "topic", "get", "Error", "createSwarm", "TestSwarmConnection", "set", "goOffline", "setConnectionState", "ConnectionState", "OFFLINE", "goOnline", "ONLINE", "peer", "protocol", "TestWireProtocol", "join", "topology", "FullyConnectedTopology", "joinSwarm", "protocolProvider", "factory", "leaveSwarm"]
7
7
  }
@@ -770,7 +770,7 @@ var Swarm = class {
770
770
  peerId: _ownPeerId
771
771
  }, {
772
772
  file: "swarm.ts",
773
- line: 80,
773
+ line: 83,
774
774
  scope: this,
775
775
  callSite: (f, a) => f(...a)
776
776
  });
@@ -787,7 +787,7 @@ var Swarm = class {
787
787
  onMessage: async (message) => await this._swarmMessenger.receiveMessage(message)
788
788
  }).catch((error) => import_log4.log.catch(error, {}, {
789
789
  file: "swarm.ts",
790
- line: 96,
790
+ line: 99,
791
791
  scope: this,
792
792
  callSite: (f, a) => f(...a)
793
793
  }));
@@ -811,7 +811,7 @@ var Swarm = class {
811
811
  async destroy() {
812
812
  (0, import_log4.log)("destroying...", {}, {
813
813
  file: "swarm.ts",
814
- line: 124,
814
+ line: 127,
815
815
  scope: this,
816
816
  callSite: (f, a) => f(...a)
817
817
  });
@@ -820,7 +820,7 @@ var Swarm = class {
820
820
  await Promise.all(Array.from(this._peers.keys()).map((key) => this._destroyPeer(key)));
821
821
  (0, import_log4.log)("destroyed", {}, {
822
822
  file: "swarm.ts",
823
- line: 128,
823
+ line: 131,
824
824
  scope: this,
825
825
  callSite: (f, a) => f(...a)
826
826
  });
@@ -835,7 +835,7 @@ var Swarm = class {
835
835
  topology: getClassName(topology)
836
836
  }, {
837
837
  file: "swarm.ts",
838
- line: 136,
838
+ line: 139,
839
839
  scope: this,
840
840
  callSite: (f, a) => f(...a)
841
841
  });
@@ -845,30 +845,31 @@ var Swarm = class {
845
845
  this._topology.update();
846
846
  }
847
847
  onSwarmEvent(swarmEvent) {
848
+ var _a;
848
849
  (0, import_log4.log)("swarm event", {
849
850
  swarmEvent
850
851
  }, {
851
852
  file: "swarm.ts",
852
- line: 149,
853
+ line: 152,
853
854
  scope: this,
854
855
  callSite: (f, a) => f(...a)
855
856
  });
857
+ if (this._ctx.disposed) {
858
+ (0, import_log4.log)("swarm event ignored for disposed swarm", {}, {
859
+ file: "swarm.ts",
860
+ line: 155,
861
+ scope: this,
862
+ callSite: (f, a) => f(...a)
863
+ });
864
+ return;
865
+ }
856
866
  if (swarmEvent.peerAvailable) {
857
- if (this._ctx.disposed) {
858
- import_log4.log.warn("ignored for offline swarm", {}, {
859
- file: "swarm.ts",
860
- line: 153,
861
- scope: this,
862
- callSite: (f, a) => f(...a)
863
- });
864
- return;
865
- }
866
867
  const peerId = import_keys3.PublicKey.from(swarmEvent.peerAvailable.peer);
867
868
  (0, import_log4.log)("new peer", {
868
869
  peerId
869
870
  }, {
870
871
  file: "swarm.ts",
871
- line: 157,
872
+ line: 161,
872
873
  scope: this,
873
874
  callSite: (f, a) => f(...a)
874
875
  });
@@ -880,10 +881,10 @@ var Swarm = class {
880
881
  const peer1 = this._peers.get(import_keys3.PublicKey.from(swarmEvent.peerLeft.peer));
881
882
  if (peer1) {
882
883
  peer1.advertizing = false;
883
- if (!peer1.connection || peer1.connection.state !== ConnectionState.CONNECTED) {
884
+ if (((_a = peer1.connection) == null ? void 0 : _a.state) !== ConnectionState.CONNECTED) {
884
885
  void this._destroyPeer(peer1.id).catch((err) => import_log4.log.catch(err, {}, {
885
886
  file: "swarm.ts",
886
- line: 168,
887
+ line: 172,
887
888
  scope: this,
888
889
  callSite: (f, a) => f(...a)
889
890
  }));
@@ -898,14 +899,14 @@ var Swarm = class {
898
899
  message
899
900
  }, {
900
901
  file: "swarm.ts",
901
- line: 178,
902
+ line: 182,
902
903
  scope: this,
903
904
  callSite: (f, a) => f(...a)
904
905
  });
905
906
  if (this._ctx.disposed) {
906
- import_log4.log.info("ignored for offline swarm", {}, {
907
+ (0, import_log4.log)("ignored for disposed swarm", {}, {
907
908
  file: "swarm.ts",
908
- line: 180,
909
+ line: 184,
909
910
  scope: this,
910
911
  callSite: (f, a) => f(...a)
911
912
  });
@@ -919,7 +920,7 @@ var Swarm = class {
919
920
  message
920
921
  }, {
921
922
  file: "swarm.ts",
922
- line: 187,
923
+ line: 191,
923
924
  scope: this,
924
925
  callSite: (f, a) => f(...a)
925
926
  });
@@ -932,7 +933,7 @@ var Swarm = class {
932
933
  message
933
934
  }, {
934
935
  file: "swarm.ts",
935
- line: 191,
936
+ line: 195,
936
937
  scope: this,
937
938
  callSite: (f, a) => f(...a)
938
939
  });
@@ -951,14 +952,14 @@ var Swarm = class {
951
952
  message
952
953
  }, {
953
954
  file: "swarm.ts",
954
- line: 202,
955
+ line: 207,
955
956
  scope: this,
956
957
  callSite: (f, a) => f(...a)
957
958
  });
958
959
  if (this._ctx.disposed) {
959
960
  import_log4.log.info("ignored for offline swarm", {}, {
960
961
  file: "swarm.ts",
961
- line: 204,
962
+ line: 209,
962
963
  scope: this,
963
964
  callSite: (f, a) => f(...a)
964
965
  });
@@ -973,24 +974,13 @@ var Swarm = class {
973
974
  // For debug purposes
974
975
  async goOffline() {
975
976
  await this._ctx.dispose();
976
- [
977
- ...this._peers.values()
978
- ].forEach((peer) => {
979
- peer.advertizing = false;
980
- });
981
977
  await Promise.all([
982
978
  ...this._peers.keys()
983
- ].map((peerId) => this._closeConnection(peerId)));
979
+ ].map((peerId) => this._destroyPeer(peerId)));
984
980
  }
985
981
  // For debug purposes
986
982
  async goOnline() {
987
983
  this._ctx = new import_context.Context();
988
- [
989
- ...this._peers.values()
990
- ].forEach((peer) => {
991
- peer.advertizing = true;
992
- });
993
- this._topology.update();
994
984
  }
995
985
  _getOrCreatePeer(peerId) {
996
986
  let peer = this._peers.get(peerId);
@@ -1047,7 +1037,7 @@ var Swarm = class {
1047
1037
  } catch (err) {
1048
1038
  import_log4.log.warn("initiation error", err, {
1049
1039
  file: "swarm.ts",
1050
- line: 311,
1040
+ line: 309,
1051
1041
  scope: this,
1052
1042
  callSite: (f, a) => f(...a)
1053
1043
  });
@@ -1069,6 +1059,7 @@ var Swarm = class {
1069
1059
  * Creates a connection then sends message over signal network.
1070
1060
  */
1071
1061
  async _initiateConnection(remoteId) {
1062
+ const ctx = this._ctx;
1072
1063
  if (remoteId.toHex() < this._ownPeerId.toHex()) {
1073
1064
  (0, import_log4.log)("initiation delay", {
1074
1065
  remoteId
@@ -1080,7 +1071,7 @@ var Swarm = class {
1080
1071
  });
1081
1072
  await (0, import_async3.sleep)(INITIATION_DELAY);
1082
1073
  }
1083
- if (this._ctx.disposed) {
1074
+ if (ctx.disposed) {
1084
1075
  return;
1085
1076
  }
1086
1077
  const peer = this._getOrCreatePeer(remoteId);
@@ -1129,6 +1120,12 @@ __decorate3([
1129
1120
  __decorate3([
1130
1121
  import_async3.synchronized
1131
1122
  ], Swarm.prototype, "onOffer", null);
1123
+ __decorate3([
1124
+ import_async3.synchronized
1125
+ ], Swarm.prototype, "onSignal", null);
1126
+ __decorate3([
1127
+ import_async3.synchronized
1128
+ ], Swarm.prototype, "goOffline", null);
1132
1129
  __decorate3([
1133
1130
  import_async3.synchronized
1134
1131
  ], Swarm.prototype, "goOnline", null);
@@ -1227,7 +1224,7 @@ var ConnectionLog = class {
1227
1224
  get swarms() {
1228
1225
  return Array.from(this._swarms.values());
1229
1226
  }
1230
- swarmJoined(swarm) {
1227
+ joinedSwarm(swarm) {
1231
1228
  const info = {
1232
1229
  id: swarm.instanceId,
1233
1230
  topic: swarm.topic,
@@ -1258,7 +1255,7 @@ var ConnectionLog = class {
1258
1255
  });
1259
1256
  });
1260
1257
  }
1261
- swarmLeft(swarm) {
1258
+ leftSwarm(swarm) {
1262
1259
  this.getSwarmInfo(swarm.instanceId).isActive = false;
1263
1260
  this.update.emit();
1264
1261
  }
@@ -1380,7 +1377,7 @@ var NetworkManager = class {
1380
1377
  }));
1381
1378
  this._mappers.set(topic, new SwarmMapper(swarm));
1382
1379
  this.topicsUpdated.emit();
1383
- (_a = this._connectionLog) == null ? void 0 : _a.swarmJoined(swarm);
1380
+ (_a = this._connectionLog) == null ? void 0 : _a.joinedSwarm(swarm);
1384
1381
  (0, import_log6.log)("joined", {
1385
1382
  topic: import_keys6.PublicKey.from(topic),
1386
1383
  count: this._swarms.size
@@ -1426,7 +1423,7 @@ var NetworkManager = class {
1426
1423
  const map = this._mappers.get(topic);
1427
1424
  map.destroy();
1428
1425
  this._mappers.delete(topic);
1429
- (_a = this._connectionLog) == null ? void 0 : _a.swarmLeft(swarm);
1426
+ (_a = this._connectionLog) == null ? void 0 : _a.leftSwarm(swarm);
1430
1427
  await swarm.destroy();
1431
1428
  this._swarms.delete(topic);
1432
1429
  await this.topicsUpdated.emit();
@@ -1447,20 +1444,20 @@ var NetworkManager = class {
1447
1444
  switch (state) {
1448
1445
  case import_services.ConnectionState.OFFLINE: {
1449
1446
  this._connectionState = state;
1450
- await this._messenger.close();
1451
- await this._signalManager.close();
1452
1447
  await Promise.all([
1453
1448
  ...this._swarms.values()
1454
1449
  ].map((swarm) => swarm.goOffline()));
1450
+ await this._messenger.close();
1451
+ await this._signalManager.close();
1455
1452
  break;
1456
1453
  }
1457
1454
  case import_services.ConnectionState.ONLINE: {
1458
1455
  this._connectionState = state;
1459
1456
  this._messenger.open();
1460
- await this._signalManager.open();
1461
1457
  await Promise.all([
1462
1458
  ...this._swarms.values()
1463
1459
  ].map((swarm) => swarm.goOnline()));
1460
+ await this._signalManager.open();
1464
1461
  break;
1465
1462
  }
1466
1463
  }