@dxos/edge-client 0.6.12-main.89e9959 → 0.6.12-main.ac23639
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 +26 -20
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +24 -20
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +26 -20
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/edge-client.d.ts +2 -0
- package/dist/types/src/edge-client.d.ts.map +1 -1
- package/dist/types/src/edge-http-client.d.ts.map +1 -1
- package/dist/types/src/utils.d.ts +2 -0
- package/dist/types/src/utils.d.ts.map +1 -0
- package/package.json +14 -14
- package/src/edge-client.ts +7 -4
- package/src/edge-http-client.ts +3 -3
- package/src/utils.ts +10 -0
|
@@ -123,11 +123,18 @@ _ts_decorate([
|
|
|
123
123
|
synchronized
|
|
124
124
|
], PersistentLifecycle.prototype, "scheduleRestart", null);
|
|
125
125
|
|
|
126
|
+
// packages/core/mesh/edge-client/src/utils.ts
|
|
127
|
+
var getEdgeUrlWithProtocol = (baseUrl, protocol2) => {
|
|
128
|
+
const isSecure = baseUrl.startsWith("https") || baseUrl.startsWith("wss");
|
|
129
|
+
const url = new URL(baseUrl);
|
|
130
|
+
url.protocol = protocol2 + (isSecure ? "s" : "");
|
|
131
|
+
return url.toString();
|
|
132
|
+
};
|
|
133
|
+
|
|
126
134
|
// packages/core/mesh/edge-client/src/edge-client.ts
|
|
127
135
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
|
|
128
136
|
var DEFAULT_TIMEOUT = 1e4;
|
|
129
137
|
var SIGNAL_KEEPALIVE_INTERVAL = 5e3;
|
|
130
|
-
var DISABLE_AUTH = true;
|
|
131
138
|
var EdgeClient = class extends Resource2 {
|
|
132
139
|
constructor(_identity, _config) {
|
|
133
140
|
super();
|
|
@@ -145,6 +152,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
145
152
|
this._ws = void 0;
|
|
146
153
|
this._keepaliveCtx = void 0;
|
|
147
154
|
this._heartBeatContext = void 0;
|
|
155
|
+
this._baseUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "ws");
|
|
148
156
|
}
|
|
149
157
|
// TODO(burdon): Attach logging.
|
|
150
158
|
get info() {
|
|
@@ -179,7 +187,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
179
187
|
info: this.info
|
|
180
188
|
}, {
|
|
181
189
|
F: __dxlog_file2,
|
|
182
|
-
L:
|
|
190
|
+
L: 122,
|
|
183
191
|
S: this,
|
|
184
192
|
C: (f, a) => f(...a)
|
|
185
193
|
});
|
|
@@ -188,7 +196,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
188
196
|
err
|
|
189
197
|
}, {
|
|
190
198
|
F: __dxlog_file2,
|
|
191
|
-
L:
|
|
199
|
+
L: 124,
|
|
192
200
|
S: this,
|
|
193
201
|
C: (f, a) => f(...a)
|
|
194
202
|
});
|
|
@@ -202,7 +210,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
202
210
|
peerKey: this._identity.peerKey
|
|
203
211
|
}, {
|
|
204
212
|
F: __dxlog_file2,
|
|
205
|
-
L:
|
|
213
|
+
L: 132,
|
|
206
214
|
S: this,
|
|
207
215
|
C: (f, a) => f(...a)
|
|
208
216
|
});
|
|
@@ -210,20 +218,20 @@ var EdgeClient = class extends Resource2 {
|
|
|
210
218
|
}
|
|
211
219
|
async _openWebSocket() {
|
|
212
220
|
let protocolHeader;
|
|
213
|
-
if (!
|
|
221
|
+
if (!this._config.disableAuth) {
|
|
214
222
|
const challenge = randomBytes(32);
|
|
215
223
|
const credential = await this._identity.presentCredentials({
|
|
216
224
|
challenge
|
|
217
225
|
});
|
|
218
226
|
protocolHeader = encodePresentationIntoAuthHeader(credential);
|
|
219
227
|
}
|
|
220
|
-
const url = new URL(`/ws/${this._identity.identityKey}/${this._identity.peerKey}`, this.
|
|
228
|
+
const url = new URL(`/ws/${this._identity.identityKey}/${this._identity.peerKey}`, this._baseUrl);
|
|
221
229
|
log2("Opening websocket", {
|
|
222
230
|
url: url.toString(),
|
|
223
231
|
protocolHeader
|
|
224
232
|
}, {
|
|
225
233
|
F: __dxlog_file2,
|
|
226
|
-
L:
|
|
234
|
+
L: 147,
|
|
227
235
|
S: this,
|
|
228
236
|
C: (f, a) => f(...a)
|
|
229
237
|
});
|
|
@@ -233,7 +241,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
233
241
|
this._ws.onopen = () => {
|
|
234
242
|
log2("opened", this.info, {
|
|
235
243
|
F: __dxlog_file2,
|
|
236
|
-
L:
|
|
244
|
+
L: 151,
|
|
237
245
|
S: this,
|
|
238
246
|
C: (f, a) => f(...a)
|
|
239
247
|
});
|
|
@@ -243,7 +251,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
243
251
|
this._ws.onclose = () => {
|
|
244
252
|
log2("closed", this.info, {
|
|
245
253
|
F: __dxlog_file2,
|
|
246
|
-
L:
|
|
254
|
+
L: 156,
|
|
247
255
|
S: this,
|
|
248
256
|
C: (f, a) => f(...a)
|
|
249
257
|
});
|
|
@@ -255,7 +263,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
255
263
|
info: event.message
|
|
256
264
|
}, {
|
|
257
265
|
F: __dxlog_file2,
|
|
258
|
-
L:
|
|
266
|
+
L: 160,
|
|
259
267
|
S: this,
|
|
260
268
|
C: (f, a) => f(...a)
|
|
261
269
|
});
|
|
@@ -273,7 +281,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
273
281
|
payload: protocol.getPayloadType(message)
|
|
274
282
|
}, {
|
|
275
283
|
F: __dxlog_file2,
|
|
276
|
-
L:
|
|
284
|
+
L: 173,
|
|
277
285
|
S: this,
|
|
278
286
|
C: (f, a) => f(...a)
|
|
279
287
|
});
|
|
@@ -287,7 +295,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
287
295
|
payload: protocol.getPayloadType(message)
|
|
288
296
|
}, {
|
|
289
297
|
F: __dxlog_file2,
|
|
290
|
-
L:
|
|
298
|
+
L: 179,
|
|
291
299
|
S: this,
|
|
292
300
|
C: (f, a) => f(...a)
|
|
293
301
|
});
|
|
@@ -300,7 +308,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
300
308
|
});
|
|
301
309
|
this._keepaliveCtx = new Context(void 0, {
|
|
302
310
|
F: __dxlog_file2,
|
|
303
|
-
L:
|
|
311
|
+
L: 189
|
|
304
312
|
});
|
|
305
313
|
scheduleTaskInterval(this._keepaliveCtx, async () => {
|
|
306
314
|
this._ws?.send("__ping__");
|
|
@@ -335,7 +343,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
335
343
|
err
|
|
336
344
|
}, {
|
|
337
345
|
F: __dxlog_file2,
|
|
338
|
-
L:
|
|
346
|
+
L: 225,
|
|
339
347
|
S: this,
|
|
340
348
|
C: (f, a) => f(...a)
|
|
341
349
|
});
|
|
@@ -349,7 +357,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
349
357
|
if (this._ready.state !== TriggerState.RESOLVED) {
|
|
350
358
|
log2("waiting for websocket to become ready", void 0, {
|
|
351
359
|
F: __dxlog_file2,
|
|
352
|
-
L:
|
|
360
|
+
L: 235,
|
|
353
361
|
S: this,
|
|
354
362
|
C: (f, a) => f(...a)
|
|
355
363
|
});
|
|
@@ -368,7 +376,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
368
376
|
payload: protocol.getPayloadType(message)
|
|
369
377
|
}, {
|
|
370
378
|
F: __dxlog_file2,
|
|
371
|
-
L:
|
|
379
|
+
L: 248,
|
|
372
380
|
S: this,
|
|
373
381
|
C: (f, a) => f(...a)
|
|
374
382
|
});
|
|
@@ -381,7 +389,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
381
389
|
void this._heartBeatContext?.dispose();
|
|
382
390
|
this._heartBeatContext = new Context(void 0, {
|
|
383
391
|
F: __dxlog_file2,
|
|
384
|
-
L:
|
|
392
|
+
L: 257
|
|
385
393
|
});
|
|
386
394
|
scheduleTask(this._heartBeatContext, () => {
|
|
387
395
|
this._persistentLifecycle.scheduleRestart();
|
|
@@ -505,9 +513,7 @@ var DEFAULT_RETRY_JITTER = 500;
|
|
|
505
513
|
var DEFAULT_MAX_RETRIES_COUNT = 3;
|
|
506
514
|
var EdgeHttpClient = class {
|
|
507
515
|
constructor(baseUrl) {
|
|
508
|
-
|
|
509
|
-
url.protocol = "https";
|
|
510
|
-
this._baseUrl = url.toString();
|
|
516
|
+
this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
|
|
511
517
|
log3("created", {
|
|
512
518
|
url: this._baseUrl
|
|
513
519
|
}, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/index.ts", "../../../src/edge-client.ts", "../../../src/errors.ts", "../../../src/persistent-lifecycle.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';\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};\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\nconst DISABLE_AUTH = true;\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 constructor(\n private _identity: EdgeIdentity,\n private readonly _config: MessengerConfig,\n ) {\n super();\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 (!DISABLE_AUTH) {\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 const url = new URL(`/ws/${this._identity.identityKey}/${this._identity.peerKey}`, this._config.socketEndpoint);\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\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} from '@dxos/protocols';\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 const url = new URL(baseUrl);\n url.protocol = 'https';\n this._baseUrl = url.toString();\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 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 const isNonRetryable = body.errorData != null;\n if (isNonRetryable) {\n throw new EdgeCallFailedError(body.reason, body.errorData);\n }\n\n processingError = new EdgeCallFailedError(body.reason);\n } else {\n processingError = EdgeCallFailedError.fromFailureResponse(response);\n if (!isRetryable(response.status)) {\n throw processingError;\n }\n }\n } catch (error: any) {\n processingError = EdgeCallFailedError.fromProcessingFailureCause(error);\n }\n\n if (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 isRetryable = (status: number) => {\n if (status === 501) {\n // Not Implemented\n return false;\n }\n // TODO: handle 401 Not Authorized\n return !(status >= 400 && status < 500);\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": ";;;;;;;;AAIA,cAAc;;;ACAd,OAAOA,eAAe;AAEtB,SAASC,SAASC,OAAOC,sBAAsBC,cAAcC,oBAAoB;AACjF,SAASC,SAASC,kBAAAA,iBAAgBC,YAAAA,iBAAgC;AAClE,SAASC,mBAAmB;AAC5B,SAASC,OAAAA,YAAW;AACpB,SAASC,WAAW;AACpB,SAAuBC,qBAAqB;AAC5C,SAASC,cAAc;;;ACRhB,IAAMC,4BAAN,cAAwCC,MAAAA;EAC7CC,cAAc;AACZ,UAAM,yBAAA;EACR;AACF;AAEO,IAAMC,2BAAN,cAAuCF,MAAAA;EAC5CC,cAAc;AACZ,UAAM,wBAAA;EACR;AACF;;;ACVA,SAASE,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
|
|
6
|
-
"names": ["WebSocket", "Trigger", "Event", "scheduleTaskInterval", "scheduleTask", "TriggerState", "Context", "LifecycleState", "Resource", "randomBytes", "log", "buf", "MessageSchema", "schema", "EdgeConnectionClosedError", "Error", "constructor", "EdgeIdentityChangedError", "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", "
|
|
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 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} 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 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 const isNonRetryable = body.errorData != null;\n if (isNonRetryable) {\n throw new EdgeCallFailedError(body.reason, body.errorData);\n }\n\n processingError = new EdgeCallFailedError(body.reason);\n } else {\n processingError = EdgeCallFailedError.fromFailureResponse(response);\n if (!isRetryable(response.status)) {\n throw processingError;\n }\n }\n } catch (error: any) {\n processingError = EdgeCallFailedError.fromProcessingFailureCause(error);\n }\n\n if (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 isRetryable = (status: number) => {\n if (status === 501) {\n // Not Implemented\n return false;\n }\n // TODO: handle 401 Not Authorized\n return !(status >= 400 && status < 500);\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": ["WebSocket", "Trigger", "Event", "scheduleTaskInterval", "scheduleTask", "TriggerState", "Context", "LifecycleState", "Resource", "randomBytes", "log", "buf", "MessageSchema", "schema", "EdgeConnectionClosedError", "Error", "constructor", "EdgeIdentityChangedError", "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", "getEdgeUrlWithProtocol", "baseUrl", "protocol", "isSecure", "startsWith", "url", "URL", "toString", "DEFAULT_TIMEOUT", "SIGNAL_KEEPALIVE_INTERVAL", "EdgeClient", "Resource", "constructor", "_identity", "_config", "reconnect", "Event", "connected", "_persistentLifecycle", "PersistentLifecycle", "start", "_openWebSocket", "stop", "_closeWebSocket", "onRestart", "emit", "_listeners", "Set", "_ready", "Trigger", "_ws", "undefined", "_keepaliveCtx", "_heartBeatContext", "_baseUrl", "getEdgeUrlWithProtocol", "socketEndpoint", "info", "open", "isOpen", "identity", "identityKey", "device", "peerKey", "isConnected", "Boolean", "state", "TriggerState", "RESOLVED", "setIdentity", "scheduleRestart", "addListener", "listener", "add", "delete", "_open", "log", "catch", "err", "warn", "_close", "close", "protocolHeader", "disableAuth", "challenge", "randomBytes", "credential", "presentCredentials", "encodePresentationIntoAuthHeader", "url", "URL", "toString", "WebSocket", "onopen", "wake", "onclose", "onerror", "event", "error", "message", "onmessage", "data", "_onHeartbeat", "toUint8Array", "buf", "fromBinary", "MessageSchema", "payload", "protocol", "getPayloadType", "wait", "timeout", "Context", "scheduleTaskInterval", "send", "throw", "EdgeIdentityChangedError", "EdgeConnectionClosedError", "reset", "dispose", "Error", "includes", "source", "toBinary", "_lifecycleState", "LifecycleState", "OPEN", "scheduleTask", "presentation", "encoded", "schema", "getCodecForType", "encode", "encodedToken", "Buffer", "from", "replace", "replaceAll", "createCredential", "signPresentation", "Keyring", "PublicKey", "createDeviceEdgeIdentity", "signer", "key", "identityKey", "toHex", "peerKey", "presentCredentials", "challenge", "signPresentation", "presentation", "credentials", "createCredential", "assertion", "issuer", "subject", "signerKey", "nonce", "createChainEdgeIdentity", "chain", "credentialsToSign", "length", "signingKey", "createEphemeralEdgeIdentity", "keyring", "Keyring", "createKey", "createTestHaloEdgeIdentity", "deviceKey", "deviceAdmission", "credential", "createStubEdgeIdentity", "PublicKey", "random", "Error", "sleep", "Context", "log", "EdgeCallFailedError", "DEFAULT_RETRY_TIMEOUT", "DEFAULT_RETRY_JITTER", "DEFAULT_MAX_RETRIES_COUNT", "EdgeHttpClient", "constructor", "baseUrl", "_baseUrl", "getEdgeUrlWithProtocol", "log", "url", "getCredentialsForNotarization", "spaceId", "args", "_call", "method", "notarizeCredentials", "body", "path", "requestContext", "context", "Context", "shouldRetry", "createRetryHandler", "request", "createRequest", "startsWith", "slice", "info", "processingError", "retryAfterHeaderValue", "Number", "NaN", "response", "fetch", "headers", "get", "ok", "json", "success", "data", "isNonRetryable", "errorData", "EdgeCallFailedError", "reason", "fromFailureResponse", "isRetryable", "status", "error", "fromProcessingFailureCause", "JSON", "stringify", "retry", "count", "retries", "maxRetries", "baseTimeout", "timeout", "jitter", "ctx", "retryAfter", "disposed", "sleep", "Math", "random"]
|
|
7
7
|
}
|
|
@@ -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/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":32878,"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":15148,"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":12455,"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/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":35317},"packages/core/mesh/edge-client/dist/lib/browser/index.mjs":{"imports":[{"path":"packages/core/mesh/edge-client/dist/lib/browser/chunk-ZWJXA37R.mjs","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":8024},"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":3612}},"bytes":18716},"packages/core/mesh/edge-client/dist/lib/browser/testing/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":6341},"packages/core/mesh/edge-client/dist/lib/browser/testing/index.mjs":{"imports":[{"path":"packages/core/mesh/edge-client/dist/lib/browser/chunk-ZWJXA37R.mjs","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":3276},"packages/core/mesh/edge-client/src/testing/index.ts":{"bytesInOutput":0}},"bytes":3493},"packages/core/mesh/edge-client/dist/lib/browser/chunk-ZWJXA37R.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":5676},"packages/core/mesh/edge-client/dist/lib/browser/chunk-ZWJXA37R.mjs":{"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}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -162,10 +162,15 @@ _ts_decorate([
|
|
|
162
162
|
_ts_decorate([
|
|
163
163
|
import_async2.synchronized
|
|
164
164
|
], PersistentLifecycle.prototype, "scheduleRestart", null);
|
|
165
|
+
var getEdgeUrlWithProtocol = (baseUrl, protocol2) => {
|
|
166
|
+
const isSecure = baseUrl.startsWith("https") || baseUrl.startsWith("wss");
|
|
167
|
+
const url = new URL(baseUrl);
|
|
168
|
+
url.protocol = protocol2 + (isSecure ? "s" : "");
|
|
169
|
+
return url.toString();
|
|
170
|
+
};
|
|
165
171
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
|
|
166
172
|
var DEFAULT_TIMEOUT = 1e4;
|
|
167
173
|
var SIGNAL_KEEPALIVE_INTERVAL = 5e3;
|
|
168
|
-
var DISABLE_AUTH = true;
|
|
169
174
|
var EdgeClient = class extends import_context.Resource {
|
|
170
175
|
constructor(_identity, _config) {
|
|
171
176
|
super();
|
|
@@ -183,6 +188,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
183
188
|
this._ws = void 0;
|
|
184
189
|
this._keepaliveCtx = void 0;
|
|
185
190
|
this._heartBeatContext = void 0;
|
|
191
|
+
this._baseUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "ws");
|
|
186
192
|
}
|
|
187
193
|
// TODO(burdon): Attach logging.
|
|
188
194
|
get info() {
|
|
@@ -217,7 +223,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
217
223
|
info: this.info
|
|
218
224
|
}, {
|
|
219
225
|
F: __dxlog_file2,
|
|
220
|
-
L:
|
|
226
|
+
L: 122,
|
|
221
227
|
S: this,
|
|
222
228
|
C: (f, a) => f(...a)
|
|
223
229
|
});
|
|
@@ -226,7 +232,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
226
232
|
err
|
|
227
233
|
}, {
|
|
228
234
|
F: __dxlog_file2,
|
|
229
|
-
L:
|
|
235
|
+
L: 124,
|
|
230
236
|
S: this,
|
|
231
237
|
C: (f, a) => f(...a)
|
|
232
238
|
});
|
|
@@ -240,7 +246,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
240
246
|
peerKey: this._identity.peerKey
|
|
241
247
|
}, {
|
|
242
248
|
F: __dxlog_file2,
|
|
243
|
-
L:
|
|
249
|
+
L: 132,
|
|
244
250
|
S: this,
|
|
245
251
|
C: (f, a) => f(...a)
|
|
246
252
|
});
|
|
@@ -248,20 +254,20 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
248
254
|
}
|
|
249
255
|
async _openWebSocket() {
|
|
250
256
|
let protocolHeader;
|
|
251
|
-
if (!
|
|
257
|
+
if (!this._config.disableAuth) {
|
|
252
258
|
const challenge = (0, import_crypto.randomBytes)(32);
|
|
253
259
|
const credential = await this._identity.presentCredentials({
|
|
254
260
|
challenge
|
|
255
261
|
});
|
|
256
262
|
protocolHeader = encodePresentationIntoAuthHeader(credential);
|
|
257
263
|
}
|
|
258
|
-
const url = new URL(`/ws/${this._identity.identityKey}/${this._identity.peerKey}`, this.
|
|
264
|
+
const url = new URL(`/ws/${this._identity.identityKey}/${this._identity.peerKey}`, this._baseUrl);
|
|
259
265
|
(0, import_log.log)("Opening websocket", {
|
|
260
266
|
url: url.toString(),
|
|
261
267
|
protocolHeader
|
|
262
268
|
}, {
|
|
263
269
|
F: __dxlog_file2,
|
|
264
|
-
L:
|
|
270
|
+
L: 147,
|
|
265
271
|
S: this,
|
|
266
272
|
C: (f, a) => f(...a)
|
|
267
273
|
});
|
|
@@ -271,7 +277,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
271
277
|
this._ws.onopen = () => {
|
|
272
278
|
(0, import_log.log)("opened", this.info, {
|
|
273
279
|
F: __dxlog_file2,
|
|
274
|
-
L:
|
|
280
|
+
L: 151,
|
|
275
281
|
S: this,
|
|
276
282
|
C: (f, a) => f(...a)
|
|
277
283
|
});
|
|
@@ -281,7 +287,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
281
287
|
this._ws.onclose = () => {
|
|
282
288
|
(0, import_log.log)("closed", this.info, {
|
|
283
289
|
F: __dxlog_file2,
|
|
284
|
-
L:
|
|
290
|
+
L: 156,
|
|
285
291
|
S: this,
|
|
286
292
|
C: (f, a) => f(...a)
|
|
287
293
|
});
|
|
@@ -293,7 +299,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
293
299
|
info: event.message
|
|
294
300
|
}, {
|
|
295
301
|
F: __dxlog_file2,
|
|
296
|
-
L:
|
|
302
|
+
L: 160,
|
|
297
303
|
S: this,
|
|
298
304
|
C: (f, a) => f(...a)
|
|
299
305
|
});
|
|
@@ -311,7 +317,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
311
317
|
payload: import_chunk_ANV2HBEH.protocol.getPayloadType(message)
|
|
312
318
|
}, {
|
|
313
319
|
F: __dxlog_file2,
|
|
314
|
-
L:
|
|
320
|
+
L: 173,
|
|
315
321
|
S: this,
|
|
316
322
|
C: (f, a) => f(...a)
|
|
317
323
|
});
|
|
@@ -325,7 +331,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
325
331
|
payload: import_chunk_ANV2HBEH.protocol.getPayloadType(message)
|
|
326
332
|
}, {
|
|
327
333
|
F: __dxlog_file2,
|
|
328
|
-
L:
|
|
334
|
+
L: 179,
|
|
329
335
|
S: this,
|
|
330
336
|
C: (f, a) => f(...a)
|
|
331
337
|
});
|
|
@@ -338,7 +344,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
338
344
|
});
|
|
339
345
|
this._keepaliveCtx = new import_context.Context(void 0, {
|
|
340
346
|
F: __dxlog_file2,
|
|
341
|
-
L:
|
|
347
|
+
L: 189
|
|
342
348
|
});
|
|
343
349
|
(0, import_async.scheduleTaskInterval)(this._keepaliveCtx, async () => {
|
|
344
350
|
this._ws?.send("__ping__");
|
|
@@ -373,7 +379,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
373
379
|
err
|
|
374
380
|
}, {
|
|
375
381
|
F: __dxlog_file2,
|
|
376
|
-
L:
|
|
382
|
+
L: 225,
|
|
377
383
|
S: this,
|
|
378
384
|
C: (f, a) => f(...a)
|
|
379
385
|
});
|
|
@@ -387,7 +393,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
387
393
|
if (this._ready.state !== import_async.TriggerState.RESOLVED) {
|
|
388
394
|
(0, import_log.log)("waiting for websocket to become ready", void 0, {
|
|
389
395
|
F: __dxlog_file2,
|
|
390
|
-
L:
|
|
396
|
+
L: 235,
|
|
391
397
|
S: this,
|
|
392
398
|
C: (f, a) => f(...a)
|
|
393
399
|
});
|
|
@@ -406,7 +412,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
406
412
|
payload: import_chunk_ANV2HBEH.protocol.getPayloadType(message)
|
|
407
413
|
}, {
|
|
408
414
|
F: __dxlog_file2,
|
|
409
|
-
L:
|
|
415
|
+
L: 248,
|
|
410
416
|
S: this,
|
|
411
417
|
C: (f, a) => f(...a)
|
|
412
418
|
});
|
|
@@ -419,7 +425,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
419
425
|
void this._heartBeatContext?.dispose();
|
|
420
426
|
this._heartBeatContext = new import_context.Context(void 0, {
|
|
421
427
|
F: __dxlog_file2,
|
|
422
|
-
L:
|
|
428
|
+
L: 257
|
|
423
429
|
});
|
|
424
430
|
(0, import_async.scheduleTask)(this._heartBeatContext, () => {
|
|
425
431
|
this._persistentLifecycle.scheduleRestart();
|
|
@@ -532,9 +538,7 @@ var DEFAULT_RETRY_JITTER = 500;
|
|
|
532
538
|
var DEFAULT_MAX_RETRIES_COUNT = 3;
|
|
533
539
|
var EdgeHttpClient = class {
|
|
534
540
|
constructor(baseUrl) {
|
|
535
|
-
|
|
536
|
-
url.protocol = "https";
|
|
537
|
-
this._baseUrl = url.toString();
|
|
541
|
+
this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
|
|
538
542
|
(0, import_log3.log)("created", {
|
|
539
543
|
url: this._baseUrl
|
|
540
544
|
}, {
|