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