@dxos/edge-client 0.6.10 → 0.6.11-staging.30cf5ba

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.
@@ -259,9 +259,6 @@ var EdgeClient = class extends Resource2 {
259
259
  get peerKey() {
260
260
  return this._peerKey;
261
261
  }
262
- get isOpen() {
263
- return this._lifecycleState === LifecycleState2.OPEN;
264
- }
265
262
  setIdentity({ peerKey, identityKey }) {
266
263
  this._peerKey = peerKey;
267
264
  this._identityKey = identityKey;
@@ -279,7 +276,7 @@ var EdgeClient = class extends Resource2 {
279
276
  info: this.info
280
277
  }, {
281
278
  F: __dxlog_file3,
282
- L: 105,
279
+ L: 101,
283
280
  S: this,
284
281
  C: (f, a) => f(...a)
285
282
  });
@@ -288,7 +285,7 @@ var EdgeClient = class extends Resource2 {
288
285
  err
289
286
  }, {
290
287
  F: __dxlog_file3,
291
- L: 107,
288
+ L: 103,
292
289
  S: this,
293
290
  C: (f, a) => f(...a)
294
291
  });
@@ -302,7 +299,7 @@ var EdgeClient = class extends Resource2 {
302
299
  peerKey: this._peerKey
303
300
  }, {
304
301
  F: __dxlog_file3,
305
- L: 115,
302
+ L: 111,
306
303
  S: this,
307
304
  C: (f, a) => f(...a)
308
305
  });
@@ -314,7 +311,7 @@ var EdgeClient = class extends Resource2 {
314
311
  this._ws.onopen = () => {
315
312
  log2("opened", this.info, {
316
313
  F: __dxlog_file3,
317
- L: 124,
314
+ L: 120,
318
315
  S: this,
319
316
  C: (f, a) => f(...a)
320
317
  });
@@ -323,7 +320,7 @@ var EdgeClient = class extends Resource2 {
323
320
  this._ws.onclose = () => {
324
321
  log2("closed", this.info, {
325
322
  F: __dxlog_file3,
326
- L: 128,
323
+ L: 124,
327
324
  S: this,
328
325
  C: (f, a) => f(...a)
329
326
  });
@@ -335,7 +332,7 @@ var EdgeClient = class extends Resource2 {
335
332
  info: event.message
336
333
  }, {
337
334
  F: __dxlog_file3,
338
- L: 132,
335
+ L: 128,
339
336
  S: this,
340
337
  C: (f, a) => f(...a)
341
338
  });
@@ -353,7 +350,7 @@ var EdgeClient = class extends Resource2 {
353
350
  payload: protocol.getPayloadType(message)
354
351
  }, {
355
352
  F: __dxlog_file3,
356
- L: 145,
353
+ L: 141,
357
354
  S: this,
358
355
  C: (f, a) => f(...a)
359
356
  });
@@ -367,7 +364,7 @@ var EdgeClient = class extends Resource2 {
367
364
  payload: protocol.getPayloadType(message)
368
365
  }, {
369
366
  F: __dxlog_file3,
370
- L: 151,
367
+ L: 147,
371
368
  S: this,
372
369
  C: (f, a) => f(...a)
373
370
  });
@@ -380,7 +377,7 @@ var EdgeClient = class extends Resource2 {
380
377
  });
381
378
  this._keepaliveCtx = new Context(void 0, {
382
379
  F: __dxlog_file3,
383
- L: 158
380
+ L: 154
384
381
  });
385
382
  scheduleTaskInterval(this._keepaliveCtx, async () => {
386
383
  this._ws?.send("__ping__");
@@ -415,7 +412,7 @@ var EdgeClient = class extends Resource2 {
415
412
  err
416
413
  }, {
417
414
  F: __dxlog_file3,
418
- L: 194,
415
+ L: 190,
419
416
  S: this,
420
417
  C: (f, a) => f(...a)
421
418
  });
@@ -433,7 +430,7 @@ var EdgeClient = class extends Resource2 {
433
430
  }
434
431
  invariant2(this._ws, void 0, {
435
432
  F: __dxlog_file3,
436
- L: 206,
433
+ L: 202,
437
434
  S: this,
438
435
  A: [
439
436
  "this._ws",
@@ -442,7 +439,7 @@ var EdgeClient = class extends Resource2 {
442
439
  });
443
440
  invariant2(!message.source || message.source.peerKey === this._peerKey, void 0, {
444
441
  F: __dxlog_file3,
445
- L: 207,
442
+ L: 203,
446
443
  S: this,
447
444
  A: [
448
445
  "!message.source || message.source.peerKey === this._peerKey",
@@ -454,7 +451,7 @@ var EdgeClient = class extends Resource2 {
454
451
  payload: protocol.getPayloadType(message)
455
452
  }, {
456
453
  F: __dxlog_file3,
457
- L: 208,
454
+ L: 204,
458
455
  S: this,
459
456
  C: (f, a) => f(...a)
460
457
  });
@@ -467,7 +464,7 @@ var EdgeClient = class extends Resource2 {
467
464
  void this._heartBeatContext?.dispose();
468
465
  this._heartBeatContext = new Context(void 0, {
469
466
  F: __dxlog_file3,
470
- L: 217
467
+ L: 213
471
468
  });
472
469
  scheduleTask(this._heartBeatContext, () => {
473
470
  this._persistentLifecycle.scheduleRestart();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/index.ts", "../../../src/edge-client.ts", "../../../src/defs.ts", "../../../src/protocol.ts", "../../../src/errors.ts", "../../../src/persistent-lifecycle.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nexport * from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nexport * from './edge-client';\nexport * from './defs';\nexport * from './protocol';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Trigger, Event, scheduleTaskInterval, scheduleTask, TriggerState } from '@dxos/async';\nimport { Context, LifecycleState, Resource, type Lifecycle } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { protocol } from './defs';\nimport { WebsocketClosedError } from './errors';\nimport { PersistentLifecycle } from './persistent-lifecycle';\nimport { type Protocol, toUint8Array } from './protocol';\n\nconst DEFAULT_TIMEOUT = 10_000;\nconst SIGNAL_KEEPALIVE_INTERVAL = 5_000;\n\nexport type MessageListener = (message: Message) => void | Promise<void>;\n\nexport interface EdgeConnection extends Required<Lifecycle> {\n reconnect: Event;\n\n get info(): any;\n get identityKey(): string;\n get peerKey(): string;\n get isOpen(): boolean;\n setIdentity(params: { peerKey: string; identityKey: string }): void;\n addListener(listener: MessageListener): () => void;\n send(message: Message): Promise<void>;\n}\n\nexport type MessengerConfig = {\n socketEndpoint: string;\n timeout?: number;\n protocol?: Protocol;\n};\n\n/**\n * Messenger client.\n */\nexport class EdgeClient extends Resource implements EdgeConnection {\n public reconnect = new Event();\n private readonly _persistentLifecycle = new PersistentLifecycle({\n start: async () => this._openWebSocket(),\n stop: async () => this._closeWebSocket(),\n onRestart: async () => this.reconnect.emit(),\n });\n\n private readonly _listeners = new Set<MessageListener>();\n private readonly _protocol: Protocol;\n private _ready = new Trigger();\n private _ws?: WebSocket = undefined;\n private _keepaliveCtx?: Context = undefined;\n private _heartBeatContext?: Context = undefined;\n\n constructor(\n private _identityKey: string,\n private _peerKey: string,\n private readonly _config: MessengerConfig,\n ) {\n super();\n this._protocol = this._config.protocol ?? protocol;\n }\n\n // TODO(burdon): Attach logging.\n public get info() {\n return {\n open: this.isOpen,\n identity: this._identityKey,\n device: this._peerKey,\n };\n }\n\n get identityKey() {\n return this._identityKey;\n }\n\n get peerKey() {\n return this._peerKey;\n }\n\n public get isOpen() {\n return this._lifecycleState === LifecycleState.OPEN;\n }\n\n setIdentity({ peerKey, identityKey }: { peerKey: string; identityKey: string }) {\n this._peerKey = peerKey;\n this._identityKey = identityKey;\n this._persistentLifecycle.scheduleRestart();\n }\n\n public addListener(listener: MessageListener): () => void {\n this._listeners.add(listener);\n return () => this._listeners.delete(listener);\n }\n\n /**\n * Open connection to messaging service.\n */\n protected override async _open() {\n log('opening...', { info: this.info });\n this._persistentLifecycle.open().catch((err) => {\n log.warn('Error while opening connection', { err });\n });\n }\n\n /**\n * Close connection and free resources.\n */\n protected override async _close() {\n log('closing...', { peerKey: this._peerKey });\n await this._persistentLifecycle.close();\n }\n\n private async _openWebSocket() {\n const url = new URL(`/ws/${this._identityKey}/${this._peerKey}`, this._config.socketEndpoint);\n this._ws = new WebSocket(url);\n\n this._ws.onopen = () => {\n log('opened', this.info);\n this._ready.wake();\n };\n this._ws.onclose = () => {\n log('closed', this.info);\n this._persistentLifecycle.scheduleRestart();\n };\n this._ws.onerror = (event) => {\n log.warn('EdgeClient socket error', { error: event.error, info: event.message });\n this._persistentLifecycle.scheduleRestart();\n };\n /**\n * https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data\n */\n this._ws.onmessage = async (event) => {\n if (event.data === '__pong__') {\n this._onHeartbeat();\n return;\n }\n const data = await toUint8Array(event.data);\n const message = buf.fromBinary(MessageSchema, data);\n log('received', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n if (message) {\n for (const listener of this._listeners) {\n try {\n await listener(message);\n } catch (err) {\n log.error('processing', { err, payload: protocol.getPayloadType(message) });\n }\n }\n }\n };\n\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n this._keepaliveCtx = new Context();\n scheduleTaskInterval(\n this._keepaliveCtx,\n async () => {\n // TODO(mykola): use RFC6455 ping/pong once implemented in the browser?\n // Cloudflare's worker responds to this `without interrupting hibernation`. https://developers.cloudflare.com/durable-objects/api/websockets/#setwebsocketautoresponse\n this._ws?.send('__ping__');\n },\n SIGNAL_KEEPALIVE_INTERVAL,\n );\n this._ws.send('__ping__');\n this._onHeartbeat();\n }\n\n private async _closeWebSocket() {\n if (!this._ws) {\n return;\n }\n try {\n this._ready.throw(new WebsocketClosedError());\n this._ready.reset();\n void this._keepaliveCtx?.dispose();\n this._keepaliveCtx = undefined;\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = undefined;\n\n // NOTE: Remove event handlers to avoid scheduling restart.\n this._ws.onopen = () => {};\n this._ws.onclose = () => {};\n this._ws.onerror = () => {};\n this._ws.close();\n this._ws = undefined;\n } catch (err) {\n if (err instanceof Error && err.message.includes('WebSocket is closed before the connection is established.')) {\n return;\n }\n log.warn('Error closing websocket', { err });\n }\n }\n\n /**\n * Send message.\n * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.\n */\n public async send(message: Message): Promise<void> {\n if (this._ready.state !== TriggerState.RESOLVED) {\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n }\n invariant(this._ws);\n invariant(!message.source || message.source.peerKey === this._peerKey);\n log('sending...', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n this._ws.send(buf.toBinary(MessageSchema, message));\n }\n\n private _onHeartbeat() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = new Context();\n scheduleTask(\n this._heartBeatContext,\n () => {\n this._persistentLifecycle.scheduleRestart();\n },\n 2 * SIGNAL_KEEPALIVE_INTERVAL,\n );\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { AnySchema } from '@bufbuild/protobuf/wkt';\n\nimport { SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { Protocol } from './protocol';\n\nexport const protocol = new Protocol([SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema, AnySchema]);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { buf, bufWkt } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema, type Peer as PeerProto } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { bufferToArray } from '@dxos/util';\n\nexport type PeerData = Partial<PeerProto>;\n\nexport const getTypename = (typeName: string) => `type.googleapis.com/${typeName}`;\n\n/**\n * NOTE: The type registry should be extended with all message types.\n */\nexport class Protocol {\n private readonly _typeRegistry: buf.Registry;\n\n constructor(types: buf.DescMessage[]) {\n this._typeRegistry = buf.createRegistry(...types);\n }\n\n get typeRegistry(): buf.Registry {\n return this._typeRegistry;\n }\n\n toJson(message: Message): any {\n try {\n return buf.toJson(MessageSchema, message, { registry: this.typeRegistry });\n } catch (err) {\n return { type: this.getPayloadType(message) };\n }\n }\n\n /**\n * Return the payload with the given type.\n */\n getPayload<Desc extends buf.DescMessage>(message: Message, type: Desc): buf.MessageShape<Desc> {\n invariant(message.payload);\n const payloadTypename = this.getPayloadType(message);\n if (type && type.typeName !== payloadTypename) {\n throw new Error(`Unexpected payload type: ${payloadTypename}; expected ${type.typeName}`);\n }\n\n invariant(bufWkt.anyIs(message.payload, type), `Unexpected payload type: ${payloadTypename}}`);\n const payload = bufWkt.anyUnpack(message.payload, this.typeRegistry) as buf.MessageShape<Desc>;\n invariant(payload, `Empty payload: ${payloadTypename}}`);\n return payload;\n }\n\n /**\n * Get the payload type.\n */\n getPayloadType(message: Message): string | undefined {\n if (!message.payload) {\n return undefined;\n }\n\n const [, type] = message.payload.typeUrl.split('/');\n return type;\n }\n\n /**\n * Create a packed message.\n */\n createMessage<Desc extends buf.DescMessage>(\n type: Desc,\n {\n source,\n target,\n payload,\n serviceId,\n }: {\n source?: PeerData;\n target?: PeerData[];\n payload?: buf.MessageInitShape<Desc>;\n serviceId?: string;\n },\n ) {\n return buf.create(MessageSchema, {\n timestamp: new Date().toISOString(),\n source,\n target,\n serviceId,\n payload: payload ? bufWkt.anyPack(type, buf.create(type, payload)) : undefined,\n });\n }\n}\n\n/**\n * Convert websocket data to Uint8Array.\n */\nexport const toUint8Array = async (data: any): Promise<Uint8Array> => {\n // Node.\n if (data instanceof Buffer) {\n return bufferToArray(data);\n }\n\n // Browser.\n if (data instanceof Blob) {\n return new Uint8Array(await (data as Blob).arrayBuffer());\n }\n\n throw new Error(`Unexpected datatype: ${data}`);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport class WebsocketClosedError extends Error {\n constructor() {\n super('WebSocket connection closed');\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { DeferredTask, sleep, synchronized } from '@dxos/async';\nimport { cancelWithContext, LifecycleState, Resource } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport { log } from '@dxos/log';\n\nconst INIT_RESTART_DELAY = 100;\nconst DEFAULT_MAX_RESTART_DELAY = 5000;\n\nexport type PersistentLifecycleParams = {\n /**\n * Create connection.\n * If promise resolves successfully, connection is considered established.\n */\n start: () => Promise<void>;\n\n /**\n * Reset connection to initial state.\n */\n stop: () => Promise<void>;\n\n /**\n * Called after successful start.\n */\n onRestart?: () => Promise<void>;\n\n /**\n * Maximum delay between restartion attempts.\n * Default: 5000ms\n */\n maxRestartDelay?: number;\n};\n\n/**\n * Handles restarts (e.g. persists connection).\n * Restarts are scheduled with exponential backoff.\n */\nexport class PersistentLifecycle extends Resource {\n private readonly _start: () => Promise<void>;\n private readonly _stop: () => Promise<void>;\n private readonly _onRestart?: () => Promise<void>;\n private readonly _maxRestartDelay: number;\n\n private _restartTask?: DeferredTask = undefined;\n private _restartAfter = 0;\n\n constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }: PersistentLifecycleParams) {\n super();\n this._start = start;\n this._stop = stop;\n this._onRestart = onRestart;\n this._maxRestartDelay = maxRestartDelay;\n }\n\n @synchronized\n protected override async _open() {\n this._restartTask = new DeferredTask(this._ctx, async () => {\n try {\n await this._restart();\n } catch (err) {\n log.warn('Restart failed', { err });\n this._restartTask?.schedule();\n }\n });\n await this._start().catch((err) => {\n log.warn('Start failed', { err });\n this._restartTask?.schedule();\n });\n }\n\n protected override async _close() {\n await this._restartTask?.join();\n await this._stop();\n this._restartTask = undefined;\n }\n\n private async _restart() {\n log(`restarting in ${this._restartAfter}ms`, { state: this._lifecycleState });\n await this._stop();\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n await cancelWithContext(this._ctx!, sleep(this._restartAfter));\n this._restartAfter = Math.min(Math.max(this._restartAfter * 2, INIT_RESTART_DELAY), this._maxRestartDelay);\n\n // May fail if the connection is not established.\n await warnAfterTimeout(5_000, 'Connection establishment takes too long', () => this._start());\n\n this._restartAfter = 0;\n await this._onRestart?.();\n }\n\n /**\n * Scheduling restart should be done from outside.\n */\n @synchronized\n scheduleRestart() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n this._restartTask!.schedule();\n }\n}\n"],
5
- "mappings": ";AAIA,cAAc;;;ACAd,OAAOA,eAAe;AAEtB,SAASC,SAASC,OAAOC,sBAAsBC,cAAcC,oBAAoB;AACjF,SAASC,SAASC,kBAAAA,iBAAgBC,YAAAA,iBAAgC;AAClE,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,OAAAA,YAAW;AACpB,SAASC,OAAAA,YAAW;AACpB,SAAuBC,iBAAAA,sBAAqB;;;ACP5C,SAASC,iBAAiB;AAE1B,SAASC,oBAAoBC,qBAAqBC,yBAAyB;;;ACF3E,SAASC,iBAAiB;AAC1B,SAASC,KAAKC,cAAc;AAC5B,SAAuBC,qBAA6C;AACpE,SAASC,qBAAqB;;AAIvB,IAAMC,cAAc,CAACC,aAAqB,uBAAuBA,QAAAA;AAKjE,IAAMC,WAAN,MAAMA;EAGXC,YAAYC,OAA0B;AACpC,SAAKC,gBAAgBT,IAAIU,eAAc,GAAIF,KAAAA;EAC7C;EAEA,IAAIG,eAA6B;AAC/B,WAAO,KAAKF;EACd;EAEAG,OAAOC,SAAuB;AAC5B,QAAI;AACF,aAAOb,IAAIY,OAAOV,eAAeW,SAAS;QAAEC,UAAU,KAAKH;MAAa,CAAA;IAC1E,SAASI,KAAK;AACZ,aAAO;QAAEC,MAAM,KAAKC,eAAeJ,OAAAA;MAAS;IAC9C;EACF;;;;EAKAK,WAAyCL,SAAkBG,MAAoC;AAC7FjB,cAAUc,QAAQM,SAAO,QAAA;;;;;;;;;AACzB,UAAMC,kBAAkB,KAAKH,eAAeJ,OAAAA;AAC5C,QAAIG,QAAQA,KAAKX,aAAae,iBAAiB;AAC7C,YAAM,IAAIC,MAAM,4BAA4BD,eAAAA,cAA6BJ,KAAKX,QAAQ,EAAE;IAC1F;AAEAN,cAAUE,OAAOqB,MAAMT,QAAQM,SAASH,IAAAA,GAAO,4BAA4BI,eAAAA,KAAkB;;;;;;;;;AAC7F,UAAMD,UAAUlB,OAAOsB,UAAUV,QAAQM,SAAS,KAAKR,YAAY;AACnEZ,cAAUoB,SAAS,kBAAkBC,eAAAA,KAAkB;;;;;;;;;AACvD,WAAOD;EACT;;;;EAKAF,eAAeJ,SAAsC;AACnD,QAAI,CAACA,QAAQM,SAAS;AACpB,aAAOK;IACT;AAEA,UAAM,CAAA,EAAGR,IAAAA,IAAQH,QAAQM,QAAQM,QAAQC,MAAM,GAAA;AAC/C,WAAOV;EACT;;;;EAKAW,cACEX,MACA,EACEY,QACAC,QACAV,SACAW,UAAS,GAOX;AACA,WAAO9B,IAAI+B,OAAO7B,eAAe;MAC/B8B,YAAW,oBAAIC,KAAAA,GAAOC,YAAW;MACjCN;MACAC;MACAC;MACAX,SAASA,UAAUlB,OAAOkC,QAAQnB,MAAMhB,IAAI+B,OAAOf,MAAMG,OAAAA,CAAAA,IAAYK;IACvE,CAAA;EACF;AACF;AAKO,IAAMY,eAAe,OAAOC,SAAAA;AAEjC,MAAIA,gBAAgBC,QAAQ;AAC1B,WAAOnC,cAAckC,IAAAA;EACvB;AAGA,MAAIA,gBAAgBE,MAAM;AACxB,WAAO,IAAIC,WAAW,MAAOH,KAAcI,YAAW,CAAA;EACxD;AAEA,QAAM,IAAIpB,MAAM,wBAAwBgB,IAAAA,EAAM;AAChD;;;AD/FO,IAAMK,WAAW,IAAIC,SAAS;EAACC;EAAoBC;EAAqBC;EAAmBC;CAAU;;;AENrG,IAAMC,uBAAN,cAAmCC,MAAAA;EACxCC,cAAc;AACZ,UAAM,6BAAA;EACR;AACF;;;ACJA,SAASC,cAAcC,OAAOC,oBAAoB;AAClD,SAASC,mBAAmBC,gBAAgBC,gBAAgB;AAC5D,SAASC,wBAAwB;AACjC,SAASC,WAAW;;;;;;;;;;;;AAEpB,IAAMC,qBAAqB;AAC3B,IAAMC,4BAA4B;AA8B3B,IAAMC,sBAAN,cAAkCL,SAAAA;EASvCM,YAAY,EAAEC,OAAOC,MAAMC,WAAWC,kBAAkBN,0BAAyB,GAA+B;AAC9G,UAAK;AAJCO,wBAA8BC;AAC9BC,yBAAgB;AAItB,SAAKC,SAASP;AACd,SAAKQ,QAAQP;AACb,SAAKQ,aAAaP;AAClB,SAAKQ,mBAAmBP;EAC1B;EAEA,MACyBQ,QAAQ;AAC/B,SAAKP,eAAe,IAAIhB,aAAa,KAAKwB,MAAM,YAAA;AAC9C,UAAI;AACF,cAAM,KAAKC,SAAQ;MACrB,SAASC,KAAK;AACZnB,YAAIoB,KAAK,kBAAkB;UAAED;QAAI,GAAA;;;;;;AACjC,aAAKV,cAAcY,SAAAA;MACrB;IACF,CAAA;AACA,UAAM,KAAKT,OAAM,EAAGU,MAAM,CAACH,QAAAA;AACzBnB,UAAIoB,KAAK,gBAAgB;QAAED;MAAI,GAAA;;;;;;AAC/B,WAAKV,cAAcY,SAAAA;IACrB,CAAA;EACF;EAEA,MAAyBE,SAAS;AAChC,UAAM,KAAKd,cAAce,KAAAA;AACzB,UAAM,KAAKX,MAAK;AAChB,SAAKJ,eAAeC;EACtB;EAEA,MAAcQ,WAAW;AACvBlB,QAAI,iBAAiB,KAAKW,aAAa,MAAM;MAAEc,OAAO,KAAKC;IAAgB,GAAA;;;;;;AAC3E,UAAM,KAAKb,MAAK;AAChB,QAAI,KAAKa,oBAAoB7B,eAAe8B,MAAM;AAChD;IACF;AACA,UAAM/B,kBAAkB,KAAKqB,MAAOvB,MAAM,KAAKiB,aAAa,CAAA;AAC5D,SAAKA,gBAAgBiB,KAAKC,IAAID,KAAKE,IAAI,KAAKnB,gBAAgB,GAAGV,kBAAAA,GAAqB,KAAKc,gBAAgB;AAGzG,UAAMhB,iBAAiB,KAAO,2CAA2C,MAAM,KAAKa,OAAM,CAAA;AAE1F,SAAKD,gBAAgB;AACrB,UAAM,KAAKG,aAAU;EACvB;;;;EAMAiB,kBAAkB;AAChB,QAAI,KAAKL,oBAAoB7B,eAAe8B,MAAM;AAChD;IACF;AACA,SAAKlB,aAAcY,SAAQ;EAC7B;AACF;;EAhDG1B;GAjBUQ,oBAAAA,WAAAA,SAAAA,IAAAA;;EA0DVR;GA1DUQ,oBAAAA,WAAAA,mBAAAA,IAAAA;;;;AJtBb,IAAM6B,kBAAkB;AACxB,IAAMC,4BAA4B;AAyB3B,IAAMC,aAAN,cAAyBC,UAAAA;EAe9BC,YACUC,cACAC,UACSC,SACjB;AACA,UAAK;SAJGF,eAAAA;SACAC,WAAAA;SACSC,UAAAA;SAjBZC,YAAY,IAAIC,MAAAA;SACNC,uBAAuB,IAAIC,oBAAoB;MAC9DC,OAAO,YAAY,KAAKC,eAAc;MACtCC,MAAM,YAAY,KAAKC,gBAAe;MACtCC,WAAW,YAAY,KAAKR,UAAUS,KAAI;IAC5C,CAAA;SAEiBC,aAAa,oBAAIC,IAAAA;SAE1BC,SAAS,IAAIC,QAAAA;SACbC,MAAkBC;SAClBC,gBAA0BD;SAC1BE,oBAA8BF;AAQpC,SAAKG,YAAY,KAAKnB,QAAQoB,YAAYA;EAC5C;;EAGA,IAAWC,OAAO;AAChB,WAAO;MACLC,MAAM,KAAKC;MACXC,UAAU,KAAK1B;MACf2B,QAAQ,KAAK1B;IACf;EACF;EAEA,IAAI2B,cAAc;AAChB,WAAO,KAAK5B;EACd;EAEA,IAAI6B,UAAU;AACZ,WAAO,KAAK5B;EACd;EAEA,IAAWwB,SAAS;AAClB,WAAO,KAAKK,oBAAoBC,gBAAeC;EACjD;EAEAC,YAAY,EAAEJ,SAASD,YAAW,GAA8C;AAC9E,SAAK3B,WAAW4B;AAChB,SAAK7B,eAAe4B;AACpB,SAAKvB,qBAAqB6B,gBAAe;EAC3C;EAEOC,YAAYC,UAAuC;AACxD,SAAKvB,WAAWwB,IAAID,QAAAA;AACpB,WAAO,MAAM,KAAKvB,WAAWyB,OAAOF,QAAAA;EACtC;;;;EAKA,MAAyBG,QAAQ;AAC/BC,IAAAA,KAAI,cAAc;MAAEjB,MAAM,KAAKA;IAAK,GAAA;;;;;;AACpC,SAAKlB,qBAAqBmB,KAAI,EAAGiB,MAAM,CAACC,QAAAA;AACtCF,MAAAA,KAAIG,KAAK,kCAAkC;QAAED;MAAI,GAAA;;;;;;IACnD,CAAA;EACF;;;;EAKA,MAAyBE,SAAS;AAChCJ,IAAAA,KAAI,cAAc;MAAEX,SAAS,KAAK5B;IAAS,GAAA;;;;;;AAC3C,UAAM,KAAKI,qBAAqBwC,MAAK;EACvC;EAEA,MAAcrC,iBAAiB;AAC7B,UAAMsC,MAAM,IAAIC,IAAI,OAAO,KAAK/C,YAAY,IAAI,KAAKC,QAAQ,IAAI,KAAKC,QAAQ8C,cAAc;AAC5F,SAAK/B,MAAM,IAAIgC,UAAUH,GAAAA;AAEzB,SAAK7B,IAAIiC,SAAS,MAAA;AAChBV,MAAAA,KAAI,UAAU,KAAKjB,MAAI;;;;;;AACvB,WAAKR,OAAOoC,KAAI;IAClB;AACA,SAAKlC,IAAImC,UAAU,MAAA;AACjBZ,MAAAA,KAAI,UAAU,KAAKjB,MAAI;;;;;;AACvB,WAAKlB,qBAAqB6B,gBAAe;IAC3C;AACA,SAAKjB,IAAIoC,UAAU,CAACC,UAAAA;AAClBd,MAAAA,KAAIG,KAAK,2BAA2B;QAAEY,OAAOD,MAAMC;QAAOhC,MAAM+B,MAAME;MAAQ,GAAA;;;;;;AAC9E,WAAKnD,qBAAqB6B,gBAAe;IAC3C;AAIA,SAAKjB,IAAIwC,YAAY,OAAOH,UAAAA;AAC1B,UAAIA,MAAMI,SAAS,YAAY;AAC7B,aAAKC,aAAY;AACjB;MACF;AACA,YAAMD,OAAO,MAAME,aAAaN,MAAMI,IAAI;AAC1C,YAAMF,UAAUK,KAAIC,WAAWC,gBAAeL,IAAAA;AAC9ClB,MAAAA,KAAI,YAAY;QAAEX,SAAS,KAAK5B;QAAU+D,SAAS1C,SAAS2C,eAAeT,OAAAA;MAAS,GAAA;;;;;;AACpF,UAAIA,SAAS;AACX,mBAAWpB,YAAY,KAAKvB,YAAY;AACtC,cAAI;AACF,kBAAMuB,SAASoB,OAAAA;UACjB,SAASd,KAAK;AACZF,YAAAA,KAAIe,MAAM,cAAc;cAAEb;cAAKsB,SAAS1C,SAAS2C,eAAeT,OAAAA;YAAS,GAAA;;;;;;UAC3E;QACF;MACF;IACF;AAEA,UAAM,KAAKzC,OAAOmD,KAAK;MAAEC,SAAS,KAAKjE,QAAQiE,WAAWxE;IAAgB,CAAA;AAC1E,SAAKwB,gBAAgB,IAAIiD,QAAAA,QAAAA;;;;AACzBC,yBACE,KAAKlD,eACL,YAAA;AAGE,WAAKF,KAAKqD,KAAK,UAAA;IACjB,GACA1E,yBAAAA;AAEF,SAAKqB,IAAIqD,KAAK,UAAA;AACd,SAAKX,aAAY;EACnB;EAEA,MAAcjD,kBAAkB;AAC9B,QAAI,CAAC,KAAKO,KAAK;AACb;IACF;AACA,QAAI;AACF,WAAKF,OAAOwD,MAAM,IAAIC,qBAAAA,CAAAA;AACtB,WAAKzD,OAAO0D,MAAK;AACjB,WAAK,KAAKtD,eAAeuD,QAAAA;AACzB,WAAKvD,gBAAgBD;AACrB,WAAK,KAAKE,mBAAmBsD,QAAAA;AAC7B,WAAKtD,oBAAoBF;AAGzB,WAAKD,IAAIiC,SAAS,MAAA;MAAO;AACzB,WAAKjC,IAAImC,UAAU,MAAA;MAAO;AAC1B,WAAKnC,IAAIoC,UAAU,MAAA;MAAO;AAC1B,WAAKpC,IAAI4B,MAAK;AACd,WAAK5B,MAAMC;IACb,SAASwB,KAAK;AACZ,UAAIA,eAAeiC,SAASjC,IAAIc,QAAQoB,SAAS,2DAAA,GAA8D;AAC7G;MACF;AACApC,MAAAA,KAAIG,KAAK,2BAA2B;QAAED;MAAI,GAAA;;;;;;IAC5C;EACF;;;;;EAMA,MAAa4B,KAAKd,SAAiC;AACjD,QAAI,KAAKzC,OAAO8D,UAAUC,aAAaC,UAAU;AAC/C,YAAM,KAAKhE,OAAOmD,KAAK;QAAEC,SAAS,KAAKjE,QAAQiE,WAAWxE;MAAgB,CAAA;IAC5E;AACAqF,IAAAA,WAAU,KAAK/D,KAAG,QAAA;;;;;;;;;AAClB+D,IAAAA,WAAU,CAACxB,QAAQyB,UAAUzB,QAAQyB,OAAOpD,YAAY,KAAK5B,UAAQ,QAAA;;;;;;;;;AACrEuC,IAAAA,KAAI,cAAc;MAAEX,SAAS,KAAK5B;MAAU+D,SAAS1C,SAAS2C,eAAeT,OAAAA;IAAS,GAAA;;;;;;AACtF,SAAKvC,IAAIqD,KAAKT,KAAIqB,SAASnB,gBAAeP,OAAAA,CAAAA;EAC5C;EAEQG,eAAe;AACrB,QAAI,KAAK7B,oBAAoBC,gBAAeC,MAAM;AAChD;IACF;AACA,SAAK,KAAKZ,mBAAmBsD,QAAAA;AAC7B,SAAKtD,oBAAoB,IAAIgD,QAAAA,QAAAA;;;;AAC7Be,iBACE,KAAK/D,mBACL,MAAA;AACE,WAAKf,qBAAqB6B,gBAAe;IAC3C,GACA,IAAItC,yBAAAA;EAER;AACF;",
6
- "names": ["WebSocket", "Trigger", "Event", "scheduleTaskInterval", "scheduleTask", "TriggerState", "Context", "LifecycleState", "Resource", "invariant", "log", "buf", "MessageSchema", "AnySchema", "SwarmRequestSchema", "SwarmResponseSchema", "TextMessageSchema", "invariant", "buf", "bufWkt", "MessageSchema", "bufferToArray", "getTypename", "typeName", "Protocol", "constructor", "types", "_typeRegistry", "createRegistry", "typeRegistry", "toJson", "message", "registry", "err", "type", "getPayloadType", "getPayload", "payload", "payloadTypename", "Error", "anyIs", "anyUnpack", "undefined", "typeUrl", "split", "createMessage", "source", "target", "serviceId", "create", "timestamp", "Date", "toISOString", "anyPack", "toUint8Array", "data", "Buffer", "Blob", "Uint8Array", "arrayBuffer", "protocol", "Protocol", "SwarmRequestSchema", "SwarmResponseSchema", "TextMessageSchema", "AnySchema", "WebsocketClosedError", "Error", "constructor", "DeferredTask", "sleep", "synchronized", "cancelWithContext", "LifecycleState", "Resource", "warnAfterTimeout", "log", "INIT_RESTART_DELAY", "DEFAULT_MAX_RESTART_DELAY", "PersistentLifecycle", "constructor", "start", "stop", "onRestart", "maxRestartDelay", "_restartTask", "undefined", "_restartAfter", "_start", "_stop", "_onRestart", "_maxRestartDelay", "_open", "_ctx", "_restart", "err", "warn", "schedule", "catch", "_close", "join", "state", "_lifecycleState", "OPEN", "Math", "min", "max", "scheduleRestart", "DEFAULT_TIMEOUT", "SIGNAL_KEEPALIVE_INTERVAL", "EdgeClient", "Resource", "constructor", "_identityKey", "_peerKey", "_config", "reconnect", "Event", "_persistentLifecycle", "PersistentLifecycle", "start", "_openWebSocket", "stop", "_closeWebSocket", "onRestart", "emit", "_listeners", "Set", "_ready", "Trigger", "_ws", "undefined", "_keepaliveCtx", "_heartBeatContext", "_protocol", "protocol", "info", "open", "isOpen", "identity", "device", "identityKey", "peerKey", "_lifecycleState", "LifecycleState", "OPEN", "setIdentity", "scheduleRestart", "addListener", "listener", "add", "delete", "_open", "log", "catch", "err", "warn", "_close", "close", "url", "URL", "socketEndpoint", "WebSocket", "onopen", "wake", "onclose", "onerror", "event", "error", "message", "onmessage", "data", "_onHeartbeat", "toUint8Array", "buf", "fromBinary", "MessageSchema", "payload", "getPayloadType", "wait", "timeout", "Context", "scheduleTaskInterval", "send", "throw", "WebsocketClosedError", "reset", "dispose", "Error", "includes", "state", "TriggerState", "RESOLVED", "invariant", "source", "toBinary", "scheduleTask"]
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nexport * from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nexport * from './edge-client';\nexport * from './defs';\nexport * from './protocol';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Trigger, Event, scheduleTaskInterval, scheduleTask, TriggerState } from '@dxos/async';\nimport { Context, LifecycleState, Resource, type Lifecycle } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { protocol } from './defs';\nimport { WebsocketClosedError } from './errors';\nimport { PersistentLifecycle } from './persistent-lifecycle';\nimport { type Protocol, toUint8Array } from './protocol';\n\nconst DEFAULT_TIMEOUT = 10_000;\nconst SIGNAL_KEEPALIVE_INTERVAL = 5_000;\n\nexport type MessageListener = (message: Message) => void | Promise<void>;\n\nexport interface EdgeConnection extends Required<Lifecycle> {\n reconnect: Event;\n\n get info(): any;\n get identityKey(): string;\n get peerKey(): string;\n get isOpen(): boolean;\n setIdentity(params: { peerKey: string; identityKey: string }): void;\n addListener(listener: MessageListener): () => void;\n send(message: Message): Promise<void>;\n}\n\nexport type MessengerConfig = {\n socketEndpoint: string;\n timeout?: number;\n protocol?: Protocol;\n};\n\n/**\n * Messenger client.\n */\nexport class EdgeClient extends Resource implements EdgeConnection {\n public reconnect = new Event();\n private readonly _persistentLifecycle = new PersistentLifecycle({\n start: async () => this._openWebSocket(),\n stop: async () => this._closeWebSocket(),\n onRestart: async () => this.reconnect.emit(),\n });\n\n private readonly _listeners = new Set<MessageListener>();\n private readonly _protocol: Protocol;\n private _ready = new Trigger();\n private _ws?: WebSocket = undefined;\n private _keepaliveCtx?: Context = undefined;\n private _heartBeatContext?: Context = undefined;\n\n constructor(\n private _identityKey: string,\n private _peerKey: string,\n private readonly _config: MessengerConfig,\n ) {\n super();\n this._protocol = this._config.protocol ?? protocol;\n }\n\n // TODO(burdon): Attach logging.\n public get info() {\n return {\n open: this.isOpen,\n identity: this._identityKey,\n device: this._peerKey,\n };\n }\n\n get identityKey() {\n return this._identityKey;\n }\n\n get peerKey() {\n return this._peerKey;\n }\n\n setIdentity({ peerKey, identityKey }: { peerKey: string; identityKey: string }) {\n this._peerKey = peerKey;\n this._identityKey = identityKey;\n this._persistentLifecycle.scheduleRestart();\n }\n\n public addListener(listener: MessageListener): () => void {\n this._listeners.add(listener);\n return () => this._listeners.delete(listener);\n }\n\n /**\n * Open connection to messaging service.\n */\n protected override async _open() {\n log('opening...', { info: this.info });\n this._persistentLifecycle.open().catch((err) => {\n log.warn('Error while opening connection', { err });\n });\n }\n\n /**\n * Close connection and free resources.\n */\n protected override async _close() {\n log('closing...', { peerKey: this._peerKey });\n await this._persistentLifecycle.close();\n }\n\n private async _openWebSocket() {\n const url = new URL(`/ws/${this._identityKey}/${this._peerKey}`, this._config.socketEndpoint);\n this._ws = new WebSocket(url);\n\n this._ws.onopen = () => {\n log('opened', this.info);\n this._ready.wake();\n };\n this._ws.onclose = () => {\n log('closed', this.info);\n this._persistentLifecycle.scheduleRestart();\n };\n this._ws.onerror = (event) => {\n log.warn('EdgeClient socket error', { error: event.error, info: event.message });\n this._persistentLifecycle.scheduleRestart();\n };\n /**\n * https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data\n */\n this._ws.onmessage = async (event) => {\n if (event.data === '__pong__') {\n this._onHeartbeat();\n return;\n }\n const data = await toUint8Array(event.data);\n const message = buf.fromBinary(MessageSchema, data);\n log('received', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n if (message) {\n for (const listener of this._listeners) {\n try {\n await listener(message);\n } catch (err) {\n log.error('processing', { err, payload: protocol.getPayloadType(message) });\n }\n }\n }\n };\n\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n this._keepaliveCtx = new Context();\n scheduleTaskInterval(\n this._keepaliveCtx,\n async () => {\n // TODO(mykola): use RFC6455 ping/pong once implemented in the browser?\n // Cloudflare's worker responds to this `without interrupting hibernation`. https://developers.cloudflare.com/durable-objects/api/websockets/#setwebsocketautoresponse\n this._ws?.send('__ping__');\n },\n SIGNAL_KEEPALIVE_INTERVAL,\n );\n this._ws.send('__ping__');\n this._onHeartbeat();\n }\n\n private async _closeWebSocket() {\n if (!this._ws) {\n return;\n }\n try {\n this._ready.throw(new WebsocketClosedError());\n this._ready.reset();\n void this._keepaliveCtx?.dispose();\n this._keepaliveCtx = undefined;\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = undefined;\n\n // NOTE: Remove event handlers to avoid scheduling restart.\n this._ws.onopen = () => {};\n this._ws.onclose = () => {};\n this._ws.onerror = () => {};\n this._ws.close();\n this._ws = undefined;\n } catch (err) {\n if (err instanceof Error && err.message.includes('WebSocket is closed before the connection is established.')) {\n return;\n }\n log.warn('Error closing websocket', { err });\n }\n }\n\n /**\n * Send message.\n * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.\n */\n public async send(message: Message): Promise<void> {\n if (this._ready.state !== TriggerState.RESOLVED) {\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n }\n invariant(this._ws);\n invariant(!message.source || message.source.peerKey === this._peerKey);\n log('sending...', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n this._ws.send(buf.toBinary(MessageSchema, message));\n }\n\n private _onHeartbeat() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = new Context();\n scheduleTask(\n this._heartBeatContext,\n () => {\n this._persistentLifecycle.scheduleRestart();\n },\n 2 * SIGNAL_KEEPALIVE_INTERVAL,\n );\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { AnySchema } from '@bufbuild/protobuf/wkt';\n\nimport { SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { Protocol } from './protocol';\n\nexport const protocol = new Protocol([SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema, AnySchema]);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { buf, bufWkt } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema, type Peer as PeerProto } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { bufferToArray } from '@dxos/util';\n\nexport type PeerData = Partial<PeerProto>;\n\nexport const getTypename = (typeName: string) => `type.googleapis.com/${typeName}`;\n\n/**\n * NOTE: The type registry should be extended with all message types.\n */\nexport class Protocol {\n private readonly _typeRegistry: buf.Registry;\n\n constructor(types: buf.DescMessage[]) {\n this._typeRegistry = buf.createRegistry(...types);\n }\n\n get typeRegistry(): buf.Registry {\n return this._typeRegistry;\n }\n\n toJson(message: Message): any {\n try {\n return buf.toJson(MessageSchema, message, { registry: this.typeRegistry });\n } catch (err) {\n return { type: this.getPayloadType(message) };\n }\n }\n\n /**\n * Return the payload with the given type.\n */\n getPayload<Desc extends buf.DescMessage>(message: Message, type: Desc): buf.MessageShape<Desc> {\n invariant(message.payload);\n const payloadTypename = this.getPayloadType(message);\n if (type && type.typeName !== payloadTypename) {\n throw new Error(`Unexpected payload type: ${payloadTypename}; expected ${type.typeName}`);\n }\n\n invariant(bufWkt.anyIs(message.payload, type), `Unexpected payload type: ${payloadTypename}}`);\n const payload = bufWkt.anyUnpack(message.payload, this.typeRegistry) as buf.MessageShape<Desc>;\n invariant(payload, `Empty payload: ${payloadTypename}}`);\n return payload;\n }\n\n /**\n * Get the payload type.\n */\n getPayloadType(message: Message): string | undefined {\n if (!message.payload) {\n return undefined;\n }\n\n const [, type] = message.payload.typeUrl.split('/');\n return type;\n }\n\n /**\n * Create a packed message.\n */\n createMessage<Desc extends buf.DescMessage>(\n type: Desc,\n {\n source,\n target,\n payload,\n serviceId,\n }: {\n source?: PeerData;\n target?: PeerData[];\n payload?: buf.MessageInitShape<Desc>;\n serviceId?: string;\n },\n ) {\n return buf.create(MessageSchema, {\n timestamp: new Date().toISOString(),\n source,\n target,\n serviceId,\n payload: payload ? bufWkt.anyPack(type, buf.create(type, payload)) : undefined,\n });\n }\n}\n\n/**\n * Convert websocket data to Uint8Array.\n */\nexport const toUint8Array = async (data: any): Promise<Uint8Array> => {\n // Node.\n if (data instanceof Buffer) {\n return bufferToArray(data);\n }\n\n // Browser.\n if (data instanceof Blob) {\n return new Uint8Array(await (data as Blob).arrayBuffer());\n }\n\n throw new Error(`Unexpected datatype: ${data}`);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport class WebsocketClosedError extends Error {\n constructor() {\n super('WebSocket connection closed');\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { DeferredTask, sleep, synchronized } from '@dxos/async';\nimport { cancelWithContext, LifecycleState, Resource } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport { log } from '@dxos/log';\n\nconst INIT_RESTART_DELAY = 100;\nconst DEFAULT_MAX_RESTART_DELAY = 5000;\n\nexport type PersistentLifecycleParams = {\n /**\n * Create connection.\n * If promise resolves successfully, connection is considered established.\n */\n start: () => Promise<void>;\n\n /**\n * Reset connection to initial state.\n */\n stop: () => Promise<void>;\n\n /**\n * Called after successful start.\n */\n onRestart?: () => Promise<void>;\n\n /**\n * Maximum delay between restartion attempts.\n * Default: 5000ms\n */\n maxRestartDelay?: number;\n};\n\n/**\n * Handles restarts (e.g. persists connection).\n * Restarts are scheduled with exponential backoff.\n */\nexport class PersistentLifecycle extends Resource {\n private readonly _start: () => Promise<void>;\n private readonly _stop: () => Promise<void>;\n private readonly _onRestart?: () => Promise<void>;\n private readonly _maxRestartDelay: number;\n\n private _restartTask?: DeferredTask = undefined;\n private _restartAfter = 0;\n\n constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }: PersistentLifecycleParams) {\n super();\n this._start = start;\n this._stop = stop;\n this._onRestart = onRestart;\n this._maxRestartDelay = maxRestartDelay;\n }\n\n @synchronized\n protected override async _open() {\n this._restartTask = new DeferredTask(this._ctx, async () => {\n try {\n await this._restart();\n } catch (err) {\n log.warn('Restart failed', { err });\n this._restartTask?.schedule();\n }\n });\n await this._start().catch((err) => {\n log.warn('Start failed', { err });\n this._restartTask?.schedule();\n });\n }\n\n protected override async _close() {\n await this._restartTask?.join();\n await this._stop();\n this._restartTask = undefined;\n }\n\n private async _restart() {\n log(`restarting in ${this._restartAfter}ms`, { state: this._lifecycleState });\n await this._stop();\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n await cancelWithContext(this._ctx!, sleep(this._restartAfter));\n this._restartAfter = Math.min(Math.max(this._restartAfter * 2, INIT_RESTART_DELAY), this._maxRestartDelay);\n\n // May fail if the connection is not established.\n await warnAfterTimeout(5_000, 'Connection establishment takes too long', () => this._start());\n\n this._restartAfter = 0;\n await this._onRestart?.();\n }\n\n /**\n * Scheduling restart should be done from outside.\n */\n @synchronized\n scheduleRestart() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n this._restartTask!.schedule();\n }\n}\n"],
5
+ "mappings": ";AAIA,cAAc;;;ACAd,OAAOA,eAAe;AAEtB,SAASC,SAASC,OAAOC,sBAAsBC,cAAcC,oBAAoB;AACjF,SAASC,SAASC,kBAAAA,iBAAgBC,YAAAA,iBAAgC;AAClE,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,OAAAA,YAAW;AACpB,SAASC,OAAAA,YAAW;AACpB,SAAuBC,iBAAAA,sBAAqB;;;ACP5C,SAASC,iBAAiB;AAE1B,SAASC,oBAAoBC,qBAAqBC,yBAAyB;;;ACF3E,SAASC,iBAAiB;AAC1B,SAASC,KAAKC,cAAc;AAC5B,SAAuBC,qBAA6C;AACpE,SAASC,qBAAqB;;AAIvB,IAAMC,cAAc,CAACC,aAAqB,uBAAuBA,QAAAA;AAKjE,IAAMC,WAAN,MAAMA;EAGXC,YAAYC,OAA0B;AACpC,SAAKC,gBAAgBT,IAAIU,eAAc,GAAIF,KAAAA;EAC7C;EAEA,IAAIG,eAA6B;AAC/B,WAAO,KAAKF;EACd;EAEAG,OAAOC,SAAuB;AAC5B,QAAI;AACF,aAAOb,IAAIY,OAAOV,eAAeW,SAAS;QAAEC,UAAU,KAAKH;MAAa,CAAA;IAC1E,SAASI,KAAK;AACZ,aAAO;QAAEC,MAAM,KAAKC,eAAeJ,OAAAA;MAAS;IAC9C;EACF;;;;EAKAK,WAAyCL,SAAkBG,MAAoC;AAC7FjB,cAAUc,QAAQM,SAAO,QAAA;;;;;;;;;AACzB,UAAMC,kBAAkB,KAAKH,eAAeJ,OAAAA;AAC5C,QAAIG,QAAQA,KAAKX,aAAae,iBAAiB;AAC7C,YAAM,IAAIC,MAAM,4BAA4BD,eAAAA,cAA6BJ,KAAKX,QAAQ,EAAE;IAC1F;AAEAN,cAAUE,OAAOqB,MAAMT,QAAQM,SAASH,IAAAA,GAAO,4BAA4BI,eAAAA,KAAkB;;;;;;;;;AAC7F,UAAMD,UAAUlB,OAAOsB,UAAUV,QAAQM,SAAS,KAAKR,YAAY;AACnEZ,cAAUoB,SAAS,kBAAkBC,eAAAA,KAAkB;;;;;;;;;AACvD,WAAOD;EACT;;;;EAKAF,eAAeJ,SAAsC;AACnD,QAAI,CAACA,QAAQM,SAAS;AACpB,aAAOK;IACT;AAEA,UAAM,CAAA,EAAGR,IAAAA,IAAQH,QAAQM,QAAQM,QAAQC,MAAM,GAAA;AAC/C,WAAOV;EACT;;;;EAKAW,cACEX,MACA,EACEY,QACAC,QACAV,SACAW,UAAS,GAOX;AACA,WAAO9B,IAAI+B,OAAO7B,eAAe;MAC/B8B,YAAW,oBAAIC,KAAAA,GAAOC,YAAW;MACjCN;MACAC;MACAC;MACAX,SAASA,UAAUlB,OAAOkC,QAAQnB,MAAMhB,IAAI+B,OAAOf,MAAMG,OAAAA,CAAAA,IAAYK;IACvE,CAAA;EACF;AACF;AAKO,IAAMY,eAAe,OAAOC,SAAAA;AAEjC,MAAIA,gBAAgBC,QAAQ;AAC1B,WAAOnC,cAAckC,IAAAA;EACvB;AAGA,MAAIA,gBAAgBE,MAAM;AACxB,WAAO,IAAIC,WAAW,MAAOH,KAAcI,YAAW,CAAA;EACxD;AAEA,QAAM,IAAIpB,MAAM,wBAAwBgB,IAAAA,EAAM;AAChD;;;AD/FO,IAAMK,WAAW,IAAIC,SAAS;EAACC;EAAoBC;EAAqBC;EAAmBC;CAAU;;;AENrG,IAAMC,uBAAN,cAAmCC,MAAAA;EACxCC,cAAc;AACZ,UAAM,6BAAA;EACR;AACF;;;ACJA,SAASC,cAAcC,OAAOC,oBAAoB;AAClD,SAASC,mBAAmBC,gBAAgBC,gBAAgB;AAC5D,SAASC,wBAAwB;AACjC,SAASC,WAAW;;;;;;;;;;;;AAEpB,IAAMC,qBAAqB;AAC3B,IAAMC,4BAA4B;AA8B3B,IAAMC,sBAAN,cAAkCL,SAAAA;EASvCM,YAAY,EAAEC,OAAOC,MAAMC,WAAWC,kBAAkBN,0BAAyB,GAA+B;AAC9G,UAAK;AAJCO,wBAA8BC;AAC9BC,yBAAgB;AAItB,SAAKC,SAASP;AACd,SAAKQ,QAAQP;AACb,SAAKQ,aAAaP;AAClB,SAAKQ,mBAAmBP;EAC1B;EAEA,MACyBQ,QAAQ;AAC/B,SAAKP,eAAe,IAAIhB,aAAa,KAAKwB,MAAM,YAAA;AAC9C,UAAI;AACF,cAAM,KAAKC,SAAQ;MACrB,SAASC,KAAK;AACZnB,YAAIoB,KAAK,kBAAkB;UAAED;QAAI,GAAA;;;;;;AACjC,aAAKV,cAAcY,SAAAA;MACrB;IACF,CAAA;AACA,UAAM,KAAKT,OAAM,EAAGU,MAAM,CAACH,QAAAA;AACzBnB,UAAIoB,KAAK,gBAAgB;QAAED;MAAI,GAAA;;;;;;AAC/B,WAAKV,cAAcY,SAAAA;IACrB,CAAA;EACF;EAEA,MAAyBE,SAAS;AAChC,UAAM,KAAKd,cAAce,KAAAA;AACzB,UAAM,KAAKX,MAAK;AAChB,SAAKJ,eAAeC;EACtB;EAEA,MAAcQ,WAAW;AACvBlB,QAAI,iBAAiB,KAAKW,aAAa,MAAM;MAAEc,OAAO,KAAKC;IAAgB,GAAA;;;;;;AAC3E,UAAM,KAAKb,MAAK;AAChB,QAAI,KAAKa,oBAAoB7B,eAAe8B,MAAM;AAChD;IACF;AACA,UAAM/B,kBAAkB,KAAKqB,MAAOvB,MAAM,KAAKiB,aAAa,CAAA;AAC5D,SAAKA,gBAAgBiB,KAAKC,IAAID,KAAKE,IAAI,KAAKnB,gBAAgB,GAAGV,kBAAAA,GAAqB,KAAKc,gBAAgB;AAGzG,UAAMhB,iBAAiB,KAAO,2CAA2C,MAAM,KAAKa,OAAM,CAAA;AAE1F,SAAKD,gBAAgB;AACrB,UAAM,KAAKG,aAAU;EACvB;;;;EAMAiB,kBAAkB;AAChB,QAAI,KAAKL,oBAAoB7B,eAAe8B,MAAM;AAChD;IACF;AACA,SAAKlB,aAAcY,SAAQ;EAC7B;AACF;;EAhDG1B;GAjBUQ,oBAAAA,WAAAA,SAAAA,IAAAA;;EA0DVR;GA1DUQ,oBAAAA,WAAAA,mBAAAA,IAAAA;;;;AJtBb,IAAM6B,kBAAkB;AACxB,IAAMC,4BAA4B;AAyB3B,IAAMC,aAAN,cAAyBC,UAAAA;EAe9BC,YACUC,cACAC,UACSC,SACjB;AACA,UAAK;SAJGF,eAAAA;SACAC,WAAAA;SACSC,UAAAA;SAjBZC,YAAY,IAAIC,MAAAA;SACNC,uBAAuB,IAAIC,oBAAoB;MAC9DC,OAAO,YAAY,KAAKC,eAAc;MACtCC,MAAM,YAAY,KAAKC,gBAAe;MACtCC,WAAW,YAAY,KAAKR,UAAUS,KAAI;IAC5C,CAAA;SAEiBC,aAAa,oBAAIC,IAAAA;SAE1BC,SAAS,IAAIC,QAAAA;SACbC,MAAkBC;SAClBC,gBAA0BD;SAC1BE,oBAA8BF;AAQpC,SAAKG,YAAY,KAAKnB,QAAQoB,YAAYA;EAC5C;;EAGA,IAAWC,OAAO;AAChB,WAAO;MACLC,MAAM,KAAKC;MACXC,UAAU,KAAK1B;MACf2B,QAAQ,KAAK1B;IACf;EACF;EAEA,IAAI2B,cAAc;AAChB,WAAO,KAAK5B;EACd;EAEA,IAAI6B,UAAU;AACZ,WAAO,KAAK5B;EACd;EAEA6B,YAAY,EAAED,SAASD,YAAW,GAA8C;AAC9E,SAAK3B,WAAW4B;AAChB,SAAK7B,eAAe4B;AACpB,SAAKvB,qBAAqB0B,gBAAe;EAC3C;EAEOC,YAAYC,UAAuC;AACxD,SAAKpB,WAAWqB,IAAID,QAAAA;AACpB,WAAO,MAAM,KAAKpB,WAAWsB,OAAOF,QAAAA;EACtC;;;;EAKA,MAAyBG,QAAQ;AAC/BC,IAAAA,KAAI,cAAc;MAAEd,MAAM,KAAKA;IAAK,GAAA;;;;;;AACpC,SAAKlB,qBAAqBmB,KAAI,EAAGc,MAAM,CAACC,QAAAA;AACtCF,MAAAA,KAAIG,KAAK,kCAAkC;QAAED;MAAI,GAAA;;;;;;IACnD,CAAA;EACF;;;;EAKA,MAAyBE,SAAS;AAChCJ,IAAAA,KAAI,cAAc;MAAER,SAAS,KAAK5B;IAAS,GAAA;;;;;;AAC3C,UAAM,KAAKI,qBAAqBqC,MAAK;EACvC;EAEA,MAAclC,iBAAiB;AAC7B,UAAMmC,MAAM,IAAIC,IAAI,OAAO,KAAK5C,YAAY,IAAI,KAAKC,QAAQ,IAAI,KAAKC,QAAQ2C,cAAc;AAC5F,SAAK5B,MAAM,IAAI6B,UAAUH,GAAAA;AAEzB,SAAK1B,IAAI8B,SAAS,MAAA;AAChBV,MAAAA,KAAI,UAAU,KAAKd,MAAI;;;;;;AACvB,WAAKR,OAAOiC,KAAI;IAClB;AACA,SAAK/B,IAAIgC,UAAU,MAAA;AACjBZ,MAAAA,KAAI,UAAU,KAAKd,MAAI;;;;;;AACvB,WAAKlB,qBAAqB0B,gBAAe;IAC3C;AACA,SAAKd,IAAIiC,UAAU,CAACC,UAAAA;AAClBd,MAAAA,KAAIG,KAAK,2BAA2B;QAAEY,OAAOD,MAAMC;QAAO7B,MAAM4B,MAAME;MAAQ,GAAA;;;;;;AAC9E,WAAKhD,qBAAqB0B,gBAAe;IAC3C;AAIA,SAAKd,IAAIqC,YAAY,OAAOH,UAAAA;AAC1B,UAAIA,MAAMI,SAAS,YAAY;AAC7B,aAAKC,aAAY;AACjB;MACF;AACA,YAAMD,OAAO,MAAME,aAAaN,MAAMI,IAAI;AAC1C,YAAMF,UAAUK,KAAIC,WAAWC,gBAAeL,IAAAA;AAC9ClB,MAAAA,KAAI,YAAY;QAAER,SAAS,KAAK5B;QAAU4D,SAASvC,SAASwC,eAAeT,OAAAA;MAAS,GAAA;;;;;;AACpF,UAAIA,SAAS;AACX,mBAAWpB,YAAY,KAAKpB,YAAY;AACtC,cAAI;AACF,kBAAMoB,SAASoB,OAAAA;UACjB,SAASd,KAAK;AACZF,YAAAA,KAAIe,MAAM,cAAc;cAAEb;cAAKsB,SAASvC,SAASwC,eAAeT,OAAAA;YAAS,GAAA;;;;;;UAC3E;QACF;MACF;IACF;AAEA,UAAM,KAAKtC,OAAOgD,KAAK;MAAEC,SAAS,KAAK9D,QAAQ8D,WAAWrE;IAAgB,CAAA;AAC1E,SAAKwB,gBAAgB,IAAI8C,QAAAA,QAAAA;;;;AACzBC,yBACE,KAAK/C,eACL,YAAA;AAGE,WAAKF,KAAKkD,KAAK,UAAA;IACjB,GACAvE,yBAAAA;AAEF,SAAKqB,IAAIkD,KAAK,UAAA;AACd,SAAKX,aAAY;EACnB;EAEA,MAAc9C,kBAAkB;AAC9B,QAAI,CAAC,KAAKO,KAAK;AACb;IACF;AACA,QAAI;AACF,WAAKF,OAAOqD,MAAM,IAAIC,qBAAAA,CAAAA;AACtB,WAAKtD,OAAOuD,MAAK;AACjB,WAAK,KAAKnD,eAAeoD,QAAAA;AACzB,WAAKpD,gBAAgBD;AACrB,WAAK,KAAKE,mBAAmBmD,QAAAA;AAC7B,WAAKnD,oBAAoBF;AAGzB,WAAKD,IAAI8B,SAAS,MAAA;MAAO;AACzB,WAAK9B,IAAIgC,UAAU,MAAA;MAAO;AAC1B,WAAKhC,IAAIiC,UAAU,MAAA;MAAO;AAC1B,WAAKjC,IAAIyB,MAAK;AACd,WAAKzB,MAAMC;IACb,SAASqB,KAAK;AACZ,UAAIA,eAAeiC,SAASjC,IAAIc,QAAQoB,SAAS,2DAAA,GAA8D;AAC7G;MACF;AACApC,MAAAA,KAAIG,KAAK,2BAA2B;QAAED;MAAI,GAAA;;;;;;IAC5C;EACF;;;;;EAMA,MAAa4B,KAAKd,SAAiC;AACjD,QAAI,KAAKtC,OAAO2D,UAAUC,aAAaC,UAAU;AAC/C,YAAM,KAAK7D,OAAOgD,KAAK;QAAEC,SAAS,KAAK9D,QAAQ8D,WAAWrE;MAAgB,CAAA;IAC5E;AACAkF,IAAAA,WAAU,KAAK5D,KAAG,QAAA;;;;;;;;;AAClB4D,IAAAA,WAAU,CAACxB,QAAQyB,UAAUzB,QAAQyB,OAAOjD,YAAY,KAAK5B,UAAQ,QAAA;;;;;;;;;AACrEoC,IAAAA,KAAI,cAAc;MAAER,SAAS,KAAK5B;MAAU4D,SAASvC,SAASwC,eAAeT,OAAAA;IAAS,GAAA;;;;;;AACtF,SAAKpC,IAAIkD,KAAKT,KAAIqB,SAASnB,gBAAeP,OAAAA,CAAAA;EAC5C;EAEQG,eAAe;AACrB,QAAI,KAAKwB,oBAAoBC,gBAAeC,MAAM;AAChD;IACF;AACA,SAAK,KAAK9D,mBAAmBmD,QAAAA;AAC7B,SAAKnD,oBAAoB,IAAI6C,QAAAA,QAAAA;;;;AAC7BkB,iBACE,KAAK/D,mBACL,MAAA;AACE,WAAKf,qBAAqB0B,gBAAe;IAC3C,GACA,IAAInC,yBAAAA;EAER;AACF;",
6
+ "names": ["WebSocket", "Trigger", "Event", "scheduleTaskInterval", "scheduleTask", "TriggerState", "Context", "LifecycleState", "Resource", "invariant", "log", "buf", "MessageSchema", "AnySchema", "SwarmRequestSchema", "SwarmResponseSchema", "TextMessageSchema", "invariant", "buf", "bufWkt", "MessageSchema", "bufferToArray", "getTypename", "typeName", "Protocol", "constructor", "types", "_typeRegistry", "createRegistry", "typeRegistry", "toJson", "message", "registry", "err", "type", "getPayloadType", "getPayload", "payload", "payloadTypename", "Error", "anyIs", "anyUnpack", "undefined", "typeUrl", "split", "createMessage", "source", "target", "serviceId", "create", "timestamp", "Date", "toISOString", "anyPack", "toUint8Array", "data", "Buffer", "Blob", "Uint8Array", "arrayBuffer", "protocol", "Protocol", "SwarmRequestSchema", "SwarmResponseSchema", "TextMessageSchema", "AnySchema", "WebsocketClosedError", "Error", "constructor", "DeferredTask", "sleep", "synchronized", "cancelWithContext", "LifecycleState", "Resource", "warnAfterTimeout", "log", "INIT_RESTART_DELAY", "DEFAULT_MAX_RESTART_DELAY", "PersistentLifecycle", "constructor", "start", "stop", "onRestart", "maxRestartDelay", "_restartTask", "undefined", "_restartAfter", "_start", "_stop", "_onRestart", "_maxRestartDelay", "_open", "_ctx", "_restart", "err", "warn", "schedule", "catch", "_close", "join", "state", "_lifecycleState", "OPEN", "Math", "min", "max", "scheduleRestart", "DEFAULT_TIMEOUT", "SIGNAL_KEEPALIVE_INTERVAL", "EdgeClient", "Resource", "constructor", "_identityKey", "_peerKey", "_config", "reconnect", "Event", "_persistentLifecycle", "PersistentLifecycle", "start", "_openWebSocket", "stop", "_closeWebSocket", "onRestart", "emit", "_listeners", "Set", "_ready", "Trigger", "_ws", "undefined", "_keepaliveCtx", "_heartBeatContext", "_protocol", "protocol", "info", "open", "isOpen", "identity", "device", "identityKey", "peerKey", "setIdentity", "scheduleRestart", "addListener", "listener", "add", "delete", "_open", "log", "catch", "err", "warn", "_close", "close", "url", "URL", "socketEndpoint", "WebSocket", "onopen", "wake", "onclose", "onerror", "event", "error", "message", "onmessage", "data", "_onHeartbeat", "toUint8Array", "buf", "fromBinary", "MessageSchema", "payload", "getPayloadType", "wait", "timeout", "Context", "scheduleTaskInterval", "send", "throw", "WebsocketClosedError", "reset", "dispose", "Error", "includes", "state", "TriggerState", "RESOLVED", "invariant", "source", "toBinary", "_lifecycleState", "LifecycleState", "OPEN", "scheduleTask"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/mesh/edge-client/src/protocol.ts":{"bytes":10314,"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/edge-client/src/defs.ts":{"bytes":1578,"imports":[{"path":"@bufbuild/protobuf/wkt","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/errors.ts":{"bytes":846,"imports":[],"format":"esm"},"packages/core/mesh/edge-client/src/persistent-lifecycle.ts":{"bytes":10868,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/edge-client/src/edge-client.ts":{"bytes":26825,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/defs.ts","kind":"import-statement","original":"./defs"},{"path":"packages/core/mesh/edge-client/src/errors.ts","kind":"import-statement","original":"./errors"},{"path":"packages/core/mesh/edge-client/src/persistent-lifecycle.ts","kind":"import-statement","original":"./persistent-lifecycle"},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/index.ts":{"bytes":849,"imports":[{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/edge-client.ts","kind":"import-statement","original":"./edge-client"},{"path":"packages/core/mesh/edge-client/src/defs.ts","kind":"import-statement","original":"./defs"},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"}},"outputs":{"packages/core/mesh/edge-client/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":23321},"packages/core/mesh/edge-client/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@bufbuild/protobuf/wkt","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"exports":["EdgeClient","Protocol","getTypename","protocol","toUint8Array"],"entryPoint":"packages/core/mesh/edge-client/src/index.ts","inputs":{"packages/core/mesh/edge-client/src/index.ts":{"bytesInOutput":60},"packages/core/mesh/edge-client/src/edge-client.ts":{"bytesInOutput":7041},"packages/core/mesh/edge-client/src/defs.ts":{"bytesInOutput":285},"packages/core/mesh/edge-client/src/protocol.ts":{"bytesInOutput":2600},"packages/core/mesh/edge-client/src/errors.ts":{"bytesInOutput":116},"packages/core/mesh/edge-client/src/persistent-lifecycle.ts":{"bytesInOutput":3041}},"bytes":13670}}}
1
+ {"inputs":{"packages/core/mesh/edge-client/src/protocol.ts":{"bytes":10314,"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/edge-client/src/defs.ts":{"bytes":1578,"imports":[{"path":"@bufbuild/protobuf/wkt","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/errors.ts":{"bytes":846,"imports":[],"format":"esm"},"packages/core/mesh/edge-client/src/persistent-lifecycle.ts":{"bytes":10868,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/edge-client/src/edge-client.ts":{"bytes":26527,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/defs.ts","kind":"import-statement","original":"./defs"},{"path":"packages/core/mesh/edge-client/src/errors.ts","kind":"import-statement","original":"./errors"},{"path":"packages/core/mesh/edge-client/src/persistent-lifecycle.ts","kind":"import-statement","original":"./persistent-lifecycle"},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/index.ts":{"bytes":849,"imports":[{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/edge-client.ts","kind":"import-statement","original":"./edge-client"},{"path":"packages/core/mesh/edge-client/src/defs.ts","kind":"import-statement","original":"./defs"},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"}},"outputs":{"packages/core/mesh/edge-client/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":23173},"packages/core/mesh/edge-client/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@bufbuild/protobuf/wkt","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"exports":["EdgeClient","Protocol","getTypename","protocol","toUint8Array"],"entryPoint":"packages/core/mesh/edge-client/src/index.ts","inputs":{"packages/core/mesh/edge-client/src/index.ts":{"bytesInOutput":60},"packages/core/mesh/edge-client/src/edge-client.ts":{"bytesInOutput":6962},"packages/core/mesh/edge-client/src/defs.ts":{"bytesInOutput":285},"packages/core/mesh/edge-client/src/protocol.ts":{"bytesInOutput":2600},"packages/core/mesh/edge-client/src/errors.ts":{"bytesInOutput":116},"packages/core/mesh/edge-client/src/persistent-lifecycle.ts":{"bytesInOutput":3041}},"bytes":13591}}}
@@ -282,9 +282,6 @@ var EdgeClient = class extends import_context.Resource {
282
282
  get peerKey() {
283
283
  return this._peerKey;
284
284
  }
285
- get isOpen() {
286
- return this._lifecycleState === import_context.LifecycleState.OPEN;
287
- }
288
285
  setIdentity({ peerKey, identityKey }) {
289
286
  this._peerKey = peerKey;
290
287
  this._identityKey = identityKey;
@@ -302,7 +299,7 @@ var EdgeClient = class extends import_context.Resource {
302
299
  info: this.info
303
300
  }, {
304
301
  F: __dxlog_file3,
305
- L: 105,
302
+ L: 101,
306
303
  S: this,
307
304
  C: (f, a) => f(...a)
308
305
  });
@@ -311,7 +308,7 @@ var EdgeClient = class extends import_context.Resource {
311
308
  err
312
309
  }, {
313
310
  F: __dxlog_file3,
314
- L: 107,
311
+ L: 103,
315
312
  S: this,
316
313
  C: (f, a) => f(...a)
317
314
  });
@@ -325,7 +322,7 @@ var EdgeClient = class extends import_context.Resource {
325
322
  peerKey: this._peerKey
326
323
  }, {
327
324
  F: __dxlog_file3,
328
- L: 115,
325
+ L: 111,
329
326
  S: this,
330
327
  C: (f, a) => f(...a)
331
328
  });
@@ -337,7 +334,7 @@ var EdgeClient = class extends import_context.Resource {
337
334
  this._ws.onopen = () => {
338
335
  (0, import_log.log)("opened", this.info, {
339
336
  F: __dxlog_file3,
340
- L: 124,
337
+ L: 120,
341
338
  S: this,
342
339
  C: (f, a) => f(...a)
343
340
  });
@@ -346,7 +343,7 @@ var EdgeClient = class extends import_context.Resource {
346
343
  this._ws.onclose = () => {
347
344
  (0, import_log.log)("closed", this.info, {
348
345
  F: __dxlog_file3,
349
- L: 128,
346
+ L: 124,
350
347
  S: this,
351
348
  C: (f, a) => f(...a)
352
349
  });
@@ -358,7 +355,7 @@ var EdgeClient = class extends import_context.Resource {
358
355
  info: event.message
359
356
  }, {
360
357
  F: __dxlog_file3,
361
- L: 132,
358
+ L: 128,
362
359
  S: this,
363
360
  C: (f, a) => f(...a)
364
361
  });
@@ -376,7 +373,7 @@ var EdgeClient = class extends import_context.Resource {
376
373
  payload: protocol.getPayloadType(message)
377
374
  }, {
378
375
  F: __dxlog_file3,
379
- L: 145,
376
+ L: 141,
380
377
  S: this,
381
378
  C: (f, a) => f(...a)
382
379
  });
@@ -390,7 +387,7 @@ var EdgeClient = class extends import_context.Resource {
390
387
  payload: protocol.getPayloadType(message)
391
388
  }, {
392
389
  F: __dxlog_file3,
393
- L: 151,
390
+ L: 147,
394
391
  S: this,
395
392
  C: (f, a) => f(...a)
396
393
  });
@@ -403,7 +400,7 @@ var EdgeClient = class extends import_context.Resource {
403
400
  });
404
401
  this._keepaliveCtx = new import_context.Context(void 0, {
405
402
  F: __dxlog_file3,
406
- L: 158
403
+ L: 154
407
404
  });
408
405
  (0, import_async.scheduleTaskInterval)(this._keepaliveCtx, async () => {
409
406
  this._ws?.send("__ping__");
@@ -438,7 +435,7 @@ var EdgeClient = class extends import_context.Resource {
438
435
  err
439
436
  }, {
440
437
  F: __dxlog_file3,
441
- L: 194,
438
+ L: 190,
442
439
  S: this,
443
440
  C: (f, a) => f(...a)
444
441
  });
@@ -456,7 +453,7 @@ var EdgeClient = class extends import_context.Resource {
456
453
  }
457
454
  (0, import_invariant.invariant)(this._ws, void 0, {
458
455
  F: __dxlog_file3,
459
- L: 206,
456
+ L: 202,
460
457
  S: this,
461
458
  A: [
462
459
  "this._ws",
@@ -465,7 +462,7 @@ var EdgeClient = class extends import_context.Resource {
465
462
  });
466
463
  (0, import_invariant.invariant)(!message.source || message.source.peerKey === this._peerKey, void 0, {
467
464
  F: __dxlog_file3,
468
- L: 207,
465
+ L: 203,
469
466
  S: this,
470
467
  A: [
471
468
  "!message.source || message.source.peerKey === this._peerKey",
@@ -477,7 +474,7 @@ var EdgeClient = class extends import_context.Resource {
477
474
  payload: protocol.getPayloadType(message)
478
475
  }, {
479
476
  F: __dxlog_file3,
480
- L: 208,
477
+ L: 204,
481
478
  S: this,
482
479
  C: (f, a) => f(...a)
483
480
  });
@@ -490,7 +487,7 @@ var EdgeClient = class extends import_context.Resource {
490
487
  void this._heartBeatContext?.dispose();
491
488
  this._heartBeatContext = new import_context.Context(void 0, {
492
489
  F: __dxlog_file3,
493
- L: 217
490
+ L: 213
494
491
  });
495
492
  (0, import_async.scheduleTask)(this._heartBeatContext, () => {
496
493
  this._persistentLifecycle.scheduleRestart();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/index.ts", "../../../src/edge-client.ts", "../../../src/defs.ts", "../../../src/protocol.ts", "../../../src/errors.ts", "../../../src/persistent-lifecycle.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nexport * from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nexport * from './edge-client';\nexport * from './defs';\nexport * from './protocol';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Trigger, Event, scheduleTaskInterval, scheduleTask, TriggerState } from '@dxos/async';\nimport { Context, LifecycleState, Resource, type Lifecycle } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { protocol } from './defs';\nimport { WebsocketClosedError } from './errors';\nimport { PersistentLifecycle } from './persistent-lifecycle';\nimport { type Protocol, toUint8Array } from './protocol';\n\nconst DEFAULT_TIMEOUT = 10_000;\nconst SIGNAL_KEEPALIVE_INTERVAL = 5_000;\n\nexport type MessageListener = (message: Message) => void | Promise<void>;\n\nexport interface EdgeConnection extends Required<Lifecycle> {\n reconnect: Event;\n\n get info(): any;\n get identityKey(): string;\n get peerKey(): string;\n get isOpen(): boolean;\n setIdentity(params: { peerKey: string; identityKey: string }): void;\n addListener(listener: MessageListener): () => void;\n send(message: Message): Promise<void>;\n}\n\nexport type MessengerConfig = {\n socketEndpoint: string;\n timeout?: number;\n protocol?: Protocol;\n};\n\n/**\n * Messenger client.\n */\nexport class EdgeClient extends Resource implements EdgeConnection {\n public reconnect = new Event();\n private readonly _persistentLifecycle = new PersistentLifecycle({\n start: async () => this._openWebSocket(),\n stop: async () => this._closeWebSocket(),\n onRestart: async () => this.reconnect.emit(),\n });\n\n private readonly _listeners = new Set<MessageListener>();\n private readonly _protocol: Protocol;\n private _ready = new Trigger();\n private _ws?: WebSocket = undefined;\n private _keepaliveCtx?: Context = undefined;\n private _heartBeatContext?: Context = undefined;\n\n constructor(\n private _identityKey: string,\n private _peerKey: string,\n private readonly _config: MessengerConfig,\n ) {\n super();\n this._protocol = this._config.protocol ?? protocol;\n }\n\n // TODO(burdon): Attach logging.\n public get info() {\n return {\n open: this.isOpen,\n identity: this._identityKey,\n device: this._peerKey,\n };\n }\n\n get identityKey() {\n return this._identityKey;\n }\n\n get peerKey() {\n return this._peerKey;\n }\n\n public get isOpen() {\n return this._lifecycleState === LifecycleState.OPEN;\n }\n\n setIdentity({ peerKey, identityKey }: { peerKey: string; identityKey: string }) {\n this._peerKey = peerKey;\n this._identityKey = identityKey;\n this._persistentLifecycle.scheduleRestart();\n }\n\n public addListener(listener: MessageListener): () => void {\n this._listeners.add(listener);\n return () => this._listeners.delete(listener);\n }\n\n /**\n * Open connection to messaging service.\n */\n protected override async _open() {\n log('opening...', { info: this.info });\n this._persistentLifecycle.open().catch((err) => {\n log.warn('Error while opening connection', { err });\n });\n }\n\n /**\n * Close connection and free resources.\n */\n protected override async _close() {\n log('closing...', { peerKey: this._peerKey });\n await this._persistentLifecycle.close();\n }\n\n private async _openWebSocket() {\n const url = new URL(`/ws/${this._identityKey}/${this._peerKey}`, this._config.socketEndpoint);\n this._ws = new WebSocket(url);\n\n this._ws.onopen = () => {\n log('opened', this.info);\n this._ready.wake();\n };\n this._ws.onclose = () => {\n log('closed', this.info);\n this._persistentLifecycle.scheduleRestart();\n };\n this._ws.onerror = (event) => {\n log.warn('EdgeClient socket error', { error: event.error, info: event.message });\n this._persistentLifecycle.scheduleRestart();\n };\n /**\n * https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data\n */\n this._ws.onmessage = async (event) => {\n if (event.data === '__pong__') {\n this._onHeartbeat();\n return;\n }\n const data = await toUint8Array(event.data);\n const message = buf.fromBinary(MessageSchema, data);\n log('received', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n if (message) {\n for (const listener of this._listeners) {\n try {\n await listener(message);\n } catch (err) {\n log.error('processing', { err, payload: protocol.getPayloadType(message) });\n }\n }\n }\n };\n\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n this._keepaliveCtx = new Context();\n scheduleTaskInterval(\n this._keepaliveCtx,\n async () => {\n // TODO(mykola): use RFC6455 ping/pong once implemented in the browser?\n // Cloudflare's worker responds to this `without interrupting hibernation`. https://developers.cloudflare.com/durable-objects/api/websockets/#setwebsocketautoresponse\n this._ws?.send('__ping__');\n },\n SIGNAL_KEEPALIVE_INTERVAL,\n );\n this._ws.send('__ping__');\n this._onHeartbeat();\n }\n\n private async _closeWebSocket() {\n if (!this._ws) {\n return;\n }\n try {\n this._ready.throw(new WebsocketClosedError());\n this._ready.reset();\n void this._keepaliveCtx?.dispose();\n this._keepaliveCtx = undefined;\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = undefined;\n\n // NOTE: Remove event handlers to avoid scheduling restart.\n this._ws.onopen = () => {};\n this._ws.onclose = () => {};\n this._ws.onerror = () => {};\n this._ws.close();\n this._ws = undefined;\n } catch (err) {\n if (err instanceof Error && err.message.includes('WebSocket is closed before the connection is established.')) {\n return;\n }\n log.warn('Error closing websocket', { err });\n }\n }\n\n /**\n * Send message.\n * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.\n */\n public async send(message: Message): Promise<void> {\n if (this._ready.state !== TriggerState.RESOLVED) {\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n }\n invariant(this._ws);\n invariant(!message.source || message.source.peerKey === this._peerKey);\n log('sending...', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n this._ws.send(buf.toBinary(MessageSchema, message));\n }\n\n private _onHeartbeat() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = new Context();\n scheduleTask(\n this._heartBeatContext,\n () => {\n this._persistentLifecycle.scheduleRestart();\n },\n 2 * SIGNAL_KEEPALIVE_INTERVAL,\n );\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { AnySchema } from '@bufbuild/protobuf/wkt';\n\nimport { SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { Protocol } from './protocol';\n\nexport const protocol = new Protocol([SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema, AnySchema]);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { buf, bufWkt } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema, type Peer as PeerProto } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { bufferToArray } from '@dxos/util';\n\nexport type PeerData = Partial<PeerProto>;\n\nexport const getTypename = (typeName: string) => `type.googleapis.com/${typeName}`;\n\n/**\n * NOTE: The type registry should be extended with all message types.\n */\nexport class Protocol {\n private readonly _typeRegistry: buf.Registry;\n\n constructor(types: buf.DescMessage[]) {\n this._typeRegistry = buf.createRegistry(...types);\n }\n\n get typeRegistry(): buf.Registry {\n return this._typeRegistry;\n }\n\n toJson(message: Message): any {\n try {\n return buf.toJson(MessageSchema, message, { registry: this.typeRegistry });\n } catch (err) {\n return { type: this.getPayloadType(message) };\n }\n }\n\n /**\n * Return the payload with the given type.\n */\n getPayload<Desc extends buf.DescMessage>(message: Message, type: Desc): buf.MessageShape<Desc> {\n invariant(message.payload);\n const payloadTypename = this.getPayloadType(message);\n if (type && type.typeName !== payloadTypename) {\n throw new Error(`Unexpected payload type: ${payloadTypename}; expected ${type.typeName}`);\n }\n\n invariant(bufWkt.anyIs(message.payload, type), `Unexpected payload type: ${payloadTypename}}`);\n const payload = bufWkt.anyUnpack(message.payload, this.typeRegistry) as buf.MessageShape<Desc>;\n invariant(payload, `Empty payload: ${payloadTypename}}`);\n return payload;\n }\n\n /**\n * Get the payload type.\n */\n getPayloadType(message: Message): string | undefined {\n if (!message.payload) {\n return undefined;\n }\n\n const [, type] = message.payload.typeUrl.split('/');\n return type;\n }\n\n /**\n * Create a packed message.\n */\n createMessage<Desc extends buf.DescMessage>(\n type: Desc,\n {\n source,\n target,\n payload,\n serviceId,\n }: {\n source?: PeerData;\n target?: PeerData[];\n payload?: buf.MessageInitShape<Desc>;\n serviceId?: string;\n },\n ) {\n return buf.create(MessageSchema, {\n timestamp: new Date().toISOString(),\n source,\n target,\n serviceId,\n payload: payload ? bufWkt.anyPack(type, buf.create(type, payload)) : undefined,\n });\n }\n}\n\n/**\n * Convert websocket data to Uint8Array.\n */\nexport const toUint8Array = async (data: any): Promise<Uint8Array> => {\n // Node.\n if (data instanceof Buffer) {\n return bufferToArray(data);\n }\n\n // Browser.\n if (data instanceof Blob) {\n return new Uint8Array(await (data as Blob).arrayBuffer());\n }\n\n throw new Error(`Unexpected datatype: ${data}`);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport class WebsocketClosedError extends Error {\n constructor() {\n super('WebSocket connection closed');\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { DeferredTask, sleep, synchronized } from '@dxos/async';\nimport { cancelWithContext, LifecycleState, Resource } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport { log } from '@dxos/log';\n\nconst INIT_RESTART_DELAY = 100;\nconst DEFAULT_MAX_RESTART_DELAY = 5000;\n\nexport type PersistentLifecycleParams = {\n /**\n * Create connection.\n * If promise resolves successfully, connection is considered established.\n */\n start: () => Promise<void>;\n\n /**\n * Reset connection to initial state.\n */\n stop: () => Promise<void>;\n\n /**\n * Called after successful start.\n */\n onRestart?: () => Promise<void>;\n\n /**\n * Maximum delay between restartion attempts.\n * Default: 5000ms\n */\n maxRestartDelay?: number;\n};\n\n/**\n * Handles restarts (e.g. persists connection).\n * Restarts are scheduled with exponential backoff.\n */\nexport class PersistentLifecycle extends Resource {\n private readonly _start: () => Promise<void>;\n private readonly _stop: () => Promise<void>;\n private readonly _onRestart?: () => Promise<void>;\n private readonly _maxRestartDelay: number;\n\n private _restartTask?: DeferredTask = undefined;\n private _restartAfter = 0;\n\n constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }: PersistentLifecycleParams) {\n super();\n this._start = start;\n this._stop = stop;\n this._onRestart = onRestart;\n this._maxRestartDelay = maxRestartDelay;\n }\n\n @synchronized\n protected override async _open() {\n this._restartTask = new DeferredTask(this._ctx, async () => {\n try {\n await this._restart();\n } catch (err) {\n log.warn('Restart failed', { err });\n this._restartTask?.schedule();\n }\n });\n await this._start().catch((err) => {\n log.warn('Start failed', { err });\n this._restartTask?.schedule();\n });\n }\n\n protected override async _close() {\n await this._restartTask?.join();\n await this._stop();\n this._restartTask = undefined;\n }\n\n private async _restart() {\n log(`restarting in ${this._restartAfter}ms`, { state: this._lifecycleState });\n await this._stop();\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n await cancelWithContext(this._ctx!, sleep(this._restartAfter));\n this._restartAfter = Math.min(Math.max(this._restartAfter * 2, INIT_RESTART_DELAY), this._maxRestartDelay);\n\n // May fail if the connection is not established.\n await warnAfterTimeout(5_000, 'Connection establishment takes too long', () => this._start());\n\n this._restartAfter = 0;\n await this._onRestart?.();\n }\n\n /**\n * Scheduling restart should be done from outside.\n */\n @synchronized\n scheduleRestart() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n this._restartTask!.schedule();\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nexport * from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nexport * from './edge-client';\nexport * from './defs';\nexport * from './protocol';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Trigger, Event, scheduleTaskInterval, scheduleTask, TriggerState } from '@dxos/async';\nimport { Context, LifecycleState, Resource, type Lifecycle } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { protocol } from './defs';\nimport { WebsocketClosedError } from './errors';\nimport { PersistentLifecycle } from './persistent-lifecycle';\nimport { type Protocol, toUint8Array } from './protocol';\n\nconst DEFAULT_TIMEOUT = 10_000;\nconst SIGNAL_KEEPALIVE_INTERVAL = 5_000;\n\nexport type MessageListener = (message: Message) => void | Promise<void>;\n\nexport interface EdgeConnection extends Required<Lifecycle> {\n reconnect: Event;\n\n get info(): any;\n get identityKey(): string;\n get peerKey(): string;\n get isOpen(): boolean;\n setIdentity(params: { peerKey: string; identityKey: string }): void;\n addListener(listener: MessageListener): () => void;\n send(message: Message): Promise<void>;\n}\n\nexport type MessengerConfig = {\n socketEndpoint: string;\n timeout?: number;\n protocol?: Protocol;\n};\n\n/**\n * Messenger client.\n */\nexport class EdgeClient extends Resource implements EdgeConnection {\n public reconnect = new Event();\n private readonly _persistentLifecycle = new PersistentLifecycle({\n start: async () => this._openWebSocket(),\n stop: async () => this._closeWebSocket(),\n onRestart: async () => this.reconnect.emit(),\n });\n\n private readonly _listeners = new Set<MessageListener>();\n private readonly _protocol: Protocol;\n private _ready = new Trigger();\n private _ws?: WebSocket = undefined;\n private _keepaliveCtx?: Context = undefined;\n private _heartBeatContext?: Context = undefined;\n\n constructor(\n private _identityKey: string,\n private _peerKey: string,\n private readonly _config: MessengerConfig,\n ) {\n super();\n this._protocol = this._config.protocol ?? protocol;\n }\n\n // TODO(burdon): Attach logging.\n public get info() {\n return {\n open: this.isOpen,\n identity: this._identityKey,\n device: this._peerKey,\n };\n }\n\n get identityKey() {\n return this._identityKey;\n }\n\n get peerKey() {\n return this._peerKey;\n }\n\n setIdentity({ peerKey, identityKey }: { peerKey: string; identityKey: string }) {\n this._peerKey = peerKey;\n this._identityKey = identityKey;\n this._persistentLifecycle.scheduleRestart();\n }\n\n public addListener(listener: MessageListener): () => void {\n this._listeners.add(listener);\n return () => this._listeners.delete(listener);\n }\n\n /**\n * Open connection to messaging service.\n */\n protected override async _open() {\n log('opening...', { info: this.info });\n this._persistentLifecycle.open().catch((err) => {\n log.warn('Error while opening connection', { err });\n });\n }\n\n /**\n * Close connection and free resources.\n */\n protected override async _close() {\n log('closing...', { peerKey: this._peerKey });\n await this._persistentLifecycle.close();\n }\n\n private async _openWebSocket() {\n const url = new URL(`/ws/${this._identityKey}/${this._peerKey}`, this._config.socketEndpoint);\n this._ws = new WebSocket(url);\n\n this._ws.onopen = () => {\n log('opened', this.info);\n this._ready.wake();\n };\n this._ws.onclose = () => {\n log('closed', this.info);\n this._persistentLifecycle.scheduleRestart();\n };\n this._ws.onerror = (event) => {\n log.warn('EdgeClient socket error', { error: event.error, info: event.message });\n this._persistentLifecycle.scheduleRestart();\n };\n /**\n * https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data\n */\n this._ws.onmessage = async (event) => {\n if (event.data === '__pong__') {\n this._onHeartbeat();\n return;\n }\n const data = await toUint8Array(event.data);\n const message = buf.fromBinary(MessageSchema, data);\n log('received', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n if (message) {\n for (const listener of this._listeners) {\n try {\n await listener(message);\n } catch (err) {\n log.error('processing', { err, payload: protocol.getPayloadType(message) });\n }\n }\n }\n };\n\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n this._keepaliveCtx = new Context();\n scheduleTaskInterval(\n this._keepaliveCtx,\n async () => {\n // TODO(mykola): use RFC6455 ping/pong once implemented in the browser?\n // Cloudflare's worker responds to this `without interrupting hibernation`. https://developers.cloudflare.com/durable-objects/api/websockets/#setwebsocketautoresponse\n this._ws?.send('__ping__');\n },\n SIGNAL_KEEPALIVE_INTERVAL,\n );\n this._ws.send('__ping__');\n this._onHeartbeat();\n }\n\n private async _closeWebSocket() {\n if (!this._ws) {\n return;\n }\n try {\n this._ready.throw(new WebsocketClosedError());\n this._ready.reset();\n void this._keepaliveCtx?.dispose();\n this._keepaliveCtx = undefined;\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = undefined;\n\n // NOTE: Remove event handlers to avoid scheduling restart.\n this._ws.onopen = () => {};\n this._ws.onclose = () => {};\n this._ws.onerror = () => {};\n this._ws.close();\n this._ws = undefined;\n } catch (err) {\n if (err instanceof Error && err.message.includes('WebSocket is closed before the connection is established.')) {\n return;\n }\n log.warn('Error closing websocket', { err });\n }\n }\n\n /**\n * Send message.\n * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.\n */\n public async send(message: Message): Promise<void> {\n if (this._ready.state !== TriggerState.RESOLVED) {\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n }\n invariant(this._ws);\n invariant(!message.source || message.source.peerKey === this._peerKey);\n log('sending...', { peerKey: this._peerKey, payload: protocol.getPayloadType(message) });\n this._ws.send(buf.toBinary(MessageSchema, message));\n }\n\n private _onHeartbeat() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n void this._heartBeatContext?.dispose();\n this._heartBeatContext = new Context();\n scheduleTask(\n this._heartBeatContext,\n () => {\n this._persistentLifecycle.scheduleRestart();\n },\n 2 * SIGNAL_KEEPALIVE_INTERVAL,\n );\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { AnySchema } from '@bufbuild/protobuf/wkt';\n\nimport { SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { Protocol } from './protocol';\n\nexport const protocol = new Protocol([SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema, AnySchema]);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { buf, bufWkt } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema, type Peer as PeerProto } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { bufferToArray } from '@dxos/util';\n\nexport type PeerData = Partial<PeerProto>;\n\nexport const getTypename = (typeName: string) => `type.googleapis.com/${typeName}`;\n\n/**\n * NOTE: The type registry should be extended with all message types.\n */\nexport class Protocol {\n private readonly _typeRegistry: buf.Registry;\n\n constructor(types: buf.DescMessage[]) {\n this._typeRegistry = buf.createRegistry(...types);\n }\n\n get typeRegistry(): buf.Registry {\n return this._typeRegistry;\n }\n\n toJson(message: Message): any {\n try {\n return buf.toJson(MessageSchema, message, { registry: this.typeRegistry });\n } catch (err) {\n return { type: this.getPayloadType(message) };\n }\n }\n\n /**\n * Return the payload with the given type.\n */\n getPayload<Desc extends buf.DescMessage>(message: Message, type: Desc): buf.MessageShape<Desc> {\n invariant(message.payload);\n const payloadTypename = this.getPayloadType(message);\n if (type && type.typeName !== payloadTypename) {\n throw new Error(`Unexpected payload type: ${payloadTypename}; expected ${type.typeName}`);\n }\n\n invariant(bufWkt.anyIs(message.payload, type), `Unexpected payload type: ${payloadTypename}}`);\n const payload = bufWkt.anyUnpack(message.payload, this.typeRegistry) as buf.MessageShape<Desc>;\n invariant(payload, `Empty payload: ${payloadTypename}}`);\n return payload;\n }\n\n /**\n * Get the payload type.\n */\n getPayloadType(message: Message): string | undefined {\n if (!message.payload) {\n return undefined;\n }\n\n const [, type] = message.payload.typeUrl.split('/');\n return type;\n }\n\n /**\n * Create a packed message.\n */\n createMessage<Desc extends buf.DescMessage>(\n type: Desc,\n {\n source,\n target,\n payload,\n serviceId,\n }: {\n source?: PeerData;\n target?: PeerData[];\n payload?: buf.MessageInitShape<Desc>;\n serviceId?: string;\n },\n ) {\n return buf.create(MessageSchema, {\n timestamp: new Date().toISOString(),\n source,\n target,\n serviceId,\n payload: payload ? bufWkt.anyPack(type, buf.create(type, payload)) : undefined,\n });\n }\n}\n\n/**\n * Convert websocket data to Uint8Array.\n */\nexport const toUint8Array = async (data: any): Promise<Uint8Array> => {\n // Node.\n if (data instanceof Buffer) {\n return bufferToArray(data);\n }\n\n // Browser.\n if (data instanceof Blob) {\n return new Uint8Array(await (data as Blob).arrayBuffer());\n }\n\n throw new Error(`Unexpected datatype: ${data}`);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport class WebsocketClosedError extends Error {\n constructor() {\n super('WebSocket connection closed');\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { DeferredTask, sleep, synchronized } from '@dxos/async';\nimport { cancelWithContext, LifecycleState, Resource } from '@dxos/context';\nimport { warnAfterTimeout } from '@dxos/debug';\nimport { log } from '@dxos/log';\n\nconst INIT_RESTART_DELAY = 100;\nconst DEFAULT_MAX_RESTART_DELAY = 5000;\n\nexport type PersistentLifecycleParams = {\n /**\n * Create connection.\n * If promise resolves successfully, connection is considered established.\n */\n start: () => Promise<void>;\n\n /**\n * Reset connection to initial state.\n */\n stop: () => Promise<void>;\n\n /**\n * Called after successful start.\n */\n onRestart?: () => Promise<void>;\n\n /**\n * Maximum delay between restartion attempts.\n * Default: 5000ms\n */\n maxRestartDelay?: number;\n};\n\n/**\n * Handles restarts (e.g. persists connection).\n * Restarts are scheduled with exponential backoff.\n */\nexport class PersistentLifecycle extends Resource {\n private readonly _start: () => Promise<void>;\n private readonly _stop: () => Promise<void>;\n private readonly _onRestart?: () => Promise<void>;\n private readonly _maxRestartDelay: number;\n\n private _restartTask?: DeferredTask = undefined;\n private _restartAfter = 0;\n\n constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }: PersistentLifecycleParams) {\n super();\n this._start = start;\n this._stop = stop;\n this._onRestart = onRestart;\n this._maxRestartDelay = maxRestartDelay;\n }\n\n @synchronized\n protected override async _open() {\n this._restartTask = new DeferredTask(this._ctx, async () => {\n try {\n await this._restart();\n } catch (err) {\n log.warn('Restart failed', { err });\n this._restartTask?.schedule();\n }\n });\n await this._start().catch((err) => {\n log.warn('Start failed', { err });\n this._restartTask?.schedule();\n });\n }\n\n protected override async _close() {\n await this._restartTask?.join();\n await this._stop();\n this._restartTask = undefined;\n }\n\n private async _restart() {\n log(`restarting in ${this._restartAfter}ms`, { state: this._lifecycleState });\n await this._stop();\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n await cancelWithContext(this._ctx!, sleep(this._restartAfter));\n this._restartAfter = Math.min(Math.max(this._restartAfter * 2, INIT_RESTART_DELAY), this._maxRestartDelay);\n\n // May fail if the connection is not established.\n await warnAfterTimeout(5_000, 'Connection establishment takes too long', () => this._start());\n\n this._restartAfter = 0;\n await this._onRestart?.();\n }\n\n /**\n * Scheduling restart should be done from outside.\n */\n @synchronized\n scheduleRestart() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n this._restartTask!.schedule();\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_messenger_pb", "import_invariant", "import_buf", "import_async", "import_context", "import_log", "getTypename", "typeName", "Protocol", "constructor", "types", "_typeRegistry", "buf", "createRegistry", "typeRegistry", "toJson", "message", "MessageSchema", "registry", "err", "type", "getPayloadType", "getPayload", "invariant", "payload", "payloadTypename", "Error", "bufWkt", "anyIs", "anyUnpack", "undefined", "typeUrl", "split", "createMessage", "source", "target", "serviceId", "create", "timestamp", "Date", "toISOString", "anyPack", "toUint8Array", "data", "Buffer", "bufferToArray", "Blob", "Uint8Array", "arrayBuffer", "protocol", "SwarmRequestSchema", "SwarmResponseSchema", "TextMessageSchema", "AnySchema", "WebsocketClosedError", "INIT_RESTART_DELAY", "DEFAULT_MAX_RESTART_DELAY", "PersistentLifecycle", "Resource", "start", "stop", "onRestart", "maxRestartDelay", "_restartTask", "_restartAfter", "_start", "_stop", "_onRestart", "_maxRestartDelay", "_open", "DeferredTask", "_ctx", "_restart", "log", "warn", "schedule", "catch", "_close", "join", "state", "_lifecycleState", "LifecycleState", "OPEN", "cancelWithContext", "sleep", "Math", "min", "max", "warnAfterTimeout", "scheduleRestart", "synchronized", "DEFAULT_TIMEOUT", "SIGNAL_KEEPALIVE_INTERVAL", "EdgeClient", "_identityKey", "_peerKey", "_config", "reconnect", "Event", "_persistentLifecycle", "_openWebSocket", "_closeWebSocket", "emit", "_listeners", "Set", "_ready", "Trigger", "_ws", "_keepaliveCtx", "_heartBeatContext", "_protocol", "info", "open", "isOpen", "identity", "device", "identityKey", "peerKey", "setIdentity", "addListener", "listener", "add", "delete", "close", "url", "URL", "socketEndpoint", "WebSocket", "onopen", "wake", "onclose", "onerror", "event", "error", "onmessage", "_onHeartbeat", "fromBinary", "wait", "timeout", "Context", "scheduleTaskInterval", "send", "throw", "reset", "dispose", "includes", "TriggerState", "RESOLVED", "toBinary", "scheduleTask"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/mesh/edge-client/src/protocol.ts":{"bytes":10314,"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/edge-client/src/defs.ts":{"bytes":1578,"imports":[{"path":"@bufbuild/protobuf/wkt","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/errors.ts":{"bytes":846,"imports":[],"format":"esm"},"packages/core/mesh/edge-client/src/persistent-lifecycle.ts":{"bytes":10868,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/edge-client/src/edge-client.ts":{"bytes":26825,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/defs.ts","kind":"import-statement","original":"./defs"},{"path":"packages/core/mesh/edge-client/src/errors.ts","kind":"import-statement","original":"./errors"},{"path":"packages/core/mesh/edge-client/src/persistent-lifecycle.ts","kind":"import-statement","original":"./persistent-lifecycle"},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/index.ts":{"bytes":849,"imports":[{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/edge-client.ts","kind":"import-statement","original":"./edge-client"},{"path":"packages/core/mesh/edge-client/src/defs.ts","kind":"import-statement","original":"./defs"},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"}},"outputs":{"packages/core/mesh/edge-client/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":23321},"packages/core/mesh/edge-client/dist/lib/node/index.cjs":{"imports":[{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@bufbuild/protobuf/wkt","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"exports":["EdgeClient","Protocol","getTypename","protocol","toUint8Array"],"entryPoint":"packages/core/mesh/edge-client/src/index.ts","inputs":{"packages/core/mesh/edge-client/src/index.ts":{"bytesInOutput":60},"packages/core/mesh/edge-client/src/edge-client.ts":{"bytesInOutput":7041},"packages/core/mesh/edge-client/src/defs.ts":{"bytesInOutput":285},"packages/core/mesh/edge-client/src/protocol.ts":{"bytesInOutput":2600},"packages/core/mesh/edge-client/src/errors.ts":{"bytesInOutput":116},"packages/core/mesh/edge-client/src/persistent-lifecycle.ts":{"bytesInOutput":3041}},"bytes":13670}}}
1
+ {"inputs":{"packages/core/mesh/edge-client/src/protocol.ts":{"bytes":10314,"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/edge-client/src/defs.ts":{"bytes":1578,"imports":[{"path":"@bufbuild/protobuf/wkt","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/errors.ts":{"bytes":846,"imports":[],"format":"esm"},"packages/core/mesh/edge-client/src/persistent-lifecycle.ts":{"bytes":10868,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/edge-client/src/edge-client.ts":{"bytes":26527,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/defs.ts","kind":"import-statement","original":"./defs"},{"path":"packages/core/mesh/edge-client/src/errors.ts","kind":"import-statement","original":"./errors"},{"path":"packages/core/mesh/edge-client/src/persistent-lifecycle.ts","kind":"import-statement","original":"./persistent-lifecycle"},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/index.ts":{"bytes":849,"imports":[{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/edge-client.ts","kind":"import-statement","original":"./edge-client"},{"path":"packages/core/mesh/edge-client/src/defs.ts","kind":"import-statement","original":"./defs"},{"path":"packages/core/mesh/edge-client/src/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"}},"outputs":{"packages/core/mesh/edge-client/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":23173},"packages/core/mesh/edge-client/dist/lib/node/index.cjs":{"imports":[{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@bufbuild/protobuf/wkt","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"exports":["EdgeClient","Protocol","getTypename","protocol","toUint8Array"],"entryPoint":"packages/core/mesh/edge-client/src/index.ts","inputs":{"packages/core/mesh/edge-client/src/index.ts":{"bytesInOutput":60},"packages/core/mesh/edge-client/src/edge-client.ts":{"bytesInOutput":6962},"packages/core/mesh/edge-client/src/defs.ts":{"bytesInOutput":285},"packages/core/mesh/edge-client/src/protocol.ts":{"bytesInOutput":2600},"packages/core/mesh/edge-client/src/errors.ts":{"bytesInOutput":116},"packages/core/mesh/edge-client/src/persistent-lifecycle.ts":{"bytesInOutput":3041}},"bytes":13591}}}
@@ -44,7 +44,6 @@ export declare class EdgeClient extends Resource implements EdgeConnection {
44
44
  };
45
45
  get identityKey(): string;
46
46
  get peerKey(): string;
47
- get isOpen(): boolean;
48
47
  setIdentity({ peerKey, identityKey }: {
49
48
  peerKey: string;
50
49
  identityKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"edge-client.d.ts","sourceRoot":"","sources":["../../../src/edge-client.ts"],"names":[],"mappings":"AAMA,OAAO,EAAW,KAAK,EAAoD,MAAM,aAAa,CAAC;AAC/F,OAAO,EAA2B,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAIlF,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,4CAA4C,CAAC;AAKzF,OAAO,EAAE,KAAK,QAAQ,EAAgB,MAAM,YAAY,CAAC;AAKzD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzE,MAAM,WAAW,cAAe,SAAQ,QAAQ,CAAC,SAAS,CAAC;IACzD,SAAS,EAAE,KAAK,CAAC;IAEjB,IAAI,IAAI,IAAI,GAAG,CAAC;IAChB,IAAI,WAAW,IAAI,MAAM,CAAC;IAC1B,IAAI,OAAO,IAAI,MAAM,CAAC;IACtB,IAAI,MAAM,IAAI,OAAO,CAAC;IACtB,WAAW,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI,CAAC;IACnD,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,qBAAa,UAAW,SAAQ,QAAS,YAAW,cAAc;IAgB9D,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAjBnB,SAAS,cAAe;IAC/B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAIlC;IAEH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,GAAG,CAAC,CAAwB;IACpC,OAAO,CAAC,aAAa,CAAC,CAAsB;IAC5C,OAAO,CAAC,iBAAiB,CAAC,CAAsB;gBAGtC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EACP,OAAO,EAAE,eAAe;IAO3C,IAAW,IAAI;;;;MAMd;IAED,IAAI,WAAW,WAEd;IAED,IAAI,OAAO,WAEV;IAED,IAAW,MAAM,YAEhB;IAED,WAAW,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE;IAMvE,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI;IAKzD;;OAEG;cACsB,KAAK;IAO9B;;OAEG;cACsB,MAAM;YAKjB,cAAc;YAqDd,eAAe;IA0B7B;;;OAGG;IACU,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlD,OAAO,CAAC,YAAY;CAcrB"}
1
+ {"version":3,"file":"edge-client.d.ts","sourceRoot":"","sources":["../../../src/edge-client.ts"],"names":[],"mappings":"AAMA,OAAO,EAAW,KAAK,EAAoD,MAAM,aAAa,CAAC;AAC/F,OAAO,EAA2B,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAIlF,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,4CAA4C,CAAC;AAKzF,OAAO,EAAE,KAAK,QAAQ,EAAgB,MAAM,YAAY,CAAC;AAKzD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzE,MAAM,WAAW,cAAe,SAAQ,QAAQ,CAAC,SAAS,CAAC;IACzD,SAAS,EAAE,KAAK,CAAC;IAEjB,IAAI,IAAI,IAAI,GAAG,CAAC;IAChB,IAAI,WAAW,IAAI,MAAM,CAAC;IAC1B,IAAI,OAAO,IAAI,MAAM,CAAC;IACtB,IAAI,MAAM,IAAI,OAAO,CAAC;IACtB,WAAW,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI,CAAC;IACnD,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,qBAAa,UAAW,SAAQ,QAAS,YAAW,cAAc;IAgB9D,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAjBnB,SAAS,cAAe;IAC/B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAIlC;IAEH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,GAAG,CAAC,CAAwB;IACpC,OAAO,CAAC,aAAa,CAAC,CAAsB;IAC5C,OAAO,CAAC,iBAAiB,CAAC,CAAsB;gBAGtC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EACP,OAAO,EAAE,eAAe;IAO3C,IAAW,IAAI;;;;MAMd;IAED,IAAI,WAAW,WAEd;IAED,IAAI,OAAO,WAEV;IAED,WAAW,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE;IAMvE,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI;IAKzD;;OAEG;cACsB,KAAK;IAO9B;;OAEG;cACsB,MAAM;YAKjB,cAAc;YAqDd,eAAe;IA0B7B;;;OAGG;IACU,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlD,OAAO,CAAC,YAAY;CAcrB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/edge-client",
3
- "version": "0.6.10",
3
+ "version": "0.6.11-staging.30cf5ba",
4
4
  "description": "EDGE Client",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -28,18 +28,18 @@
28
28
  "@bufbuild/protobuf": "^2.0.0",
29
29
  "isomorphic-ws": "^5.0.0",
30
30
  "ws": "^8.14.2",
31
- "@dxos/async": "0.6.10",
32
- "@dxos/invariant": "0.6.10",
33
- "@dxos/context": "0.6.10",
34
- "@dxos/log": "0.6.10",
35
- "@dxos/debug": "0.6.10",
36
- "@dxos/node-std": "0.6.10",
37
- "@dxos/protocols": "0.6.10",
38
- "@dxos/util": "0.6.10"
31
+ "@dxos/async": "0.6.11-staging.30cf5ba",
32
+ "@dxos/context": "0.6.11-staging.30cf5ba",
33
+ "@dxos/invariant": "0.6.11-staging.30cf5ba",
34
+ "@dxos/debug": "0.6.11-staging.30cf5ba",
35
+ "@dxos/log": "0.6.11-staging.30cf5ba",
36
+ "@dxos/node-std": "0.6.11-staging.30cf5ba",
37
+ "@dxos/protocols": "0.6.11-staging.30cf5ba",
38
+ "@dxos/util": "0.6.11-staging.30cf5ba"
39
39
  },
40
40
  "devDependencies": {
41
41
  "jest-websocket-mock": "^2.5.0",
42
- "@dxos/keys": "0.6.10"
42
+ "@dxos/keys": "0.6.11-staging.30cf5ba"
43
43
  },
44
44
  "publishConfig": {
45
45
  "access": "public"
@@ -83,10 +83,6 @@ export class EdgeClient extends Resource implements EdgeConnection {
83
83
  return this._peerKey;
84
84
  }
85
85
 
86
- public get isOpen() {
87
- return this._lifecycleState === LifecycleState.OPEN;
88
- }
89
-
90
86
  setIdentity({ peerKey, identityKey }: { peerKey: string; identityKey: string }) {
91
87
  this._peerKey = peerKey;
92
88
  this._identityKey = identityKey;