@dxos/edge-client 0.8.4-main.fffef41 → 0.8.4-staging.60fe92afc8

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 (70) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/{node-esm/chunk-JTBFRYNM.mjs → neutral/chunk-L5ZHLJ4B.mjs} +54 -47
  3. package/dist/lib/neutral/chunk-L5ZHLJ4B.mjs.map +7 -0
  4. package/dist/lib/neutral/chunk-WQKMEZJR.mjs +30 -0
  5. package/dist/lib/neutral/chunk-WQKMEZJR.mjs.map +7 -0
  6. package/dist/lib/neutral/cors-proxy.mjs +7 -0
  7. package/dist/lib/{browser → neutral}/edge-ws-muxer.mjs +1 -1
  8. package/dist/lib/{browser → neutral}/index.mjs +553 -467
  9. package/dist/lib/neutral/index.mjs.map +7 -0
  10. package/dist/lib/neutral/meta.json +1 -0
  11. package/dist/lib/{browser → neutral}/testing/index.mjs +6 -31
  12. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  13. package/dist/types/src/auth.d.ts.map +1 -1
  14. package/dist/types/src/base-http-client.d.ts +48 -0
  15. package/dist/types/src/base-http-client.d.ts.map +1 -0
  16. package/dist/types/src/cors-proxy.d.ts +6 -0
  17. package/dist/types/src/cors-proxy.d.ts.map +1 -0
  18. package/dist/types/src/edge-ai-http-client.d.ts +65 -0
  19. package/dist/types/src/edge-ai-http-client.d.ts.map +1 -0
  20. package/dist/types/src/edge-client.d.ts +6 -3
  21. package/dist/types/src/edge-client.d.ts.map +1 -1
  22. package/dist/types/src/edge-http-client.d.ts +76 -75
  23. package/dist/types/src/edge-http-client.d.ts.map +1 -1
  24. package/dist/types/src/edge-identity.d.ts.map +1 -1
  25. package/dist/types/src/edge-ws-connection.d.ts +1 -0
  26. package/dist/types/src/edge-ws-connection.d.ts.map +1 -1
  27. package/dist/types/src/edge-ws-muxer.d.ts.map +1 -1
  28. package/dist/types/src/errors.d.ts.map +1 -1
  29. package/dist/types/src/http-client.d.ts +2 -2
  30. package/dist/types/src/http-client.d.ts.map +1 -1
  31. package/dist/types/src/hub-http-client.d.ts +39 -0
  32. package/dist/types/src/hub-http-client.d.ts.map +1 -0
  33. package/dist/types/src/index.d.ts +4 -0
  34. package/dist/types/src/index.d.ts.map +1 -1
  35. package/dist/types/src/protocol.d.ts +1 -1
  36. package/dist/types/src/protocol.d.ts.map +1 -1
  37. package/dist/types/src/testing/test-server.d.ts.map +1 -1
  38. package/dist/types/src/testing/test-utils.d.ts +2 -2
  39. package/dist/types/src/testing/test-utils.d.ts.map +1 -1
  40. package/dist/types/src/utils.d.ts +1 -1
  41. package/dist/types/src/utils.d.ts.map +1 -1
  42. package/dist/types/tsconfig.tsbuildinfo +1 -1
  43. package/package.json +33 -32
  44. package/src/base-http-client.ts +243 -0
  45. package/src/cors-proxy.ts +38 -0
  46. package/src/edge-ai-http-client.ts +129 -0
  47. package/src/edge-client.test.ts +16 -11
  48. package/src/edge-client.ts +37 -7
  49. package/src/edge-http-client.test.ts +36 -2
  50. package/src/edge-http-client.ts +237 -270
  51. package/src/edge-ws-connection.ts +2 -1
  52. package/src/edge-ws-muxer.ts +49 -5
  53. package/src/http-client.test.ts +3 -2
  54. package/src/hub-http-client.ts +118 -0
  55. package/src/index.ts +4 -0
  56. package/src/testing/test-utils.ts +4 -4
  57. package/dist/lib/browser/chunk-VESGVCLQ.mjs +0 -301
  58. package/dist/lib/browser/chunk-VESGVCLQ.mjs.map +0 -7
  59. package/dist/lib/browser/index.mjs.map +0 -7
  60. package/dist/lib/browser/meta.json +0 -1
  61. package/dist/lib/browser/testing/index.mjs.map +0 -7
  62. package/dist/lib/node-esm/chunk-JTBFRYNM.mjs.map +0 -7
  63. package/dist/lib/node-esm/edge-ws-muxer.mjs +0 -12
  64. package/dist/lib/node-esm/index.mjs +0 -1363
  65. package/dist/lib/node-esm/index.mjs.map +0 -7
  66. package/dist/lib/node-esm/meta.json +0 -1
  67. package/dist/lib/node-esm/testing/index.mjs +0 -186
  68. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  69. /package/dist/lib/{browser/edge-ws-muxer.mjs.map → neutral/cors-proxy.mjs.map} +0 -0
  70. /package/dist/lib/{node-esm → neutral}/edge-ws-muxer.mjs.map +0 -0
@@ -1,3 +1,6 @@
1
+ import {
2
+ proxyFetchLegacy
3
+ } from "./chunk-WQKMEZJR.mjs";
1
4
  import {
2
5
  CLOUDFLARE_MESSAGE_MAX_BYTES,
3
6
  CLOUDFLARE_RPC_MAX_BYTES,
@@ -6,7 +9,7 @@ import {
6
9
  getTypename,
7
10
  protocol,
8
11
  toUint8Array
9
- } from "./chunk-VESGVCLQ.mjs";
12
+ } from "./chunk-L5ZHLJ4B.mjs";
10
13
 
11
14
  // src/index.ts
12
15
  export * from "@dxos/protocols/buf/dxos/edge/messenger_pb";
@@ -60,15 +63,7 @@ var createChainEdgeIdentity = async (signer, identityKey, peerKey, chain, creden
60
63
  identityKey: identityKey.toHex(),
61
64
  peerKey: peerKey.toHex(),
62
65
  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
- });
66
+ invariant(chain, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 56, S: void 0, A: ["chain", ""] });
72
67
  return signPresentation({
73
68
  presentation: {
74
69
  credentials: credentialsToSign
@@ -124,6 +119,7 @@ var createStubEdgeIdentity = () => {
124
119
 
125
120
  // src/edge-client.ts
126
121
  import { Event, PersistentLifecycle, Trigger, TriggerState, scheduleMicroTask, scheduleTaskInterval as scheduleTaskInterval2 } from "@dxos/async";
122
+ import { TRACE_SPAN_ATTRIBUTE } from "@dxos/context";
127
123
  import { Resource as Resource2 } from "@dxos/context";
128
124
  import { log as log2, logInfo as logInfo2 } from "@dxos/log";
129
125
  import { EdgeStatus } from "@dxos/protocols/proto/dxos/client/services";
@@ -133,35 +129,11 @@ import { invariant as invariant2 } from "@dxos/invariant";
133
129
  import { schema } from "@dxos/protocols/proto";
134
130
  var __dxlog_file2 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-identity.ts";
135
131
  var handleAuthChallenge = async (failedResponse, identity) => {
136
- invariant2(failedResponse.status === 401, void 0, {
137
- F: __dxlog_file2,
138
- L: 21,
139
- S: void 0,
140
- A: [
141
- "failedResponse.status === 401",
142
- ""
143
- ]
144
- });
132
+ invariant2(failedResponse.status === 401, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 7, S: void 0, A: ["failedResponse.status === 401", ""] });
145
133
  const headerValue = failedResponse.headers.get("Www-Authenticate");
146
- invariant2(headerValue?.startsWith("VerifiablePresentation challenge="), void 0, {
147
- F: __dxlog_file2,
148
- L: 24,
149
- S: void 0,
150
- A: [
151
- "headerValue?.startsWith('VerifiablePresentation challenge=')",
152
- ""
153
- ]
154
- });
134
+ invariant2(headerValue?.startsWith("VerifiablePresentation challenge="), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 9, S: void 0, A: ["headerValue?.startsWith('VerifiablePresentation challenge=')", ""] });
155
135
  const challenge = headerValue?.slice("VerifiablePresentation challenge=".length);
156
- invariant2(challenge, void 0, {
157
- F: __dxlog_file2,
158
- L: 27,
159
- S: void 0,
160
- A: [
161
- "challenge",
162
- ""
163
- ]
164
- });
136
+ invariant2(challenge, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 11, S: void 0, A: ["challenge", ""] });
165
137
  const presentation = await identity.presentCredentials({
166
138
  challenge: Buffer.from(challenge, "base64")
167
139
  });
@@ -177,13 +149,13 @@ import { log, logInfo } from "@dxos/log";
177
149
  import { EdgeWebsocketProtocol } from "@dxos/protocols";
178
150
  import { buf } from "@dxos/protocols/buf";
179
151
  import { MessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
152
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-ws-connection.ts";
180
153
  function _ts_decorate(decorators, target, key, desc) {
181
154
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
182
155
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
183
156
  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;
184
157
  return c > 3 && r && Object.defineProperty(target, key, r), r;
185
158
  }
186
- var __dxlog_file3 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-ws-connection.ts";
187
159
  var SIGNAL_KEEPALIVE_INTERVAL = 4e3;
188
160
  var SIGNAL_KEEPALIVE_TIMEOUT = 12e3;
189
161
  var EdgeWsConnection = class extends Resource {
@@ -235,33 +207,12 @@ var EdgeWsConnection = class extends Resource {
235
207
  return this._messagesReceived;
236
208
  }
237
209
  send(message) {
238
- invariant3(this._ws, void 0, {
239
- F: __dxlog_file3,
240
- L: 93,
241
- S: this,
242
- A: [
243
- "this._ws",
244
- ""
245
- ]
246
- });
247
- invariant3(this._wsMuxer, void 0, {
248
- F: __dxlog_file3,
249
- L: 94,
250
- S: this,
251
- A: [
252
- "this._wsMuxer",
253
- ""
254
- ]
255
- });
210
+ invariant3(this._ws, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 72, S: this, A: ["this._ws", ""] });
211
+ invariant3(this._wsMuxer, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 73, S: this, A: ["this._wsMuxer", ""] });
256
212
  log("sending...", {
257
213
  peerKey: this._identity.peerKey,
258
214
  payload: protocol.getPayloadType(message)
259
- }, {
260
- F: __dxlog_file3,
261
- L: 95,
262
- S: this,
263
- C: (f, a) => f(...a)
264
- });
215
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 74, S: this });
265
216
  this._messagesSent++;
266
217
  if (this._ws?.protocol.includes(EdgeWebsocketProtocol.V0)) {
267
218
  const binary = buf.toBinary(MessageSchema, message);
@@ -270,12 +221,7 @@ var EdgeWsConnection = class extends Resource {
270
221
  byteLength: binary.byteLength,
271
222
  serviceId: message.serviceId,
272
223
  payload: protocol.getPayloadType(message)
273
- }, {
274
- F: __dxlog_file3,
275
- L: 100,
276
- S: this,
277
- C: (f, a) => f(...a)
278
- });
224
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 82, S: this });
279
225
  return;
280
226
  }
281
227
  this._recordBytes(binary.byteLength, 0);
@@ -283,12 +229,7 @@ var EdgeWsConnection = class extends Resource {
283
229
  } else {
284
230
  const binary = buf.toBinary(MessageSchema, message);
285
231
  this._recordBytes(binary.byteLength, 0);
286
- this._wsMuxer.send(message).catch((e) => log.catch(e, void 0, {
287
- F: __dxlog_file3,
288
- L: 113,
289
- S: this,
290
- C: (f, a) => f(...a)
291
- }));
232
+ this._wsMuxer.send(message).catch((e) => log.catch(e, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 95, S: this }));
292
233
  }
293
234
  }
294
235
  async _open() {
@@ -300,17 +241,14 @@ var EdgeWsConnection = class extends Resource {
300
241
  this._connectionInfo.protocolHeader
301
242
  ] : [
302
243
  ...baseProtocols
303
- ]);
244
+ ], this._connectionInfo.headers ? {
245
+ headers: this._connectionInfo.headers
246
+ } : void 0);
304
247
  const muxer = new WebSocketMuxer(this._ws);
305
248
  this._wsMuxer = muxer;
306
249
  this._ws.onopen = () => {
307
250
  if (this.isOpen) {
308
- log("connected", void 0, {
309
- F: __dxlog_file3,
310
- L: 130,
311
- S: this,
312
- C: (f, a) => f(...a)
313
- });
251
+ log("connected", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 114, S: this });
314
252
  this._openTimestamp = Date.now();
315
253
  this._callbacks.onConnected();
316
254
  this._scheduleHeartbeats();
@@ -318,12 +256,7 @@ var EdgeWsConnection = class extends Resource {
318
256
  } else {
319
257
  log.verbose("connected after becoming inactive", {
320
258
  currentIdentity: this._identity
321
- }, {
322
- F: __dxlog_file3,
323
- L: 136,
324
- S: this,
325
- C: (f, a) => f(...a)
326
- });
259
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 120, S: this });
327
260
  }
328
261
  };
329
262
  this._ws.onclose = (event) => {
@@ -331,12 +264,7 @@ var EdgeWsConnection = class extends Resource {
331
264
  log.warn("server disconnected", {
332
265
  code: event.code,
333
266
  reason: event.reason
334
- }, {
335
- F: __dxlog_file3,
336
- L: 141,
337
- S: this,
338
- C: (f, a) => f(...a)
339
- });
267
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 127, S: this });
340
268
  this._callbacks.onRestartRequired();
341
269
  muxer.destroy();
342
270
  }
@@ -346,34 +274,19 @@ var EdgeWsConnection = class extends Resource {
346
274
  log.warn("edge connection socket error", {
347
275
  error: event.error,
348
276
  info: event.message
349
- }, {
350
- F: __dxlog_file3,
351
- L: 148,
352
- S: this,
353
- C: (f, a) => f(...a)
354
- });
277
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 137, S: this });
355
278
  this._callbacks.onRestartRequired();
356
279
  } else {
357
280
  log.verbose("error ignored on closed connection", {
358
281
  error: event.error
359
- }, {
360
- F: __dxlog_file3,
361
- L: 151,
362
- S: this,
363
- C: (f, a) => f(...a)
364
- });
282
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 143, S: this });
365
283
  }
366
284
  };
367
285
  this._ws.onmessage = async (event) => {
368
286
  if (!this.isOpen) {
369
287
  log.verbose("message ignored on closed connection", {
370
288
  event: event.type
371
- }, {
372
- F: __dxlog_file3,
373
- L: 159,
374
- S: this,
375
- C: (f, a) => f(...a)
376
- });
289
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 152, S: this });
377
290
  return;
378
291
  }
379
292
  this._lastReceivedMessageTimestamp = Date.now();
@@ -396,12 +309,7 @@ var EdgeWsConnection = class extends Resource {
396
309
  log("received", {
397
310
  from: message.source,
398
311
  payload: protocol.getPayloadType(message)
399
- }, {
400
- F: __dxlog_file3,
401
- L: 185,
402
- S: this,
403
- C: (f, a) => f(...a)
404
- });
312
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 175, S: this });
405
313
  this._callbacks.onMessage(message);
406
314
  }
407
315
  };
@@ -420,24 +328,11 @@ var EdgeWsConnection = class extends Resource {
420
328
  }
421
329
  log.warn("error closing websocket", {
422
330
  err
423
- }, {
424
- F: __dxlog_file3,
425
- L: 203,
426
- S: this,
427
- C: (f, a) => f(...a)
428
- });
331
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 194, S: this });
429
332
  }
430
333
  }
431
334
  _scheduleHeartbeats() {
432
- invariant3(this._ws, void 0, {
433
- F: __dxlog_file3,
434
- L: 208,
435
- S: this,
436
- A: [
437
- "this._ws",
438
- ""
439
- ]
440
- });
335
+ invariant3(this._ws, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 200, S: this, A: ["this._ws", ""] });
441
336
  scheduleTaskInterval(this._ctx, async () => {
442
337
  this._pingTimestamp = Date.now();
443
338
  this._ws?.send("__ping__");
@@ -451,21 +346,13 @@ var EdgeWsConnection = class extends Resource {
451
346
  return;
452
347
  }
453
348
  void this._inactivityTimeoutCtx?.dispose();
454
- this._inactivityTimeoutCtx = new Context(void 0, {
455
- F: __dxlog_file3,
456
- L: 229
457
- });
349
+ this._inactivityTimeoutCtx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 216 });
458
350
  scheduleTask(this._inactivityTimeoutCtx, () => {
459
351
  if (this.isOpen) {
460
352
  if (Date.now() - this._lastReceivedMessageTimestamp > SIGNAL_KEEPALIVE_TIMEOUT) {
461
353
  log.warn("restart due to inactivity timeout", {
462
354
  lastReceivedMessageTimestamp: this._lastReceivedMessageTimestamp
463
- }, {
464
- F: __dxlog_file3,
465
- L: 235,
466
- S: this,
467
- C: (f, a) => f(...a)
468
- });
355
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 220, S: this });
469
356
  this._callbacks.onRestartRequired();
470
357
  } else {
471
358
  this._rescheduleHeartbeatTimeout();
@@ -540,13 +427,13 @@ var getEdgeUrlWithProtocol = (baseUrl, protocol2) => {
540
427
  };
541
428
 
542
429
  // src/edge-client.ts
430
+ var __dxlog_file4 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
543
431
  function _ts_decorate2(decorators, target, key, desc) {
544
432
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
545
433
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
546
434
  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;
547
435
  return c > 3 && r && Object.defineProperty(target, key, r), r;
548
436
  }
549
- var __dxlog_file4 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
550
437
  var DEFAULT_TIMEOUT = 1e4;
551
438
  var STATUS_REFRESH_INTERVAL = 1e3;
552
439
  var EdgeClient = class extends Resource2 {
@@ -598,12 +485,7 @@ var EdgeClient = class extends Resource2 {
598
485
  log2("Edge identity changed", {
599
486
  identity,
600
487
  oldIdentity: this._identity
601
- }, {
602
- F: __dxlog_file4,
603
- L: 118,
604
- S: this,
605
- C: (f, a) => f(...a)
606
- });
488
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 74, S: this });
607
489
  this._identity = identity;
608
490
  this._closeCurrentConnection(new EdgeIdentityChangedError());
609
491
  void this._persistentLifecycle.scheduleRestart();
@@ -613,14 +495,9 @@ var EdgeClient = class extends Resource2 {
613
495
  * Send message.
614
496
  * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.
615
497
  */
616
- async send(message) {
498
+ async send(ctx, message) {
617
499
  if (this._ready.state !== TriggerState.RESOLVED) {
618
- log2("waiting for websocket", void 0, {
619
- F: __dxlog_file4,
620
- L: 131,
621
- S: this,
622
- C: (f, a) => f(...a)
623
- });
500
+ log2("waiting for websocket", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 88, S: this });
624
501
  await this._ready.wait({
625
502
  timeout: this._config.timeout ?? DEFAULT_TIMEOUT
626
503
  });
@@ -631,6 +508,14 @@ var EdgeClient = class extends Resource2 {
631
508
  if (message.source && (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)) {
632
509
  throw new EdgeIdentityChangedError();
633
510
  }
511
+ const traceCtx = ctx.getAttribute(TRACE_SPAN_ATTRIBUTE);
512
+ if (traceCtx) {
513
+ message.traceContext = {
514
+ $typeName: "dxos.edge.messenger.TraceContext",
515
+ traceparent: traceCtx.traceparent,
516
+ tracestate: traceCtx.tracestate
517
+ };
518
+ }
634
519
  this._currentConnection.send(message);
635
520
  }
636
521
  onMessage(listener) {
@@ -645,12 +530,7 @@ var EdgeClient = class extends Resource2 {
645
530
  try {
646
531
  listener();
647
532
  } catch (error) {
648
- log2.catch(error, void 0, {
649
- F: __dxlog_file4,
650
- L: 164,
651
- S: this,
652
- C: (f, a) => f(...a)
653
- });
533
+ log2.catch(error, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 123, S: this });
654
534
  }
655
535
  }
656
536
  });
@@ -663,21 +543,11 @@ var EdgeClient = class extends Resource2 {
663
543
  async _open() {
664
544
  log2("opening...", {
665
545
  info: this.info
666
- }, {
667
- F: __dxlog_file4,
668
- L: 177,
669
- S: this,
670
- C: (f, a) => f(...a)
671
- });
546
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 133, S: this });
672
547
  this._persistentLifecycle.open().catch((err) => {
673
548
  log2.warn("Error while opening connection", {
674
549
  err
675
- }, {
676
- F: __dxlog_file4,
677
- L: 179,
678
- S: this,
679
- C: (f, a) => f(...a)
680
- });
550
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 137, S: this });
681
551
  });
682
552
  scheduleTaskInterval2(this._ctx, async () => {
683
553
  if (!this._currentConnection) {
@@ -692,12 +562,7 @@ var EdgeClient = class extends Resource2 {
692
562
  async _close() {
693
563
  log2("closing...", {
694
564
  peerKey: this._identity.peerKey
695
- }, {
696
- F: __dxlog_file4,
697
- L: 199,
698
- S: this,
699
- C: (f, a) => f(...a)
700
- });
565
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 152, S: this });
701
566
  this._closeCurrentConnection();
702
567
  await this._persistentLifecycle.close();
703
568
  }
@@ -709,12 +574,7 @@ var EdgeClient = class extends Resource2 {
709
574
  const path = `/ws/${identity.identityKey}/${identity.peerKey}`;
710
575
  const protocolHeader = this._config.disableAuth ? void 0 : await this._createAuthHeader(path);
711
576
  if (this._identity !== identity) {
712
- log2("identity changed during auth header request", void 0, {
713
- F: __dxlog_file4,
714
- L: 213,
715
- S: this,
716
- C: (f, a) => f(...a)
717
- });
577
+ log2("identity changed during auth header request", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 166, S: this });
718
578
  return void 0;
719
579
  }
720
580
  const restartRequired = new Trigger();
@@ -722,27 +582,20 @@ var EdgeClient = class extends Resource2 {
722
582
  log2("Opening websocket", {
723
583
  url: url.toString(),
724
584
  protocolHeader
725
- }, {
726
- F: __dxlog_file4,
727
- L: 219,
728
- S: this,
729
- C: (f, a) => f(...a)
730
- });
585
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 171, S: this });
731
586
  const connection = new EdgeWsConnection(identity, {
732
587
  url,
733
- protocolHeader
588
+ protocolHeader,
589
+ headers: this._config.clientTag ? {
590
+ "X-DXOS-Client-Tag": this._config.clientTag
591
+ } : void 0
734
592
  }, {
735
593
  onConnected: () => {
736
594
  if (this._isActive(connection)) {
737
595
  this._ready.wake();
738
596
  this._notifyReconnected();
739
597
  } else {
740
- log2.verbose("connected callback ignored, because connection is not active", void 0, {
741
- F: __dxlog_file4,
742
- L: 229,
743
- S: this,
744
- C: (f, a) => f(...a)
745
- });
598
+ log2.verbose("connected callback ignored, because connection is not active", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 187, S: this });
746
599
  }
747
600
  },
748
601
  onRestartRequired: () => {
@@ -750,12 +603,7 @@ var EdgeClient = class extends Resource2 {
750
603
  this._closeCurrentConnection();
751
604
  void this._persistentLifecycle.scheduleRestart();
752
605
  } else {
753
- log2.verbose("restart requested by inactive connection", void 0, {
754
- F: __dxlog_file4,
755
- L: 237,
756
- S: this,
757
- C: (f, a) => f(...a)
758
- });
606
+ log2.verbose("restart requested by inactive connection", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 195, S: this });
759
607
  }
760
608
  restartRequired.wake();
761
609
  },
@@ -766,23 +614,21 @@ var EdgeClient = class extends Resource2 {
766
614
  log2.verbose("ignored a message on inactive connection", {
767
615
  from: message.source,
768
616
  type: message.payload?.typeUrl
769
- }, {
770
- F: __dxlog_file4,
771
- L: 245,
772
- S: this,
773
- C: (f, a) => f(...a)
774
- });
617
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 203, S: this });
775
618
  }
776
619
  }
777
620
  });
778
621
  this._currentConnection = connection;
779
622
  await connection.open();
780
- await Promise.race([
623
+ const becameReady = await Promise.race([
781
624
  this._ready.wait({
782
625
  timeout: this._config.timeout ?? DEFAULT_TIMEOUT
783
- }),
784
- restartRequired
626
+ }).then(() => true, () => false),
627
+ restartRequired.wait().then(() => false)
785
628
  ]);
629
+ if (!becameReady) {
630
+ throw new EdgeConnectionClosedError();
631
+ }
786
632
  return connection;
787
633
  }
788
634
  async _disconnect(state) {
@@ -803,12 +649,7 @@ var EdgeClient = class extends Resource2 {
803
649
  } catch (err) {
804
650
  log2.error("ws reconnect listener failed", {
805
651
  err
806
- }, {
807
- F: __dxlog_file4,
808
- L: 280,
809
- S: this,
810
- C: (f, a) => f(...a)
811
- });
652
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 244, S: this });
812
653
  }
813
654
  }
814
655
  }
@@ -820,12 +661,7 @@ var EdgeClient = class extends Resource2 {
820
661
  log2.error("ws incoming message processing failed", {
821
662
  err,
822
663
  payload: protocol.getPayloadType(message)
823
- }, {
824
- F: __dxlog_file4,
825
- L: 290,
826
- S: this,
827
- C: (f, a) => f(...a)
828
- });
664
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 255, S: this });
829
665
  }
830
666
  }
831
667
  }
@@ -841,12 +677,7 @@ var EdgeClient = class extends Resource2 {
841
677
  log2.warn("no auth challenge from edge", {
842
678
  status: response.status,
843
679
  statusText: response.statusText
844
- }, {
845
- F: __dxlog_file4,
846
- L: 302,
847
- S: this,
848
- C: (f, a) => f(...a)
849
- });
680
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 271, S: this });
850
681
  return void 0;
851
682
  }
852
683
  }
@@ -860,17 +691,12 @@ var encodePresentationWsAuthHeader = (encodedPresentation) => {
860
691
  return `base64url.bearer.authorization.dxos.org.${encodedToken}`;
861
692
  };
862
693
 
863
- // src/edge-http-client.ts
864
- import * as FetchHttpClient from "@effect/platform/FetchHttpClient";
865
- import * as HttpClient from "@effect/platform/HttpClient";
866
- import * as Effect2 from "effect/Effect";
867
- import * as Function from "effect/Function";
694
+ // src/base-http-client.ts
868
695
  import { sleep } from "@dxos/async";
869
- import { Context as Context3 } from "@dxos/context";
696
+ import { TRACE_SPAN_ATTRIBUTE as TRACE_SPAN_ATTRIBUTE2 } from "@dxos/context";
870
697
  import { invariant as invariant4 } from "@dxos/invariant";
871
698
  import { log as log4 } from "@dxos/log";
872
- import { EdgeAuthChallengeError, EdgeCallFailedError } from "@dxos/protocols";
873
- import { createUrl } from "@dxos/util";
699
+ import { EDGE_CLIENT_TAG_HEADER, EdgeAuthChallengeError, EdgeCallFailedError } from "@dxos/protocols";
874
700
 
875
701
  // src/http-client.ts
876
702
  import * as Context2 from "effect/Context";
@@ -903,41 +729,31 @@ var withRetryConfig = (effect) => Effect.gen(function* () {
903
729
  var withLogging = (effect) => effect.pipe(Effect.tap((res) => {
904
730
  log3.info("response", {
905
731
  status: res.status
906
- }, {
907
- F: __dxlog_file5,
908
- L: 66,
909
- S: void 0,
910
- C: (f, a) => f(...a)
911
- });
732
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 31, S: void 0 });
912
733
  }));
913
734
  var encodeAuthHeader = (challenge) => {
914
735
  const encodedChallenge = Buffer.from(challenge).toString("base64");
915
736
  return `VerifiablePresentation pb;base64,${encodedChallenge}`;
916
737
  };
917
738
 
918
- // src/edge-http-client.ts
919
- var __dxlog_file6 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-http-client.ts";
739
+ // src/base-http-client.ts
740
+ var __dxlog_file6 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/base-http-client.ts";
920
741
  var DEFAULT_RETRY_TIMEOUT = 1500;
921
742
  var DEFAULT_RETRY_JITTER = 500;
922
743
  var DEFAULT_MAX_RETRIES_COUNT = 3;
923
744
  var WARNING_BODY_SIZE = 10 * 1024 * 1024;
924
- var EdgeHttpClient = class {
745
+ var BaseHttpClient = class {
925
746
  _baseUrl;
747
+ _clientTag;
926
748
  _edgeIdentity;
927
- /**
928
- * Auth header is cached until receiving the next 401 from EDGE, at which point it gets refreshed.
929
- */
749
+ /** Auth header cached until next 401. */
930
750
  _authHeader;
931
- constructor(baseUrl) {
751
+ constructor(baseUrl, options) {
932
752
  this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
753
+ this._clientTag = options?.clientTag;
933
754
  log4("created", {
934
755
  url: this._baseUrl
935
- }, {
936
- F: __dxlog_file6,
937
- L: 107,
938
- S: this,
939
- C: (f, a) => f(...a)
940
- });
756
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 24, S: this });
941
757
  }
942
758
  get baseUrl() {
943
759
  return this._baseUrl;
@@ -948,27 +764,276 @@ var EdgeHttpClient = class {
948
764
  this._authHeader = void 0;
949
765
  }
950
766
  }
767
+ // TODO(mykola): Extend `_call` to support streaming/raw `Response` returns so
768
+ // `EdgeHttpClient.anthropicAiRequest` can be absorbed here and the auth/retry loop
769
+ // stops being duplicated across the two paths.
770
+ async _call(ctx, url, args) {
771
+ const shouldRetry = createRetryHandler(args);
772
+ log4("fetch", {
773
+ url,
774
+ hasBody: args.body !== void 0,
775
+ bodySize: typeof args.body === "string" ? args.body.length : void 0
776
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 43, S: this });
777
+ const traceHeaders = getTraceHeaders(ctx);
778
+ let handledAuth = false;
779
+ const tryCount = 1;
780
+ while (true) {
781
+ let processingError = void 0;
782
+ try {
783
+ if (!this._authHeader && args.auth) {
784
+ const response2 = await fetch(new URL("/auth", this._baseUrl));
785
+ if (response2.status === 401) {
786
+ this._authHeader = await this._handleUnauthorized(response2);
787
+ }
788
+ }
789
+ const request = createRequest(args, this._authHeader, traceHeaders, this._clientTag);
790
+ log4("call", {
791
+ url,
792
+ tryCount,
793
+ authHeader: !!this._authHeader
794
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 61, S: this });
795
+ const response = await fetch(url, request);
796
+ if (response.ok) {
797
+ const contentType2 = response.headers.get("Content-Type") ?? "";
798
+ if (response.status === 204 || response.headers.get("Content-Length") === "0" || !contentType2.includes("application/json")) {
799
+ return void 0;
800
+ }
801
+ const body2 = await response.clone().json();
802
+ if (typeof body2 !== "object" || body2 === null) {
803
+ return body2;
804
+ }
805
+ if (!("success" in body2)) {
806
+ return body2;
807
+ }
808
+ if (body2.success) {
809
+ return body2.data;
810
+ }
811
+ } else if (response.status === 401 && response.headers.get("WWW-Authenticate") !== null && !handledAuth) {
812
+ this._authHeader = await this._handleUnauthorized(response);
813
+ handledAuth = true;
814
+ continue;
815
+ }
816
+ const contentType = response.headers.get("Content-Type") ?? "";
817
+ const body = contentType.startsWith("application/json") ? await response.clone().json() : void 0;
818
+ invariant4(!body?.success, "Expected body to not be a failure response or undefined.", { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 92, S: this, A: ["!body?.success", "'Expected body to not be a failure response or undefined.'"] });
819
+ if (body?.data?.type === "auth_challenge" && typeof body?.data?.challenge === "string") {
820
+ processingError = new EdgeAuthChallengeError(body.data.challenge, body.data);
821
+ } else if (body?.success === false) {
822
+ processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);
823
+ } else {
824
+ invariant4(!response.ok, "Expected response to not be ok.", { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 98, S: this, A: ["!response.ok", "'Expected response to not be ok.'"] });
825
+ processingError = await EdgeCallFailedError.fromHttpFailure(response);
826
+ }
827
+ } catch (error) {
828
+ processingError = EdgeCallFailedError.fromProcessingFailureCause(error);
829
+ }
830
+ if (processingError?.isRetryable && await shouldRetry(ctx, processingError.retryAfterMs)) {
831
+ log4.verbose("retrying request", {
832
+ url,
833
+ processingError
834
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 105, S: this });
835
+ } else {
836
+ throw processingError;
837
+ }
838
+ }
839
+ }
840
+ async _handleUnauthorized(response) {
841
+ if (!this._edgeIdentity) {
842
+ log4.warn("unauthorized response received before identity was set", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 116, S: this });
843
+ throw await EdgeCallFailedError.fromHttpFailure(response);
844
+ }
845
+ const challenge = await handleAuthChallenge(response, this._edgeIdentity);
846
+ return encodeAuthHeader(challenge);
847
+ }
848
+ };
849
+ var createRequest = ({ method, body, json = true }, authHeader, traceHeaders, clientTag) => {
850
+ let requestBody;
851
+ const headers = {};
852
+ if (json) {
853
+ requestBody = body === void 0 ? void 0 : JSON.stringify(body);
854
+ headers["Content-Type"] = "application/json";
855
+ } else {
856
+ requestBody = body;
857
+ }
858
+ if (typeof requestBody === "string" && requestBody.length > WARNING_BODY_SIZE) {
859
+ log4.warn("Request with large body", {
860
+ bodySize: requestBody.length
861
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 133, S: void 0 });
862
+ }
863
+ if (authHeader) {
864
+ headers["Authorization"] = authHeader;
865
+ }
866
+ if (traceHeaders) {
867
+ Object.assign(headers, traceHeaders);
868
+ }
869
+ if (clientTag) {
870
+ headers[EDGE_CLIENT_TAG_HEADER] = clientTag;
871
+ }
872
+ return {
873
+ method,
874
+ body: requestBody,
875
+ headers
876
+ };
877
+ };
878
+ var getTraceHeaders = (ctx) => {
879
+ const traceCtx = ctx.getAttribute(TRACE_SPAN_ATTRIBUTE2);
880
+ if (!traceCtx) {
881
+ return void 0;
882
+ }
883
+ const headers = {
884
+ traceparent: traceCtx.traceparent
885
+ };
886
+ if (traceCtx.tracestate) {
887
+ headers.tracestate = traceCtx.tracestate;
888
+ }
889
+ return headers;
890
+ };
891
+ var createRetryHandler = ({ retry: retry2 }) => {
892
+ if (!retry2 || retry2.count < 1) {
893
+ return async () => false;
894
+ }
895
+ let retries = 0;
896
+ const maxRetries = retry2.count ?? DEFAULT_MAX_RETRIES_COUNT;
897
+ const baseTimeout = retry2.timeout ?? DEFAULT_RETRY_TIMEOUT;
898
+ const jitter = retry2.jitter ?? DEFAULT_RETRY_JITTER;
899
+ return async (ctx, retryAfter) => {
900
+ if (++retries > maxRetries || ctx.disposed) {
901
+ return false;
902
+ }
903
+ if (retryAfter) {
904
+ await sleep(retryAfter);
905
+ } else {
906
+ const timeout2 = baseTimeout + Math.random() * jitter;
907
+ await sleep(timeout2);
908
+ }
909
+ return true;
910
+ };
911
+ };
912
+
913
+ // src/edge-ai-http-client.ts
914
+ import * as Headers2 from "@effect/platform/Headers";
915
+ import * as HttpClient from "@effect/platform/HttpClient";
916
+ import * as HttpClientError from "@effect/platform/HttpClientError";
917
+ import * as HttpClientResponse from "@effect/platform/HttpClientResponse";
918
+ import * as Effect2 from "effect/Effect";
919
+ import * as FiberRef from "effect/FiberRef";
920
+ import * as Layer2 from "effect/Layer";
921
+ import * as Stream from "effect/Stream";
922
+ import { BaseError } from "@dxos/errors";
923
+ import { log as log5 } from "@dxos/log";
924
+ import { BYOK_HEADER } from "@dxos/protocols";
925
+ var __dxlog_file7 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-ai-http-client.ts";
926
+ var ByokError = class extends BaseError.extend("ByokError", "BYOK authentication failed") {
927
+ constructor(options) {
928
+ super({
929
+ context: {
930
+ status: options.status,
931
+ provider: options.provider
932
+ },
933
+ ...options
934
+ });
935
+ }
936
+ };
937
+ var requestInitTagKey = "@effect/platform/FetchHttpClient/FetchOptions";
938
+ var EdgeAiHttpClient = class _EdgeAiHttpClient {
939
+ static make = (getClient) => HttpClient.make((request, url, signal, fiber) => {
940
+ const edgeClient = getClient();
941
+ const context = fiber.getFiberRef(FiberRef.currentContext);
942
+ const options = context.unsafeMap.get(requestInitTagKey) ?? {};
943
+ const headers = options.headers ? Headers2.merge(Headers2.fromInput(options.headers), request.headers) : request.headers;
944
+ const carriedByok = !!headers[BYOK_HEADER.toLowerCase()];
945
+ const send = (body) => Effect2.tryPromise({
946
+ try: () => edgeClient.anthropicAiRequest(new Request(url, {
947
+ ...options,
948
+ method: request.method,
949
+ headers,
950
+ body,
951
+ signal
952
+ })),
953
+ catch: (cause) => {
954
+ log5.error("Failed to fetch", {
955
+ cause
956
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 60, S: this });
957
+ return new HttpClientError.RequestError({
958
+ request,
959
+ reason: "Transport",
960
+ cause
961
+ });
962
+ }
963
+ }).pipe(Effect2.flatMap((response) => {
964
+ const httpResponse = HttpClientResponse.fromWeb(request, response);
965
+ if (carriedByok && (response.status === 401 || response.status === 403)) {
966
+ return Effect2.tryPromise({
967
+ try: () => response.clone().json(),
968
+ catch: () => void 0
969
+ }).pipe(Effect2.orElseSucceed(() => void 0), Effect2.flatMap((body2) => Effect2.fail(new HttpClientError.ResponseError({
970
+ request,
971
+ response: httpResponse,
972
+ reason: "StatusCode",
973
+ cause: new ByokError({
974
+ status: response.status,
975
+ provider: "anthropic.com",
976
+ message: body2?.error?.message ?? "Authentication failed"
977
+ })
978
+ }))));
979
+ }
980
+ return Effect2.succeed(httpResponse);
981
+ }));
982
+ switch (request.body._tag) {
983
+ case "Raw":
984
+ case "Uint8Array":
985
+ return send(request.body.body);
986
+ case "FormData":
987
+ return send(request.body.formData);
988
+ case "Stream":
989
+ return Stream.toReadableStreamEffect(request.body.stream).pipe(Effect2.flatMap(send));
990
+ }
991
+ return send(void 0);
992
+ });
993
+ static layer = (getClient) => Layer2.succeed(HttpClient.HttpClient, _EdgeAiHttpClient.make(getClient));
994
+ };
995
+
996
+ // src/edge-http-client.ts
997
+ import * as FetchHttpClient from "@effect/platform/FetchHttpClient";
998
+ import * as HttpClient3 from "@effect/platform/HttpClient";
999
+ import * as HttpClientRequest from "@effect/platform/HttpClientRequest";
1000
+ import * as Effect3 from "effect/Effect";
1001
+ import * as Function from "effect/Function";
1002
+ import { EffectEx } from "@dxos/effect";
1003
+ import { invariant as invariant5 } from "@dxos/invariant";
1004
+ import { log as log6 } from "@dxos/log";
1005
+ import { EDGE_CLIENT_TAG_HEADER as EDGE_CLIENT_TAG_HEADER2 } from "@dxos/protocols";
1006
+ import { createUrl } from "@dxos/util";
1007
+ var __dxlog_file8 = "/__w/dxos/dxos/packages/core/mesh/edge-client/src/edge-http-client.ts";
1008
+ var EdgeHttpClient = class extends BaseHttpClient {
1009
+ constructor(baseUrl, options) {
1010
+ super(baseUrl, options);
1011
+ log6("created", {
1012
+ url: this.baseUrl
1013
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 25, S: this });
1014
+ }
951
1015
  //
952
1016
  // Status
953
1017
  //
954
- async getStatus(args) {
955
- return this._call(new URL("/status", this.baseUrl), {
1018
+ async getStatus(ctx, args) {
1019
+ return this._call(ctx, new URL("/status", this.baseUrl), {
956
1020
  ...args,
957
- method: "GET"
1021
+ method: "GET",
1022
+ auth: true
958
1023
  });
959
1024
  }
960
1025
  //
961
1026
  // Agents
962
1027
  //
963
- createAgent(body, args) {
964
- return this._call(new URL("/agents/create", this.baseUrl), {
1028
+ createAgent(ctx, body, args) {
1029
+ return this._call(ctx, new URL("/agents/create", this.baseUrl), {
965
1030
  ...args,
966
1031
  method: "POST",
967
1032
  body
968
1033
  });
969
1034
  }
970
- getAgentStatus(request, args) {
971
- return this._call(new URL(`/users/${request.ownerIdentityKey.toHex()}/agent/status`, this.baseUrl), {
1035
+ getAgentStatus(ctx, request, args) {
1036
+ return this._call(ctx, new URL(`/users/${request.ownerIdentityKey.toHex()}/agent/status`, this.baseUrl), {
972
1037
  ...args,
973
1038
  method: "GET"
974
1039
  });
@@ -976,14 +1041,14 @@ var EdgeHttpClient = class {
976
1041
  //
977
1042
  // Credentials
978
1043
  //
979
- getCredentialsForNotarization(spaceId, args) {
980
- return this._call(new URL(`/spaces/${spaceId}/notarization`, this.baseUrl), {
1044
+ getCredentialsForNotarization(ctx, spaceId, args) {
1045
+ return this._call(ctx, new URL(`/spaces/${spaceId}/notarization`, this.baseUrl), {
981
1046
  ...args,
982
1047
  method: "GET"
983
1048
  });
984
1049
  }
985
- async notarizeCredentials(spaceId, body, args) {
986
- await this._call(new URL(`/spaces/${spaceId}/notarization`, this.baseUrl), {
1050
+ async notarizeCredentials(ctx, spaceId, body, args) {
1051
+ await this._call(ctx, new URL(`/spaces/${spaceId}/notarization`, this.baseUrl), {
987
1052
  ...args,
988
1053
  body,
989
1054
  method: "POST"
@@ -992,28 +1057,35 @@ var EdgeHttpClient = class {
992
1057
  //
993
1058
  // Identity
994
1059
  //
995
- async recoverIdentity(body, args) {
996
- return this._call(new URL("/identity/recover", this.baseUrl), {
1060
+ async recoverIdentity(ctx, body, args) {
1061
+ return this._call(ctx, new URL("/identity/recover", this.baseUrl), {
997
1062
  ...args,
998
1063
  body,
999
1064
  method: "POST"
1000
1065
  });
1001
1066
  }
1002
1067
  //
1003
- // Invitations
1068
+ // Invitations (space join)
1004
1069
  //
1005
- async joinSpaceByInvitation(spaceId, body, args) {
1006
- return this._call(new URL(`/spaces/${spaceId}/join`, this.baseUrl), {
1070
+ async joinSpaceByInvitation(ctx, spaceId, body, args) {
1071
+ return this._call(ctx, new URL(`/spaces/${spaceId}/join`, this.baseUrl), {
1007
1072
  ...args,
1008
1073
  body,
1009
1074
  method: "POST"
1010
1075
  });
1011
1076
  }
1012
1077
  //
1013
- // OAuth and credentials
1078
+ // OAuth
1014
1079
  //
1015
- async initiateOAuthFlow(body, args) {
1016
- return this._call(new URL("/oauth/initiate", this.baseUrl), {
1080
+ async initiateOAuthFlow(ctx, body, args) {
1081
+ return this._call(ctx, new URL("/oauth/initiate", this.baseUrl), {
1082
+ ...args,
1083
+ body,
1084
+ method: "POST"
1085
+ });
1086
+ }
1087
+ async completeOAuthRegistration(ctx, body, args) {
1088
+ return this._call(ctx, new URL("/oauth/registration/complete", this.baseUrl), {
1017
1089
  ...args,
1018
1090
  body,
1019
1091
  method: "POST"
@@ -1022,8 +1094,8 @@ var EdgeHttpClient = class {
1022
1094
  //
1023
1095
  // Spaces
1024
1096
  //
1025
- async createSpace(body, args) {
1026
- return this._call(new URL("/spaces/create", this.baseUrl), {
1097
+ async createSpace(ctx, body, args) {
1098
+ return this._call(ctx, new URL("/spaces/create", this.baseUrl), {
1027
1099
  ...args,
1028
1100
  body,
1029
1101
  method: "POST"
@@ -1032,9 +1104,10 @@ var EdgeHttpClient = class {
1032
1104
  //
1033
1105
  // Queues
1034
1106
  //
1035
- async queryQueue(subspaceTag, spaceId, query, args) {
1036
- const { queueId } = query;
1037
- return this._call(createUrl(new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}/query`, this.baseUrl), {
1107
+ async queryQueue(ctx, subspaceTag, spaceId, query, args) {
1108
+ const queueId = query.queueIds?.[0];
1109
+ invariant5(queueId, "queueId required", { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 123, S: this, A: ["queueId", "'queueId required'"] });
1110
+ return this._call(ctx, createUrl(new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}/query`, this.baseUrl), {
1038
1111
  after: query.after,
1039
1112
  before: query.before,
1040
1113
  limit: query.limit,
@@ -1045,8 +1118,8 @@ var EdgeHttpClient = class {
1045
1118
  method: "GET"
1046
1119
  });
1047
1120
  }
1048
- async insertIntoQueue(subspaceTag, spaceId, queueId, objects, args) {
1049
- return this._call(new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}`, this.baseUrl), {
1121
+ async insertIntoQueue(ctx, subspaceTag, spaceId, queueId, objects, args) {
1122
+ return this._call(ctx, new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}`, this.baseUrl), {
1050
1123
  ...args,
1051
1124
  body: {
1052
1125
  objects
@@ -1054,8 +1127,8 @@ var EdgeHttpClient = class {
1054
1127
  method: "POST"
1055
1128
  });
1056
1129
  }
1057
- async deleteFromQueue(subspaceTag, spaceId, queueId, objectIds, args) {
1058
- return this._call(createUrl(new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}`, this.baseUrl), {
1130
+ async deleteFromQueue(ctx, subspaceTag, spaceId, queueId, objectIds, args) {
1131
+ return this._call(ctx, createUrl(new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}`, this.baseUrl), {
1059
1132
  ids: objectIds.join(",")
1060
1133
  }), {
1061
1134
  ...args,
@@ -1065,7 +1138,7 @@ var EdgeHttpClient = class {
1065
1138
  //
1066
1139
  // Functions
1067
1140
  //
1068
- async uploadFunction(pathParts, body, args) {
1141
+ async uploadFunction(ctx, pathParts, body, args) {
1069
1142
  const formData = new FormData();
1070
1143
  formData.append("name", body.name ?? "");
1071
1144
  formData.append("version", body.version);
@@ -1085,20 +1158,20 @@ var EdgeHttpClient = class {
1085
1158
  pathParts.functionId
1086
1159
  ] : []
1087
1160
  ].join("/");
1088
- return this._call(new URL(path, this.baseUrl), {
1161
+ return this._call(ctx, new URL(path, this.baseUrl), {
1089
1162
  ...args,
1090
1163
  body: formData,
1091
1164
  method: "PUT",
1092
1165
  json: false
1093
1166
  });
1094
1167
  }
1095
- async listFunctions(args) {
1096
- return this._call(new URL("/functions", this.baseUrl), {
1168
+ async listFunctions(ctx, args) {
1169
+ return this._call(ctx, new URL("/functions", this.baseUrl), {
1097
1170
  ...args,
1098
1171
  method: "GET"
1099
1172
  });
1100
1173
  }
1101
- async invokeFunction(params, input, args) {
1174
+ async invokeFunction(ctx, params, input, args) {
1102
1175
  const url = new URL(`/functions/${params.functionId}`, this.baseUrl);
1103
1176
  if (params.version) {
1104
1177
  url.searchParams.set("version", params.version);
@@ -1112,18 +1185,17 @@ var EdgeHttpClient = class {
1112
1185
  if (params.subrequestsLimit) {
1113
1186
  url.searchParams.set("subrequestsLimit", params.subrequestsLimit.toString());
1114
1187
  }
1115
- return this._call(url, {
1188
+ return this._call(ctx, url, {
1116
1189
  ...args,
1117
1190
  body: input,
1118
- method: "POST",
1119
- rawResponse: true
1191
+ method: "POST"
1120
1192
  });
1121
1193
  }
1122
1194
  //
1123
1195
  // Workflows
1124
1196
  //
1125
- async executeWorkflow(spaceId, graphId, input, args) {
1126
- return this._call(new URL(`/workflows/${spaceId}/${graphId}`, this.baseUrl), {
1197
+ async executeWorkflow(ctx, spaceId, graphId, input, args) {
1198
+ return this._call(ctx, new URL(`/workflows/${spaceId}/${graphId}`, this.baseUrl), {
1127
1199
  ...args,
1128
1200
  body: input,
1129
1201
  method: "POST"
@@ -1132,217 +1204,229 @@ var EdgeHttpClient = class {
1132
1204
  //
1133
1205
  // Triggers
1134
1206
  //
1135
- async getCronTriggers(spaceId) {
1136
- return this._call(new URL(`/test/functions/${spaceId}/triggers/crons`, this.baseUrl), {
1207
+ async getCronTriggers(ctx, spaceId) {
1208
+ return this._call(ctx, new URL(`/functions/${spaceId}/triggers/crons`, this.baseUrl), {
1209
+ method: "GET"
1210
+ });
1211
+ }
1212
+ async getTriggersDispatcherStatus(ctx, spaceId, args) {
1213
+ return this._call(ctx, new URL(`/triggers/${spaceId}/status`, this.baseUrl), {
1214
+ ...args,
1215
+ method: "GET",
1216
+ auth: true
1217
+ });
1218
+ }
1219
+ async forceRunCronTrigger(ctx, spaceId, triggerId) {
1220
+ return this._call(ctx, new URL(`/functions/${spaceId}/triggers/crons/${triggerId}/run`, this.baseUrl), {
1221
+ method: "POST"
1222
+ });
1223
+ }
1224
+ //
1225
+ // Query
1226
+ //
1227
+ async execQuery(ctx, spaceId, body, args) {
1228
+ return this._call(ctx, new URL(`/spaces/${spaceId}/exec-query`, this.baseUrl), {
1229
+ ...args,
1230
+ body,
1231
+ method: "POST"
1232
+ });
1233
+ }
1234
+ //
1235
+ // Registry
1236
+ //
1237
+ async getRegistryPlugins(ctx, args) {
1238
+ return this._call(ctx, new URL("/registry/plugins", this.baseUrl), {
1239
+ ...args,
1240
+ method: "GET"
1241
+ });
1242
+ }
1243
+ async getRegistryPluginVersions(ctx, repo, args) {
1244
+ return this._call(ctx, new URL(`/registry/plugins/${encodeURIComponent(repo)}/versions`, this.baseUrl), {
1245
+ ...args,
1137
1246
  method: "GET"
1138
1247
  });
1139
1248
  }
1140
1249
  //
1141
- // Import/Export space.
1250
+ // Import/Export
1142
1251
  //
1143
- async importBundle(spaceId, body, args) {
1144
- return this._call(new URL(`/spaces/${spaceId}/import`, this.baseUrl), {
1252
+ async importBundle(ctx, spaceId, body, args) {
1253
+ return this._call(ctx, new URL(`/spaces/${spaceId}/import`, this.baseUrl), {
1145
1254
  ...args,
1146
1255
  body,
1147
1256
  method: "PUT"
1148
1257
  });
1149
1258
  }
1150
- async exportBundle(spaceId, body, args) {
1151
- return this._call(new URL(`/spaces/${spaceId}/export`, this.baseUrl), {
1259
+ async exportBundle(ctx, spaceId, body, args) {
1260
+ return this._call(ctx, new URL(`/spaces/${spaceId}/export`, this.baseUrl), {
1152
1261
  ...args,
1153
1262
  body,
1154
1263
  method: "POST"
1155
1264
  });
1156
1265
  }
1157
1266
  //
1158
- // Internal
1267
+ // Proxy
1159
1268
  //
1160
- async _fetch(url, _args) {
1161
- return Function.pipe(HttpClient.get(url), withLogging, withRetryConfig, Effect2.provide(FetchHttpClient.layer), Effect2.provide(HttpConfig.default), Effect2.withSpan("EdgeHttpClient"), Effect2.runPromise);
1269
+ /**
1270
+ * Fetch through the edge proxy for third-party REST APIs.
1271
+ * TEMPORARY: currently routes through legacy open proxy. See https://github.com/dxos/edge/pull/576.
1272
+ */
1273
+ async proxyFetch(target, init = {}) {
1274
+ return proxyFetchLegacy(target, init, this._clientTag);
1162
1275
  }
1163
- // TODO(burdon): Refactor with effect (see edge-http-client.test.ts).
1164
- async _call(url, args) {
1165
- const shouldRetry = createRetryHandler(args);
1166
- const requestContext = args.context ?? Context3.default(void 0, {
1167
- F: __dxlog_file6,
1168
- L: 400
1169
- });
1170
- log4("fetch", {
1171
- url,
1172
- request: args.body
1173
- }, {
1174
- F: __dxlog_file6,
1175
- L: 401,
1176
- S: this,
1177
- C: (f, a) => f(...a)
1178
- });
1276
+ //
1277
+ // AI service.
1278
+ //
1279
+ /**
1280
+ * Issue an authenticated request to the EDGE AI route (`/ai/generate/anthropic/*`), which
1281
+ * proxies to the AI service. Used as the backend HTTP client for the Anthropic AI provider
1282
+ * (see {@link EdgeAiHttpClient}).
1283
+ *
1284
+ * Returns the raw `Response` so streaming bodies are forwarded unchanged to `@effect/ai`.
1285
+ * Requires an identity to have been set via {@link setIdentity}.
1286
+ */
1287
+ // TODO(mykola): Merge into `BaseHttpClient._call` once it can return a streaming/raw `Response`;
1288
+ // the auth/retry loop below duplicates the one in `_call`.
1289
+ async anthropicAiRequest(request) {
1290
+ const incoming = new URL(request.url);
1291
+ const base = this.baseUrl.replace(/\/$/, "");
1292
+ const target = new URL(`${base}/ai/generate/anthropic${incoming.pathname}${incoming.search}`);
1293
+ const method = request.method;
1294
+ const body = method === "GET" || method === "HEAD" ? void 0 : await request.arrayBuffer();
1179
1295
  let handledAuth = false;
1180
- const tryCount = 1;
1181
1296
  while (true) {
1182
- let processingError = void 0;
1183
- try {
1184
- if (!this._authHeader && args.auth) {
1185
- const response2 = await fetch(new URL(`/auth`, this.baseUrl));
1186
- if (response2.status === 401) {
1187
- this._authHeader = await this._handleUnauthorized(response2);
1188
- }
1297
+ if (!this._authHeader) {
1298
+ const authResponse = await fetch(new URL("/auth", this.baseUrl));
1299
+ if (authResponse.status === 401) {
1300
+ this._authHeader = await this._handleUnauthorized(authResponse);
1189
1301
  }
1190
- const request = createRequest(args, this._authHeader);
1191
- log4("call edge", {
1192
- url,
1193
- tryCount,
1194
- authHeader: !!this._authHeader
1195
- }, {
1196
- F: __dxlog_file6,
1197
- L: 416,
1198
- S: this,
1199
- C: (f, a) => f(...a)
1200
- });
1201
- const response = await fetch(url, request);
1202
- if (response.ok) {
1203
- const body2 = await response.clone().json();
1204
- if (args.rawResponse) {
1205
- return body2;
1206
- }
1207
- invariant4(body2, "Expected body to be present", {
1208
- F: __dxlog_file6,
1209
- L: 424,
1210
- S: this,
1211
- A: [
1212
- "body",
1213
- "'Expected body to be present'"
1214
- ]
1215
- });
1216
- if (!("success" in body2)) {
1217
- return body2;
1218
- }
1219
- if (body2.success) {
1220
- return body2.data;
1221
- }
1222
- } else if (response.status === 401 && !handledAuth) {
1223
- this._authHeader = await this._handleUnauthorized(response);
1224
- handledAuth = true;
1225
- continue;
1226
- }
1227
- const body = response.headers.get("Content-Type") === "application/json" ? await response.clone().json() : void 0;
1228
- invariant4(!body?.success, "Expected body to not be a failure response or undefined.", {
1229
- F: __dxlog_file6,
1230
- L: 440,
1231
- S: this,
1232
- A: [
1233
- "!body?.success",
1234
- "'Expected body to not be a failure response or undefined.'"
1235
- ]
1236
- });
1237
- if (body?.errorData?.type === "auth_challenge" && typeof body?.errorData?.challenge === "string") {
1238
- processingError = new EdgeAuthChallengeError(body.errorData.challenge, body.errorData);
1239
- } else if (body?.success === false) {
1240
- processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);
1241
- } else {
1242
- invariant4(!response.ok, "Expected response to not be ok.", {
1243
- F: __dxlog_file6,
1244
- L: 447,
1245
- S: this,
1246
- A: [
1247
- "!response.ok",
1248
- "'Expected response to not be ok.'"
1249
- ]
1250
- });
1251
- processingError = await EdgeCallFailedError.fromHttpFailure(response);
1252
- }
1253
- } catch (error) {
1254
- processingError = EdgeCallFailedError.fromProcessingFailureCause(error);
1255
1302
  }
1256
- if (processingError?.isRetryable && await shouldRetry(requestContext, processingError.retryAfterMs)) {
1257
- log4.verbose("retrying edge request", {
1258
- url,
1259
- processingError
1260
- }, {
1261
- F: __dxlog_file6,
1262
- L: 455,
1263
- S: this,
1264
- C: (f, a) => f(...a)
1265
- });
1266
- } else {
1267
- throw processingError;
1303
+ const headers = new Headers(request.headers);
1304
+ if (this._authHeader) {
1305
+ headers.set("Authorization", this._authHeader);
1268
1306
  }
1269
- }
1270
- }
1271
- async _handleUnauthorized(response) {
1272
- if (!this._edgeIdentity) {
1273
- log4.warn("unauthorized response received before identity was set", void 0, {
1274
- F: __dxlog_file6,
1275
- L: 464,
1276
- S: this,
1277
- C: (f, a) => f(...a)
1307
+ if (this._clientTag) {
1308
+ headers.set(EDGE_CLIENT_TAG_HEADER2, this._clientTag);
1309
+ }
1310
+ const response = await fetch(target, {
1311
+ method,
1312
+ headers,
1313
+ body,
1314
+ signal: request.signal
1278
1315
  });
1279
- throw await EdgeCallFailedError.fromHttpFailure(response);
1316
+ if (response.status === 401 && response.headers.get("WWW-Authenticate") !== null && !handledAuth) {
1317
+ this._authHeader = await this._handleUnauthorized(response);
1318
+ handledAuth = true;
1319
+ continue;
1320
+ }
1321
+ return response;
1280
1322
  }
1281
- const challenge = await handleAuthChallenge(response, this._edgeIdentity);
1282
- return encodeAuthHeader(challenge);
1323
+ }
1324
+ //
1325
+ // Internal (Effect-based, used by tests)
1326
+ //
1327
+ async _fetch(url, _args) {
1328
+ return Function.pipe(HttpClient3.execute(HttpClientRequest.make(_args.method)(url.toString())), withLogging, withRetryConfig, Effect3.provide(FetchHttpClient.layer), Effect3.provide(HttpConfig.default), Effect3.withSpan("EdgeHttpClient"), EffectEx.runAndForwardErrors);
1283
1329
  }
1284
1330
  };
1285
- var createRequest = ({ method, body, json = true }, authHeader) => {
1286
- let requestBody;
1287
- const headers = {};
1288
- if (json) {
1289
- requestBody = body && JSON.stringify(body);
1290
- headers["Content-Type"] = "application/json";
1291
- } else {
1292
- requestBody = body;
1331
+ var getFileMimeType = (filename) => [
1332
+ ".js",
1333
+ ".mjs"
1334
+ ].some((ext) => filename.endsWith(ext)) ? "application/javascript+module" : filename.endsWith(".wasm") ? "application/wasm" : "application/octet-stream";
1335
+
1336
+ // src/hub-http-client.ts
1337
+ var HubHttpClient = class extends BaseHttpClient {
1338
+ constructor(hubUrl, options) {
1339
+ super(hubUrl, options);
1293
1340
  }
1294
- if (typeof requestBody === "string" && requestBody.length > WARNING_BODY_SIZE) {
1295
- log4.warn("Request with large body", {
1296
- bodySize: requestBody.length
1297
- }, {
1298
- F: __dxlog_file6,
1299
- L: 488,
1300
- S: void 0,
1301
- C: (f, a) => f(...a)
1341
+ //
1342
+ // Public (unauthenticated) endpoints
1343
+ //
1344
+ async checkEmailExists(ctx, body, args) {
1345
+ return this._call(ctx, new URL("/account/email/exists", this.baseUrl), {
1346
+ ...args,
1347
+ body,
1348
+ method: "POST"
1302
1349
  });
1303
1350
  }
1304
- if (authHeader) {
1305
- headers["Authorization"] = authHeader;
1351
+ async validateInvitationCode(ctx, body, args) {
1352
+ return this._call(ctx, new URL("/account/invitation-code/validate", this.baseUrl), {
1353
+ ...args,
1354
+ body,
1355
+ method: "POST"
1356
+ });
1306
1357
  }
1307
- return {
1308
- method,
1309
- body: requestBody,
1310
- headers
1311
- };
1312
- };
1313
- var createRetryHandler = ({ retry: retry2 }) => {
1314
- if (!retry2 || retry2.count < 1) {
1315
- return async () => false;
1358
+ async redeemInvitationCode(ctx, body, args) {
1359
+ return this._call(ctx, new URL("/account/invitation-code/redeem", this.baseUrl), {
1360
+ ...args,
1361
+ body,
1362
+ method: "POST"
1363
+ });
1364
+ }
1365
+ /**
1366
+ * Existing-account email login. Server inlines `token` for test emails; regular
1367
+ * emails are delivered out-of-band. Response is identical for unknown emails
1368
+ * (enumeration-safe).
1369
+ */
1370
+ async login(ctx, body, args) {
1371
+ return this._call(ctx, new URL("/account/login", this.baseUrl), {
1372
+ ...args,
1373
+ body,
1374
+ method: "POST"
1375
+ });
1376
+ }
1377
+ async requestAccess(ctx, body, args) {
1378
+ return this._call(ctx, new URL("/account/request-access", this.baseUrl), {
1379
+ ...args,
1380
+ body,
1381
+ method: "POST"
1382
+ });
1383
+ }
1384
+ //
1385
+ // Authenticated (VP) endpoints
1386
+ //
1387
+ async getAccount(ctx, args) {
1388
+ return this._call(ctx, new URL("/account/me", this.baseUrl), {
1389
+ ...args,
1390
+ method: "GET"
1391
+ });
1392
+ }
1393
+ async deleteAccount(ctx, args) {
1394
+ return this._call(ctx, new URL("/account/me", this.baseUrl), {
1395
+ ...args,
1396
+ method: "DELETE"
1397
+ });
1398
+ }
1399
+ async listAccountInvitations(ctx, args) {
1400
+ return this._call(ctx, new URL("/account/invitation", this.baseUrl), {
1401
+ ...args,
1402
+ method: "GET"
1403
+ });
1404
+ }
1405
+ async issueAccountInvitation(ctx, args) {
1406
+ return this._call(ctx, new URL("/account/invitation/issue", this.baseUrl), {
1407
+ ...args,
1408
+ method: "POST"
1409
+ });
1410
+ }
1411
+ async resendVerificationEmail(ctx, args) {
1412
+ return this._call(ctx, new URL("/account/email/resend-verification", this.baseUrl), {
1413
+ ...args,
1414
+ method: "POST"
1415
+ });
1316
1416
  }
1317
- let retries = 0;
1318
- const maxRetries = retry2.count ?? DEFAULT_MAX_RETRIES_COUNT;
1319
- const baseTimeout = retry2.timeout ?? DEFAULT_RETRY_TIMEOUT;
1320
- const jitter = retry2.jitter ?? DEFAULT_RETRY_JITTER;
1321
- return async (ctx, retryAfter) => {
1322
- if (++retries > maxRetries || ctx.disposed) {
1323
- return false;
1324
- }
1325
- if (retryAfter) {
1326
- await sleep(retryAfter);
1327
- } else {
1328
- const timeout2 = baseTimeout + Math.random() * jitter;
1329
- await sleep(timeout2);
1330
- }
1331
- return true;
1332
- };
1333
1417
  };
1334
- var getFileMimeType = (filename) => [
1335
- ".js",
1336
- ".mjs"
1337
- ].some((codeExtension) => filename.endsWith(codeExtension)) ? "application/javascript+module" : filename.endsWith(".wasm") ? "application/wasm" : "application/octet-stream";
1338
1418
  export {
1419
+ BaseHttpClient,
1420
+ ByokError,
1339
1421
  CLOUDFLARE_MESSAGE_MAX_BYTES,
1340
1422
  CLOUDFLARE_RPC_MAX_BYTES,
1423
+ EdgeAiHttpClient,
1341
1424
  EdgeClient,
1342
1425
  EdgeConnectionClosedError,
1343
1426
  EdgeHttpClient,
1344
1427
  EdgeIdentityChangedError,
1345
1428
  HttpConfig,
1429
+ HubHttpClient,
1346
1430
  Protocol,
1347
1431
  WebSocketMuxer,
1348
1432
  createChainEdgeIdentity,
@@ -1354,6 +1438,8 @@ export {
1354
1438
  getTypename,
1355
1439
  handleAuthChallenge,
1356
1440
  protocol,
1441
+ proxyFetchLegacy,
1442
+ requestInitTagKey,
1357
1443
  toUint8Array,
1358
1444
  withLogging,
1359
1445
  withRetry,