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