@dxos/edge-client 0.6.12 → 0.6.13-main.548ca8d

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