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