@dxos/edge-client 0.6.13-main.ed424a1 → 0.6.13-staging.1e988a3

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.
Files changed (58) hide show
  1. package/dist/lib/browser/index.mjs +179 -391
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +176 -390
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/types/src/defs.d.ts.map +1 -1
  8. package/dist/types/src/edge-client.d.ts +13 -24
  9. package/dist/types/src/edge-client.d.ts.map +1 -1
  10. package/dist/types/src/errors.d.ts +1 -4
  11. package/dist/types/src/errors.d.ts.map +1 -1
  12. package/dist/types/src/index.d.ts +0 -3
  13. package/dist/types/src/index.d.ts.map +1 -1
  14. package/dist/types/src/protocol.d.ts +2 -2
  15. package/dist/types/src/protocol.d.ts.map +1 -1
  16. package/dist/types/src/test-utils.d.ts +11 -0
  17. package/dist/types/src/test-utils.d.ts.map +1 -0
  18. package/package.json +14 -29
  19. package/src/defs.ts +3 -2
  20. package/src/edge-client.test.ts +18 -50
  21. package/src/edge-client.ts +24 -84
  22. package/src/errors.ts +2 -8
  23. package/src/index.ts +0 -3
  24. package/src/persistent-lifecycle.test.ts +2 -2
  25. package/src/protocol.test.ts +2 -1
  26. package/src/protocol.ts +2 -2
  27. package/src/test-utils.ts +49 -0
  28. package/src/websocket.test.ts +4 -5
  29. package/dist/lib/browser/chunk-ZWJXA37R.mjs +0 -113
  30. package/dist/lib/browser/chunk-ZWJXA37R.mjs.map +0 -7
  31. package/dist/lib/browser/testing/index.mjs +0 -125
  32. package/dist/lib/browser/testing/index.mjs.map +0 -7
  33. package/dist/lib/node/chunk-ANV2HBEH.cjs +0 -136
  34. package/dist/lib/node/chunk-ANV2HBEH.cjs.map +0 -7
  35. package/dist/lib/node/testing/index.cjs +0 -155
  36. package/dist/lib/node/testing/index.cjs.map +0 -7
  37. package/dist/lib/node-esm/chunk-HNVT57AU.mjs +0 -115
  38. package/dist/lib/node-esm/chunk-HNVT57AU.mjs.map +0 -7
  39. package/dist/lib/node-esm/index.mjs +0 -690
  40. package/dist/lib/node-esm/index.mjs.map +0 -7
  41. package/dist/lib/node-esm/meta.json +0 -1
  42. package/dist/lib/node-esm/testing/index.mjs +0 -126
  43. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  44. package/dist/types/src/auth.d.ts +0 -22
  45. package/dist/types/src/auth.d.ts.map +0 -1
  46. package/dist/types/src/edge-http-client.d.ts +0 -39
  47. package/dist/types/src/edge-http-client.d.ts.map +0 -1
  48. package/dist/types/src/testing/index.d.ts +0 -2
  49. package/dist/types/src/testing/index.d.ts.map +0 -1
  50. package/dist/types/src/testing/test-utils.d.ts +0 -21
  51. package/dist/types/src/testing/test-utils.d.ts.map +0 -1
  52. package/dist/types/src/utils.d.ts +0 -2
  53. package/dist/types/src/utils.d.ts.map +0 -1
  54. package/src/auth.ts +0 -135
  55. package/src/edge-http-client.ts +0 -167
  56. package/src/testing/index.ts +0 -5
  57. package/src/testing/test-utils.ts +0 -114
  58. package/src/utils.ts +0 -10
@@ -1,10 +1,3 @@
1
- import {
2
- Protocol,
3
- getTypename,
4
- protocol,
5
- toUint8Array
6
- } from "./chunk-ZWJXA37R.mjs";
7
-
8
1
  // packages/core/mesh/edge-client/src/index.ts
9
2
  export * from "@dxos/protocols/buf/dxos/edge/messenger_pb";
10
3
 
@@ -12,21 +5,123 @@ export * from "@dxos/protocols/buf/dxos/edge/messenger_pb";
12
5
  import WebSocket from "isomorphic-ws";
13
6
  import { Trigger, Event, scheduleTaskInterval, scheduleTask, TriggerState } from "@dxos/async";
14
7
  import { Context, LifecycleState as LifecycleState2, Resource as Resource2 } from "@dxos/context";
15
- import { randomBytes } from "@dxos/crypto";
8
+ import { invariant as invariant2 } from "@dxos/invariant";
16
9
  import { log as log2 } from "@dxos/log";
17
- import { buf } from "@dxos/protocols/buf";
18
- import { MessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
19
- import { schema } from "@dxos/protocols/proto";
10
+ import { buf as buf2 } from "@dxos/protocols/buf";
11
+ import { MessageSchema as MessageSchema2 } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
20
12
 
21
- // packages/core/mesh/edge-client/src/errors.ts
22
- var EdgeConnectionClosedError = class extends Error {
23
- constructor() {
24
- super("Edge connection closed.");
13
+ // packages/core/mesh/edge-client/src/defs.ts
14
+ import { AnySchema } from "@bufbuild/protobuf/wkt";
15
+ import { SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
16
+
17
+ // packages/core/mesh/edge-client/src/protocol.ts
18
+ import { invariant } from "@dxos/invariant";
19
+ import { buf, bufWkt } from "@dxos/protocols/buf";
20
+ import { MessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
21
+ import { bufferToArray } from "@dxos/util";
22
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/protocol.ts";
23
+ var getTypename = (typeName) => `type.googleapis.com/${typeName}`;
24
+ var Protocol = class {
25
+ constructor(types) {
26
+ this._typeRegistry = buf.createRegistry(...types);
27
+ }
28
+ get typeRegistry() {
29
+ return this._typeRegistry;
30
+ }
31
+ toJson(message) {
32
+ try {
33
+ return buf.toJson(MessageSchema, message, {
34
+ registry: this.typeRegistry
35
+ });
36
+ } catch (err) {
37
+ return {
38
+ type: this.getPayloadType(message)
39
+ };
40
+ }
41
+ }
42
+ /**
43
+ * Return the payload with the given type.
44
+ */
45
+ getPayload(message, type) {
46
+ invariant(message.payload, void 0, {
47
+ F: __dxlog_file,
48
+ L: 40,
49
+ S: this,
50
+ A: [
51
+ "message.payload",
52
+ ""
53
+ ]
54
+ });
55
+ const payloadTypename = this.getPayloadType(message);
56
+ if (type && type.typeName !== payloadTypename) {
57
+ throw new Error(`Unexpected payload type: ${payloadTypename}; expected ${type.typeName}`);
58
+ }
59
+ invariant(bufWkt.anyIs(message.payload, type), `Unexpected payload type: ${payloadTypename}}`, {
60
+ F: __dxlog_file,
61
+ L: 46,
62
+ S: this,
63
+ A: [
64
+ "bufWkt.anyIs(message.payload, type)",
65
+ "`Unexpected payload type: ${payloadTypename}}`"
66
+ ]
67
+ });
68
+ const payload = bufWkt.anyUnpack(message.payload, this.typeRegistry);
69
+ invariant(payload, `Empty payload: ${payloadTypename}}`, {
70
+ F: __dxlog_file,
71
+ L: 48,
72
+ S: this,
73
+ A: [
74
+ "payload",
75
+ "`Empty payload: ${payloadTypename}}`"
76
+ ]
77
+ });
78
+ return payload;
79
+ }
80
+ /**
81
+ * Get the payload type.
82
+ */
83
+ getPayloadType(message) {
84
+ if (!message.payload) {
85
+ return void 0;
86
+ }
87
+ const [, type] = message.payload.typeUrl.split("/");
88
+ return type;
89
+ }
90
+ /**
91
+ * Create a packed message.
92
+ */
93
+ createMessage(type, { source, target, payload, serviceId }) {
94
+ return buf.create(MessageSchema, {
95
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
96
+ source,
97
+ target,
98
+ serviceId,
99
+ payload: payload ? bufWkt.anyPack(type, buf.create(type, payload)) : void 0
100
+ });
25
101
  }
26
102
  };
27
- var EdgeIdentityChangedError = class extends Error {
103
+ var toUint8Array = async (data) => {
104
+ if (data instanceof Buffer) {
105
+ return bufferToArray(data);
106
+ }
107
+ if (data instanceof Blob) {
108
+ return new Uint8Array(await data.arrayBuffer());
109
+ }
110
+ throw new Error(`Unexpected datatype: ${data}`);
111
+ };
112
+
113
+ // packages/core/mesh/edge-client/src/defs.ts
114
+ var protocol = new Protocol([
115
+ SwarmRequestSchema,
116
+ SwarmResponseSchema,
117
+ TextMessageSchema,
118
+ AnySchema
119
+ ]);
120
+
121
+ // packages/core/mesh/edge-client/src/errors.ts
122
+ var WebsocketClosedError = class extends Error {
28
123
  constructor() {
29
- super("Edge identity changed.");
124
+ super("WebSocket connection closed");
30
125
  }
31
126
  };
32
127
 
@@ -41,7 +136,7 @@ function _ts_decorate(decorators, target, key, desc) {
41
136
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
42
137
  return c > 3 && r && Object.defineProperty(target, key, r), r;
43
138
  }
44
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/persistent-lifecycle.ts";
139
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/persistent-lifecycle.ts";
45
140
  var INIT_RESTART_DELAY = 100;
46
141
  var DEFAULT_MAX_RESTART_DELAY = 5e3;
47
142
  var PersistentLifecycle = class extends Resource {
@@ -62,7 +157,7 @@ var PersistentLifecycle = class extends Resource {
62
157
  log.warn("Restart failed", {
63
158
  err
64
159
  }, {
65
- F: __dxlog_file,
160
+ F: __dxlog_file2,
66
161
  L: 64,
67
162
  S: this,
68
163
  C: (f, a) => f(...a)
@@ -74,7 +169,7 @@ var PersistentLifecycle = class extends Resource {
74
169
  log.warn("Start failed", {
75
170
  err
76
171
  }, {
77
- F: __dxlog_file,
172
+ F: __dxlog_file2,
78
173
  L: 69,
79
174
  S: this,
80
175
  C: (f, a) => f(...a)
@@ -91,7 +186,7 @@ var PersistentLifecycle = class extends Resource {
91
186
  log(`restarting in ${this._restartAfter}ms`, {
92
187
  state: this._lifecycleState
93
188
  }, {
94
- F: __dxlog_file,
189
+ F: __dxlog_file2,
95
190
  L: 81,
96
191
  S: this,
97
192
  C: (f, a) => f(...a)
@@ -123,25 +218,17 @@ _ts_decorate([
123
218
  synchronized
124
219
  ], PersistentLifecycle.prototype, "scheduleRestart", null);
125
220
 
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
-
134
221
  // packages/core/mesh/edge-client/src/edge-client.ts
135
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
222
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
136
223
  var DEFAULT_TIMEOUT = 1e4;
137
224
  var SIGNAL_KEEPALIVE_INTERVAL = 5e3;
138
225
  var EdgeClient = class extends Resource2 {
139
- constructor(_identity, _config) {
226
+ constructor(_identityKey, _peerKey, _config) {
140
227
  super();
141
- this._identity = _identity;
228
+ this._identityKey = _identityKey;
229
+ this._peerKey = _peerKey;
142
230
  this._config = _config;
143
231
  this.reconnect = new Event();
144
- this.connected = new Event();
145
232
  this._persistentLifecycle = new PersistentLifecycle({
146
233
  start: async () => this._openWebSocket(),
147
234
  stop: async () => this._closeWebSocket(),
@@ -152,39 +239,26 @@ var EdgeClient = class extends Resource2 {
152
239
  this._ws = void 0;
153
240
  this._keepaliveCtx = void 0;
154
241
  this._heartBeatContext = void 0;
155
- this._baseUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "ws");
242
+ this._protocol = this._config.protocol ?? protocol;
156
243
  }
157
244
  // TODO(burdon): Attach logging.
158
245
  get info() {
159
246
  return {
160
247
  open: this.isOpen,
161
- identity: this._identity.identityKey,
162
- device: this._identity.peerKey
248
+ identity: this._identityKey,
249
+ device: this._peerKey
163
250
  };
164
251
  }
165
- get isConnected() {
166
- return Boolean(this._ws) && this._ready.state === TriggerState.RESOLVED;
167
- }
168
252
  get identityKey() {
169
- return this._identity.identityKey;
253
+ return this._identityKey;
170
254
  }
171
255
  get peerKey() {
172
- return this._identity.peerKey;
256
+ return this._peerKey;
173
257
  }
174
- setIdentity(identity) {
175
- if (identity.identityKey !== this._identity.identityKey || identity.peerKey !== this._identity.peerKey) {
176
- log2("Edge identity changed", {
177
- identity,
178
- oldIdentity: this._identity
179
- }, {
180
- F: __dxlog_file2,
181
- L: 110,
182
- S: this,
183
- C: (f, a) => f(...a)
184
- });
185
- this._identity = identity;
186
- this._persistentLifecycle.scheduleRestart();
187
- }
258
+ setIdentity({ peerKey, identityKey }) {
259
+ this._peerKey = peerKey;
260
+ this._identityKey = identityKey;
261
+ this._persistentLifecycle.scheduleRestart();
188
262
  }
189
263
  addListener(listener) {
190
264
  this._listeners.add(listener);
@@ -197,8 +271,8 @@ var EdgeClient = class extends Resource2 {
197
271
  log2("opening...", {
198
272
  info: this.info
199
273
  }, {
200
- F: __dxlog_file2,
201
- L: 125,
274
+ F: __dxlog_file3,
275
+ L: 101,
202
276
  S: this,
203
277
  C: (f, a) => f(...a)
204
278
  });
@@ -206,8 +280,8 @@ var EdgeClient = class extends Resource2 {
206
280
  log2.warn("Error while opening connection", {
207
281
  err
208
282
  }, {
209
- F: __dxlog_file2,
210
- L: 127,
283
+ F: __dxlog_file3,
284
+ L: 103,
211
285
  S: this,
212
286
  C: (f, a) => f(...a)
213
287
  });
@@ -218,54 +292,31 @@ var EdgeClient = class extends Resource2 {
218
292
  */
219
293
  async _close() {
220
294
  log2("closing...", {
221
- peerKey: this._identity.peerKey
295
+ peerKey: this._peerKey
222
296
  }, {
223
- F: __dxlog_file2,
224
- L: 135,
297
+ F: __dxlog_file3,
298
+ L: 111,
225
299
  S: this,
226
300
  C: (f, a) => f(...a)
227
301
  });
228
302
  await this._persistentLifecycle.close();
229
303
  }
230
304
  async _openWebSocket() {
231
- let protocolHeader;
232
- if (!this._config.disableAuth) {
233
- const challenge = randomBytes(32);
234
- const credential = await this._identity.presentCredentials({
235
- challenge
236
- });
237
- protocolHeader = encodePresentationIntoAuthHeader(credential);
238
- }
239
- if (this._ctx.disposed) {
240
- return;
241
- }
242
- const url = new URL(`/ws/${this._identity.identityKey}/${this._identity.peerKey}`, this._baseUrl);
243
- log2("Opening websocket", {
244
- url: url.toString(),
245
- protocolHeader
246
- }, {
247
- F: __dxlog_file2,
248
- L: 154,
249
- S: this,
250
- C: (f, a) => f(...a)
251
- });
252
- this._ws = new WebSocket(url, protocolHeader ? [
253
- protocolHeader
254
- ] : []);
305
+ const url = new URL(`/ws/${this._identityKey}/${this._peerKey}`, this._config.socketEndpoint);
306
+ this._ws = new WebSocket(url);
255
307
  this._ws.onopen = () => {
256
308
  log2("opened", this.info, {
257
- F: __dxlog_file2,
258
- L: 158,
309
+ F: __dxlog_file3,
310
+ L: 120,
259
311
  S: this,
260
312
  C: (f, a) => f(...a)
261
313
  });
262
314
  this._ready.wake();
263
- this.connected.emit();
264
315
  };
265
316
  this._ws.onclose = () => {
266
317
  log2("closed", this.info, {
267
- F: __dxlog_file2,
268
- L: 163,
318
+ F: __dxlog_file3,
319
+ L: 124,
269
320
  S: this,
270
321
  C: (f, a) => f(...a)
271
322
  });
@@ -276,8 +327,8 @@ var EdgeClient = class extends Resource2 {
276
327
  error: event.error,
277
328
  info: event.message
278
329
  }, {
279
- F: __dxlog_file2,
280
- L: 167,
330
+ F: __dxlog_file3,
331
+ L: 128,
281
332
  S: this,
282
333
  C: (f, a) => f(...a)
283
334
  });
@@ -289,13 +340,13 @@ var EdgeClient = class extends Resource2 {
289
340
  return;
290
341
  }
291
342
  const data = await toUint8Array(event.data);
292
- const message = buf.fromBinary(MessageSchema, data);
343
+ const message = buf2.fromBinary(MessageSchema2, data);
293
344
  log2("received", {
294
- peerKey: this._identity.peerKey,
345
+ peerKey: this._peerKey,
295
346
  payload: protocol.getPayloadType(message)
296
347
  }, {
297
- F: __dxlog_file2,
298
- L: 180,
348
+ F: __dxlog_file3,
349
+ L: 141,
299
350
  S: this,
300
351
  C: (f, a) => f(...a)
301
352
  });
@@ -308,8 +359,8 @@ var EdgeClient = class extends Resource2 {
308
359
  err,
309
360
  payload: protocol.getPayloadType(message)
310
361
  }, {
311
- F: __dxlog_file2,
312
- L: 186,
362
+ F: __dxlog_file3,
363
+ L: 147,
313
364
  S: this,
314
365
  C: (f, a) => f(...a)
315
366
  });
@@ -320,18 +371,9 @@ var EdgeClient = class extends Resource2 {
320
371
  await this._ready.wait({
321
372
  timeout: this._config.timeout ?? DEFAULT_TIMEOUT
322
373
  });
323
- log2("Websocket is ready", {
324
- identity: this._identity.identityKey,
325
- peer: this._identity.peerKey
326
- }, {
327
- F: __dxlog_file2,
328
- L: 194,
329
- S: this,
330
- C: (f, a) => f(...a)
331
- });
332
374
  this._keepaliveCtx = new Context(void 0, {
333
- F: __dxlog_file2,
334
- L: 197
375
+ F: __dxlog_file3,
376
+ L: 154
335
377
  });
336
378
  scheduleTaskInterval(this._keepaliveCtx, async () => {
337
379
  this._ws?.send("__ping__");
@@ -344,7 +386,7 @@ var EdgeClient = class extends Resource2 {
344
386
  return;
345
387
  }
346
388
  try {
347
- this._ready.throw(this.isOpen ? new EdgeIdentityChangedError() : new EdgeConnectionClosedError());
389
+ this._ready.throw(new WebsocketClosedError());
348
390
  this._ready.reset();
349
391
  void this._keepaliveCtx?.dispose();
350
392
  this._keepaliveCtx = void 0;
@@ -365,8 +407,8 @@ var EdgeClient = class extends Resource2 {
365
407
  log2.warn("Error closing websocket", {
366
408
  err
367
409
  }, {
368
- F: __dxlog_file2,
369
- L: 233,
410
+ F: __dxlog_file3,
411
+ L: 190,
370
412
  S: this,
371
413
  C: (f, a) => f(...a)
372
414
  });
@@ -378,32 +420,38 @@ var EdgeClient = class extends Resource2 {
378
420
  */
379
421
  async send(message) {
380
422
  if (this._ready.state !== TriggerState.RESOLVED) {
381
- log2("waiting for websocket to become ready", void 0, {
382
- F: __dxlog_file2,
383
- L: 243,
384
- S: this,
385
- C: (f, a) => f(...a)
386
- });
387
423
  await this._ready.wait({
388
424
  timeout: this._config.timeout ?? DEFAULT_TIMEOUT
389
425
  });
390
426
  }
391
- if (!this._ws) {
392
- throw new EdgeConnectionClosedError();
393
- }
394
- if (message.source && (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)) {
395
- throw new EdgeIdentityChangedError();
396
- }
427
+ invariant2(this._ws, void 0, {
428
+ F: __dxlog_file3,
429
+ L: 202,
430
+ S: this,
431
+ A: [
432
+ "this._ws",
433
+ ""
434
+ ]
435
+ });
436
+ invariant2(!message.source || message.source.peerKey === this._peerKey, void 0, {
437
+ F: __dxlog_file3,
438
+ L: 203,
439
+ S: this,
440
+ A: [
441
+ "!message.source || message.source.peerKey === this._peerKey",
442
+ ""
443
+ ]
444
+ });
397
445
  log2("sending...", {
398
- peerKey: this._identity.peerKey,
446
+ peerKey: this._peerKey,
399
447
  payload: protocol.getPayloadType(message)
400
448
  }, {
401
- F: __dxlog_file2,
402
- L: 256,
449
+ F: __dxlog_file3,
450
+ L: 204,
403
451
  S: this,
404
452
  C: (f, a) => f(...a)
405
453
  });
406
- this._ws.send(buf.toBinary(MessageSchema, message));
454
+ this._ws.send(buf2.toBinary(MessageSchema2, message));
407
455
  }
408
456
  _onHeartbeat() {
409
457
  if (this._lifecycleState !== LifecycleState2.OPEN) {
@@ -411,277 +459,17 @@ var EdgeClient = class extends Resource2 {
411
459
  }
412
460
  void this._heartBeatContext?.dispose();
413
461
  this._heartBeatContext = new Context(void 0, {
414
- F: __dxlog_file2,
415
- L: 265
462
+ F: __dxlog_file3,
463
+ L: 213
416
464
  });
417
465
  scheduleTask(this._heartBeatContext, () => {
418
466
  this._persistentLifecycle.scheduleRestart();
419
467
  }, 2 * SIGNAL_KEEPALIVE_INTERVAL);
420
468
  }
421
469
  };
422
- var encodePresentationIntoAuthHeader = (presentation) => {
423
- const encoded = schema.getCodecForType("dxos.halo.credentials.Presentation").encode(presentation);
424
- const encodedToken = Buffer.from(encoded).toString("base64").replace(/=*$/, "").replaceAll("/", "|");
425
- return `base64url.bearer.authorization.dxos.org.${encodedToken}`;
426
- };
427
-
428
- // packages/core/mesh/edge-client/src/auth.ts
429
- import { createCredential, signPresentation } from "@dxos/credentials";
430
- import { Keyring } from "@dxos/keyring";
431
- import { PublicKey } from "@dxos/keys";
432
- var createDeviceEdgeIdentity = async (signer, key) => {
433
- return {
434
- identityKey: key.toHex(),
435
- peerKey: key.toHex(),
436
- presentCredentials: async ({ challenge }) => {
437
- return signPresentation({
438
- presentation: {
439
- credentials: [
440
- // Verifier requires at least one credential in the presentation to establish the subject.
441
- await createCredential({
442
- assertion: {
443
- "@type": "dxos.halo.credentials.Auth"
444
- },
445
- issuer: key,
446
- subject: key,
447
- signer
448
- })
449
- ]
450
- },
451
- signer,
452
- signerKey: key,
453
- nonce: challenge
454
- });
455
- }
456
- };
457
- };
458
- var createChainEdgeIdentity = async (signer, identityKey, peerKey, chain, credentials) => {
459
- const credentialsToSign = credentials.length > 0 ? credentials : [
460
- await createCredential({
461
- assertion: {
462
- "@type": "dxos.halo.credentials.Auth"
463
- },
464
- issuer: identityKey,
465
- subject: identityKey,
466
- signer,
467
- chain,
468
- signingKey: peerKey
469
- })
470
- ];
471
- return {
472
- identityKey: identityKey.toHex(),
473
- peerKey: peerKey.toHex(),
474
- presentCredentials: async ({ challenge }) => {
475
- return signPresentation({
476
- presentation: {
477
- credentials: credentialsToSign
478
- },
479
- signer,
480
- nonce: challenge,
481
- signerKey: peerKey,
482
- chain
483
- });
484
- }
485
- };
486
- };
487
- var createEphemeralEdgeIdentity = async () => {
488
- const keyring = new Keyring();
489
- const key = await keyring.createKey();
490
- return createDeviceEdgeIdentity(keyring, key);
491
- };
492
- var createTestHaloEdgeIdentity = async (signer, identityKey, deviceKey) => {
493
- const deviceAdmission = await createCredential({
494
- assertion: {
495
- "@type": "dxos.halo.credentials.AuthorizedDevice",
496
- deviceKey,
497
- identityKey
498
- },
499
- issuer: identityKey,
500
- subject: deviceKey,
501
- signer
502
- });
503
- return createChainEdgeIdentity(signer, identityKey, deviceKey, {
504
- credential: deviceAdmission
505
- }, [
506
- await createCredential({
507
- assertion: {
508
- "@type": "dxos.halo.credentials.Auth"
509
- },
510
- issuer: identityKey,
511
- subject: identityKey,
512
- signer
513
- })
514
- ]);
515
- };
516
- var createStubEdgeIdentity = () => {
517
- const identityKey = PublicKey.random();
518
- const deviceKey = PublicKey.random();
519
- return {
520
- identityKey: identityKey.toHex(),
521
- peerKey: deviceKey.toHex(),
522
- presentCredentials: async () => {
523
- throw new Error("Stub identity does not support authentication.");
524
- }
525
- };
526
- };
527
-
528
- // packages/core/mesh/edge-client/src/edge-http-client.ts
529
- import { sleep as sleep2 } from "@dxos/async";
530
- import { Context as Context2 } from "@dxos/context";
531
- import { log as log3 } from "@dxos/log";
532
- import { EdgeCallFailedError, EdgeAuthChallengeError } from "@dxos/protocols";
533
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-http-client.ts";
534
- var DEFAULT_RETRY_TIMEOUT = 1500;
535
- var DEFAULT_RETRY_JITTER = 500;
536
- var DEFAULT_MAX_RETRIES_COUNT = 3;
537
- var EdgeHttpClient = class {
538
- constructor(baseUrl) {
539
- this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
540
- log3("created", {
541
- url: this._baseUrl
542
- }, {
543
- F: __dxlog_file3,
544
- L: 33,
545
- S: this,
546
- C: (f, a) => f(...a)
547
- });
548
- }
549
- createAgent(body, args) {
550
- return this._call("/agents/create", {
551
- ...args,
552
- method: "POST",
553
- body
554
- });
555
- }
556
- getAgentStatus(request, args) {
557
- return this._call(`/users/${request.ownerIdentityKey.toHex()}/agent/status`, {
558
- ...args,
559
- method: "GET"
560
- });
561
- }
562
- getCredentialsForNotarization(spaceId, args) {
563
- return this._call(`/spaces/${spaceId}/notarization`, {
564
- ...args,
565
- method: "GET"
566
- });
567
- }
568
- async notarizeCredentials(spaceId, body, args) {
569
- await this._call(`/spaces/${spaceId}/notarization`, {
570
- ...args,
571
- body,
572
- method: "POST"
573
- });
574
- }
575
- async joinSpaceByInvitation(spaceId, body, args) {
576
- return this._call(`/spaces/${spaceId}/join`, {
577
- ...args,
578
- body,
579
- method: "POST"
580
- });
581
- }
582
- async _call(path, args) {
583
- const requestContext = args.context ?? new Context2(void 0, {
584
- F: __dxlog_file3,
585
- L: 68
586
- });
587
- const shouldRetry = createRetryHandler(args);
588
- const request = createRequest(args);
589
- const url = `${this._baseUrl}${path.startsWith("/") ? path.slice(1) : path}`;
590
- log3.info("call", {
591
- method: args.method,
592
- path,
593
- request: args.body
594
- }, {
595
- F: __dxlog_file3,
596
- L: 73,
597
- S: this,
598
- C: (f, a) => f(...a)
599
- });
600
- while (true) {
601
- let processingError;
602
- let retryAfterHeaderValue = Number.NaN;
603
- try {
604
- const response = await fetch(url, request);
605
- retryAfterHeaderValue = Number(response.headers.get("Retry-After"));
606
- if (response.ok) {
607
- const body = await response.json();
608
- if (body.success) {
609
- return body.data;
610
- }
611
- log3.info("unsuccessful edge response", {
612
- path,
613
- body
614
- }, {
615
- F: __dxlog_file3,
616
- L: 89,
617
- S: this,
618
- C: (f, a) => f(...a)
619
- });
620
- if (body.errorData?.type === "auth_challenge" && typeof body.errorData?.challenge === "string") {
621
- processingError = new EdgeAuthChallengeError(body.errorData.challenge, body.errorData);
622
- } else {
623
- processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);
624
- }
625
- } else {
626
- processingError = EdgeCallFailedError.fromHttpFailure(response);
627
- }
628
- } catch (error) {
629
- processingError = EdgeCallFailedError.fromProcessingFailureCause(error);
630
- }
631
- if (processingError.isRetryable && await shouldRetry(requestContext, retryAfterHeaderValue)) {
632
- log3.info("retrying edge request", {
633
- path,
634
- processingError
635
- }, {
636
- F: __dxlog_file3,
637
- L: 104,
638
- S: this,
639
- C: (f, a) => f(...a)
640
- });
641
- } else {
642
- throw processingError;
643
- }
644
- }
645
- }
646
- };
647
- var createRequest = (args) => {
648
- return {
649
- method: args.method,
650
- body: args.body && JSON.stringify(args.body)
651
- };
652
- };
653
- var createRetryHandler = (args) => {
654
- if (!args.retry || args.retry.count < 1) {
655
- return async () => false;
656
- }
657
- let retries = 0;
658
- const maxRetries = args.retry.count ?? DEFAULT_MAX_RETRIES_COUNT;
659
- const baseTimeout = args.retry.timeout ?? DEFAULT_RETRY_TIMEOUT;
660
- const jitter = args.retry.jitter ?? DEFAULT_RETRY_JITTER;
661
- return async (ctx, retryAfter) => {
662
- if (++retries > maxRetries || ctx.disposed) {
663
- return false;
664
- }
665
- if (retryAfter) {
666
- await sleep2(retryAfter);
667
- } else {
668
- const timeout = baseTimeout + Math.random() * jitter;
669
- await sleep2(timeout);
670
- }
671
- return true;
672
- };
673
- };
674
470
  export {
675
471
  EdgeClient,
676
- EdgeConnectionClosedError,
677
- EdgeHttpClient,
678
- EdgeIdentityChangedError,
679
472
  Protocol,
680
- createChainEdgeIdentity,
681
- createDeviceEdgeIdentity,
682
- createEphemeralEdgeIdentity,
683
- createStubEdgeIdentity,
684
- createTestHaloEdgeIdentity,
685
473
  getTypename,
686
474
  protocol,
687
475
  toUint8Array