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