@dxos/edge-client 0.6.13-main.548ca8d → 0.6.13-staging.1e988a3
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/index.mjs +178 -347
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +175 -346
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/defs.d.ts.map +1 -1
- package/dist/types/src/edge-client.d.ts +13 -24
- package/dist/types/src/edge-client.d.ts.map +1 -1
- package/dist/types/src/errors.d.ts +1 -4
- package/dist/types/src/errors.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/protocol.d.ts +2 -2
- package/dist/types/src/protocol.d.ts.map +1 -1
- package/dist/types/src/test-utils.d.ts +11 -0
- package/dist/types/src/test-utils.d.ts.map +1 -0
- package/package.json +14 -29
- package/src/defs.ts +3 -2
- package/src/edge-client.test.ts +18 -50
- package/src/edge-client.ts +23 -79
- package/src/errors.ts +2 -8
- package/src/index.ts +0 -3
- package/src/persistent-lifecycle.test.ts +2 -2
- package/src/protocol.test.ts +2 -1
- package/src/protocol.ts +2 -2
- package/src/test-utils.ts +49 -0
- package/src/websocket.test.ts +4 -5
- package/dist/lib/browser/chunk-ZWJXA37R.mjs +0 -113
- package/dist/lib/browser/chunk-ZWJXA37R.mjs.map +0 -7
- package/dist/lib/browser/testing/index.mjs +0 -125
- package/dist/lib/browser/testing/index.mjs.map +0 -7
- package/dist/lib/node/chunk-ANV2HBEH.cjs +0 -136
- package/dist/lib/node/chunk-ANV2HBEH.cjs.map +0 -7
- package/dist/lib/node/testing/index.cjs +0 -155
- package/dist/lib/node/testing/index.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-HNVT57AU.mjs +0 -115
- package/dist/lib/node-esm/chunk-HNVT57AU.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -647
- 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 -126
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/types/src/auth.d.ts +0 -22
- package/dist/types/src/auth.d.ts.map +0 -1
- package/dist/types/src/edge-http-client.d.ts +0 -35
- package/dist/types/src/edge-http-client.d.ts.map +0 -1
- package/dist/types/src/testing/index.d.ts +0 -2
- package/dist/types/src/testing/index.d.ts.map +0 -1
- package/dist/types/src/testing/test-utils.d.ts +0 -21
- package/dist/types/src/testing/test-utils.d.ts.map +0 -1
- package/dist/types/src/utils.d.ts +0 -2
- package/dist/types/src/utils.d.ts.map +0 -1
- package/src/auth.ts +0 -135
- package/src/edge-http-client.ts +0 -151
- package/src/testing/index.ts +0 -5
- package/src/testing/test-utils.ts +0 -114
- package/src/utils.ts +0 -10
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Protocol,
|
|
3
|
-
getTypename,
|
|
4
|
-
protocol,
|
|
5
|
-
toUint8Array
|
|
6
|
-
} from "./chunk-ZWJXA37R.mjs";
|
|
7
|
-
|
|
8
1
|
// packages/core/mesh/edge-client/src/index.ts
|
|
9
2
|
export * from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
10
3
|
|
|
@@ -12,21 +5,123 @@ export * from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
|
12
5
|
import WebSocket from "isomorphic-ws";
|
|
13
6
|
import { Trigger, Event, scheduleTaskInterval, scheduleTask, TriggerState } from "@dxos/async";
|
|
14
7
|
import { Context, LifecycleState as LifecycleState2, Resource as Resource2 } from "@dxos/context";
|
|
15
|
-
import {
|
|
8
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
16
9
|
import { log as log2 } from "@dxos/log";
|
|
17
|
-
import { buf } from "@dxos/protocols/buf";
|
|
18
|
-
import { MessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
19
|
-
import { schema } from "@dxos/protocols/proto";
|
|
10
|
+
import { buf as buf2 } from "@dxos/protocols/buf";
|
|
11
|
+
import { MessageSchema as MessageSchema2 } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
20
12
|
|
|
21
|
-
// packages/core/mesh/edge-client/src/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
// packages/core/mesh/edge-client/src/defs.ts
|
|
14
|
+
import { AnySchema } from "@bufbuild/protobuf/wkt";
|
|
15
|
+
import { SwarmRequestSchema, SwarmResponseSchema, TextMessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
16
|
+
|
|
17
|
+
// packages/core/mesh/edge-client/src/protocol.ts
|
|
18
|
+
import { invariant } from "@dxos/invariant";
|
|
19
|
+
import { buf, bufWkt } from "@dxos/protocols/buf";
|
|
20
|
+
import { MessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
21
|
+
import { bufferToArray } from "@dxos/util";
|
|
22
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/protocol.ts";
|
|
23
|
+
var getTypename = (typeName) => `type.googleapis.com/${typeName}`;
|
|
24
|
+
var Protocol = class {
|
|
25
|
+
constructor(types) {
|
|
26
|
+
this._typeRegistry = buf.createRegistry(...types);
|
|
27
|
+
}
|
|
28
|
+
get typeRegistry() {
|
|
29
|
+
return this._typeRegistry;
|
|
30
|
+
}
|
|
31
|
+
toJson(message) {
|
|
32
|
+
try {
|
|
33
|
+
return buf.toJson(MessageSchema, message, {
|
|
34
|
+
registry: this.typeRegistry
|
|
35
|
+
});
|
|
36
|
+
} catch (err) {
|
|
37
|
+
return {
|
|
38
|
+
type: this.getPayloadType(message)
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Return the payload with the given type.
|
|
44
|
+
*/
|
|
45
|
+
getPayload(message, type) {
|
|
46
|
+
invariant(message.payload, void 0, {
|
|
47
|
+
F: __dxlog_file,
|
|
48
|
+
L: 40,
|
|
49
|
+
S: this,
|
|
50
|
+
A: [
|
|
51
|
+
"message.payload",
|
|
52
|
+
""
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
const payloadTypename = this.getPayloadType(message);
|
|
56
|
+
if (type && type.typeName !== payloadTypename) {
|
|
57
|
+
throw new Error(`Unexpected payload type: ${payloadTypename}; expected ${type.typeName}`);
|
|
58
|
+
}
|
|
59
|
+
invariant(bufWkt.anyIs(message.payload, type), `Unexpected payload type: ${payloadTypename}}`, {
|
|
60
|
+
F: __dxlog_file,
|
|
61
|
+
L: 46,
|
|
62
|
+
S: this,
|
|
63
|
+
A: [
|
|
64
|
+
"bufWkt.anyIs(message.payload, type)",
|
|
65
|
+
"`Unexpected payload type: ${payloadTypename}}`"
|
|
66
|
+
]
|
|
67
|
+
});
|
|
68
|
+
const payload = bufWkt.anyUnpack(message.payload, this.typeRegistry);
|
|
69
|
+
invariant(payload, `Empty payload: ${payloadTypename}}`, {
|
|
70
|
+
F: __dxlog_file,
|
|
71
|
+
L: 48,
|
|
72
|
+
S: this,
|
|
73
|
+
A: [
|
|
74
|
+
"payload",
|
|
75
|
+
"`Empty payload: ${payloadTypename}}`"
|
|
76
|
+
]
|
|
77
|
+
});
|
|
78
|
+
return payload;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get the payload type.
|
|
82
|
+
*/
|
|
83
|
+
getPayloadType(message) {
|
|
84
|
+
if (!message.payload) {
|
|
85
|
+
return void 0;
|
|
86
|
+
}
|
|
87
|
+
const [, type] = message.payload.typeUrl.split("/");
|
|
88
|
+
return type;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a packed message.
|
|
92
|
+
*/
|
|
93
|
+
createMessage(type, { source, target, payload, serviceId }) {
|
|
94
|
+
return buf.create(MessageSchema, {
|
|
95
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
96
|
+
source,
|
|
97
|
+
target,
|
|
98
|
+
serviceId,
|
|
99
|
+
payload: payload ? bufWkt.anyPack(type, buf.create(type, payload)) : void 0
|
|
100
|
+
});
|
|
25
101
|
}
|
|
26
102
|
};
|
|
27
|
-
var
|
|
103
|
+
var toUint8Array = async (data) => {
|
|
104
|
+
if (data instanceof Buffer) {
|
|
105
|
+
return bufferToArray(data);
|
|
106
|
+
}
|
|
107
|
+
if (data instanceof Blob) {
|
|
108
|
+
return new Uint8Array(await data.arrayBuffer());
|
|
109
|
+
}
|
|
110
|
+
throw new Error(`Unexpected datatype: ${data}`);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// packages/core/mesh/edge-client/src/defs.ts
|
|
114
|
+
var protocol = new Protocol([
|
|
115
|
+
SwarmRequestSchema,
|
|
116
|
+
SwarmResponseSchema,
|
|
117
|
+
TextMessageSchema,
|
|
118
|
+
AnySchema
|
|
119
|
+
]);
|
|
120
|
+
|
|
121
|
+
// packages/core/mesh/edge-client/src/errors.ts
|
|
122
|
+
var WebsocketClosedError = class extends Error {
|
|
28
123
|
constructor() {
|
|
29
|
-
super("
|
|
124
|
+
super("WebSocket connection closed");
|
|
30
125
|
}
|
|
31
126
|
};
|
|
32
127
|
|
|
@@ -41,7 +136,7 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
41
136
|
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;
|
|
42
137
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
43
138
|
}
|
|
44
|
-
var
|
|
139
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/persistent-lifecycle.ts";
|
|
45
140
|
var INIT_RESTART_DELAY = 100;
|
|
46
141
|
var DEFAULT_MAX_RESTART_DELAY = 5e3;
|
|
47
142
|
var PersistentLifecycle = class extends Resource {
|
|
@@ -62,7 +157,7 @@ var PersistentLifecycle = class extends Resource {
|
|
|
62
157
|
log.warn("Restart failed", {
|
|
63
158
|
err
|
|
64
159
|
}, {
|
|
65
|
-
F:
|
|
160
|
+
F: __dxlog_file2,
|
|
66
161
|
L: 64,
|
|
67
162
|
S: this,
|
|
68
163
|
C: (f, a) => f(...a)
|
|
@@ -74,7 +169,7 @@ var PersistentLifecycle = class extends Resource {
|
|
|
74
169
|
log.warn("Start failed", {
|
|
75
170
|
err
|
|
76
171
|
}, {
|
|
77
|
-
F:
|
|
172
|
+
F: __dxlog_file2,
|
|
78
173
|
L: 69,
|
|
79
174
|
S: this,
|
|
80
175
|
C: (f, a) => f(...a)
|
|
@@ -91,7 +186,7 @@ var PersistentLifecycle = class extends Resource {
|
|
|
91
186
|
log(`restarting in ${this._restartAfter}ms`, {
|
|
92
187
|
state: this._lifecycleState
|
|
93
188
|
}, {
|
|
94
|
-
F:
|
|
189
|
+
F: __dxlog_file2,
|
|
95
190
|
L: 81,
|
|
96
191
|
S: this,
|
|
97
192
|
C: (f, a) => f(...a)
|
|
@@ -123,25 +218,17 @@ _ts_decorate([
|
|
|
123
218
|
synchronized
|
|
124
219
|
], PersistentLifecycle.prototype, "scheduleRestart", null);
|
|
125
220
|
|
|
126
|
-
// packages/core/mesh/edge-client/src/utils.ts
|
|
127
|
-
var getEdgeUrlWithProtocol = (baseUrl, protocol2) => {
|
|
128
|
-
const isSecure = baseUrl.startsWith("https") || baseUrl.startsWith("wss");
|
|
129
|
-
const url = new URL(baseUrl);
|
|
130
|
-
url.protocol = protocol2 + (isSecure ? "s" : "");
|
|
131
|
-
return url.toString();
|
|
132
|
-
};
|
|
133
|
-
|
|
134
221
|
// packages/core/mesh/edge-client/src/edge-client.ts
|
|
135
|
-
var
|
|
222
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
|
|
136
223
|
var DEFAULT_TIMEOUT = 1e4;
|
|
137
224
|
var SIGNAL_KEEPALIVE_INTERVAL = 5e3;
|
|
138
225
|
var EdgeClient = class extends Resource2 {
|
|
139
|
-
constructor(
|
|
226
|
+
constructor(_identityKey, _peerKey, _config) {
|
|
140
227
|
super();
|
|
141
|
-
this.
|
|
228
|
+
this._identityKey = _identityKey;
|
|
229
|
+
this._peerKey = _peerKey;
|
|
142
230
|
this._config = _config;
|
|
143
231
|
this.reconnect = new Event();
|
|
144
|
-
this.connected = new Event();
|
|
145
232
|
this._persistentLifecycle = new PersistentLifecycle({
|
|
146
233
|
start: async () => this._openWebSocket(),
|
|
147
234
|
stop: async () => this._closeWebSocket(),
|
|
@@ -152,27 +239,25 @@ var EdgeClient = class extends Resource2 {
|
|
|
152
239
|
this._ws = void 0;
|
|
153
240
|
this._keepaliveCtx = void 0;
|
|
154
241
|
this._heartBeatContext = void 0;
|
|
155
|
-
this.
|
|
242
|
+
this._protocol = this._config.protocol ?? protocol;
|
|
156
243
|
}
|
|
157
244
|
// TODO(burdon): Attach logging.
|
|
158
245
|
get info() {
|
|
159
246
|
return {
|
|
160
247
|
open: this.isOpen,
|
|
161
|
-
identity: this.
|
|
162
|
-
device: this.
|
|
248
|
+
identity: this._identityKey,
|
|
249
|
+
device: this._peerKey
|
|
163
250
|
};
|
|
164
251
|
}
|
|
165
|
-
get isConnected() {
|
|
166
|
-
return Boolean(this._ws) && this._ready.state === TriggerState.RESOLVED;
|
|
167
|
-
}
|
|
168
252
|
get identityKey() {
|
|
169
|
-
return this.
|
|
253
|
+
return this._identityKey;
|
|
170
254
|
}
|
|
171
255
|
get peerKey() {
|
|
172
|
-
return this.
|
|
256
|
+
return this._peerKey;
|
|
173
257
|
}
|
|
174
|
-
setIdentity(
|
|
175
|
-
this.
|
|
258
|
+
setIdentity({ peerKey, identityKey }) {
|
|
259
|
+
this._peerKey = peerKey;
|
|
260
|
+
this._identityKey = identityKey;
|
|
176
261
|
this._persistentLifecycle.scheduleRestart();
|
|
177
262
|
}
|
|
178
263
|
addListener(listener) {
|
|
@@ -186,8 +271,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
186
271
|
log2("opening...", {
|
|
187
272
|
info: this.info
|
|
188
273
|
}, {
|
|
189
|
-
F:
|
|
190
|
-
L:
|
|
274
|
+
F: __dxlog_file3,
|
|
275
|
+
L: 101,
|
|
191
276
|
S: this,
|
|
192
277
|
C: (f, a) => f(...a)
|
|
193
278
|
});
|
|
@@ -195,8 +280,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
195
280
|
log2.warn("Error while opening connection", {
|
|
196
281
|
err
|
|
197
282
|
}, {
|
|
198
|
-
F:
|
|
199
|
-
L:
|
|
283
|
+
F: __dxlog_file3,
|
|
284
|
+
L: 103,
|
|
200
285
|
S: this,
|
|
201
286
|
C: (f, a) => f(...a)
|
|
202
287
|
});
|
|
@@ -207,54 +292,31 @@ var EdgeClient = class extends Resource2 {
|
|
|
207
292
|
*/
|
|
208
293
|
async _close() {
|
|
209
294
|
log2("closing...", {
|
|
210
|
-
peerKey: this.
|
|
295
|
+
peerKey: this._peerKey
|
|
211
296
|
}, {
|
|
212
|
-
F:
|
|
213
|
-
L:
|
|
297
|
+
F: __dxlog_file3,
|
|
298
|
+
L: 111,
|
|
214
299
|
S: this,
|
|
215
300
|
C: (f, a) => f(...a)
|
|
216
301
|
});
|
|
217
302
|
await this._persistentLifecycle.close();
|
|
218
303
|
}
|
|
219
304
|
async _openWebSocket() {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const challenge = randomBytes(32);
|
|
223
|
-
const credential = await this._identity.presentCredentials({
|
|
224
|
-
challenge
|
|
225
|
-
});
|
|
226
|
-
protocolHeader = encodePresentationIntoAuthHeader(credential);
|
|
227
|
-
}
|
|
228
|
-
if (this._ctx.disposed) {
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
const url = new URL(`/ws/${this._identity.identityKey}/${this._identity.peerKey}`, this._baseUrl);
|
|
232
|
-
log2("Opening websocket", {
|
|
233
|
-
url: url.toString(),
|
|
234
|
-
protocolHeader
|
|
235
|
-
}, {
|
|
236
|
-
F: __dxlog_file2,
|
|
237
|
-
L: 151,
|
|
238
|
-
S: this,
|
|
239
|
-
C: (f, a) => f(...a)
|
|
240
|
-
});
|
|
241
|
-
this._ws = new WebSocket(url, protocolHeader ? [
|
|
242
|
-
protocolHeader
|
|
243
|
-
] : []);
|
|
305
|
+
const url = new URL(`/ws/${this._identityKey}/${this._peerKey}`, this._config.socketEndpoint);
|
|
306
|
+
this._ws = new WebSocket(url);
|
|
244
307
|
this._ws.onopen = () => {
|
|
245
308
|
log2("opened", this.info, {
|
|
246
|
-
F:
|
|
247
|
-
L:
|
|
309
|
+
F: __dxlog_file3,
|
|
310
|
+
L: 120,
|
|
248
311
|
S: this,
|
|
249
312
|
C: (f, a) => f(...a)
|
|
250
313
|
});
|
|
251
314
|
this._ready.wake();
|
|
252
|
-
this.connected.emit();
|
|
253
315
|
};
|
|
254
316
|
this._ws.onclose = () => {
|
|
255
317
|
log2("closed", this.info, {
|
|
256
|
-
F:
|
|
257
|
-
L:
|
|
318
|
+
F: __dxlog_file3,
|
|
319
|
+
L: 124,
|
|
258
320
|
S: this,
|
|
259
321
|
C: (f, a) => f(...a)
|
|
260
322
|
});
|
|
@@ -265,8 +327,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
265
327
|
error: event.error,
|
|
266
328
|
info: event.message
|
|
267
329
|
}, {
|
|
268
|
-
F:
|
|
269
|
-
L:
|
|
330
|
+
F: __dxlog_file3,
|
|
331
|
+
L: 128,
|
|
270
332
|
S: this,
|
|
271
333
|
C: (f, a) => f(...a)
|
|
272
334
|
});
|
|
@@ -278,13 +340,13 @@ var EdgeClient = class extends Resource2 {
|
|
|
278
340
|
return;
|
|
279
341
|
}
|
|
280
342
|
const data = await toUint8Array(event.data);
|
|
281
|
-
const message =
|
|
343
|
+
const message = buf2.fromBinary(MessageSchema2, data);
|
|
282
344
|
log2("received", {
|
|
283
|
-
peerKey: this.
|
|
345
|
+
peerKey: this._peerKey,
|
|
284
346
|
payload: protocol.getPayloadType(message)
|
|
285
347
|
}, {
|
|
286
|
-
F:
|
|
287
|
-
L:
|
|
348
|
+
F: __dxlog_file3,
|
|
349
|
+
L: 141,
|
|
288
350
|
S: this,
|
|
289
351
|
C: (f, a) => f(...a)
|
|
290
352
|
});
|
|
@@ -297,8 +359,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
297
359
|
err,
|
|
298
360
|
payload: protocol.getPayloadType(message)
|
|
299
361
|
}, {
|
|
300
|
-
F:
|
|
301
|
-
L:
|
|
362
|
+
F: __dxlog_file3,
|
|
363
|
+
L: 147,
|
|
302
364
|
S: this,
|
|
303
365
|
C: (f, a) => f(...a)
|
|
304
366
|
});
|
|
@@ -310,8 +372,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
310
372
|
timeout: this._config.timeout ?? DEFAULT_TIMEOUT
|
|
311
373
|
});
|
|
312
374
|
this._keepaliveCtx = new Context(void 0, {
|
|
313
|
-
F:
|
|
314
|
-
L:
|
|
375
|
+
F: __dxlog_file3,
|
|
376
|
+
L: 154
|
|
315
377
|
});
|
|
316
378
|
scheduleTaskInterval(this._keepaliveCtx, async () => {
|
|
317
379
|
this._ws?.send("__ping__");
|
|
@@ -324,7 +386,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
324
386
|
return;
|
|
325
387
|
}
|
|
326
388
|
try {
|
|
327
|
-
this._ready.throw(
|
|
389
|
+
this._ready.throw(new WebsocketClosedError());
|
|
328
390
|
this._ready.reset();
|
|
329
391
|
void this._keepaliveCtx?.dispose();
|
|
330
392
|
this._keepaliveCtx = void 0;
|
|
@@ -345,8 +407,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
345
407
|
log2.warn("Error closing websocket", {
|
|
346
408
|
err
|
|
347
409
|
}, {
|
|
348
|
-
F:
|
|
349
|
-
L:
|
|
410
|
+
F: __dxlog_file3,
|
|
411
|
+
L: 190,
|
|
350
412
|
S: this,
|
|
351
413
|
C: (f, a) => f(...a)
|
|
352
414
|
});
|
|
@@ -358,32 +420,38 @@ var EdgeClient = class extends Resource2 {
|
|
|
358
420
|
*/
|
|
359
421
|
async send(message) {
|
|
360
422
|
if (this._ready.state !== TriggerState.RESOLVED) {
|
|
361
|
-
log2("waiting for websocket to become ready", void 0, {
|
|
362
|
-
F: __dxlog_file2,
|
|
363
|
-
L: 239,
|
|
364
|
-
S: this,
|
|
365
|
-
C: (f, a) => f(...a)
|
|
366
|
-
});
|
|
367
423
|
await this._ready.wait({
|
|
368
424
|
timeout: this._config.timeout ?? DEFAULT_TIMEOUT
|
|
369
425
|
});
|
|
370
426
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
427
|
+
invariant2(this._ws, void 0, {
|
|
428
|
+
F: __dxlog_file3,
|
|
429
|
+
L: 202,
|
|
430
|
+
S: this,
|
|
431
|
+
A: [
|
|
432
|
+
"this._ws",
|
|
433
|
+
""
|
|
434
|
+
]
|
|
435
|
+
});
|
|
436
|
+
invariant2(!message.source || message.source.peerKey === this._peerKey, void 0, {
|
|
437
|
+
F: __dxlog_file3,
|
|
438
|
+
L: 203,
|
|
439
|
+
S: this,
|
|
440
|
+
A: [
|
|
441
|
+
"!message.source || message.source.peerKey === this._peerKey",
|
|
442
|
+
""
|
|
443
|
+
]
|
|
444
|
+
});
|
|
377
445
|
log2("sending...", {
|
|
378
|
-
peerKey: this.
|
|
446
|
+
peerKey: this._peerKey,
|
|
379
447
|
payload: protocol.getPayloadType(message)
|
|
380
448
|
}, {
|
|
381
|
-
F:
|
|
382
|
-
L:
|
|
449
|
+
F: __dxlog_file3,
|
|
450
|
+
L: 204,
|
|
383
451
|
S: this,
|
|
384
452
|
C: (f, a) => f(...a)
|
|
385
453
|
});
|
|
386
|
-
this._ws.send(
|
|
454
|
+
this._ws.send(buf2.toBinary(MessageSchema2, message));
|
|
387
455
|
}
|
|
388
456
|
_onHeartbeat() {
|
|
389
457
|
if (this._lifecycleState !== LifecycleState2.OPEN) {
|
|
@@ -391,254 +459,17 @@ var EdgeClient = class extends Resource2 {
|
|
|
391
459
|
}
|
|
392
460
|
void this._heartBeatContext?.dispose();
|
|
393
461
|
this._heartBeatContext = new Context(void 0, {
|
|
394
|
-
F:
|
|
395
|
-
L:
|
|
462
|
+
F: __dxlog_file3,
|
|
463
|
+
L: 213
|
|
396
464
|
});
|
|
397
465
|
scheduleTask(this._heartBeatContext, () => {
|
|
398
466
|
this._persistentLifecycle.scheduleRestart();
|
|
399
467
|
}, 2 * SIGNAL_KEEPALIVE_INTERVAL);
|
|
400
468
|
}
|
|
401
469
|
};
|
|
402
|
-
var encodePresentationIntoAuthHeader = (presentation) => {
|
|
403
|
-
const encoded = schema.getCodecForType("dxos.halo.credentials.Presentation").encode(presentation);
|
|
404
|
-
const encodedToken = Buffer.from(encoded).toString("base64").replace(/=*$/, "").replaceAll("/", "|");
|
|
405
|
-
return `base64url.bearer.authorization.dxos.org.${encodedToken}`;
|
|
406
|
-
};
|
|
407
|
-
|
|
408
|
-
// packages/core/mesh/edge-client/src/auth.ts
|
|
409
|
-
import { createCredential, signPresentation } from "@dxos/credentials";
|
|
410
|
-
import { Keyring } from "@dxos/keyring";
|
|
411
|
-
import { PublicKey } from "@dxos/keys";
|
|
412
|
-
var createDeviceEdgeIdentity = async (signer, key) => {
|
|
413
|
-
return {
|
|
414
|
-
identityKey: key.toHex(),
|
|
415
|
-
peerKey: key.toHex(),
|
|
416
|
-
presentCredentials: async ({ challenge }) => {
|
|
417
|
-
return signPresentation({
|
|
418
|
-
presentation: {
|
|
419
|
-
credentials: [
|
|
420
|
-
// Verifier requires at least one credential in the presentation to establish the subject.
|
|
421
|
-
await createCredential({
|
|
422
|
-
assertion: {
|
|
423
|
-
"@type": "dxos.halo.credentials.Auth"
|
|
424
|
-
},
|
|
425
|
-
issuer: key,
|
|
426
|
-
subject: key,
|
|
427
|
-
signer
|
|
428
|
-
})
|
|
429
|
-
]
|
|
430
|
-
},
|
|
431
|
-
signer,
|
|
432
|
-
signerKey: key,
|
|
433
|
-
nonce: challenge
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
};
|
|
437
|
-
};
|
|
438
|
-
var createChainEdgeIdentity = async (signer, identityKey, peerKey, chain, credentials) => {
|
|
439
|
-
const credentialsToSign = credentials.length > 0 ? credentials : [
|
|
440
|
-
await createCredential({
|
|
441
|
-
assertion: {
|
|
442
|
-
"@type": "dxos.halo.credentials.Auth"
|
|
443
|
-
},
|
|
444
|
-
issuer: identityKey,
|
|
445
|
-
subject: identityKey,
|
|
446
|
-
signer,
|
|
447
|
-
chain,
|
|
448
|
-
signingKey: peerKey
|
|
449
|
-
})
|
|
450
|
-
];
|
|
451
|
-
return {
|
|
452
|
-
identityKey: identityKey.toHex(),
|
|
453
|
-
peerKey: peerKey.toHex(),
|
|
454
|
-
presentCredentials: async ({ challenge }) => {
|
|
455
|
-
return signPresentation({
|
|
456
|
-
presentation: {
|
|
457
|
-
credentials: credentialsToSign
|
|
458
|
-
},
|
|
459
|
-
signer,
|
|
460
|
-
nonce: challenge,
|
|
461
|
-
signerKey: peerKey,
|
|
462
|
-
chain
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
};
|
|
466
|
-
};
|
|
467
|
-
var createEphemeralEdgeIdentity = async () => {
|
|
468
|
-
const keyring = new Keyring();
|
|
469
|
-
const key = await keyring.createKey();
|
|
470
|
-
return createDeviceEdgeIdentity(keyring, key);
|
|
471
|
-
};
|
|
472
|
-
var createTestHaloEdgeIdentity = async (signer, identityKey, deviceKey) => {
|
|
473
|
-
const deviceAdmission = await createCredential({
|
|
474
|
-
assertion: {
|
|
475
|
-
"@type": "dxos.halo.credentials.AuthorizedDevice",
|
|
476
|
-
deviceKey,
|
|
477
|
-
identityKey
|
|
478
|
-
},
|
|
479
|
-
issuer: identityKey,
|
|
480
|
-
subject: deviceKey,
|
|
481
|
-
signer
|
|
482
|
-
});
|
|
483
|
-
return createChainEdgeIdentity(signer, identityKey, deviceKey, {
|
|
484
|
-
credential: deviceAdmission
|
|
485
|
-
}, [
|
|
486
|
-
await createCredential({
|
|
487
|
-
assertion: {
|
|
488
|
-
"@type": "dxos.halo.credentials.Auth"
|
|
489
|
-
},
|
|
490
|
-
issuer: identityKey,
|
|
491
|
-
subject: identityKey,
|
|
492
|
-
signer
|
|
493
|
-
})
|
|
494
|
-
]);
|
|
495
|
-
};
|
|
496
|
-
var createStubEdgeIdentity = () => {
|
|
497
|
-
const identityKey = PublicKey.random();
|
|
498
|
-
const deviceKey = PublicKey.random();
|
|
499
|
-
return {
|
|
500
|
-
identityKey: identityKey.toHex(),
|
|
501
|
-
peerKey: deviceKey.toHex(),
|
|
502
|
-
presentCredentials: async () => {
|
|
503
|
-
throw new Error("Stub identity does not support authentication.");
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
};
|
|
507
|
-
|
|
508
|
-
// packages/core/mesh/edge-client/src/edge-http-client.ts
|
|
509
|
-
import { sleep as sleep2 } from "@dxos/async";
|
|
510
|
-
import { Context as Context2 } from "@dxos/context";
|
|
511
|
-
import { log as log3 } from "@dxos/log";
|
|
512
|
-
import { EdgeCallFailedError, EdgeAuthChallengeError } from "@dxos/protocols";
|
|
513
|
-
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-http-client.ts";
|
|
514
|
-
var DEFAULT_RETRY_TIMEOUT = 1500;
|
|
515
|
-
var DEFAULT_RETRY_JITTER = 500;
|
|
516
|
-
var DEFAULT_MAX_RETRIES_COUNT = 3;
|
|
517
|
-
var EdgeHttpClient = class {
|
|
518
|
-
constructor(baseUrl) {
|
|
519
|
-
this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
|
|
520
|
-
log3("created", {
|
|
521
|
-
url: this._baseUrl
|
|
522
|
-
}, {
|
|
523
|
-
F: __dxlog_file3,
|
|
524
|
-
L: 30,
|
|
525
|
-
S: this,
|
|
526
|
-
C: (f, a) => f(...a)
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
getCredentialsForNotarization(spaceId, args) {
|
|
530
|
-
return this._call(`/spaces/${spaceId}/notarization`, {
|
|
531
|
-
...args,
|
|
532
|
-
method: "GET"
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
async notarizeCredentials(spaceId, body, args) {
|
|
536
|
-
await this._call(`/spaces/${spaceId}/notarization`, {
|
|
537
|
-
...args,
|
|
538
|
-
body,
|
|
539
|
-
method: "POST"
|
|
540
|
-
});
|
|
541
|
-
}
|
|
542
|
-
async joinSpaceByInvitation(spaceId, body, args) {
|
|
543
|
-
return this._call(`/spaces/${spaceId}/join`, {
|
|
544
|
-
...args,
|
|
545
|
-
body,
|
|
546
|
-
method: "POST"
|
|
547
|
-
});
|
|
548
|
-
}
|
|
549
|
-
async _call(path, args) {
|
|
550
|
-
const requestContext = args.context ?? new Context2(void 0, {
|
|
551
|
-
F: __dxlog_file3,
|
|
552
|
-
L: 54
|
|
553
|
-
});
|
|
554
|
-
const shouldRetry = createRetryHandler(args);
|
|
555
|
-
const request = createRequest(args);
|
|
556
|
-
const url = `${this._baseUrl}${path.startsWith("/") ? path.slice(1) : path}`;
|
|
557
|
-
log3.info("call", {
|
|
558
|
-
method: args.method,
|
|
559
|
-
path
|
|
560
|
-
}, {
|
|
561
|
-
F: __dxlog_file3,
|
|
562
|
-
L: 59,
|
|
563
|
-
S: this,
|
|
564
|
-
C: (f, a) => f(...a)
|
|
565
|
-
});
|
|
566
|
-
while (true) {
|
|
567
|
-
let processingError;
|
|
568
|
-
let retryAfterHeaderValue = Number.NaN;
|
|
569
|
-
try {
|
|
570
|
-
const response = await fetch(url, request);
|
|
571
|
-
retryAfterHeaderValue = Number(response.headers.get("Retry-After"));
|
|
572
|
-
if (response.ok) {
|
|
573
|
-
const body = await response.json();
|
|
574
|
-
if (body.success) {
|
|
575
|
-
return body.data;
|
|
576
|
-
}
|
|
577
|
-
if (body.errorData?.type === "auth_challenge" && typeof body.errorData?.challenge === "string") {
|
|
578
|
-
processingError = new EdgeAuthChallengeError(body.errorData.challenge, body.errorData);
|
|
579
|
-
} else {
|
|
580
|
-
processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);
|
|
581
|
-
}
|
|
582
|
-
} else {
|
|
583
|
-
processingError = EdgeCallFailedError.fromHttpFailure(response);
|
|
584
|
-
}
|
|
585
|
-
} catch (error) {
|
|
586
|
-
processingError = EdgeCallFailedError.fromProcessingFailureCause(error);
|
|
587
|
-
}
|
|
588
|
-
if (processingError.isRetryable && await shouldRetry(requestContext, retryAfterHeaderValue)) {
|
|
589
|
-
log3.info("retrying edge request", {
|
|
590
|
-
path,
|
|
591
|
-
processingError
|
|
592
|
-
}, {
|
|
593
|
-
F: __dxlog_file3,
|
|
594
|
-
L: 88,
|
|
595
|
-
S: this,
|
|
596
|
-
C: (f, a) => f(...a)
|
|
597
|
-
});
|
|
598
|
-
} else {
|
|
599
|
-
throw processingError;
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
};
|
|
604
|
-
var createRequest = (args) => {
|
|
605
|
-
return {
|
|
606
|
-
method: args.method,
|
|
607
|
-
body: args.body && JSON.stringify(args.body)
|
|
608
|
-
};
|
|
609
|
-
};
|
|
610
|
-
var createRetryHandler = (args) => {
|
|
611
|
-
if (!args.retry || args.retry.count < 1) {
|
|
612
|
-
return async () => false;
|
|
613
|
-
}
|
|
614
|
-
let retries = 0;
|
|
615
|
-
const maxRetries = args.retry.count ?? DEFAULT_MAX_RETRIES_COUNT;
|
|
616
|
-
const baseTimeout = args.retry.timeout ?? DEFAULT_RETRY_TIMEOUT;
|
|
617
|
-
const jitter = args.retry.jitter ?? DEFAULT_RETRY_JITTER;
|
|
618
|
-
return async (ctx, retryAfter) => {
|
|
619
|
-
if (++retries > maxRetries || ctx.disposed) {
|
|
620
|
-
return false;
|
|
621
|
-
}
|
|
622
|
-
if (retryAfter) {
|
|
623
|
-
await sleep2(retryAfter);
|
|
624
|
-
} else {
|
|
625
|
-
const timeout = baseTimeout + Math.random() * jitter;
|
|
626
|
-
await sleep2(timeout);
|
|
627
|
-
}
|
|
628
|
-
return true;
|
|
629
|
-
};
|
|
630
|
-
};
|
|
631
470
|
export {
|
|
632
471
|
EdgeClient,
|
|
633
|
-
EdgeConnectionClosedError,
|
|
634
|
-
EdgeHttpClient,
|
|
635
|
-
EdgeIdentityChangedError,
|
|
636
472
|
Protocol,
|
|
637
|
-
createChainEdgeIdentity,
|
|
638
|
-
createDeviceEdgeIdentity,
|
|
639
|
-
createEphemeralEdgeIdentity,
|
|
640
|
-
createStubEdgeIdentity,
|
|
641
|
-
createTestHaloEdgeIdentity,
|
|
642
473
|
getTypename,
|
|
643
474
|
protocol,
|
|
644
475
|
toUint8Array
|