@dxos/edge-client 0.8.4-main.3f58842 → 0.8.4-main.406dc2a

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 (41) 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 +533 -279
  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 +533 -279
  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 -2
  20. package/dist/types/src/edge-http-client.d.ts.map +1 -1
  21. package/dist/types/src/edge-ws-connection.d.ts +19 -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/http-client.d.ts +10 -7
  25. package/dist/types/src/http-client.d.ts.map +1 -1
  26. package/dist/types/src/index.d.ts +4 -3
  27. package/dist/types/src/index.d.ts.map +1 -1
  28. package/dist/types/src/testing/test-utils.d.ts +1 -1
  29. package/dist/types/src/testing/test-utils.d.ts.map +1 -1
  30. package/dist/types/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +18 -15
  32. package/src/edge-client.test.ts +4 -4
  33. package/src/edge-client.ts +73 -42
  34. package/src/edge-http-client.ts +158 -23
  35. package/src/edge-ws-connection.ts +119 -6
  36. package/src/edge-ws-muxer.ts +1 -1
  37. package/src/http-client.test.ts +8 -5
  38. package/src/http-client.ts +13 -7
  39. package/src/index.ts +4 -3
  40. package/src/testing/test-utils.ts +4 -4
  41. 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, scheduleTaskInterval as scheduleTaskInterval2 } 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, this._lastReceivedMessageTimestamp = Date.now();
81
- }
82
203
  get info() {
83
204
  return {
84
205
  open: this.isOpen,
@@ -86,19 +207,37 @@ var EdgeWsConnection = class extends Resource {
86
207
  device: this._identity.peerKey
87
208
  };
88
209
  }
210
+ get rtt() {
211
+ return this._rtt;
212
+ }
213
+ get uptime() {
214
+ return this._openTimestamp ? (Date.now() - this._openTimestamp) / 1e3 : 0;
215
+ }
216
+ get uploadRate() {
217
+ return this._uploadRate;
218
+ }
219
+ get downloadRate() {
220
+ return this._downloadRate;
221
+ }
222
+ get messagesSent() {
223
+ return this._messagesSent;
224
+ }
225
+ get messagesReceived() {
226
+ return this._messagesReceived;
227
+ }
89
228
  send(message) {
90
- invariant2(this._ws, void 0, {
91
- F: __dxlog_file2,
92
- L: 53,
229
+ invariant3(this._ws, void 0, {
230
+ F: __dxlog_file3,
231
+ L: 93,
93
232
  S: this,
94
233
  A: [
95
234
  "this._ws",
96
235
  ""
97
236
  ]
98
237
  });
99
- invariant2(this._wsMuxer, void 0, {
100
- F: __dxlog_file2,
101
- L: 54,
238
+ invariant3(this._wsMuxer, void 0, {
239
+ F: __dxlog_file3,
240
+ L: 94,
102
241
  S: this,
103
242
  A: [
104
243
  "this._wsMuxer",
@@ -109,11 +248,12 @@ var EdgeWsConnection = class extends Resource {
109
248
  peerKey: this._identity.peerKey,
110
249
  payload: protocol.getPayloadType(message)
111
250
  }, {
112
- F: __dxlog_file2,
113
- L: 55,
251
+ F: __dxlog_file3,
252
+ L: 95,
114
253
  S: this,
115
254
  C: (f, a) => f(...a)
116
255
  });
256
+ this._messagesSent++;
117
257
  if (this._ws?.protocol.includes(EdgeWebsocketProtocol.V0)) {
118
258
  const binary = buf.toBinary(MessageSchema, message);
119
259
  if (binary.length > CLOUDFLARE_MESSAGE_MAX_BYTES) {
@@ -122,18 +262,21 @@ var EdgeWsConnection = class extends Resource {
122
262
  serviceId: message.serviceId,
123
263
  payload: protocol.getPayloadType(message)
124
264
  }, {
125
- F: __dxlog_file2,
126
- L: 59,
265
+ F: __dxlog_file3,
266
+ L: 100,
127
267
  S: this,
128
268
  C: (f, a) => f(...a)
129
269
  });
130
270
  return;
131
271
  }
272
+ this._recordBytes(binary.byteLength, 0);
132
273
  this._ws.send(binary);
133
274
  } else {
275
+ const binary = buf.toBinary(MessageSchema, message);
276
+ this._recordBytes(binary.byteLength, 0);
134
277
  this._wsMuxer.send(message).catch((e) => log.catch(e, void 0, {
135
- F: __dxlog_file2,
136
- L: 68,
278
+ F: __dxlog_file3,
279
+ L: 113,
137
280
  S: this,
138
281
  C: (f, a) => f(...a)
139
282
  }));
@@ -154,19 +297,21 @@ var EdgeWsConnection = class extends Resource {
154
297
  this._ws.onopen = () => {
155
298
  if (this.isOpen) {
156
299
  log("connected", void 0, {
157
- F: __dxlog_file2,
158
- L: 85,
300
+ F: __dxlog_file3,
301
+ L: 130,
159
302
  S: this,
160
303
  C: (f, a) => f(...a)
161
304
  });
305
+ this._openTimestamp = Date.now();
162
306
  this._callbacks.onConnected();
163
307
  this._scheduleHeartbeats();
308
+ this._scheduleRateCalculation();
164
309
  } else {
165
310
  log.verbose("connected after becoming inactive", {
166
311
  currentIdentity: this._identity
167
312
  }, {
168
- F: __dxlog_file2,
169
- L: 89,
313
+ F: __dxlog_file3,
314
+ L: 136,
170
315
  S: this,
171
316
  C: (f, a) => f(...a)
172
317
  });
@@ -174,12 +319,12 @@ var EdgeWsConnection = class extends Resource {
174
319
  };
175
320
  this._ws.onclose = (event) => {
176
321
  if (this.isOpen) {
177
- log.warn("disconnected while being open", {
322
+ log.warn("server disconnected", {
178
323
  code: event.code,
179
324
  reason: event.reason
180
325
  }, {
181
- F: __dxlog_file2,
182
- L: 94,
326
+ F: __dxlog_file3,
327
+ L: 141,
183
328
  S: this,
184
329
  C: (f, a) => f(...a)
185
330
  });
@@ -193,8 +338,8 @@ var EdgeWsConnection = class extends Resource {
193
338
  error: event.error,
194
339
  info: event.message
195
340
  }, {
196
- F: __dxlog_file2,
197
- L: 101,
341
+ F: __dxlog_file3,
342
+ L: 148,
198
343
  S: this,
199
344
  C: (f, a) => f(...a)
200
345
  });
@@ -203,8 +348,8 @@ var EdgeWsConnection = class extends Resource {
203
348
  log.verbose("error ignored on closed connection", {
204
349
  error: event.error
205
350
  }, {
206
- F: __dxlog_file2,
207
- L: 104,
351
+ F: __dxlog_file3,
352
+ L: 151,
208
353
  S: this,
209
354
  C: (f, a) => f(...a)
210
355
  });
@@ -215,8 +360,8 @@ var EdgeWsConnection = class extends Resource {
215
360
  log.verbose("message ignored on closed connection", {
216
361
  event: event.type
217
362
  }, {
218
- F: __dxlog_file2,
219
- L: 112,
363
+ F: __dxlog_file3,
364
+ L: 159,
220
365
  S: this,
221
366
  C: (f, a) => f(...a)
222
367
  });
@@ -224,21 +369,27 @@ var EdgeWsConnection = class extends Resource {
224
369
  }
225
370
  this._lastReceivedMessageTimestamp = Date.now();
226
371
  if (event.data === "__pong__") {
372
+ if (this._pingTimestamp) {
373
+ this._rtt = Date.now() - this._pingTimestamp;
374
+ this._pingTimestamp = void 0;
375
+ }
227
376
  this._rescheduleHeartbeatTimeout();
228
377
  return;
229
378
  }
230
379
  const bytes = await toUint8Array(event.data);
380
+ this._recordBytes(0, bytes.byteLength);
231
381
  if (!this.isOpen) {
232
382
  return;
233
383
  }
384
+ this._messagesReceived++;
234
385
  const message = this._ws?.protocol?.includes(EdgeWebsocketProtocol.V0) ? buf.fromBinary(MessageSchema, bytes) : muxer.receiveData(bytes);
235
386
  if (message) {
236
387
  log("received", {
237
388
  from: message.source,
238
389
  payload: protocol.getPayloadType(message)
239
390
  }, {
240
- F: __dxlog_file2,
241
- L: 130,
391
+ F: __dxlog_file3,
392
+ L: 185,
242
393
  S: this,
243
394
  C: (f, a) => f(...a)
244
395
  });
@@ -258,20 +409,20 @@ var EdgeWsConnection = class extends Resource {
258
409
  if (err instanceof Error && err.message.includes("WebSocket is closed before the connection is established.")) {
259
410
  return;
260
411
  }
261
- log.warn("Error closing websocket", {
412
+ log.warn("error closing websocket", {
262
413
  err
263
414
  }, {
264
- F: __dxlog_file2,
265
- L: 148,
415
+ F: __dxlog_file3,
416
+ L: 203,
266
417
  S: this,
267
418
  C: (f, a) => f(...a)
268
419
  });
269
420
  }
270
421
  }
271
422
  _scheduleHeartbeats() {
272
- invariant2(this._ws, void 0, {
273
- F: __dxlog_file2,
274
- L: 153,
423
+ invariant3(this._ws, void 0, {
424
+ F: __dxlog_file3,
425
+ L: 208,
275
426
  S: this,
276
427
  A: [
277
428
  "this._ws",
@@ -279,8 +430,10 @@ var EdgeWsConnection = class extends Resource {
279
430
  ]
280
431
  });
281
432
  scheduleTaskInterval(this._ctx, async () => {
433
+ this._pingTimestamp = Date.now();
282
434
  this._ws?.send("__ping__");
283
435
  }, SIGNAL_KEEPALIVE_INTERVAL);
436
+ this._pingTimestamp = Date.now();
284
437
  this._ws.send("__ping__");
285
438
  this._rescheduleHeartbeatTimeout();
286
439
  }
@@ -290,8 +443,8 @@ var EdgeWsConnection = class extends Resource {
290
443
  }
291
444
  void this._inactivityTimeoutCtx?.dispose();
292
445
  this._inactivityTimeoutCtx = new Context(void 0, {
293
- F: __dxlog_file2,
294
- L: 172
446
+ F: __dxlog_file3,
447
+ L: 229
295
448
  });
296
449
  scheduleTask(this._inactivityTimeoutCtx, () => {
297
450
  if (this.isOpen) {
@@ -299,8 +452,8 @@ var EdgeWsConnection = class extends Resource {
299
452
  log.warn("restart due to inactivity timeout", {
300
453
  lastReceivedMessageTimestamp: this._lastReceivedMessageTimestamp
301
454
  }, {
302
- F: __dxlog_file2,
303
- L: 178,
455
+ F: __dxlog_file3,
456
+ L: 235,
304
457
  S: this,
305
458
  C: (f, a) => f(...a)
306
459
  });
@@ -311,6 +464,62 @@ var EdgeWsConnection = class extends Resource {
311
464
  }
312
465
  }, SIGNAL_KEEPALIVE_TIMEOUT);
313
466
  }
467
+ _recordBytes(sent, received) {
468
+ const now = Date.now();
469
+ const currentSecond = Math.floor(now / 1e3) * 1e3;
470
+ const existingSample = this._bytesSamples.find((s) => Math.floor(s.timestamp / 1e3) * 1e3 === currentSecond);
471
+ if (existingSample) {
472
+ existingSample.sent += sent;
473
+ existingSample.received += received;
474
+ } else {
475
+ this._bytesSamples.push({
476
+ timestamp: now,
477
+ sent,
478
+ received
479
+ });
480
+ }
481
+ }
482
+ _scheduleRateCalculation() {
483
+ scheduleTaskInterval(this._ctx, async () => {
484
+ this._calculateRates();
485
+ }, this._rateUpdateInterval);
486
+ this._calculateRates();
487
+ }
488
+ _calculateRates() {
489
+ const now = Date.now();
490
+ const cutoff = now - this._rateWindow;
491
+ this._bytesSamples = this._bytesSamples.filter((s) => s.timestamp > cutoff);
492
+ if (this._bytesSamples.length === 0) {
493
+ this._uploadRate = 0;
494
+ this._downloadRate = 0;
495
+ return;
496
+ }
497
+ let totalSent = 0;
498
+ let totalReceived = 0;
499
+ const oldestTimestamp = Math.min(...this._bytesSamples.map((s) => s.timestamp));
500
+ const timeSpan = (now - oldestTimestamp) / 1e3;
501
+ for (const sample of this._bytesSamples) {
502
+ totalSent += sample.sent;
503
+ totalReceived += sample.received;
504
+ }
505
+ this._uploadRate = timeSpan > 0 ? Math.round(totalSent / timeSpan) : 0;
506
+ this._downloadRate = timeSpan > 0 ? Math.round(totalReceived / timeSpan) : 0;
507
+ }
508
+ constructor(_identity, _connectionInfo, _callbacks) {
509
+ 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), _define_property(this, "_openTimestamp", void 0), // Latency tracking.
510
+ _define_property(this, "_pingTimestamp", void 0), _define_property(this, "_rtt", void 0), // Rate tracking with sliding window.
511
+ _define_property(this, "_uploadRate", void 0), _define_property(this, "_downloadRate", void 0), _define_property(
512
+ this,
513
+ "_rateWindow",
514
+ void 0
515
+ // 10 second sliding window.
516
+ ), _define_property(
517
+ this,
518
+ "_rateUpdateInterval",
519
+ void 0
520
+ // Update rates every second.
521
+ ), _define_property(this, "_bytesSamples", void 0), _define_property(this, "_messagesSent", void 0), _define_property(this, "_messagesReceived", void 0), this._identity = _identity, this._connectionInfo = _connectionInfo, this._callbacks = _callbacks, this._lastReceivedMessageTimestamp = Date.now(), this._rtt = 0, this._uploadRate = 0, this._downloadRate = 0, this._rateWindow = 1e4, this._rateUpdateInterval = 1e3, this._bytesSamples = [], this._messagesSent = 0, this._messagesReceived = 0;
522
+ }
314
523
  };
315
524
  _ts_decorate([
316
525
  logInfo
@@ -337,23 +546,29 @@ var getEdgeUrlWithProtocol = (baseUrl, protocol2) => {
337
546
  };
338
547
 
339
548
  // src/edge-client.ts
549
+ function _define_property2(obj, key, value) {
550
+ if (key in obj) {
551
+ Object.defineProperty(obj, key, {
552
+ value,
553
+ enumerable: true,
554
+ configurable: true,
555
+ writable: true
556
+ });
557
+ } else {
558
+ obj[key] = value;
559
+ }
560
+ return obj;
561
+ }
340
562
  function _ts_decorate2(decorators, target, key, desc) {
341
563
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
342
564
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
343
565
  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;
344
566
  return c > 3 && r && Object.defineProperty(target, key, r), r;
345
567
  }
346
- var __dxlog_file3 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
568
+ var __dxlog_file4 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
347
569
  var DEFAULT_TIMEOUT = 1e4;
570
+ var STATUS_REFRESH_INTERVAL = 1e3;
348
571
  var EdgeClient = class extends Resource2 {
349
- constructor(_identity, _config) {
350
- super(), this._identity = _identity, this._config = _config, this.statusChanged = new Event(), this._persistentLifecycle = new PersistentLifecycle({
351
- start: async () => this._connect(),
352
- stop: async (state) => this._disconnect(state)
353
- }), this._messageListeners = /* @__PURE__ */ new Set(), this._reconnectListeners = /* @__PURE__ */ new Set(), this._currentConnection = void 0, this._ready = new Trigger(), this._isActive = (connection) => connection === this._currentConnection;
354
- this._baseWsUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "ws");
355
- this._baseHttpUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "http");
356
- }
357
572
  get info() {
358
573
  return {
359
574
  open: this.isOpen,
@@ -363,7 +578,15 @@ var EdgeClient = class extends Resource2 {
363
578
  };
364
579
  }
365
580
  get status() {
366
- return Boolean(this._currentConnection) && this._ready.state === TriggerState.RESOLVED ? EdgeStatus.CONNECTED : EdgeStatus.NOT_CONNECTED;
581
+ return {
582
+ state: Boolean(this._currentConnection) && this._ready.state === TriggerState.RESOLVED ? EdgeStatus.ConnectionState.CONNECTED : EdgeStatus.ConnectionState.NOT_CONNECTED,
583
+ uptime: this._currentConnection?.uptime ?? 0,
584
+ rtt: this._currentConnection?.rtt ?? 0,
585
+ rateBytesUp: this._currentConnection?.uploadRate ?? 0,
586
+ rateBytesDown: this._currentConnection?.downloadRate ?? 0,
587
+ messagesSent: this._currentConnection?.messagesSent ?? 0,
588
+ messagesReceived: this._currentConnection?.messagesReceived ?? 0
589
+ };
367
590
  }
368
591
  get identityKey() {
369
592
  return this._identity.identityKey;
@@ -377,8 +600,8 @@ var EdgeClient = class extends Resource2 {
377
600
  identity,
378
601
  oldIdentity: this._identity
379
602
  }, {
380
- F: __dxlog_file3,
381
- L: 99,
603
+ F: __dxlog_file4,
604
+ L: 118,
382
605
  S: this,
383
606
  C: (f, a) => f(...a)
384
607
  });
@@ -387,6 +610,30 @@ var EdgeClient = class extends Resource2 {
387
610
  void this._persistentLifecycle.scheduleRestart();
388
611
  }
389
612
  }
613
+ /**
614
+ * Send message.
615
+ * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.
616
+ */
617
+ async send(message) {
618
+ if (this._ready.state !== TriggerState.RESOLVED) {
619
+ log2("waiting for websocket", void 0, {
620
+ F: __dxlog_file4,
621
+ L: 131,
622
+ S: this,
623
+ C: (f, a) => f(...a)
624
+ });
625
+ await this._ready.wait({
626
+ timeout: this._config.timeout ?? DEFAULT_TIMEOUT
627
+ });
628
+ }
629
+ if (!this._currentConnection) {
630
+ throw new EdgeConnectionClosedError();
631
+ }
632
+ if (message.source && (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)) {
633
+ throw new EdgeIdentityChangedError();
634
+ }
635
+ this._currentConnection.send(message);
636
+ }
390
637
  onMessage(listener) {
391
638
  this._messageListeners.add(listener);
392
639
  return () => this._messageListeners.delete(listener);
@@ -400,8 +647,8 @@ var EdgeClient = class extends Resource2 {
400
647
  listener();
401
648
  } catch (error) {
402
649
  log2.catch(error, void 0, {
403
- F: __dxlog_file3,
404
- L: 121,
650
+ F: __dxlog_file4,
651
+ L: 164,
405
652
  S: this,
406
653
  C: (f, a) => f(...a)
407
654
  });
@@ -418,8 +665,8 @@ var EdgeClient = class extends Resource2 {
418
665
  log2("opening...", {
419
666
  info: this.info
420
667
  }, {
421
- F: __dxlog_file3,
422
- L: 133,
668
+ F: __dxlog_file4,
669
+ L: 177,
423
670
  S: this,
424
671
  C: (f, a) => f(...a)
425
672
  });
@@ -427,12 +674,18 @@ var EdgeClient = class extends Resource2 {
427
674
  log2.warn("Error while opening connection", {
428
675
  err
429
676
  }, {
430
- F: __dxlog_file3,
431
- L: 135,
677
+ F: __dxlog_file4,
678
+ L: 179,
432
679
  S: this,
433
680
  C: (f, a) => f(...a)
434
681
  });
435
682
  });
683
+ scheduleTaskInterval2(this._ctx, async () => {
684
+ if (!this._currentConnection) {
685
+ return;
686
+ }
687
+ this.statusChanged.emit(this.status);
688
+ }, STATUS_REFRESH_INTERVAL);
436
689
  }
437
690
  /**
438
691
  * Close connection and free resources.
@@ -441,8 +694,8 @@ var EdgeClient = class extends Resource2 {
441
694
  log2("closing...", {
442
695
  peerKey: this._identity.peerKey
443
696
  }, {
444
- F: __dxlog_file3,
445
- L: 143,
697
+ F: __dxlog_file4,
698
+ L: 199,
446
699
  S: this,
447
700
  C: (f, a) => f(...a)
448
701
  });
@@ -458,8 +711,8 @@ var EdgeClient = class extends Resource2 {
458
711
  const protocolHeader = this._config.disableAuth ? void 0 : await this._createAuthHeader(path);
459
712
  if (this._identity !== identity) {
460
713
  log2("identity changed during auth header request", void 0, {
461
- F: __dxlog_file3,
462
- L: 157,
714
+ F: __dxlog_file4,
715
+ L: 213,
463
716
  S: this,
464
717
  C: (f, a) => f(...a)
465
718
  });
@@ -471,8 +724,8 @@ var EdgeClient = class extends Resource2 {
471
724
  url: url.toString(),
472
725
  protocolHeader
473
726
  }, {
474
- F: __dxlog_file3,
475
- L: 163,
727
+ F: __dxlog_file4,
728
+ L: 219,
476
729
  S: this,
477
730
  C: (f, a) => f(...a)
478
731
  });
@@ -486,8 +739,8 @@ var EdgeClient = class extends Resource2 {
486
739
  this._notifyReconnected();
487
740
  } else {
488
741
  log2.verbose("connected callback ignored, because connection is not active", void 0, {
489
- F: __dxlog_file3,
490
- L: 173,
742
+ F: __dxlog_file4,
743
+ L: 229,
491
744
  S: this,
492
745
  C: (f, a) => f(...a)
493
746
  });
@@ -499,8 +752,8 @@ var EdgeClient = class extends Resource2 {
499
752
  void this._persistentLifecycle.scheduleRestart();
500
753
  } else {
501
754
  log2.verbose("restart requested by inactive connection", void 0, {
502
- F: __dxlog_file3,
503
- L: 181,
755
+ F: __dxlog_file4,
756
+ L: 237,
504
757
  S: this,
505
758
  C: (f, a) => f(...a)
506
759
  });
@@ -515,8 +768,8 @@ var EdgeClient = class extends Resource2 {
515
768
  from: message.source,
516
769
  type: message.payload?.typeUrl
517
770
  }, {
518
- F: __dxlog_file3,
519
- L: 189,
771
+ F: __dxlog_file4,
772
+ L: 245,
520
773
  S: this,
521
774
  C: (f, a) => f(...a)
522
775
  });
@@ -552,8 +805,8 @@ var EdgeClient = class extends Resource2 {
552
805
  log2.error("ws reconnect listener failed", {
553
806
  err
554
807
  }, {
555
- F: __dxlog_file3,
556
- L: 225,
808
+ F: __dxlog_file4,
809
+ L: 280,
557
810
  S: this,
558
811
  C: (f, a) => f(...a)
559
812
  });
@@ -569,38 +822,14 @@ var EdgeClient = class extends Resource2 {
569
822
  err,
570
823
  payload: protocol.getPayloadType(message)
571
824
  }, {
572
- F: __dxlog_file3,
573
- L: 235,
825
+ F: __dxlog_file4,
826
+ L: 290,
574
827
  S: this,
575
828
  C: (f, a) => f(...a)
576
829
  });
577
830
  }
578
831
  }
579
832
  }
580
- /**
581
- * Send message.
582
- * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.
583
- */
584
- async send(message) {
585
- if (this._ready.state !== TriggerState.RESOLVED) {
586
- log2("waiting for websocket to become ready", void 0, {
587
- F: __dxlog_file3,
588
- L: 246,
589
- S: this,
590
- C: (f, a) => f(...a)
591
- });
592
- await this._ready.wait({
593
- timeout: this._config.timeout ?? DEFAULT_TIMEOUT
594
- });
595
- }
596
- if (!this._currentConnection) {
597
- throw new EdgeConnectionClosedError();
598
- }
599
- if (message.source && (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)) {
600
- throw new EdgeIdentityChangedError();
601
- }
602
- this._currentConnection.send(message);
603
- }
604
833
  async _createAuthHeader(path) {
605
834
  const httpUrl = new URL(path, this._baseHttpUrl);
606
835
  httpUrl.protocol = getEdgeUrlWithProtocol(this._baseWsUrl.toString(), "http");
@@ -614,14 +843,22 @@ var EdgeClient = class extends Resource2 {
614
843
  status: response.status,
615
844
  statusText: response.statusText
616
845
  }, {
617
- F: __dxlog_file3,
618
- L: 271,
846
+ F: __dxlog_file4,
847
+ L: 302,
619
848
  S: this,
620
849
  C: (f, a) => f(...a)
621
850
  });
622
851
  return void 0;
623
852
  }
624
853
  }
854
+ constructor(_identity, _config) {
855
+ 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({
856
+ start: async () => this._connect(),
857
+ stop: async (state) => this._disconnect(state)
858
+ }), this._messageListeners = /* @__PURE__ */ new Set(), this._reconnectListeners = /* @__PURE__ */ new Set(), this._currentConnection = void 0, this._ready = new Trigger(), this._isActive = (connection) => connection === this._currentConnection;
859
+ this._baseWsUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "ws");
860
+ this._baseHttpUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "http");
861
+ }
625
862
  };
626
863
  _ts_decorate2([
627
864
  logInfo2
@@ -631,120 +868,11 @@ var encodePresentationWsAuthHeader = (encodedPresentation) => {
631
868
  return `base64url.bearer.authorization.dxos.org.${encodedToken}`;
632
869
  };
633
870
 
634
- // src/auth.ts
635
- import { createCredential, signPresentation } from "@dxos/credentials";
636
- import { invariant as invariant3 } from "@dxos/invariant";
637
- import { Keyring } from "@dxos/keyring";
638
- import { PublicKey } from "@dxos/keys";
639
- var __dxlog_file4 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/auth.ts";
640
- var createDeviceEdgeIdentity = async (signer, key) => {
641
- return {
642
- identityKey: key.toHex(),
643
- peerKey: key.toHex(),
644
- presentCredentials: async ({ challenge }) => {
645
- return signPresentation({
646
- presentation: {
647
- credentials: [
648
- // Verifier requires at least one credential in the presentation to establish the subject.
649
- await createCredential({
650
- assertion: {
651
- "@type": "dxos.halo.credentials.Auth"
652
- },
653
- issuer: key,
654
- subject: key,
655
- signer
656
- })
657
- ]
658
- },
659
- signer,
660
- signerKey: key,
661
- nonce: challenge
662
- });
663
- }
664
- };
665
- };
666
- var createChainEdgeIdentity = async (signer, identityKey, peerKey, chain, credentials) => {
667
- const credentialsToSign = credentials.length > 0 ? credentials : [
668
- await createCredential({
669
- assertion: {
670
- "@type": "dxos.halo.credentials.Auth"
671
- },
672
- issuer: identityKey,
673
- subject: identityKey,
674
- signer,
675
- chain,
676
- signingKey: peerKey
677
- })
678
- ];
679
- return {
680
- identityKey: identityKey.toHex(),
681
- peerKey: peerKey.toHex(),
682
- presentCredentials: async ({ challenge }) => {
683
- invariant3(chain, void 0, {
684
- F: __dxlog_file4,
685
- L: 75,
686
- S: void 0,
687
- A: [
688
- "chain",
689
- ""
690
- ]
691
- });
692
- return signPresentation({
693
- presentation: {
694
- credentials: credentialsToSign
695
- },
696
- signer,
697
- nonce: challenge,
698
- signerKey: peerKey,
699
- chain
700
- });
701
- }
702
- };
703
- };
704
- var createEphemeralEdgeIdentity = async () => {
705
- const keyring = new Keyring();
706
- const key = await keyring.createKey();
707
- return createDeviceEdgeIdentity(keyring, key);
708
- };
709
- var createTestHaloEdgeIdentity = async (signer, identityKey, deviceKey) => {
710
- const deviceAdmission = await createCredential({
711
- assertion: {
712
- "@type": "dxos.halo.credentials.AuthorizedDevice",
713
- deviceKey,
714
- identityKey
715
- },
716
- issuer: identityKey,
717
- subject: deviceKey,
718
- signer
719
- });
720
- return createChainEdgeIdentity(signer, identityKey, deviceKey, {
721
- credential: deviceAdmission
722
- }, [
723
- await createCredential({
724
- assertion: {
725
- "@type": "dxos.halo.credentials.Auth"
726
- },
727
- issuer: identityKey,
728
- subject: identityKey,
729
- signer
730
- })
731
- ]);
732
- };
733
- var createStubEdgeIdentity = () => {
734
- const identityKey = PublicKey.random();
735
- const deviceKey = PublicKey.random();
736
- return {
737
- identityKey: identityKey.toHex(),
738
- peerKey: deviceKey.toHex(),
739
- presentCredentials: async () => {
740
- throw new Error("Stub identity does not support authentication.");
741
- }
742
- };
743
- };
744
-
745
871
  // src/edge-http-client.ts
746
- import { FetchHttpClient, HttpClient } from "@effect/platform";
747
- import { Effect as Effect2, pipe } from "effect";
872
+ import * as FetchHttpClient from "@effect/platform/FetchHttpClient";
873
+ import * as HttpClient from "@effect/platform/HttpClient";
874
+ import * as Effect2 from "effect/Effect";
875
+ import * as Function from "effect/Function";
748
876
  import { sleep } from "@dxos/async";
749
877
  import { Context as Context3 } from "@dxos/context";
750
878
  import { log as log4 } from "@dxos/log";
@@ -752,23 +880,39 @@ import { EdgeAuthChallengeError, EdgeCallFailedError } from "@dxos/protocols";
752
880
  import { createUrl } from "@dxos/util";
753
881
 
754
882
  // src/http-client.ts
755
- import { Context as Context2, Duration, Effect, Layer, Schedule } from "effect";
883
+ import * as Context2 from "effect/Context";
884
+ import * as Duration from "effect/Duration";
885
+ import * as Effect from "effect/Effect";
886
+ import * as Layer from "effect/Layer";
887
+ import * as Schedule from "effect/Schedule";
756
888
  import { log as log3 } from "@dxos/log";
757
- var __dxlog_file5 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/http-client.ts";
758
- var HttpConfig = class _HttpConfig extends Context2.Tag("HttpConfig")() {
759
- static {
760
- this.default = Layer.succeed(_HttpConfig, {
761
- timeout: Duration.millis(1e3),
762
- retryTimes: 3,
763
- retryBaseDelay: Duration.millis(1e3)
889
+ function _define_property3(obj, key, value) {
890
+ if (key in obj) {
891
+ Object.defineProperty(obj, key, {
892
+ value,
893
+ enumerable: true,
894
+ configurable: true,
895
+ writable: true
764
896
  });
897
+ } else {
898
+ obj[key] = value;
765
899
  }
900
+ return obj;
901
+ }
902
+ var __dxlog_file5 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/http-client.ts";
903
+ var _Context_Tag;
904
+ var HttpConfig = class extends (_Context_Tag = Context2.Tag("HttpConfig")()) {
766
905
  };
767
- var withRetry = (effect, { timeout = Duration.millis(1e3), retryBaseDelay = Duration.millis(1e3), retryTimes = 3 } = {}) => {
906
+ _define_property3(HttpConfig, "default", Layer.succeed(HttpConfig, {
907
+ timeout: Duration.millis(1e3),
908
+ retryTimes: 3,
909
+ retryBaseDelay: Duration.millis(1e3)
910
+ }));
911
+ var withRetry = (effect, { timeout: timeout2 = Duration.millis(1e3), retryBaseDelay = Duration.millis(1e3), retryTimes = 3 } = {}) => {
768
912
  return effect.pipe(Effect.flatMap((res) => (
769
913
  // Treat 500 errors as retryable?
770
914
  res.status === 500 ? Effect.fail(new Error(res.status.toString())) : res.json
771
- )), Effect.timeout(timeout), Effect.retry({
915
+ )), Effect.timeout(timeout2), Effect.retry({
772
916
  schedule: Schedule.exponential(retryBaseDelay).pipe(Schedule.jittered),
773
917
  times: retryTimes
774
918
  }));
@@ -781,7 +925,7 @@ var withLogging = (effect) => effect.pipe(Effect.tap((res) => log3.info("respons
781
925
  status: res.status
782
926
  }, {
783
927
  F: __dxlog_file5,
784
- L: 58,
928
+ L: 64,
785
929
  S: void 0,
786
930
  C: (f, a) => f(...a)
787
931
  })));
@@ -791,22 +935,25 @@ var encodeAuthHeader = (challenge) => {
791
935
  };
792
936
 
793
937
  // src/edge-http-client.ts
938
+ function _define_property4(obj, key, value) {
939
+ if (key in obj) {
940
+ Object.defineProperty(obj, key, {
941
+ value,
942
+ enumerable: true,
943
+ configurable: true,
944
+ writable: true
945
+ });
946
+ } else {
947
+ obj[key] = value;
948
+ }
949
+ return obj;
950
+ }
794
951
  var __dxlog_file6 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-http-client.ts";
795
952
  var DEFAULT_RETRY_TIMEOUT = 1500;
796
953
  var DEFAULT_RETRY_JITTER = 500;
797
954
  var DEFAULT_MAX_RETRIES_COUNT = 3;
955
+ var WARNING_BODY_SIZE = 10 * 1024 * 1024;
798
956
  var EdgeHttpClient = class {
799
- constructor(baseUrl) {
800
- this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
801
- log4("created", {
802
- url: this._baseUrl
803
- }, {
804
- F: __dxlog_file6,
805
- L: 84,
806
- S: this,
807
- C: (f, a) => f(...a)
808
- });
809
- }
810
957
  get baseUrl() {
811
958
  return this._baseUrl;
812
959
  }
@@ -880,12 +1027,6 @@ var EdgeHttpClient = class {
880
1027
  //
881
1028
  // OAuth and credentials
882
1029
  //
883
- async listFunctions(args) {
884
- return this._call(new URL("/functions", this.baseUrl), {
885
- ...args,
886
- method: "GET"
887
- });
888
- }
889
1030
  async initiateOAuthFlow(body, args) {
890
1031
  return this._call(new URL("/oauth/initiate", this.baseUrl), {
891
1032
  ...args,
@@ -940,6 +1081,18 @@ var EdgeHttpClient = class {
940
1081
  // Functions
941
1082
  //
942
1083
  async uploadFunction(pathParts, body, args) {
1084
+ const formData = new FormData();
1085
+ formData.append("name", body.name ?? "");
1086
+ formData.append("version", body.version);
1087
+ formData.append("ownerPublicKey", body.ownerPublicKey);
1088
+ formData.append("entryPoint", body.entryPoint);
1089
+ for (const [filename, content] of Object.entries(body.assets)) {
1090
+ formData.append("assets", new Blob([
1091
+ content
1092
+ ], {
1093
+ type: getFileMimeType(filename)
1094
+ }), filename);
1095
+ }
943
1096
  const path = [
944
1097
  "functions",
945
1098
  ...pathParts.functionId ? [
@@ -948,8 +1101,36 @@ var EdgeHttpClient = class {
948
1101
  ].join("/");
949
1102
  return this._call(new URL(path, this.baseUrl), {
950
1103
  ...args,
951
- body,
952
- method: "PUT"
1104
+ body: formData,
1105
+ method: "PUT",
1106
+ json: false
1107
+ });
1108
+ }
1109
+ async listFunctions(args) {
1110
+ return this._call(new URL("/functions", this.baseUrl), {
1111
+ ...args,
1112
+ method: "GET"
1113
+ });
1114
+ }
1115
+ async invokeFunction(params, input, args) {
1116
+ const url = new URL(`/functions/${params.functionId}`, this.baseUrl);
1117
+ if (params.version) {
1118
+ url.searchParams.set("version", params.version);
1119
+ }
1120
+ if (params.spaceId) {
1121
+ url.searchParams.set("spaceId", params.spaceId.toString());
1122
+ }
1123
+ if (params.cpuTimeLimit) {
1124
+ url.searchParams.set("cpuTimeLimit", params.cpuTimeLimit.toString());
1125
+ }
1126
+ if (params.subrequestsLimit) {
1127
+ url.searchParams.set("subrequestsLimit", params.subrequestsLimit.toString());
1128
+ }
1129
+ return this._call(url, {
1130
+ ...args,
1131
+ body: input,
1132
+ method: "POST",
1133
+ rawResponse: true
953
1134
  });
954
1135
  }
955
1136
  //
@@ -963,30 +1144,55 @@ var EdgeHttpClient = class {
963
1144
  });
964
1145
  }
965
1146
  //
1147
+ // Triggers
1148
+ //
1149
+ async getCronTriggers(spaceId) {
1150
+ return this._call(new URL(`/test/functions/${spaceId}/triggers/crons`, this.baseUrl), {
1151
+ method: "GET"
1152
+ });
1153
+ }
1154
+ //
1155
+ // Import/Export space.
1156
+ //
1157
+ async importBundle(spaceId, body, args) {
1158
+ return this._call(new URL(`/spaces/${spaceId}/import`, this.baseUrl), {
1159
+ ...args,
1160
+ body,
1161
+ method: "PUT"
1162
+ });
1163
+ }
1164
+ async exportBundle(spaceId, body, args) {
1165
+ return this._call(new URL(`/spaces/${spaceId}/export`, this.baseUrl), {
1166
+ ...args,
1167
+ body,
1168
+ method: "POST"
1169
+ });
1170
+ }
1171
+ //
966
1172
  // Internal
967
1173
  //
968
1174
  async _fetch(url, args) {
969
- return pipe(HttpClient.get(url), withLogging, withRetryConfig, Effect2.provide(FetchHttpClient.layer), Effect2.provide(HttpConfig.default), Effect2.withSpan("EdgeHttpClient"), Effect2.runPromise);
1175
+ return Function.pipe(HttpClient.get(url), withLogging, withRetryConfig, Effect2.provide(FetchHttpClient.layer), Effect2.provide(HttpConfig.default), Effect2.withSpan("EdgeHttpClient"), Effect2.runPromise);
970
1176
  }
971
1177
  // TODO(burdon): Refactor with effect (see edge-http-client.test.ts).
972
1178
  async _call(url, args) {
973
1179
  const shouldRetry = createRetryHandler(args);
974
1180
  const requestContext = args.context ?? new Context3(void 0, {
975
1181
  F: __dxlog_file6,
976
- L: 293
1182
+ L: 391
977
1183
  });
978
1184
  log4("fetch", {
979
1185
  url,
980
1186
  request: args.body
981
1187
  }, {
982
1188
  F: __dxlog_file6,
983
- L: 294,
1189
+ L: 392,
984
1190
  S: this,
985
1191
  C: (f, a) => f(...a)
986
1192
  });
987
1193
  let handledAuth = false;
988
1194
  while (true) {
989
- let processingError;
1195
+ let processingError = void 0;
990
1196
  let retryAfterHeaderValue = Number.NaN;
991
1197
  try {
992
1198
  const request = createRequest(args, this._authHeader);
@@ -994,6 +1200,12 @@ var EdgeHttpClient = class {
994
1200
  retryAfterHeaderValue = Number(response.headers.get("Retry-After"));
995
1201
  if (response.ok) {
996
1202
  const body = await response.json();
1203
+ if (args.rawResponse) {
1204
+ return body;
1205
+ }
1206
+ if (!("success" in body)) {
1207
+ return body;
1208
+ }
997
1209
  if (body.success) {
998
1210
  return body.data;
999
1211
  }
@@ -1002,13 +1214,13 @@ var EdgeHttpClient = class {
1002
1214
  body
1003
1215
  }, {
1004
1216
  F: __dxlog_file6,
1005
- L: 310,
1217
+ L: 417,
1006
1218
  S: this,
1007
1219
  C: (f, a) => f(...a)
1008
1220
  });
1009
1221
  if (body.errorData?.type === "auth_challenge" && typeof body.errorData?.challenge === "string") {
1010
1222
  processingError = new EdgeAuthChallengeError(body.errorData.challenge, body.errorData);
1011
- } else {
1223
+ } else if (body.errorData) {
1012
1224
  processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);
1013
1225
  }
1014
1226
  } else if (response.status === 401 && !handledAuth) {
@@ -1016,18 +1228,18 @@ var EdgeHttpClient = class {
1016
1228
  handledAuth = true;
1017
1229
  continue;
1018
1230
  } else {
1019
- processingError = EdgeCallFailedError.fromHttpFailure(response);
1231
+ processingError = await EdgeCallFailedError.fromHttpFailure(response);
1020
1232
  }
1021
1233
  } catch (error) {
1022
1234
  processingError = EdgeCallFailedError.fromProcessingFailureCause(error);
1023
1235
  }
1024
- if (processingError.isRetryable && await shouldRetry(requestContext, retryAfterHeaderValue)) {
1236
+ if (processingError?.isRetryable && await shouldRetry(requestContext, retryAfterHeaderValue)) {
1025
1237
  log4("retrying edge request", {
1026
1238
  url,
1027
1239
  processingError
1028
1240
  }, {
1029
1241
  F: __dxlog_file6,
1030
- L: 328,
1242
+ L: 435,
1031
1243
  S: this,
1032
1244
  C: (f, a) => f(...a)
1033
1245
  });
@@ -1040,33 +1252,66 @@ var EdgeHttpClient = class {
1040
1252
  if (!this._edgeIdentity) {
1041
1253
  log4.warn("unauthorized response received before identity was set", void 0, {
1042
1254
  F: __dxlog_file6,
1043
- L: 337,
1255
+ L: 444,
1044
1256
  S: this,
1045
1257
  C: (f, a) => f(...a)
1046
1258
  });
1047
- throw EdgeCallFailedError.fromHttpFailure(response);
1259
+ throw await EdgeCallFailedError.fromHttpFailure(response);
1048
1260
  }
1049
1261
  const challenge = await handleAuthChallenge(response, this._edgeIdentity);
1050
1262
  return encodeAuthHeader(challenge);
1051
1263
  }
1264
+ constructor(baseUrl) {
1265
+ _define_property4(this, "_baseUrl", void 0);
1266
+ _define_property4(this, "_edgeIdentity", void 0);
1267
+ _define_property4(this, "_authHeader", void 0);
1268
+ this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
1269
+ log4("created", {
1270
+ url: this._baseUrl
1271
+ }, {
1272
+ F: __dxlog_file6,
1273
+ L: 99,
1274
+ S: this,
1275
+ C: (f, a) => f(...a)
1276
+ });
1277
+ }
1052
1278
  };
1053
- var createRequest = ({ method, body }, authHeader) => {
1279
+ var createRequest = ({ method, body, json = true }, authHeader) => {
1280
+ let requestBody;
1281
+ const headers = {};
1282
+ if (json) {
1283
+ requestBody = body && JSON.stringify(body);
1284
+ headers["Content-Type"] = "application/json";
1285
+ } else {
1286
+ requestBody = body;
1287
+ }
1288
+ if (typeof requestBody === "string" && requestBody.length > WARNING_BODY_SIZE) {
1289
+ log4.warn("Request with large body", {
1290
+ bodySize: requestBody.length
1291
+ }, {
1292
+ F: __dxlog_file6,
1293
+ L: 468,
1294
+ S: void 0,
1295
+ C: (f, a) => f(...a)
1296
+ });
1297
+ }
1298
+ if (authHeader) {
1299
+ headers["Authorization"] = authHeader;
1300
+ }
1054
1301
  return {
1055
1302
  method,
1056
- body: body && JSON.stringify(body),
1057
- headers: authHeader ? {
1058
- Authorization: authHeader
1059
- } : void 0
1303
+ body: requestBody,
1304
+ headers
1060
1305
  };
1061
1306
  };
1062
- var createRetryHandler = ({ retry }) => {
1063
- if (!retry || retry.count < 1) {
1307
+ var createRetryHandler = ({ retry: retry2 }) => {
1308
+ if (!retry2 || retry2.count < 1) {
1064
1309
  return async () => false;
1065
1310
  }
1066
1311
  let retries = 0;
1067
- const maxRetries = retry.count ?? DEFAULT_MAX_RETRIES_COUNT;
1068
- const baseTimeout = retry.timeout ?? DEFAULT_RETRY_TIMEOUT;
1069
- const jitter = retry.jitter ?? DEFAULT_RETRY_JITTER;
1312
+ const maxRetries = retry2.count ?? DEFAULT_MAX_RETRIES_COUNT;
1313
+ const baseTimeout = retry2.timeout ?? DEFAULT_RETRY_TIMEOUT;
1314
+ const jitter = retry2.jitter ?? DEFAULT_RETRY_JITTER;
1070
1315
  return async (ctx, retryAfter) => {
1071
1316
  if (++retries > maxRetries || ctx.disposed) {
1072
1317
  return false;
@@ -1074,12 +1319,16 @@ var createRetryHandler = ({ retry }) => {
1074
1319
  if (retryAfter) {
1075
1320
  await sleep(retryAfter);
1076
1321
  } else {
1077
- const timeout = baseTimeout + Math.random() * jitter;
1078
- await sleep(timeout);
1322
+ const timeout2 = baseTimeout + Math.random() * jitter;
1323
+ await sleep(timeout2);
1079
1324
  }
1080
1325
  return true;
1081
1326
  };
1082
1327
  };
1328
+ var getFileMimeType = (filename) => [
1329
+ ".js",
1330
+ ".mjs"
1331
+ ].some((codeExtension) => filename.endsWith(codeExtension)) ? "application/javascript+module" : filename.endsWith(".wasm") ? "application/wasm" : "application/octet-stream";
1083
1332
  export {
1084
1333
  CLOUDFLARE_MESSAGE_MAX_BYTES,
1085
1334
  CLOUDFLARE_RPC_MAX_BYTES,
@@ -1087,6 +1336,7 @@ export {
1087
1336
  EdgeConnectionClosedError,
1088
1337
  EdgeHttpClient,
1089
1338
  EdgeIdentityChangedError,
1339
+ HttpConfig,
1090
1340
  Protocol,
1091
1341
  WebSocketMuxer,
1092
1342
  createChainEdgeIdentity,
@@ -1094,9 +1344,13 @@ export {
1094
1344
  createEphemeralEdgeIdentity,
1095
1345
  createStubEdgeIdentity,
1096
1346
  createTestHaloEdgeIdentity,
1347
+ encodeAuthHeader,
1097
1348
  getTypename,
1098
1349
  handleAuthChallenge,
1099
1350
  protocol,
1100
- toUint8Array
1351
+ toUint8Array,
1352
+ withLogging,
1353
+ withRetry,
1354
+ withRetryConfig
1101
1355
  };
1102
1356
  //# sourceMappingURL=index.mjs.map