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