@dxos/edge-client 0.6.13-main.548ca8d → 0.6.13-main.ed424a1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +64 -21
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +64 -21
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +64 -21
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/edge-client.d.ts.map +1 -1
- package/dist/types/src/edge-http-client.d.ts +6 -2
- package/dist/types/src/edge-http-client.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/edge-client.ts +6 -2
- package/src/edge-http-client.ts +18 -2
package/dist/lib/node/index.cjs
CHANGED
|
@@ -208,8 +208,19 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
208
208
|
return this._identity.peerKey;
|
|
209
209
|
}
|
|
210
210
|
setIdentity(identity) {
|
|
211
|
-
this._identity
|
|
212
|
-
|
|
211
|
+
if (identity.identityKey !== this._identity.identityKey || identity.peerKey !== this._identity.peerKey) {
|
|
212
|
+
(0, import_log.log)("Edge identity changed", {
|
|
213
|
+
identity,
|
|
214
|
+
oldIdentity: this._identity
|
|
215
|
+
}, {
|
|
216
|
+
F: __dxlog_file2,
|
|
217
|
+
L: 110,
|
|
218
|
+
S: this,
|
|
219
|
+
C: (f, a) => f(...a)
|
|
220
|
+
});
|
|
221
|
+
this._identity = identity;
|
|
222
|
+
this._persistentLifecycle.scheduleRestart();
|
|
223
|
+
}
|
|
213
224
|
}
|
|
214
225
|
addListener(listener) {
|
|
215
226
|
this._listeners.add(listener);
|
|
@@ -223,7 +234,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
223
234
|
info: this.info
|
|
224
235
|
}, {
|
|
225
236
|
F: __dxlog_file2,
|
|
226
|
-
L:
|
|
237
|
+
L: 125,
|
|
227
238
|
S: this,
|
|
228
239
|
C: (f, a) => f(...a)
|
|
229
240
|
});
|
|
@@ -232,7 +243,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
232
243
|
err
|
|
233
244
|
}, {
|
|
234
245
|
F: __dxlog_file2,
|
|
235
|
-
L:
|
|
246
|
+
L: 127,
|
|
236
247
|
S: this,
|
|
237
248
|
C: (f, a) => f(...a)
|
|
238
249
|
});
|
|
@@ -246,7 +257,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
246
257
|
peerKey: this._identity.peerKey
|
|
247
258
|
}, {
|
|
248
259
|
F: __dxlog_file2,
|
|
249
|
-
L:
|
|
260
|
+
L: 135,
|
|
250
261
|
S: this,
|
|
251
262
|
C: (f, a) => f(...a)
|
|
252
263
|
});
|
|
@@ -270,7 +281,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
270
281
|
protocolHeader
|
|
271
282
|
}, {
|
|
272
283
|
F: __dxlog_file2,
|
|
273
|
-
L:
|
|
284
|
+
L: 154,
|
|
274
285
|
S: this,
|
|
275
286
|
C: (f, a) => f(...a)
|
|
276
287
|
});
|
|
@@ -280,7 +291,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
280
291
|
this._ws.onopen = () => {
|
|
281
292
|
(0, import_log.log)("opened", this.info, {
|
|
282
293
|
F: __dxlog_file2,
|
|
283
|
-
L:
|
|
294
|
+
L: 158,
|
|
284
295
|
S: this,
|
|
285
296
|
C: (f, a) => f(...a)
|
|
286
297
|
});
|
|
@@ -290,7 +301,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
290
301
|
this._ws.onclose = () => {
|
|
291
302
|
(0, import_log.log)("closed", this.info, {
|
|
292
303
|
F: __dxlog_file2,
|
|
293
|
-
L:
|
|
304
|
+
L: 163,
|
|
294
305
|
S: this,
|
|
295
306
|
C: (f, a) => f(...a)
|
|
296
307
|
});
|
|
@@ -302,7 +313,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
302
313
|
info: event.message
|
|
303
314
|
}, {
|
|
304
315
|
F: __dxlog_file2,
|
|
305
|
-
L:
|
|
316
|
+
L: 167,
|
|
306
317
|
S: this,
|
|
307
318
|
C: (f, a) => f(...a)
|
|
308
319
|
});
|
|
@@ -320,7 +331,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
320
331
|
payload: import_chunk_ANV2HBEH.protocol.getPayloadType(message)
|
|
321
332
|
}, {
|
|
322
333
|
F: __dxlog_file2,
|
|
323
|
-
L:
|
|
334
|
+
L: 180,
|
|
324
335
|
S: this,
|
|
325
336
|
C: (f, a) => f(...a)
|
|
326
337
|
});
|
|
@@ -334,7 +345,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
334
345
|
payload: import_chunk_ANV2HBEH.protocol.getPayloadType(message)
|
|
335
346
|
}, {
|
|
336
347
|
F: __dxlog_file2,
|
|
337
|
-
L:
|
|
348
|
+
L: 186,
|
|
338
349
|
S: this,
|
|
339
350
|
C: (f, a) => f(...a)
|
|
340
351
|
});
|
|
@@ -345,9 +356,18 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
345
356
|
await this._ready.wait({
|
|
346
357
|
timeout: this._config.timeout ?? DEFAULT_TIMEOUT
|
|
347
358
|
});
|
|
359
|
+
(0, import_log.log)("Websocket is ready", {
|
|
360
|
+
identity: this._identity.identityKey,
|
|
361
|
+
peer: this._identity.peerKey
|
|
362
|
+
}, {
|
|
363
|
+
F: __dxlog_file2,
|
|
364
|
+
L: 194,
|
|
365
|
+
S: this,
|
|
366
|
+
C: (f, a) => f(...a)
|
|
367
|
+
});
|
|
348
368
|
this._keepaliveCtx = new import_context.Context(void 0, {
|
|
349
369
|
F: __dxlog_file2,
|
|
350
|
-
L:
|
|
370
|
+
L: 197
|
|
351
371
|
});
|
|
352
372
|
(0, import_async.scheduleTaskInterval)(this._keepaliveCtx, async () => {
|
|
353
373
|
this._ws?.send("__ping__");
|
|
@@ -382,7 +402,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
382
402
|
err
|
|
383
403
|
}, {
|
|
384
404
|
F: __dxlog_file2,
|
|
385
|
-
L:
|
|
405
|
+
L: 233,
|
|
386
406
|
S: this,
|
|
387
407
|
C: (f, a) => f(...a)
|
|
388
408
|
});
|
|
@@ -396,7 +416,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
396
416
|
if (this._ready.state !== import_async.TriggerState.RESOLVED) {
|
|
397
417
|
(0, import_log.log)("waiting for websocket to become ready", void 0, {
|
|
398
418
|
F: __dxlog_file2,
|
|
399
|
-
L:
|
|
419
|
+
L: 243,
|
|
400
420
|
S: this,
|
|
401
421
|
C: (f, a) => f(...a)
|
|
402
422
|
});
|
|
@@ -415,7 +435,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
415
435
|
payload: import_chunk_ANV2HBEH.protocol.getPayloadType(message)
|
|
416
436
|
}, {
|
|
417
437
|
F: __dxlog_file2,
|
|
418
|
-
L:
|
|
438
|
+
L: 256,
|
|
419
439
|
S: this,
|
|
420
440
|
C: (f, a) => f(...a)
|
|
421
441
|
});
|
|
@@ -428,7 +448,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
428
448
|
void this._heartBeatContext?.dispose();
|
|
429
449
|
this._heartBeatContext = new import_context.Context(void 0, {
|
|
430
450
|
F: __dxlog_file2,
|
|
431
|
-
L:
|
|
451
|
+
L: 265
|
|
432
452
|
});
|
|
433
453
|
(0, import_async.scheduleTask)(this._heartBeatContext, () => {
|
|
434
454
|
this._persistentLifecycle.scheduleRestart();
|
|
@@ -546,11 +566,24 @@ var EdgeHttpClient = class {
|
|
|
546
566
|
url: this._baseUrl
|
|
547
567
|
}, {
|
|
548
568
|
F: __dxlog_file3,
|
|
549
|
-
L:
|
|
569
|
+
L: 33,
|
|
550
570
|
S: this,
|
|
551
571
|
C: (f, a) => f(...a)
|
|
552
572
|
});
|
|
553
573
|
}
|
|
574
|
+
createAgent(body, args) {
|
|
575
|
+
return this._call("/agents/create", {
|
|
576
|
+
...args,
|
|
577
|
+
method: "POST",
|
|
578
|
+
body
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
getAgentStatus(request, args) {
|
|
582
|
+
return this._call(`/users/${request.ownerIdentityKey.toHex()}/agent/status`, {
|
|
583
|
+
...args,
|
|
584
|
+
method: "GET"
|
|
585
|
+
});
|
|
586
|
+
}
|
|
554
587
|
getCredentialsForNotarization(spaceId, args) {
|
|
555
588
|
return this._call(`/spaces/${spaceId}/notarization`, {
|
|
556
589
|
...args,
|
|
@@ -574,17 +607,18 @@ var EdgeHttpClient = class {
|
|
|
574
607
|
async _call(path, args) {
|
|
575
608
|
const requestContext = args.context ?? new import_context3.Context(void 0, {
|
|
576
609
|
F: __dxlog_file3,
|
|
577
|
-
L:
|
|
610
|
+
L: 68
|
|
578
611
|
});
|
|
579
612
|
const shouldRetry = createRetryHandler(args);
|
|
580
613
|
const request = createRequest(args);
|
|
581
614
|
const url = `${this._baseUrl}${path.startsWith("/") ? path.slice(1) : path}`;
|
|
582
615
|
import_log3.log.info("call", {
|
|
583
616
|
method: args.method,
|
|
584
|
-
path
|
|
617
|
+
path,
|
|
618
|
+
request: args.body
|
|
585
619
|
}, {
|
|
586
620
|
F: __dxlog_file3,
|
|
587
|
-
L:
|
|
621
|
+
L: 73,
|
|
588
622
|
S: this,
|
|
589
623
|
C: (f, a) => f(...a)
|
|
590
624
|
});
|
|
@@ -599,6 +633,15 @@ var EdgeHttpClient = class {
|
|
|
599
633
|
if (body.success) {
|
|
600
634
|
return body.data;
|
|
601
635
|
}
|
|
636
|
+
import_log3.log.info("unsuccessful edge response", {
|
|
637
|
+
path,
|
|
638
|
+
body
|
|
639
|
+
}, {
|
|
640
|
+
F: __dxlog_file3,
|
|
641
|
+
L: 89,
|
|
642
|
+
S: this,
|
|
643
|
+
C: (f, a) => f(...a)
|
|
644
|
+
});
|
|
602
645
|
if (body.errorData?.type === "auth_challenge" && typeof body.errorData?.challenge === "string") {
|
|
603
646
|
processingError = new import_protocols.EdgeAuthChallengeError(body.errorData.challenge, body.errorData);
|
|
604
647
|
} else {
|
|
@@ -616,7 +659,7 @@ var EdgeHttpClient = class {
|
|
|
616
659
|
processingError
|
|
617
660
|
}, {
|
|
618
661
|
F: __dxlog_file3,
|
|
619
|
-
L:
|
|
662
|
+
L: 104,
|
|
620
663
|
S: this,
|
|
621
664
|
C: (f, a) => f(...a)
|
|
622
665
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/index.ts", "../../../src/edge-client.ts", "../../../src/errors.ts", "../../../src/persistent-lifecycle.ts", "../../../src/utils.ts", "../../../src/auth.ts", "../../../src/edge-http-client.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';\nexport * from './errors';\nexport * from './auth';\nexport * from './edge-http-client';\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 { randomBytes } from '@dxos/crypto';\nimport { log } from '@dxos/log';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { schema } from '@dxos/protocols/proto';\nimport { type Presentation } from '@dxos/protocols/proto/dxos/halo/credentials';\n\nimport { protocol } from './defs';\nimport { EdgeConnectionClosedError, EdgeIdentityChangedError } from './errors';\nimport { PersistentLifecycle } from './persistent-lifecycle';\nimport { type Protocol, toUint8Array } from './protocol';\nimport { getEdgeUrlWithProtocol } from './utils';\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 connected: Event;\n reconnect: Event;\n\n get info(): any;\n get identityKey(): string;\n get peerKey(): string;\n get isOpen(): boolean;\n get isConnected(): boolean;\n setIdentity(identity: EdgeIdentity): 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 disableAuth?: boolean;\n};\n\nexport interface EdgeIdentity {\n peerKey: string;\n identityKey: string;\n /**\n * Returns credential presentation issued by the identity key.\n * Presentation must have the provided challenge.\n * Presentation may include ServiceAccess credentials.\n */\n presentCredentials({ challenge }: { challenge: Uint8Array }): Promise<Presentation>;\n}\n\n/**\n * Messenger client.\n */\nexport class EdgeClient extends Resource implements EdgeConnection {\n public readonly reconnect = new Event();\n public readonly connected = 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 _ready = new Trigger();\n private _ws?: WebSocket = undefined;\n private _keepaliveCtx?: Context = undefined;\n private _heartBeatContext?: Context = undefined;\n\n private _baseUrl: string;\n\n constructor(\n private _identity: EdgeIdentity,\n private readonly _config: MessengerConfig,\n ) {\n super();\n this._baseUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, 'ws');\n }\n\n // TODO(burdon): Attach logging.\n public get info() {\n return {\n open: this.isOpen,\n identity: this._identity.identityKey,\n device: this._identity.peerKey,\n };\n }\n\n get isConnected() {\n return Boolean(this._ws) && this._ready.state === TriggerState.RESOLVED;\n }\n\n get identityKey() {\n return this._identity.identityKey;\n }\n\n get peerKey() {\n return this._identity.peerKey;\n }\n\n setIdentity(identity: EdgeIdentity) {\n this._identity = identity;\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._identity.peerKey });\n await this._persistentLifecycle.close();\n }\n\n private async _openWebSocket() {\n let protocolHeader: string | undefined;\n\n if (!this._config.disableAuth) {\n // TODO(dmaretskyi): Get challenge from the WWW-Authenticate header returned by the endpoint.\n const challenge = randomBytes(32);\n const credential = await this._identity.presentCredentials({ challenge });\n protocolHeader = encodePresentationIntoAuthHeader(credential);\n }\n\n if (this._ctx.disposed) {\n return;\n }\n\n const url = new URL(`/ws/${this._identity.identityKey}/${this._identity.peerKey}`, this._baseUrl);\n log('Opening websocket', { url: url.toString(), protocolHeader });\n this._ws = new WebSocket(url, protocolHeader ? [protocolHeader] : []);\n\n this._ws.onopen = () => {\n log('opened', this.info);\n this._ready.wake();\n this.connected.emit();\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._identity.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 // TODO(dmaretskyi): Potential race condition here since web socket errors don't resolve this trigger.\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n\n // TODO(dmaretskyi): Potential leak: context re-assigned without disposing the previous one.\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(this.isOpen ? new EdgeIdentityChangedError() : new EdgeConnectionClosedError());\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 log('waiting for websocket to become ready');\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n }\n if (!this._ws) {\n throw new EdgeConnectionClosedError();\n }\n if (\n message.source &&\n (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)\n ) {\n throw new EdgeIdentityChangedError();\n }\n\n log('sending...', { peerKey: this._identity.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\nconst encodePresentationIntoAuthHeader = (presentation: Presentation): string => {\n const encoded = schema.getCodecForType('dxos.halo.credentials.Presentation').encode(presentation);\n // = and / characters are not allowed in the WebSocket subprotocol header.\n const encodedToken = Buffer.from(encoded).toString('base64').replace(/=*$/, '').replaceAll('/', '|');\n\n return `base64url.bearer.authorization.dxos.org.${encodedToken}`;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport class EdgeConnectionClosedError extends Error {\n constructor() {\n super('Edge connection closed.');\n }\n}\n\nexport class EdgeIdentityChangedError extends Error {\n constructor() {\n super('Edge identity changed.');\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", "//\n// Copyright 2024 DXOS.org\n//\n\nexport const getEdgeUrlWithProtocol = (baseUrl: string, protocol: 'http' | 'ws') => {\n const isSecure = baseUrl.startsWith('https') || baseUrl.startsWith('wss');\n const url = new URL(baseUrl);\n url.protocol = protocol + (isSecure ? 's' : '');\n return url.toString();\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { createCredential, signPresentation } from '@dxos/credentials';\nimport { type Signer } from '@dxos/crypto';\nimport { Keyring } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { type Chain, type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';\n\nimport type { EdgeIdentity } from './edge-client';\n\n/**\n * Edge identity backed by a device key without a credential chain.\n */\nexport const createDeviceEdgeIdentity = async (signer: Signer, key: PublicKey): Promise<EdgeIdentity> => {\n return {\n identityKey: key.toHex(),\n peerKey: key.toHex(),\n presentCredentials: async ({ challenge }) => {\n return signPresentation({\n presentation: {\n credentials: [\n // Verifier requires at least one credential in the presentation to establish the subject.\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: key,\n subject: key,\n signer,\n }),\n ],\n },\n signer,\n signerKey: key,\n nonce: challenge,\n });\n },\n };\n};\n\n/**\n * Edge identity backed by a chain of credentials.\n */\nexport const createChainEdgeIdentity = async (\n signer: Signer,\n identityKey: PublicKey,\n peerKey: PublicKey,\n chain: Chain,\n credentials: Credential[],\n): Promise<EdgeIdentity> => {\n const credentialsToSign =\n credentials.length > 0\n ? credentials\n : [\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: identityKey,\n subject: identityKey,\n signer,\n chain,\n signingKey: peerKey,\n }),\n ];\n\n return {\n identityKey: identityKey.toHex(),\n peerKey: peerKey.toHex(),\n presentCredentials: async ({ challenge }) => {\n return signPresentation({\n presentation: {\n credentials: credentialsToSign,\n },\n signer,\n nonce: challenge,\n signerKey: peerKey,\n chain,\n });\n },\n };\n};\n\n/**\n * Edge identity backed by a random ephemeral key without HALO.\n */\nexport const createEphemeralEdgeIdentity = async (): Promise<EdgeIdentity> => {\n const keyring = new Keyring();\n const key = await keyring.createKey();\n return createDeviceEdgeIdentity(keyring, key);\n};\n\n/**\n * Creates a HALO chain of credentials to act as an edge identity.\n */\nexport const createTestHaloEdgeIdentity = async (\n signer: Signer,\n identityKey: PublicKey,\n deviceKey: PublicKey,\n): Promise<EdgeIdentity> => {\n const deviceAdmission = await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.AuthorizedDevice',\n deviceKey,\n identityKey,\n },\n issuer: identityKey,\n subject: deviceKey,\n signer,\n });\n return createChainEdgeIdentity(signer, identityKey, deviceKey, { credential: deviceAdmission }, [\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: identityKey,\n subject: identityKey,\n signer,\n }),\n ]);\n};\n\nexport const createStubEdgeIdentity = (): EdgeIdentity => {\n const identityKey = PublicKey.random();\n const deviceKey = PublicKey.random();\n return {\n identityKey: identityKey.toHex(),\n peerKey: deviceKey.toHex(),\n presentCredentials: async () => {\n throw new Error('Stub identity does not support authentication.');\n },\n };\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { sleep } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n EdgeCallFailedError,\n type EdgeHttpResponse,\n type GetNotarizationResponseBody,\n type PostNotarizationRequestBody,\n type JoinSpaceRequest,\n type JoinSpaceResponseBody,\n EdgeAuthChallengeError,\n} from '@dxos/protocols';\n\nimport { getEdgeUrlWithProtocol } from './utils';\n\nconst DEFAULT_RETRY_TIMEOUT = 1500;\nconst DEFAULT_RETRY_JITTER = 500;\nconst DEFAULT_MAX_RETRIES_COUNT = 3;\n\nexport class EdgeHttpClient {\n private readonly _baseUrl: string;\n\n constructor(baseUrl: string) {\n this._baseUrl = getEdgeUrlWithProtocol(baseUrl, 'http');\n log('created', { url: this._baseUrl });\n }\n\n public getCredentialsForNotarization(spaceId: SpaceId, args?: EdgeHttpGetArgs): Promise<GetNotarizationResponseBody> {\n return this._call(`/spaces/${spaceId}/notarization`, { ...args, method: 'GET' });\n }\n\n public async notarizeCredentials(\n spaceId: SpaceId,\n body: PostNotarizationRequestBody,\n args?: EdgeHttpGetArgs,\n ): Promise<void> {\n await this._call(`/spaces/${spaceId}/notarization`, { ...args, body, method: 'POST' });\n }\n\n public async joinSpaceByInvitation(\n spaceId: SpaceId,\n body: JoinSpaceRequest,\n args?: EdgeHttpGetArgs,\n ): Promise<JoinSpaceResponseBody> {\n return this._call(`/spaces/${spaceId}/join`, { ...args, body, method: 'POST' });\n }\n\n private async _call<T>(path: string, args: EdgeHttpCallArgs): Promise<T> {\n const requestContext = args.context ?? new Context();\n const shouldRetry = createRetryHandler(args);\n const request = createRequest(args);\n const url = `${this._baseUrl}${path.startsWith('/') ? path.slice(1) : path}`;\n\n log.info('call', { method: args.method, path });\n\n while (true) {\n let processingError: EdgeCallFailedError;\n let retryAfterHeaderValue: number = Number.NaN;\n try {\n const response = await fetch(url, request);\n\n retryAfterHeaderValue = Number(response.headers.get('Retry-After'));\n\n if (response.ok) {\n const body = (await response.json()) as EdgeHttpResponse<T>;\n if (body.success) {\n return body.data;\n }\n\n if (body.errorData?.type === 'auth_challenge' && typeof body.errorData?.challenge === 'string') {\n processingError = new EdgeAuthChallengeError(body.errorData.challenge, body.errorData);\n } else {\n processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);\n }\n } else {\n processingError = EdgeCallFailedError.fromHttpFailure(response);\n }\n } catch (error: any) {\n processingError = EdgeCallFailedError.fromProcessingFailureCause(error);\n }\n\n if (processingError.isRetryable && (await shouldRetry(requestContext, retryAfterHeaderValue))) {\n log.info('retrying edge request', { path, processingError });\n } else {\n throw processingError;\n }\n }\n }\n}\n\nconst createRequest = (args: EdgeHttpCallArgs): RequestInit => {\n return {\n method: args.method,\n body: args.body && JSON.stringify(args.body),\n };\n};\n\nconst createRetryHandler = (args: EdgeHttpCallArgs) => {\n if (!args.retry || args.retry.count < 1) {\n return async () => false;\n }\n let retries = 0;\n const maxRetries = args.retry.count ?? DEFAULT_MAX_RETRIES_COUNT;\n const baseTimeout = args.retry.timeout ?? DEFAULT_RETRY_TIMEOUT;\n const jitter = args.retry.jitter ?? DEFAULT_RETRY_JITTER;\n return async (ctx: Context, retryAfter: number) => {\n if (++retries > maxRetries || ctx.disposed) {\n return false;\n }\n\n if (retryAfter) {\n await sleep(retryAfter);\n } else {\n const timeout = baseTimeout + Math.random() * jitter;\n await sleep(timeout);\n }\n\n return true;\n };\n};\n\nexport type RetryConfig = {\n /**\n * A number of call retries, not counting the initial request.\n */\n count: number;\n /**\n * Delay before retries in ms.\n */\n timeout?: number;\n /**\n * A random amount of time before retrying to help prevent large bursts of requests.\n */\n jitter?: number;\n};\n\nexport type EdgeHttpGetArgs = { context?: Context; retry?: RetryConfig };\n\nexport type EdgeHttpPostArgs = { context?: Context; body?: any; retry?: RetryConfig };\n\ntype EdgeHttpCallArgs = {\n method: string;\n body?: any;\n context?: Context;\n retry?: RetryConfig;\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["import_async", "import_context", "import_log", "EdgeConnectionClosedError", "Error", "constructor", "EdgeIdentityChangedError", "INIT_RESTART_DELAY", "DEFAULT_MAX_RESTART_DELAY", "PersistentLifecycle", "Resource", "start", "stop", "onRestart", "maxRestartDelay", "_restartTask", "undefined", "_restartAfter", "_start", "_stop", "_onRestart", "_maxRestartDelay", "_open", "DeferredTask", "_ctx", "_restart", "err", "log", "warn", "schedule", "catch", "_close", "join", "state", "_lifecycleState", "LifecycleState", "OPEN", "cancelWithContext", "sleep", "Math", "min", "max", "warnAfterTimeout", "scheduleRestart", "synchronized", "getEdgeUrlWithProtocol", "baseUrl", "protocol", "isSecure", "startsWith", "url", "URL", "toString", "DEFAULT_TIMEOUT", "SIGNAL_KEEPALIVE_INTERVAL", "EdgeClient", "_identity", "_config", "reconnect", "Event", "connected", "_persistentLifecycle", "_openWebSocket", "_closeWebSocket", "emit", "_listeners", "Set", "_ready", "Trigger", "_ws", "_keepaliveCtx", "_heartBeatContext", "_baseUrl", "socketEndpoint", "info", "open", "isOpen", "identity", "identityKey", "device", "peerKey", "isConnected", "Boolean", "TriggerState", "RESOLVED", "setIdentity", "addListener", "listener", "add", "delete", "close", "protocolHeader", "disableAuth", "challenge", "randomBytes", "credential", "presentCredentials", "encodePresentationIntoAuthHeader", "disposed", "WebSocket", "onopen", "wake", "onclose", "onerror", "event", "error", "message", "onmessage", "data", "_onHeartbeat", "toUint8Array", "buf", "fromBinary", "MessageSchema", "payload", "getPayloadType", "wait", "timeout", "Context", "scheduleTaskInterval", "send", "throw", "reset", "dispose", "includes", "source", "toBinary", "scheduleTask", "presentation", "encoded", "schema", "getCodecForType", "encode", "encodedToken", "Buffer", "from", "replace", "replaceAll", "createDeviceEdgeIdentity", "signer", "key", "toHex", "signPresentation", "credentials", "createCredential", "assertion", "issuer", "subject", "signerKey", "nonce", "createChainEdgeIdentity", "chain", "credentialsToSign", "length", "signingKey", "createEphemeralEdgeIdentity", "keyring", "Keyring", "createKey", "createTestHaloEdgeIdentity", "deviceKey", "deviceAdmission", "createStubEdgeIdentity", "PublicKey", "random", "DEFAULT_RETRY_TIMEOUT", "DEFAULT_RETRY_JITTER", "DEFAULT_MAX_RETRIES_COUNT", "EdgeHttpClient", "
|
|
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';\nexport * from './errors';\nexport * from './auth';\nexport * from './edge-http-client';\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 { randomBytes } from '@dxos/crypto';\nimport { log } from '@dxos/log';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { schema } from '@dxos/protocols/proto';\nimport { type Presentation } from '@dxos/protocols/proto/dxos/halo/credentials';\n\nimport { protocol } from './defs';\nimport { EdgeConnectionClosedError, EdgeIdentityChangedError } from './errors';\nimport { PersistentLifecycle } from './persistent-lifecycle';\nimport { type Protocol, toUint8Array } from './protocol';\nimport { getEdgeUrlWithProtocol } from './utils';\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 connected: Event;\n reconnect: Event;\n\n get info(): any;\n get identityKey(): string;\n get peerKey(): string;\n get isOpen(): boolean;\n get isConnected(): boolean;\n setIdentity(identity: EdgeIdentity): 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 disableAuth?: boolean;\n};\n\nexport interface EdgeIdentity {\n peerKey: string;\n identityKey: string;\n /**\n * Returns credential presentation issued by the identity key.\n * Presentation must have the provided challenge.\n * Presentation may include ServiceAccess credentials.\n */\n presentCredentials({ challenge }: { challenge: Uint8Array }): Promise<Presentation>;\n}\n\n/**\n * Messenger client.\n */\nexport class EdgeClient extends Resource implements EdgeConnection {\n public readonly reconnect = new Event();\n public readonly connected = 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 _ready = new Trigger();\n private _ws?: WebSocket = undefined;\n private _keepaliveCtx?: Context = undefined;\n private _heartBeatContext?: Context = undefined;\n\n private _baseUrl: string;\n\n constructor(\n private _identity: EdgeIdentity,\n private readonly _config: MessengerConfig,\n ) {\n super();\n this._baseUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, 'ws');\n }\n\n // TODO(burdon): Attach logging.\n public get info() {\n return {\n open: this.isOpen,\n identity: this._identity.identityKey,\n device: this._identity.peerKey,\n };\n }\n\n get isConnected() {\n return Boolean(this._ws) && this._ready.state === TriggerState.RESOLVED;\n }\n\n get identityKey() {\n return this._identity.identityKey;\n }\n\n get peerKey() {\n return this._identity.peerKey;\n }\n\n setIdentity(identity: EdgeIdentity) {\n if (identity.identityKey !== this._identity.identityKey || identity.peerKey !== this._identity.peerKey) {\n log('Edge identity changed', { identity, oldIdentity: this._identity });\n this._identity = identity;\n this._persistentLifecycle.scheduleRestart();\n }\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._identity.peerKey });\n await this._persistentLifecycle.close();\n }\n\n private async _openWebSocket() {\n let protocolHeader: string | undefined;\n\n if (!this._config.disableAuth) {\n // TODO(dmaretskyi): Get challenge from the WWW-Authenticate header returned by the endpoint.\n const challenge = randomBytes(32);\n const credential = await this._identity.presentCredentials({ challenge });\n protocolHeader = encodePresentationIntoAuthHeader(credential);\n }\n\n if (this._ctx.disposed) {\n return;\n }\n\n const url = new URL(`/ws/${this._identity.identityKey}/${this._identity.peerKey}`, this._baseUrl);\n log('Opening websocket', { url: url.toString(), protocolHeader });\n this._ws = new WebSocket(url, protocolHeader ? [protocolHeader] : []);\n\n this._ws.onopen = () => {\n log('opened', this.info);\n this._ready.wake();\n this.connected.emit();\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._identity.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 // TODO(dmaretskyi): Potential race condition here since web socket errors don't resolve this trigger.\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n log('Websocket is ready', { identity: this._identity.identityKey, peer: this._identity.peerKey });\n\n // TODO(dmaretskyi): Potential leak: context re-assigned without disposing the previous one.\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(this.isOpen ? new EdgeIdentityChangedError() : new EdgeConnectionClosedError());\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 log('waiting for websocket to become ready');\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n }\n if (!this._ws) {\n throw new EdgeConnectionClosedError();\n }\n if (\n message.source &&\n (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)\n ) {\n throw new EdgeIdentityChangedError();\n }\n\n log('sending...', { peerKey: this._identity.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\nconst encodePresentationIntoAuthHeader = (presentation: Presentation): string => {\n const encoded = schema.getCodecForType('dxos.halo.credentials.Presentation').encode(presentation);\n // = and / characters are not allowed in the WebSocket subprotocol header.\n const encodedToken = Buffer.from(encoded).toString('base64').replace(/=*$/, '').replaceAll('/', '|');\n\n return `base64url.bearer.authorization.dxos.org.${encodedToken}`;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport class EdgeConnectionClosedError extends Error {\n constructor() {\n super('Edge connection closed.');\n }\n}\n\nexport class EdgeIdentityChangedError extends Error {\n constructor() {\n super('Edge identity changed.');\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", "//\n// Copyright 2024 DXOS.org\n//\n\nexport const getEdgeUrlWithProtocol = (baseUrl: string, protocol: 'http' | 'ws') => {\n const isSecure = baseUrl.startsWith('https') || baseUrl.startsWith('wss');\n const url = new URL(baseUrl);\n url.protocol = protocol + (isSecure ? 's' : '');\n return url.toString();\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { createCredential, signPresentation } from '@dxos/credentials';\nimport { type Signer } from '@dxos/crypto';\nimport { Keyring } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { type Chain, type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';\n\nimport type { EdgeIdentity } from './edge-client';\n\n/**\n * Edge identity backed by a device key without a credential chain.\n */\nexport const createDeviceEdgeIdentity = async (signer: Signer, key: PublicKey): Promise<EdgeIdentity> => {\n return {\n identityKey: key.toHex(),\n peerKey: key.toHex(),\n presentCredentials: async ({ challenge }) => {\n return signPresentation({\n presentation: {\n credentials: [\n // Verifier requires at least one credential in the presentation to establish the subject.\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: key,\n subject: key,\n signer,\n }),\n ],\n },\n signer,\n signerKey: key,\n nonce: challenge,\n });\n },\n };\n};\n\n/**\n * Edge identity backed by a chain of credentials.\n */\nexport const createChainEdgeIdentity = async (\n signer: Signer,\n identityKey: PublicKey,\n peerKey: PublicKey,\n chain: Chain,\n credentials: Credential[],\n): Promise<EdgeIdentity> => {\n const credentialsToSign =\n credentials.length > 0\n ? credentials\n : [\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: identityKey,\n subject: identityKey,\n signer,\n chain,\n signingKey: peerKey,\n }),\n ];\n\n return {\n identityKey: identityKey.toHex(),\n peerKey: peerKey.toHex(),\n presentCredentials: async ({ challenge }) => {\n return signPresentation({\n presentation: {\n credentials: credentialsToSign,\n },\n signer,\n nonce: challenge,\n signerKey: peerKey,\n chain,\n });\n },\n };\n};\n\n/**\n * Edge identity backed by a random ephemeral key without HALO.\n */\nexport const createEphemeralEdgeIdentity = async (): Promise<EdgeIdentity> => {\n const keyring = new Keyring();\n const key = await keyring.createKey();\n return createDeviceEdgeIdentity(keyring, key);\n};\n\n/**\n * Creates a HALO chain of credentials to act as an edge identity.\n */\nexport const createTestHaloEdgeIdentity = async (\n signer: Signer,\n identityKey: PublicKey,\n deviceKey: PublicKey,\n): Promise<EdgeIdentity> => {\n const deviceAdmission = await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.AuthorizedDevice',\n deviceKey,\n identityKey,\n },\n issuer: identityKey,\n subject: deviceKey,\n signer,\n });\n return createChainEdgeIdentity(signer, identityKey, deviceKey, { credential: deviceAdmission }, [\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: identityKey,\n subject: identityKey,\n signer,\n }),\n ]);\n};\n\nexport const createStubEdgeIdentity = (): EdgeIdentity => {\n const identityKey = PublicKey.random();\n const deviceKey = PublicKey.random();\n return {\n identityKey: identityKey.toHex(),\n peerKey: deviceKey.toHex(),\n presentCredentials: async () => {\n throw new Error('Stub identity does not support authentication.');\n },\n };\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { sleep } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { type PublicKey, type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n EdgeCallFailedError,\n type EdgeHttpResponse,\n type GetNotarizationResponseBody,\n type PostNotarizationRequestBody,\n type JoinSpaceRequest,\n type JoinSpaceResponseBody,\n EdgeAuthChallengeError,\n type CreateAgentResponseBody,\n type CreateAgentRequestBody,\n type GetAgentStatusResponseBody,\n} from '@dxos/protocols';\n\nimport { getEdgeUrlWithProtocol } from './utils';\n\nconst DEFAULT_RETRY_TIMEOUT = 1500;\nconst DEFAULT_RETRY_JITTER = 500;\nconst DEFAULT_MAX_RETRIES_COUNT = 3;\n\nexport class EdgeHttpClient {\n private readonly _baseUrl: string;\n\n constructor(baseUrl: string) {\n this._baseUrl = getEdgeUrlWithProtocol(baseUrl, 'http');\n log('created', { url: this._baseUrl });\n }\n\n public createAgent(body: CreateAgentRequestBody, args?: EdgeHttpGetArgs): Promise<CreateAgentResponseBody> {\n return this._call('/agents/create', { ...args, method: 'POST', body });\n }\n\n public getAgentStatus(\n request: { ownerIdentityKey: PublicKey },\n args?: EdgeHttpGetArgs,\n ): Promise<GetAgentStatusResponseBody> {\n return this._call(`/users/${request.ownerIdentityKey.toHex()}/agent/status`, { ...args, method: 'GET' });\n }\n\n public getCredentialsForNotarization(spaceId: SpaceId, args?: EdgeHttpGetArgs): Promise<GetNotarizationResponseBody> {\n return this._call(`/spaces/${spaceId}/notarization`, { ...args, method: 'GET' });\n }\n\n public async notarizeCredentials(\n spaceId: SpaceId,\n body: PostNotarizationRequestBody,\n args?: EdgeHttpGetArgs,\n ): Promise<void> {\n await this._call(`/spaces/${spaceId}/notarization`, { ...args, body, method: 'POST' });\n }\n\n public async joinSpaceByInvitation(\n spaceId: SpaceId,\n body: JoinSpaceRequest,\n args?: EdgeHttpGetArgs,\n ): Promise<JoinSpaceResponseBody> {\n return this._call(`/spaces/${spaceId}/join`, { ...args, body, method: 'POST' });\n }\n\n private async _call<T>(path: string, args: EdgeHttpCallArgs): Promise<T> {\n const requestContext = args.context ?? new Context();\n const shouldRetry = createRetryHandler(args);\n const request = createRequest(args);\n const url = `${this._baseUrl}${path.startsWith('/') ? path.slice(1) : path}`;\n\n log.info('call', { method: args.method, path, request: args.body });\n\n while (true) {\n let processingError: EdgeCallFailedError;\n let retryAfterHeaderValue: number = Number.NaN;\n try {\n const response = await fetch(url, request);\n\n retryAfterHeaderValue = Number(response.headers.get('Retry-After'));\n\n if (response.ok) {\n const body = (await response.json()) as EdgeHttpResponse<T>;\n if (body.success) {\n return body.data;\n }\n\n log.info('unsuccessful edge response', { path, body });\n\n if (body.errorData?.type === 'auth_challenge' && typeof body.errorData?.challenge === 'string') {\n processingError = new EdgeAuthChallengeError(body.errorData.challenge, body.errorData);\n } else {\n processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);\n }\n } else {\n processingError = EdgeCallFailedError.fromHttpFailure(response);\n }\n } catch (error: any) {\n processingError = EdgeCallFailedError.fromProcessingFailureCause(error);\n }\n\n if (processingError.isRetryable && (await shouldRetry(requestContext, retryAfterHeaderValue))) {\n log.info('retrying edge request', { path, processingError });\n } else {\n throw processingError;\n }\n }\n }\n}\n\nconst createRequest = (args: EdgeHttpCallArgs): RequestInit => {\n return {\n method: args.method,\n body: args.body && JSON.stringify(args.body),\n };\n};\n\nconst createRetryHandler = (args: EdgeHttpCallArgs) => {\n if (!args.retry || args.retry.count < 1) {\n return async () => false;\n }\n let retries = 0;\n const maxRetries = args.retry.count ?? DEFAULT_MAX_RETRIES_COUNT;\n const baseTimeout = args.retry.timeout ?? DEFAULT_RETRY_TIMEOUT;\n const jitter = args.retry.jitter ?? DEFAULT_RETRY_JITTER;\n return async (ctx: Context, retryAfter: number) => {\n if (++retries > maxRetries || ctx.disposed) {\n return false;\n }\n\n if (retryAfter) {\n await sleep(retryAfter);\n } else {\n const timeout = baseTimeout + Math.random() * jitter;\n await sleep(timeout);\n }\n\n return true;\n };\n};\n\nexport type RetryConfig = {\n /**\n * A number of call retries, not counting the initial request.\n */\n count: number;\n /**\n * Delay before retries in ms.\n */\n timeout?: number;\n /**\n * A random amount of time before retrying to help prevent large bursts of requests.\n */\n jitter?: number;\n};\n\nexport type EdgeHttpGetArgs = { context?: Context; retry?: RetryConfig };\n\nexport type EdgeHttpPostArgs = { context?: Context; body?: any; retry?: RetryConfig };\n\ntype EdgeHttpCallArgs = {\n method: string;\n body?: any;\n context?: Context;\n retry?: RetryConfig;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_async", "import_context", "import_log", "EdgeConnectionClosedError", "Error", "constructor", "EdgeIdentityChangedError", "INIT_RESTART_DELAY", "DEFAULT_MAX_RESTART_DELAY", "PersistentLifecycle", "Resource", "start", "stop", "onRestart", "maxRestartDelay", "_restartTask", "undefined", "_restartAfter", "_start", "_stop", "_onRestart", "_maxRestartDelay", "_open", "DeferredTask", "_ctx", "_restart", "err", "log", "warn", "schedule", "catch", "_close", "join", "state", "_lifecycleState", "LifecycleState", "OPEN", "cancelWithContext", "sleep", "Math", "min", "max", "warnAfterTimeout", "scheduleRestart", "synchronized", "getEdgeUrlWithProtocol", "baseUrl", "protocol", "isSecure", "startsWith", "url", "URL", "toString", "DEFAULT_TIMEOUT", "SIGNAL_KEEPALIVE_INTERVAL", "EdgeClient", "_identity", "_config", "reconnect", "Event", "connected", "_persistentLifecycle", "_openWebSocket", "_closeWebSocket", "emit", "_listeners", "Set", "_ready", "Trigger", "_ws", "_keepaliveCtx", "_heartBeatContext", "_baseUrl", "socketEndpoint", "info", "open", "isOpen", "identity", "identityKey", "device", "peerKey", "isConnected", "Boolean", "TriggerState", "RESOLVED", "setIdentity", "oldIdentity", "addListener", "listener", "add", "delete", "close", "protocolHeader", "disableAuth", "challenge", "randomBytes", "credential", "presentCredentials", "encodePresentationIntoAuthHeader", "disposed", "WebSocket", "onopen", "wake", "onclose", "onerror", "event", "error", "message", "onmessage", "data", "_onHeartbeat", "toUint8Array", "buf", "fromBinary", "MessageSchema", "payload", "getPayloadType", "wait", "timeout", "peer", "Context", "scheduleTaskInterval", "send", "throw", "reset", "dispose", "includes", "source", "toBinary", "scheduleTask", "presentation", "encoded", "schema", "getCodecForType", "encode", "encodedToken", "Buffer", "from", "replace", "replaceAll", "createDeviceEdgeIdentity", "signer", "key", "toHex", "signPresentation", "credentials", "createCredential", "assertion", "issuer", "subject", "signerKey", "nonce", "createChainEdgeIdentity", "chain", "credentialsToSign", "length", "signingKey", "createEphemeralEdgeIdentity", "keyring", "Keyring", "createKey", "createTestHaloEdgeIdentity", "deviceKey", "deviceAdmission", "createStubEdgeIdentity", "PublicKey", "random", "DEFAULT_RETRY_TIMEOUT", "DEFAULT_RETRY_JITTER", "DEFAULT_MAX_RETRIES_COUNT", "EdgeHttpClient", "createAgent", "body", "args", "_call", "method", "getAgentStatus", "request", "ownerIdentityKey", "getCredentialsForNotarization", "spaceId", "notarizeCredentials", "joinSpaceByInvitation", "path", "requestContext", "context", "shouldRetry", "createRetryHandler", "createRequest", "slice", "processingError", "retryAfterHeaderValue", "Number", "NaN", "response", "fetch", "headers", "get", "ok", "json", "success", "errorData", "type", "EdgeAuthChallengeError", "EdgeCallFailedError", "fromUnsuccessfulResponse", "fromHttpFailure", "fromProcessingFailureCause", "isRetryable", "JSON", "stringify", "retry", "count", "retries", "maxRetries", "baseTimeout", "jitter", "ctx", "retryAfter"]
|
|
7
7
|
}
|
package/dist/lib/node/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/core/mesh/edge-client/src/protocol.ts":{"bytes":10334,"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":1607,"imports":[{"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/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/errors.ts":{"bytes":1265,"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/utils.ts":{"bytes":1451,"imports":[],"format":"esm"},"packages/core/mesh/edge-client/src/edge-client.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/core/mesh/edge-client/src/protocol.ts":{"bytes":10334,"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":1607,"imports":[{"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/protocol.ts","kind":"import-statement","original":"./protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/errors.ts":{"bytes":1265,"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/utils.ts":{"bytes":1451,"imports":[],"format":"esm"},"packages/core/mesh/edge-client/src/edge-client.ts":{"bytes":34622,"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/crypto","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":"@dxos/protocols/proto","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"},{"path":"packages/core/mesh/edge-client/src/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/core/mesh/edge-client/src/auth.ts":{"bytes":11621,"imports":[{"path":"@dxos/credentials","kind":"import-statement","external":true},{"path":"@dxos/keyring","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/edge-client/src/edge-http-client.ts":{"bytes":17695,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"packages/core/mesh/edge-client/src/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/core/mesh/edge-client/src/index.ts":{"bytes":1127,"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"},{"path":"packages/core/mesh/edge-client/src/errors.ts","kind":"import-statement","original":"./errors"},{"path":"packages/core/mesh/edge-client/src/auth.ts","kind":"import-statement","original":"./auth"},{"path":"packages/core/mesh/edge-client/src/edge-http-client.ts","kind":"import-statement","original":"./edge-http-client"}],"format":"esm"},"packages/core/mesh/edge-client/src/testing/test-utils.ts":{"bytes":12827,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","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/protocol.ts","kind":"import-statement","original":"../protocol"}],"format":"esm"},"packages/core/mesh/edge-client/src/testing/index.ts":{"bytes":516,"imports":[{"path":"packages/core/mesh/edge-client/src/testing/test-utils.ts","kind":"import-statement","original":"./test-utils"}],"format":"esm"}},"outputs":{"packages/core/mesh/edge-client/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":37283},"packages/core/mesh/edge-client/dist/lib/node/index.cjs":{"imports":[{"path":"packages/core/mesh/edge-client/dist/lib/node/chunk-ANV2HBEH.cjs","kind":"import-statement"},{"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/crypto","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":"@dxos/protocols/proto","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},{"path":"@dxos/credentials","kind":"import-statement","external":true},{"path":"@dxos/keyring","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true}],"exports":["EdgeClient","EdgeConnectionClosedError","EdgeHttpClient","EdgeIdentityChangedError","Protocol","createChainEdgeIdentity","createDeviceEdgeIdentity","createEphemeralEdgeIdentity","createStubEdgeIdentity","createTestHaloEdgeIdentity","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":8604},"packages/core/mesh/edge-client/src/errors.ts":{"bytesInOutput":232},"packages/core/mesh/edge-client/src/persistent-lifecycle.ts":{"bytesInOutput":3015},"packages/core/mesh/edge-client/src/utils.ts":{"bytesInOutput":244},"packages/core/mesh/edge-client/src/auth.ts":{"bytesInOutput":2681},"packages/core/mesh/edge-client/src/edge-http-client.ts":{"bytesInOutput":4241}},"bytes":19925},"packages/core/mesh/edge-client/dist/lib/node/testing/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":6549},"packages/core/mesh/edge-client/dist/lib/node/testing/index.cjs":{"imports":[{"path":"packages/core/mesh/edge-client/dist/lib/node/chunk-ANV2HBEH.cjs","kind":"import-statement"},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","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}],"exports":["DEFAULT_PORT","createTestEdgeWsServer"],"entryPoint":"packages/core/mesh/edge-client/src/testing/index.ts","inputs":{"packages/core/mesh/edge-client/src/testing/test-utils.ts":{"bytesInOutput":3368},"packages/core/mesh/edge-client/src/testing/index.ts":{"bytesInOutput":0}},"bytes":3585},"packages/core/mesh/edge-client/dist/lib/node/chunk-ANV2HBEH.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":5676},"packages/core/mesh/edge-client/dist/lib/node/chunk-ANV2HBEH.cjs":{"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},{"path":"@dxos/protocols/buf","kind":"import-statement","external":true},{"path":"@dxos/protocols/buf/dxos/edge/messenger_pb","kind":"import-statement","external":true}],"exports":["Protocol","getTypename","protocol","toUint8Array"],"inputs":{"packages/core/mesh/edge-client/src/protocol.ts":{"bytesInOutput":2600},"packages/core/mesh/edge-client/src/defs.ts":{"bytesInOutput":298}},"bytes":3106}}}
|