@dxos/edge-client 0.8.4-main.84f28bd → 0.8.4-main.a4bbb77

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 (36) hide show
  1. package/dist/lib/browser/{chunk-LMP5TVOP.mjs → chunk-IKP53CBQ.mjs} +44 -11
  2. package/dist/lib/browser/{chunk-LMP5TVOP.mjs.map → chunk-IKP53CBQ.mjs.map} +3 -3
  3. package/dist/lib/browser/edge-ws-muxer.mjs +1 -1
  4. package/dist/lib/browser/index.mjs +420 -259
  5. package/dist/lib/browser/index.mjs.map +4 -4
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/testing/index.mjs +1 -1
  8. package/dist/lib/browser/testing/index.mjs.map +2 -2
  9. package/dist/lib/node-esm/{chunk-X7J46ISZ.mjs → chunk-DR5YNW5K.mjs} +44 -11
  10. package/dist/lib/node-esm/{chunk-X7J46ISZ.mjs.map → chunk-DR5YNW5K.mjs.map} +3 -3
  11. package/dist/lib/node-esm/edge-ws-muxer.mjs +1 -1
  12. package/dist/lib/node-esm/index.mjs +420 -259
  13. package/dist/lib/node-esm/index.mjs.map +4 -4
  14. package/dist/lib/node-esm/meta.json +1 -1
  15. package/dist/lib/node-esm/testing/index.mjs +1 -1
  16. package/dist/lib/node-esm/testing/index.mjs.map +2 -2
  17. package/dist/types/src/edge-client.d.ts +15 -15
  18. package/dist/types/src/edge-client.d.ts.map +1 -1
  19. package/dist/types/src/edge-http-client.d.ts +21 -1
  20. package/dist/types/src/edge-http-client.d.ts.map +1 -1
  21. package/dist/types/src/edge-ws-connection.d.ts +1 -0
  22. package/dist/types/src/edge-ws-connection.d.ts.map +1 -1
  23. package/dist/types/src/edge-ws-muxer.d.ts.map +1 -1
  24. package/dist/types/src/index.d.ts +4 -3
  25. package/dist/types/src/index.d.ts.map +1 -1
  26. package/dist/types/src/testing/test-utils.d.ts.map +1 -1
  27. package/dist/types/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +18 -15
  29. package/src/edge-client.ts +40 -40
  30. package/src/edge-http-client.ts +153 -16
  31. package/src/edge-ws-connection.ts +11 -3
  32. package/src/edge-ws-muxer.ts +1 -1
  33. package/src/http-client.test.ts +2 -2
  34. package/src/index.ts +4 -3
  35. package/src/testing/test-utils.ts +1 -1
  36. package/src/websocket.test.ts +1 -1
@@ -7,24 +7,135 @@ import {
7
7
  getTypename,
8
8
  protocol,
9
9
  toUint8Array
10
- } from "./chunk-X7J46ISZ.mjs";
10
+ } from "./chunk-DR5YNW5K.mjs";
11
11
 
12
12
  // src/index.ts
13
13
  export * from "@dxos/protocols/buf/dxos/edge/messenger_pb";
14
14
 
15
+ // src/auth.ts
16
+ import { createCredential, signPresentation } from "@dxos/credentials";
17
+ import { invariant } from "@dxos/invariant";
18
+ import { Keyring } from "@dxos/keyring";
19
+ import { PublicKey } from "@dxos/keys";
20
+ var __dxlog_file = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/auth.ts";
21
+ var createDeviceEdgeIdentity = async (signer, key) => {
22
+ return {
23
+ identityKey: key.toHex(),
24
+ peerKey: key.toHex(),
25
+ presentCredentials: async ({ challenge }) => {
26
+ return signPresentation({
27
+ presentation: {
28
+ credentials: [
29
+ // Verifier requires at least one credential in the presentation to establish the subject.
30
+ await createCredential({
31
+ assertion: {
32
+ "@type": "dxos.halo.credentials.Auth"
33
+ },
34
+ issuer: key,
35
+ subject: key,
36
+ signer
37
+ })
38
+ ]
39
+ },
40
+ signer,
41
+ signerKey: key,
42
+ nonce: challenge
43
+ });
44
+ }
45
+ };
46
+ };
47
+ var createChainEdgeIdentity = async (signer, identityKey, peerKey, chain, credentials) => {
48
+ const credentialsToSign = credentials.length > 0 ? credentials : [
49
+ await createCredential({
50
+ assertion: {
51
+ "@type": "dxos.halo.credentials.Auth"
52
+ },
53
+ issuer: identityKey,
54
+ subject: identityKey,
55
+ signer,
56
+ chain,
57
+ signingKey: peerKey
58
+ })
59
+ ];
60
+ return {
61
+ identityKey: identityKey.toHex(),
62
+ peerKey: peerKey.toHex(),
63
+ presentCredentials: async ({ challenge }) => {
64
+ invariant(chain, void 0, {
65
+ F: __dxlog_file,
66
+ L: 75,
67
+ S: void 0,
68
+ A: [
69
+ "chain",
70
+ ""
71
+ ]
72
+ });
73
+ return signPresentation({
74
+ presentation: {
75
+ credentials: credentialsToSign
76
+ },
77
+ signer,
78
+ nonce: challenge,
79
+ signerKey: peerKey,
80
+ chain
81
+ });
82
+ }
83
+ };
84
+ };
85
+ var createEphemeralEdgeIdentity = async () => {
86
+ const keyring = new Keyring();
87
+ const key = await keyring.createKey();
88
+ return createDeviceEdgeIdentity(keyring, key);
89
+ };
90
+ var createTestHaloEdgeIdentity = async (signer, identityKey, deviceKey) => {
91
+ const deviceAdmission = await createCredential({
92
+ assertion: {
93
+ "@type": "dxos.halo.credentials.AuthorizedDevice",
94
+ deviceKey,
95
+ identityKey
96
+ },
97
+ issuer: identityKey,
98
+ subject: deviceKey,
99
+ signer
100
+ });
101
+ return createChainEdgeIdentity(signer, identityKey, deviceKey, {
102
+ credential: deviceAdmission
103
+ }, [
104
+ await createCredential({
105
+ assertion: {
106
+ "@type": "dxos.halo.credentials.Auth"
107
+ },
108
+ issuer: identityKey,
109
+ subject: identityKey,
110
+ signer
111
+ })
112
+ ]);
113
+ };
114
+ var createStubEdgeIdentity = () => {
115
+ const identityKey = PublicKey.random();
116
+ const deviceKey = PublicKey.random();
117
+ return {
118
+ identityKey: identityKey.toHex(),
119
+ peerKey: deviceKey.toHex(),
120
+ presentCredentials: async () => {
121
+ throw new Error("Stub identity does not support authentication.");
122
+ }
123
+ };
124
+ };
125
+
15
126
  // src/edge-client.ts
16
- import { Trigger, scheduleMicroTask, TriggerState, PersistentLifecycle, Event } from "@dxos/async";
127
+ import { Event, PersistentLifecycle, Trigger, TriggerState, scheduleMicroTask } from "@dxos/async";
17
128
  import { Resource as Resource2 } from "@dxos/context";
18
129
  import { log as log2, logInfo as logInfo2 } from "@dxos/log";
19
130
  import { EdgeStatus } from "@dxos/protocols/proto/dxos/client/services";
20
131
 
21
132
  // src/edge-identity.ts
22
- import { invariant } from "@dxos/invariant";
133
+ import { invariant as invariant2 } from "@dxos/invariant";
23
134
  import { schema } from "@dxos/protocols/proto";
24
- var __dxlog_file = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-identity.ts";
135
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-identity.ts";
25
136
  var handleAuthChallenge = async (failedResponse, identity) => {
26
- invariant(failedResponse.status === 401, void 0, {
27
- F: __dxlog_file,
137
+ invariant2(failedResponse.status === 401, void 0, {
138
+ F: __dxlog_file2,
28
139
  L: 21,
29
140
  S: void 0,
30
141
  A: [
@@ -33,8 +144,8 @@ var handleAuthChallenge = async (failedResponse, identity) => {
33
144
  ]
34
145
  });
35
146
  const headerValue = failedResponse.headers.get("Www-Authenticate");
36
- invariant(headerValue?.startsWith("VerifiablePresentation challenge="), void 0, {
37
- F: __dxlog_file,
147
+ invariant2(headerValue?.startsWith("VerifiablePresentation challenge="), void 0, {
148
+ F: __dxlog_file2,
38
149
  L: 24,
39
150
  S: void 0,
40
151
  A: [
@@ -43,8 +154,8 @@ var handleAuthChallenge = async (failedResponse, identity) => {
43
154
  ]
44
155
  });
45
156
  const challenge = headerValue?.slice("VerifiablePresentation challenge=".length);
46
- invariant(challenge, void 0, {
47
- F: __dxlog_file,
157
+ invariant2(challenge, void 0, {
158
+ F: __dxlog_file2,
48
159
  L: 27,
49
160
  S: void 0,
50
161
  A: [
@@ -62,24 +173,34 @@ var handleAuthChallenge = async (failedResponse, identity) => {
62
173
  import WebSocket from "isomorphic-ws";
63
174
  import { scheduleTask, scheduleTaskInterval } from "@dxos/async";
64
175
  import { Context, Resource } from "@dxos/context";
65
- import { invariant as invariant2 } from "@dxos/invariant";
176
+ import { invariant as invariant3 } from "@dxos/invariant";
66
177
  import { log, logInfo } from "@dxos/log";
67
178
  import { EdgeWebsocketProtocol } from "@dxos/protocols";
68
179
  import { buf } from "@dxos/protocols/buf";
69
180
  import { MessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
181
+ function _define_property(obj, key, value) {
182
+ if (key in obj) {
183
+ Object.defineProperty(obj, key, {
184
+ value,
185
+ enumerable: true,
186
+ configurable: true,
187
+ writable: true
188
+ });
189
+ } else {
190
+ obj[key] = value;
191
+ }
192
+ return obj;
193
+ }
70
194
  function _ts_decorate(decorators, target, key, desc) {
71
195
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
72
196
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
73
197
  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;
74
198
  return c > 3 && r && Object.defineProperty(target, key, r), r;
75
199
  }
76
- var __dxlog_file2 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-ws-connection.ts";
200
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-ws-connection.ts";
77
201
  var SIGNAL_KEEPALIVE_INTERVAL = 4e3;
78
202
  var SIGNAL_KEEPALIVE_TIMEOUT = 12e3;
79
203
  var EdgeWsConnection = class extends Resource {
80
- constructor(_identity, _connectionInfo, _callbacks) {
81
- super(), this._identity = _identity, this._connectionInfo = _connectionInfo, this._callbacks = _callbacks;
82
- }
83
204
  get info() {
84
205
  return {
85
206
  open: this.isOpen,
@@ -88,18 +209,18 @@ var EdgeWsConnection = class extends Resource {
88
209
  };
89
210
  }
90
211
  send(message) {
91
- invariant2(this._ws, void 0, {
92
- F: __dxlog_file2,
93
- L: 52,
212
+ invariant3(this._ws, void 0, {
213
+ F: __dxlog_file3,
214
+ L: 53,
94
215
  S: this,
95
216
  A: [
96
217
  "this._ws",
97
218
  ""
98
219
  ]
99
220
  });
100
- invariant2(this._wsMuxer, void 0, {
101
- F: __dxlog_file2,
102
- L: 53,
221
+ invariant3(this._wsMuxer, void 0, {
222
+ F: __dxlog_file3,
223
+ L: 54,
103
224
  S: this,
104
225
  A: [
105
226
  "this._wsMuxer",
@@ -110,8 +231,8 @@ var EdgeWsConnection = class extends Resource {
110
231
  peerKey: this._identity.peerKey,
111
232
  payload: protocol.getPayloadType(message)
112
233
  }, {
113
- F: __dxlog_file2,
114
- L: 54,
234
+ F: __dxlog_file3,
235
+ L: 55,
115
236
  S: this,
116
237
  C: (f, a) => f(...a)
117
238
  });
@@ -123,8 +244,8 @@ var EdgeWsConnection = class extends Resource {
123
244
  serviceId: message.serviceId,
124
245
  payload: protocol.getPayloadType(message)
125
246
  }, {
126
- F: __dxlog_file2,
127
- L: 58,
247
+ F: __dxlog_file3,
248
+ L: 59,
128
249
  S: this,
129
250
  C: (f, a) => f(...a)
130
251
  });
@@ -133,8 +254,8 @@ var EdgeWsConnection = class extends Resource {
133
254
  this._ws.send(binary);
134
255
  } else {
135
256
  this._wsMuxer.send(message).catch((e) => log.catch(e, void 0, {
136
- F: __dxlog_file2,
137
- L: 67,
257
+ F: __dxlog_file3,
258
+ L: 68,
138
259
  S: this,
139
260
  C: (f, a) => f(...a)
140
261
  }));
@@ -155,8 +276,8 @@ var EdgeWsConnection = class extends Resource {
155
276
  this._ws.onopen = () => {
156
277
  if (this.isOpen) {
157
278
  log("connected", void 0, {
158
- F: __dxlog_file2,
159
- L: 84,
279
+ F: __dxlog_file3,
280
+ L: 85,
160
281
  S: this,
161
282
  C: (f, a) => f(...a)
162
283
  });
@@ -166,8 +287,8 @@ var EdgeWsConnection = class extends Resource {
166
287
  log.verbose("connected after becoming inactive", {
167
288
  currentIdentity: this._identity
168
289
  }, {
169
- F: __dxlog_file2,
170
- L: 88,
290
+ F: __dxlog_file3,
291
+ L: 89,
171
292
  S: this,
172
293
  C: (f, a) => f(...a)
173
294
  });
@@ -179,8 +300,8 @@ var EdgeWsConnection = class extends Resource {
179
300
  code: event.code,
180
301
  reason: event.reason
181
302
  }, {
182
- F: __dxlog_file2,
183
- L: 93,
303
+ F: __dxlog_file3,
304
+ L: 94,
184
305
  S: this,
185
306
  C: (f, a) => f(...a)
186
307
  });
@@ -194,8 +315,8 @@ var EdgeWsConnection = class extends Resource {
194
315
  error: event.error,
195
316
  info: event.message
196
317
  }, {
197
- F: __dxlog_file2,
198
- L: 100,
318
+ F: __dxlog_file3,
319
+ L: 101,
199
320
  S: this,
200
321
  C: (f, a) => f(...a)
201
322
  });
@@ -204,8 +325,8 @@ var EdgeWsConnection = class extends Resource {
204
325
  log.verbose("error ignored on closed connection", {
205
326
  error: event.error
206
327
  }, {
207
- F: __dxlog_file2,
208
- L: 103,
328
+ F: __dxlog_file3,
329
+ L: 104,
209
330
  S: this,
210
331
  C: (f, a) => f(...a)
211
332
  });
@@ -216,13 +337,14 @@ var EdgeWsConnection = class extends Resource {
216
337
  log.verbose("message ignored on closed connection", {
217
338
  event: event.type
218
339
  }, {
219
- F: __dxlog_file2,
220
- L: 111,
340
+ F: __dxlog_file3,
341
+ L: 112,
221
342
  S: this,
222
343
  C: (f, a) => f(...a)
223
344
  });
224
345
  return;
225
346
  }
347
+ this._lastReceivedMessageTimestamp = Date.now();
226
348
  if (event.data === "__pong__") {
227
349
  this._rescheduleHeartbeatTimeout();
228
350
  return;
@@ -237,8 +359,8 @@ var EdgeWsConnection = class extends Resource {
237
359
  from: message.source,
238
360
  payload: protocol.getPayloadType(message)
239
361
  }, {
240
- F: __dxlog_file2,
241
- L: 128,
362
+ F: __dxlog_file3,
363
+ L: 130,
242
364
  S: this,
243
365
  C: (f, a) => f(...a)
244
366
  });
@@ -261,17 +383,17 @@ var EdgeWsConnection = class extends Resource {
261
383
  log.warn("Error closing websocket", {
262
384
  err
263
385
  }, {
264
- F: __dxlog_file2,
265
- L: 146,
386
+ F: __dxlog_file3,
387
+ L: 148,
266
388
  S: this,
267
389
  C: (f, a) => f(...a)
268
390
  });
269
391
  }
270
392
  }
271
393
  _scheduleHeartbeats() {
272
- invariant2(this._ws, void 0, {
273
- F: __dxlog_file2,
274
- L: 151,
394
+ invariant3(this._ws, void 0, {
395
+ F: __dxlog_file3,
396
+ L: 153,
275
397
  S: this,
276
398
  A: [
277
399
  "this._ws",
@@ -290,21 +412,30 @@ var EdgeWsConnection = class extends Resource {
290
412
  }
291
413
  void this._inactivityTimeoutCtx?.dispose();
292
414
  this._inactivityTimeoutCtx = new Context(void 0, {
293
- F: __dxlog_file2,
294
- L: 170
415
+ F: __dxlog_file3,
416
+ L: 172
295
417
  });
296
418
  scheduleTask(this._inactivityTimeoutCtx, () => {
297
419
  if (this.isOpen) {
298
- log.warn("restart due to inactivity timeout", void 0, {
299
- F: __dxlog_file2,
300
- L: 175,
301
- S: this,
302
- C: (f, a) => f(...a)
303
- });
304
- this._callbacks.onRestartRequired();
420
+ if (Date.now() - this._lastReceivedMessageTimestamp > SIGNAL_KEEPALIVE_TIMEOUT) {
421
+ log.warn("restart due to inactivity timeout", {
422
+ lastReceivedMessageTimestamp: this._lastReceivedMessageTimestamp
423
+ }, {
424
+ F: __dxlog_file3,
425
+ L: 178,
426
+ S: this,
427
+ C: (f, a) => f(...a)
428
+ });
429
+ this._callbacks.onRestartRequired();
430
+ } else {
431
+ this._rescheduleHeartbeatTimeout();
432
+ }
305
433
  }
306
434
  }, SIGNAL_KEEPALIVE_TIMEOUT);
307
435
  }
436
+ constructor(_identity, _connectionInfo, _callbacks) {
437
+ super(), _define_property(this, "_identity", void 0), _define_property(this, "_connectionInfo", void 0), _define_property(this, "_callbacks", void 0), _define_property(this, "_inactivityTimeoutCtx", void 0), _define_property(this, "_ws", void 0), _define_property(this, "_wsMuxer", void 0), _define_property(this, "_lastReceivedMessageTimestamp", void 0), this._identity = _identity, this._connectionInfo = _connectionInfo, this._callbacks = _callbacks, this._lastReceivedMessageTimestamp = Date.now();
438
+ }
308
439
  };
309
440
  _ts_decorate([
310
441
  logInfo
@@ -331,23 +462,28 @@ var getEdgeUrlWithProtocol = (baseUrl, protocol2) => {
331
462
  };
332
463
 
333
464
  // src/edge-client.ts
465
+ function _define_property2(obj, key, value) {
466
+ if (key in obj) {
467
+ Object.defineProperty(obj, key, {
468
+ value,
469
+ enumerable: true,
470
+ configurable: true,
471
+ writable: true
472
+ });
473
+ } else {
474
+ obj[key] = value;
475
+ }
476
+ return obj;
477
+ }
334
478
  function _ts_decorate2(decorators, target, key, desc) {
335
479
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
336
480
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
337
481
  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;
338
482
  return c > 3 && r && Object.defineProperty(target, key, r), r;
339
483
  }
340
- var __dxlog_file3 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
484
+ var __dxlog_file4 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
341
485
  var DEFAULT_TIMEOUT = 1e4;
342
486
  var EdgeClient = class extends Resource2 {
343
- constructor(_identity, _config) {
344
- super(), this._identity = _identity, this._config = _config, this.statusChanged = new Event(), this._persistentLifecycle = new PersistentLifecycle({
345
- start: async () => this._connect(),
346
- stop: async (state) => this._disconnect(state)
347
- }), this._messageListeners = /* @__PURE__ */ new Set(), this._reconnectListeners = /* @__PURE__ */ new Set(), this._currentConnection = void 0, this._ready = new Trigger(), this._isActive = (connection) => connection === this._currentConnection;
348
- this._baseWsUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "ws");
349
- this._baseHttpUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "http");
350
- }
351
487
  get info() {
352
488
  return {
353
489
  open: this.isOpen,
@@ -371,7 +507,7 @@ var EdgeClient = class extends Resource2 {
371
507
  identity,
372
508
  oldIdentity: this._identity
373
509
  }, {
374
- F: __dxlog_file3,
510
+ F: __dxlog_file4,
375
511
  L: 99,
376
512
  S: this,
377
513
  C: (f, a) => f(...a)
@@ -381,6 +517,30 @@ var EdgeClient = class extends Resource2 {
381
517
  void this._persistentLifecycle.scheduleRestart();
382
518
  }
383
519
  }
520
+ /**
521
+ * Send message.
522
+ * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.
523
+ */
524
+ async send(message) {
525
+ if (this._ready.state !== TriggerState.RESOLVED) {
526
+ log2("waiting for websocket", void 0, {
527
+ F: __dxlog_file4,
528
+ L: 112,
529
+ S: this,
530
+ C: (f, a) => f(...a)
531
+ });
532
+ await this._ready.wait({
533
+ timeout: this._config.timeout ?? DEFAULT_TIMEOUT
534
+ });
535
+ }
536
+ if (!this._currentConnection) {
537
+ throw new EdgeConnectionClosedError();
538
+ }
539
+ if (message.source && (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)) {
540
+ throw new EdgeIdentityChangedError();
541
+ }
542
+ this._currentConnection.send(message);
543
+ }
384
544
  onMessage(listener) {
385
545
  this._messageListeners.add(listener);
386
546
  return () => this._messageListeners.delete(listener);
@@ -394,8 +554,8 @@ var EdgeClient = class extends Resource2 {
394
554
  listener();
395
555
  } catch (error) {
396
556
  log2.catch(error, void 0, {
397
- F: __dxlog_file3,
398
- L: 121,
557
+ F: __dxlog_file4,
558
+ L: 145,
399
559
  S: this,
400
560
  C: (f, a) => f(...a)
401
561
  });
@@ -412,8 +572,8 @@ var EdgeClient = class extends Resource2 {
412
572
  log2("opening...", {
413
573
  info: this.info
414
574
  }, {
415
- F: __dxlog_file3,
416
- L: 133,
575
+ F: __dxlog_file4,
576
+ L: 158,
417
577
  S: this,
418
578
  C: (f, a) => f(...a)
419
579
  });
@@ -421,8 +581,8 @@ var EdgeClient = class extends Resource2 {
421
581
  log2.warn("Error while opening connection", {
422
582
  err
423
583
  }, {
424
- F: __dxlog_file3,
425
- L: 135,
584
+ F: __dxlog_file4,
585
+ L: 160,
426
586
  S: this,
427
587
  C: (f, a) => f(...a)
428
588
  });
@@ -435,8 +595,8 @@ var EdgeClient = class extends Resource2 {
435
595
  log2("closing...", {
436
596
  peerKey: this._identity.peerKey
437
597
  }, {
438
- F: __dxlog_file3,
439
- L: 143,
598
+ F: __dxlog_file4,
599
+ L: 168,
440
600
  S: this,
441
601
  C: (f, a) => f(...a)
442
602
  });
@@ -452,8 +612,8 @@ var EdgeClient = class extends Resource2 {
452
612
  const protocolHeader = this._config.disableAuth ? void 0 : await this._createAuthHeader(path);
453
613
  if (this._identity !== identity) {
454
614
  log2("identity changed during auth header request", void 0, {
455
- F: __dxlog_file3,
456
- L: 157,
615
+ F: __dxlog_file4,
616
+ L: 182,
457
617
  S: this,
458
618
  C: (f, a) => f(...a)
459
619
  });
@@ -465,8 +625,8 @@ var EdgeClient = class extends Resource2 {
465
625
  url: url.toString(),
466
626
  protocolHeader
467
627
  }, {
468
- F: __dxlog_file3,
469
- L: 163,
628
+ F: __dxlog_file4,
629
+ L: 188,
470
630
  S: this,
471
631
  C: (f, a) => f(...a)
472
632
  });
@@ -480,8 +640,8 @@ var EdgeClient = class extends Resource2 {
480
640
  this._notifyReconnected();
481
641
  } else {
482
642
  log2.verbose("connected callback ignored, because connection is not active", void 0, {
483
- F: __dxlog_file3,
484
- L: 173,
643
+ F: __dxlog_file4,
644
+ L: 198,
485
645
  S: this,
486
646
  C: (f, a) => f(...a)
487
647
  });
@@ -493,8 +653,8 @@ var EdgeClient = class extends Resource2 {
493
653
  void this._persistentLifecycle.scheduleRestart();
494
654
  } else {
495
655
  log2.verbose("restart requested by inactive connection", void 0, {
496
- F: __dxlog_file3,
497
- L: 181,
656
+ F: __dxlog_file4,
657
+ L: 206,
498
658
  S: this,
499
659
  C: (f, a) => f(...a)
500
660
  });
@@ -509,8 +669,8 @@ var EdgeClient = class extends Resource2 {
509
669
  from: message.source,
510
670
  type: message.payload?.typeUrl
511
671
  }, {
512
- F: __dxlog_file3,
513
- L: 189,
672
+ F: __dxlog_file4,
673
+ L: 214,
514
674
  S: this,
515
675
  C: (f, a) => f(...a)
516
676
  });
@@ -546,8 +706,8 @@ var EdgeClient = class extends Resource2 {
546
706
  log2.error("ws reconnect listener failed", {
547
707
  err
548
708
  }, {
549
- F: __dxlog_file3,
550
- L: 225,
709
+ F: __dxlog_file4,
710
+ L: 249,
551
711
  S: this,
552
712
  C: (f, a) => f(...a)
553
713
  });
@@ -563,38 +723,14 @@ var EdgeClient = class extends Resource2 {
563
723
  err,
564
724
  payload: protocol.getPayloadType(message)
565
725
  }, {
566
- F: __dxlog_file3,
567
- L: 235,
726
+ F: __dxlog_file4,
727
+ L: 259,
568
728
  S: this,
569
729
  C: (f, a) => f(...a)
570
730
  });
571
731
  }
572
732
  }
573
733
  }
574
- /**
575
- * Send message.
576
- * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.
577
- */
578
- async send(message) {
579
- if (this._ready.state !== TriggerState.RESOLVED) {
580
- log2("waiting for websocket to become ready", void 0, {
581
- F: __dxlog_file3,
582
- L: 246,
583
- S: this,
584
- C: (f, a) => f(...a)
585
- });
586
- await this._ready.wait({
587
- timeout: this._config.timeout ?? DEFAULT_TIMEOUT
588
- });
589
- }
590
- if (!this._currentConnection) {
591
- throw new EdgeConnectionClosedError();
592
- }
593
- if (message.source && (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)) {
594
- throw new EdgeIdentityChangedError();
595
- }
596
- this._currentConnection.send(message);
597
- }
598
734
  async _createAuthHeader(path) {
599
735
  const httpUrl = new URL(path, this._baseHttpUrl);
600
736
  httpUrl.protocol = getEdgeUrlWithProtocol(this._baseWsUrl.toString(), "http");
@@ -608,7 +744,7 @@ var EdgeClient = class extends Resource2 {
608
744
  status: response.status,
609
745
  statusText: response.statusText
610
746
  }, {
611
- F: __dxlog_file3,
747
+ F: __dxlog_file4,
612
748
  L: 271,
613
749
  S: this,
614
750
  C: (f, a) => f(...a)
@@ -616,6 +752,14 @@ var EdgeClient = class extends Resource2 {
616
752
  return void 0;
617
753
  }
618
754
  }
755
+ constructor(_identity, _config) {
756
+ super(), _define_property2(this, "_identity", void 0), _define_property2(this, "_config", void 0), _define_property2(this, "statusChanged", void 0), _define_property2(this, "_persistentLifecycle", void 0), _define_property2(this, "_messageListeners", void 0), _define_property2(this, "_reconnectListeners", void 0), _define_property2(this, "_baseWsUrl", void 0), _define_property2(this, "_baseHttpUrl", void 0), _define_property2(this, "_currentConnection", void 0), _define_property2(this, "_ready", void 0), _define_property2(this, "_isActive", void 0), this._identity = _identity, this._config = _config, this.statusChanged = new Event(), this._persistentLifecycle = new PersistentLifecycle({
757
+ start: async () => this._connect(),
758
+ stop: async (state) => this._disconnect(state)
759
+ }), this._messageListeners = /* @__PURE__ */ new Set(), this._reconnectListeners = /* @__PURE__ */ new Set(), this._currentConnection = void 0, this._ready = new Trigger(), this._isActive = (connection) => connection === this._currentConnection;
760
+ this._baseWsUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "ws");
761
+ this._baseHttpUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "http");
762
+ }
619
763
  };
620
764
  _ts_decorate2([
621
765
  logInfo2
@@ -625,117 +769,6 @@ var encodePresentationWsAuthHeader = (encodedPresentation) => {
625
769
  return `base64url.bearer.authorization.dxos.org.${encodedToken}`;
626
770
  };
627
771
 
628
- // src/auth.ts
629
- import { createCredential, signPresentation } from "@dxos/credentials";
630
- import { invariant as invariant3 } from "@dxos/invariant";
631
- import { Keyring } from "@dxos/keyring";
632
- import { PublicKey } from "@dxos/keys";
633
- var __dxlog_file4 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/auth.ts";
634
- var createDeviceEdgeIdentity = async (signer, key) => {
635
- return {
636
- identityKey: key.toHex(),
637
- peerKey: key.toHex(),
638
- presentCredentials: async ({ challenge }) => {
639
- return signPresentation({
640
- presentation: {
641
- credentials: [
642
- // Verifier requires at least one credential in the presentation to establish the subject.
643
- await createCredential({
644
- assertion: {
645
- "@type": "dxos.halo.credentials.Auth"
646
- },
647
- issuer: key,
648
- subject: key,
649
- signer
650
- })
651
- ]
652
- },
653
- signer,
654
- signerKey: key,
655
- nonce: challenge
656
- });
657
- }
658
- };
659
- };
660
- var createChainEdgeIdentity = async (signer, identityKey, peerKey, chain, credentials) => {
661
- const credentialsToSign = credentials.length > 0 ? credentials : [
662
- await createCredential({
663
- assertion: {
664
- "@type": "dxos.halo.credentials.Auth"
665
- },
666
- issuer: identityKey,
667
- subject: identityKey,
668
- signer,
669
- chain,
670
- signingKey: peerKey
671
- })
672
- ];
673
- return {
674
- identityKey: identityKey.toHex(),
675
- peerKey: peerKey.toHex(),
676
- presentCredentials: async ({ challenge }) => {
677
- invariant3(chain, void 0, {
678
- F: __dxlog_file4,
679
- L: 75,
680
- S: void 0,
681
- A: [
682
- "chain",
683
- ""
684
- ]
685
- });
686
- return signPresentation({
687
- presentation: {
688
- credentials: credentialsToSign
689
- },
690
- signer,
691
- nonce: challenge,
692
- signerKey: peerKey,
693
- chain
694
- });
695
- }
696
- };
697
- };
698
- var createEphemeralEdgeIdentity = async () => {
699
- const keyring = new Keyring();
700
- const key = await keyring.createKey();
701
- return createDeviceEdgeIdentity(keyring, key);
702
- };
703
- var createTestHaloEdgeIdentity = async (signer, identityKey, deviceKey) => {
704
- const deviceAdmission = await createCredential({
705
- assertion: {
706
- "@type": "dxos.halo.credentials.AuthorizedDevice",
707
- deviceKey,
708
- identityKey
709
- },
710
- issuer: identityKey,
711
- subject: deviceKey,
712
- signer
713
- });
714
- return createChainEdgeIdentity(signer, identityKey, deviceKey, {
715
- credential: deviceAdmission
716
- }, [
717
- await createCredential({
718
- assertion: {
719
- "@type": "dxos.halo.credentials.Auth"
720
- },
721
- issuer: identityKey,
722
- subject: identityKey,
723
- signer
724
- })
725
- ]);
726
- };
727
- var createStubEdgeIdentity = () => {
728
- const identityKey = PublicKey.random();
729
- const deviceKey = PublicKey.random();
730
- return {
731
- identityKey: identityKey.toHex(),
732
- peerKey: deviceKey.toHex(),
733
- presentCredentials: async () => {
734
- throw new Error("Stub identity does not support authentication.");
735
- }
736
- };
737
- };
738
-
739
772
  // src/edge-http-client.ts
740
773
  import { FetchHttpClient, HttpClient } from "@effect/platform";
741
774
  import { Effect as Effect2, pipe } from "effect";
@@ -748,16 +781,28 @@ import { createUrl } from "@dxos/util";
748
781
  // src/http-client.ts
749
782
  import { Context as Context2, Duration, Effect, Layer, Schedule } from "effect";
750
783
  import { log as log3 } from "@dxos/log";
751
- var __dxlog_file5 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/http-client.ts";
752
- var HttpConfig = class _HttpConfig extends Context2.Tag("HttpConfig")() {
753
- static {
754
- this.default = Layer.succeed(_HttpConfig, {
755
- timeout: Duration.millis(1e3),
756
- retryTimes: 3,
757
- retryBaseDelay: Duration.millis(1e3)
784
+ function _define_property3(obj, key, value) {
785
+ if (key in obj) {
786
+ Object.defineProperty(obj, key, {
787
+ value,
788
+ enumerable: true,
789
+ configurable: true,
790
+ writable: true
758
791
  });
792
+ } else {
793
+ obj[key] = value;
759
794
  }
795
+ return obj;
796
+ }
797
+ var __dxlog_file5 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/http-client.ts";
798
+ var _Context_Tag;
799
+ var HttpConfig = class extends (_Context_Tag = Context2.Tag("HttpConfig")()) {
760
800
  };
801
+ _define_property3(HttpConfig, "default", Layer.succeed(HttpConfig, {
802
+ timeout: Duration.millis(1e3),
803
+ retryTimes: 3,
804
+ retryBaseDelay: Duration.millis(1e3)
805
+ }));
761
806
  var withRetry = (effect, { timeout = Duration.millis(1e3), retryBaseDelay = Duration.millis(1e3), retryTimes = 3 } = {}) => {
762
807
  return effect.pipe(Effect.flatMap((res) => (
763
808
  // Treat 500 errors as retryable?
@@ -785,22 +830,25 @@ var encodeAuthHeader = (challenge) => {
785
830
  };
786
831
 
787
832
  // src/edge-http-client.ts
833
+ function _define_property4(obj, key, value) {
834
+ if (key in obj) {
835
+ Object.defineProperty(obj, key, {
836
+ value,
837
+ enumerable: true,
838
+ configurable: true,
839
+ writable: true
840
+ });
841
+ } else {
842
+ obj[key] = value;
843
+ }
844
+ return obj;
845
+ }
788
846
  var __dxlog_file6 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-http-client.ts";
789
847
  var DEFAULT_RETRY_TIMEOUT = 1500;
790
848
  var DEFAULT_RETRY_JITTER = 500;
791
849
  var DEFAULT_MAX_RETRIES_COUNT = 3;
850
+ var WARNING_BODY_SIZE = 10 * 1024 * 1024;
792
851
  var EdgeHttpClient = class {
793
- constructor(baseUrl) {
794
- this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
795
- log4("created", {
796
- url: this._baseUrl
797
- }, {
798
- F: __dxlog_file6,
799
- L: 84,
800
- S: this,
801
- C: (f, a) => f(...a)
802
- });
803
- }
804
852
  get baseUrl() {
805
853
  return this._baseUrl;
806
854
  }
@@ -928,6 +976,18 @@ var EdgeHttpClient = class {
928
976
  // Functions
929
977
  //
930
978
  async uploadFunction(pathParts, body, args) {
979
+ const formData = new FormData();
980
+ formData.append("name", body.name ?? "");
981
+ formData.append("version", body.version);
982
+ formData.append("ownerPublicKey", body.ownerPublicKey);
983
+ formData.append("entryPoint", body.entryPoint);
984
+ for (const [filename, content] of Object.entries(body.assets)) {
985
+ formData.append("assets", new Blob([
986
+ content
987
+ ], {
988
+ type: getFileMimeType(filename)
989
+ }), filename);
990
+ }
931
991
  const path = [
932
992
  "functions",
933
993
  ...pathParts.functionId ? [
@@ -936,8 +996,36 @@ var EdgeHttpClient = class {
936
996
  ].join("/");
937
997
  return this._call(new URL(path, this.baseUrl), {
938
998
  ...args,
939
- body,
940
- method: "PUT"
999
+ body: formData,
1000
+ method: "PUT",
1001
+ json: false
1002
+ });
1003
+ }
1004
+ async listFunctions(args) {
1005
+ return this._call(new URL("/functions", this.baseUrl), {
1006
+ ...args,
1007
+ method: "GET"
1008
+ });
1009
+ }
1010
+ async invokeFunction(params, input, args) {
1011
+ const url = new URL(`/functions/${params.functionId}`, this.baseUrl);
1012
+ if (params.version) {
1013
+ url.searchParams.set("version", params.version);
1014
+ }
1015
+ if (params.spaceId) {
1016
+ url.searchParams.set("spaceId", params.spaceId.toString());
1017
+ }
1018
+ if (params.cpuTimeLimit) {
1019
+ url.searchParams.set("cpuTimeLimit", params.cpuTimeLimit.toString());
1020
+ }
1021
+ if (params.subrequestsLimit) {
1022
+ url.searchParams.set("subrequestsLimit", params.subrequestsLimit.toString());
1023
+ }
1024
+ return this._call(url, {
1025
+ ...args,
1026
+ body: input,
1027
+ method: "POST",
1028
+ rawResponse: true
941
1029
  });
942
1030
  }
943
1031
  //
@@ -951,6 +1039,31 @@ var EdgeHttpClient = class {
951
1039
  });
952
1040
  }
953
1041
  //
1042
+ // Triggers
1043
+ //
1044
+ async getCronTriggers(spaceId) {
1045
+ return this._call(new URL(`/test/functions/${spaceId}/triggers/crons`, this.baseUrl), {
1046
+ method: "GET"
1047
+ });
1048
+ }
1049
+ //
1050
+ // Import/Export space.
1051
+ //
1052
+ async importBundle(spaceId, body, args) {
1053
+ return this._call(new URL(`/spaces/${spaceId}/import`, this.baseUrl), {
1054
+ ...args,
1055
+ body,
1056
+ method: "PUT"
1057
+ });
1058
+ }
1059
+ async exportBundle(spaceId, body, args) {
1060
+ return this._call(new URL(`/spaces/${spaceId}/export`, this.baseUrl), {
1061
+ ...args,
1062
+ body,
1063
+ method: "POST"
1064
+ });
1065
+ }
1066
+ //
954
1067
  // Internal
955
1068
  //
956
1069
  async _fetch(url, args) {
@@ -961,20 +1074,20 @@ var EdgeHttpClient = class {
961
1074
  const shouldRetry = createRetryHandler(args);
962
1075
  const requestContext = args.context ?? new Context3(void 0, {
963
1076
  F: __dxlog_file6,
964
- L: 289
1077
+ L: 389
965
1078
  });
966
1079
  log4("fetch", {
967
1080
  url,
968
1081
  request: args.body
969
1082
  }, {
970
1083
  F: __dxlog_file6,
971
- L: 290,
1084
+ L: 390,
972
1085
  S: this,
973
1086
  C: (f, a) => f(...a)
974
1087
  });
975
1088
  let handledAuth = false;
976
1089
  while (true) {
977
- let processingError;
1090
+ let processingError = void 0;
978
1091
  let retryAfterHeaderValue = Number.NaN;
979
1092
  try {
980
1093
  const request = createRequest(args, this._authHeader);
@@ -982,6 +1095,12 @@ var EdgeHttpClient = class {
982
1095
  retryAfterHeaderValue = Number(response.headers.get("Retry-After"));
983
1096
  if (response.ok) {
984
1097
  const body = await response.json();
1098
+ if (args.rawResponse) {
1099
+ return body;
1100
+ }
1101
+ if (!("success" in body)) {
1102
+ return body;
1103
+ }
985
1104
  if (body.success) {
986
1105
  return body.data;
987
1106
  }
@@ -990,13 +1109,13 @@ var EdgeHttpClient = class {
990
1109
  body
991
1110
  }, {
992
1111
  F: __dxlog_file6,
993
- L: 306,
1112
+ L: 415,
994
1113
  S: this,
995
1114
  C: (f, a) => f(...a)
996
1115
  });
997
1116
  if (body.errorData?.type === "auth_challenge" && typeof body.errorData?.challenge === "string") {
998
1117
  processingError = new EdgeAuthChallengeError(body.errorData.challenge, body.errorData);
999
- } else {
1118
+ } else if (body.errorData) {
1000
1119
  processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);
1001
1120
  }
1002
1121
  } else if (response.status === 401 && !handledAuth) {
@@ -1004,18 +1123,18 @@ var EdgeHttpClient = class {
1004
1123
  handledAuth = true;
1005
1124
  continue;
1006
1125
  } else {
1007
- processingError = EdgeCallFailedError.fromHttpFailure(response);
1126
+ processingError = await EdgeCallFailedError.fromHttpFailure(response);
1008
1127
  }
1009
1128
  } catch (error) {
1010
1129
  processingError = EdgeCallFailedError.fromProcessingFailureCause(error);
1011
1130
  }
1012
- if (processingError.isRetryable && await shouldRetry(requestContext, retryAfterHeaderValue)) {
1131
+ if (processingError?.isRetryable && await shouldRetry(requestContext, retryAfterHeaderValue)) {
1013
1132
  log4("retrying edge request", {
1014
1133
  url,
1015
1134
  processingError
1016
1135
  }, {
1017
1136
  F: __dxlog_file6,
1018
- L: 324,
1137
+ L: 433,
1019
1138
  S: this,
1020
1139
  C: (f, a) => f(...a)
1021
1140
  });
@@ -1028,23 +1147,56 @@ var EdgeHttpClient = class {
1028
1147
  if (!this._edgeIdentity) {
1029
1148
  log4.warn("unauthorized response received before identity was set", void 0, {
1030
1149
  F: __dxlog_file6,
1031
- L: 333,
1150
+ L: 442,
1032
1151
  S: this,
1033
1152
  C: (f, a) => f(...a)
1034
1153
  });
1035
- throw EdgeCallFailedError.fromHttpFailure(response);
1154
+ throw await EdgeCallFailedError.fromHttpFailure(response);
1036
1155
  }
1037
1156
  const challenge = await handleAuthChallenge(response, this._edgeIdentity);
1038
1157
  return encodeAuthHeader(challenge);
1039
1158
  }
1159
+ constructor(baseUrl) {
1160
+ _define_property4(this, "_baseUrl", void 0);
1161
+ _define_property4(this, "_edgeIdentity", void 0);
1162
+ _define_property4(this, "_authHeader", void 0);
1163
+ this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
1164
+ log4("created", {
1165
+ url: this._baseUrl
1166
+ }, {
1167
+ F: __dxlog_file6,
1168
+ L: 97,
1169
+ S: this,
1170
+ C: (f, a) => f(...a)
1171
+ });
1172
+ }
1040
1173
  };
1041
- var createRequest = ({ method, body }, authHeader) => {
1174
+ var createRequest = ({ method, body, json = true }, authHeader) => {
1175
+ let requestBody;
1176
+ const headers = {};
1177
+ if (json) {
1178
+ requestBody = body && JSON.stringify(body);
1179
+ headers["Content-Type"] = "application/json";
1180
+ } else {
1181
+ requestBody = body;
1182
+ }
1183
+ if (typeof requestBody === "string" && requestBody.length > WARNING_BODY_SIZE) {
1184
+ log4.warn("Request with large body", {
1185
+ bodySize: requestBody.length
1186
+ }, {
1187
+ F: __dxlog_file6,
1188
+ L: 466,
1189
+ S: void 0,
1190
+ C: (f, a) => f(...a)
1191
+ });
1192
+ }
1193
+ if (authHeader) {
1194
+ headers["Authorization"] = authHeader;
1195
+ }
1042
1196
  return {
1043
1197
  method,
1044
- body: body && JSON.stringify(body),
1045
- headers: authHeader ? {
1046
- Authorization: authHeader
1047
- } : void 0
1198
+ body: requestBody,
1199
+ headers
1048
1200
  };
1049
1201
  };
1050
1202
  var createRetryHandler = ({ retry }) => {
@@ -1068,6 +1220,10 @@ var createRetryHandler = ({ retry }) => {
1068
1220
  return true;
1069
1221
  };
1070
1222
  };
1223
+ var getFileMimeType = (filename) => [
1224
+ ".js",
1225
+ ".mjs"
1226
+ ].some((codeExtension) => filename.endsWith(codeExtension)) ? "application/javascript+module" : filename.endsWith(".wasm") ? "application/wasm" : "application/octet-stream";
1071
1227
  export {
1072
1228
  CLOUDFLARE_MESSAGE_MAX_BYTES,
1073
1229
  CLOUDFLARE_RPC_MAX_BYTES,
@@ -1075,6 +1231,7 @@ export {
1075
1231
  EdgeConnectionClosedError,
1076
1232
  EdgeHttpClient,
1077
1233
  EdgeIdentityChangedError,
1234
+ HttpConfig,
1078
1235
  Protocol,
1079
1236
  WebSocketMuxer,
1080
1237
  createChainEdgeIdentity,
@@ -1082,9 +1239,13 @@ export {
1082
1239
  createEphemeralEdgeIdentity,
1083
1240
  createStubEdgeIdentity,
1084
1241
  createTestHaloEdgeIdentity,
1242
+ encodeAuthHeader,
1085
1243
  getTypename,
1086
1244
  handleAuthChallenge,
1087
1245
  protocol,
1088
- toUint8Array
1246
+ toUint8Array,
1247
+ withLogging,
1248
+ withRetry,
1249
+ withRetryConfig
1089
1250
  };
1090
1251
  //# sourceMappingURL=index.mjs.map