@dxos/edge-client 0.6.13-main.ed424a1 → 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 +179 -391
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +176 -390
- 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 +24 -84
- 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 -690
- 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 -39
- 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 -167
- 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,39 +239,26 @@ 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
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
oldIdentity: this._identity
|
|
179
|
-
}, {
|
|
180
|
-
F: __dxlog_file2,
|
|
181
|
-
L: 110,
|
|
182
|
-
S: this,
|
|
183
|
-
C: (f, a) => f(...a)
|
|
184
|
-
});
|
|
185
|
-
this._identity = identity;
|
|
186
|
-
this._persistentLifecycle.scheduleRestart();
|
|
187
|
-
}
|
|
258
|
+
setIdentity({ peerKey, identityKey }) {
|
|
259
|
+
this._peerKey = peerKey;
|
|
260
|
+
this._identityKey = identityKey;
|
|
261
|
+
this._persistentLifecycle.scheduleRestart();
|
|
188
262
|
}
|
|
189
263
|
addListener(listener) {
|
|
190
264
|
this._listeners.add(listener);
|
|
@@ -197,8 +271,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
197
271
|
log2("opening...", {
|
|
198
272
|
info: this.info
|
|
199
273
|
}, {
|
|
200
|
-
F:
|
|
201
|
-
L:
|
|
274
|
+
F: __dxlog_file3,
|
|
275
|
+
L: 101,
|
|
202
276
|
S: this,
|
|
203
277
|
C: (f, a) => f(...a)
|
|
204
278
|
});
|
|
@@ -206,8 +280,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
206
280
|
log2.warn("Error while opening connection", {
|
|
207
281
|
err
|
|
208
282
|
}, {
|
|
209
|
-
F:
|
|
210
|
-
L:
|
|
283
|
+
F: __dxlog_file3,
|
|
284
|
+
L: 103,
|
|
211
285
|
S: this,
|
|
212
286
|
C: (f, a) => f(...a)
|
|
213
287
|
});
|
|
@@ -218,54 +292,31 @@ var EdgeClient = class extends Resource2 {
|
|
|
218
292
|
*/
|
|
219
293
|
async _close() {
|
|
220
294
|
log2("closing...", {
|
|
221
|
-
peerKey: this.
|
|
295
|
+
peerKey: this._peerKey
|
|
222
296
|
}, {
|
|
223
|
-
F:
|
|
224
|
-
L:
|
|
297
|
+
F: __dxlog_file3,
|
|
298
|
+
L: 111,
|
|
225
299
|
S: this,
|
|
226
300
|
C: (f, a) => f(...a)
|
|
227
301
|
});
|
|
228
302
|
await this._persistentLifecycle.close();
|
|
229
303
|
}
|
|
230
304
|
async _openWebSocket() {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const challenge = randomBytes(32);
|
|
234
|
-
const credential = await this._identity.presentCredentials({
|
|
235
|
-
challenge
|
|
236
|
-
});
|
|
237
|
-
protocolHeader = encodePresentationIntoAuthHeader(credential);
|
|
238
|
-
}
|
|
239
|
-
if (this._ctx.disposed) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
const url = new URL(`/ws/${this._identity.identityKey}/${this._identity.peerKey}`, this._baseUrl);
|
|
243
|
-
log2("Opening websocket", {
|
|
244
|
-
url: url.toString(),
|
|
245
|
-
protocolHeader
|
|
246
|
-
}, {
|
|
247
|
-
F: __dxlog_file2,
|
|
248
|
-
L: 154,
|
|
249
|
-
S: this,
|
|
250
|
-
C: (f, a) => f(...a)
|
|
251
|
-
});
|
|
252
|
-
this._ws = new WebSocket(url, protocolHeader ? [
|
|
253
|
-
protocolHeader
|
|
254
|
-
] : []);
|
|
305
|
+
const url = new URL(`/ws/${this._identityKey}/${this._peerKey}`, this._config.socketEndpoint);
|
|
306
|
+
this._ws = new WebSocket(url);
|
|
255
307
|
this._ws.onopen = () => {
|
|
256
308
|
log2("opened", this.info, {
|
|
257
|
-
F:
|
|
258
|
-
L:
|
|
309
|
+
F: __dxlog_file3,
|
|
310
|
+
L: 120,
|
|
259
311
|
S: this,
|
|
260
312
|
C: (f, a) => f(...a)
|
|
261
313
|
});
|
|
262
314
|
this._ready.wake();
|
|
263
|
-
this.connected.emit();
|
|
264
315
|
};
|
|
265
316
|
this._ws.onclose = () => {
|
|
266
317
|
log2("closed", this.info, {
|
|
267
|
-
F:
|
|
268
|
-
L:
|
|
318
|
+
F: __dxlog_file3,
|
|
319
|
+
L: 124,
|
|
269
320
|
S: this,
|
|
270
321
|
C: (f, a) => f(...a)
|
|
271
322
|
});
|
|
@@ -276,8 +327,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
276
327
|
error: event.error,
|
|
277
328
|
info: event.message
|
|
278
329
|
}, {
|
|
279
|
-
F:
|
|
280
|
-
L:
|
|
330
|
+
F: __dxlog_file3,
|
|
331
|
+
L: 128,
|
|
281
332
|
S: this,
|
|
282
333
|
C: (f, a) => f(...a)
|
|
283
334
|
});
|
|
@@ -289,13 +340,13 @@ var EdgeClient = class extends Resource2 {
|
|
|
289
340
|
return;
|
|
290
341
|
}
|
|
291
342
|
const data = await toUint8Array(event.data);
|
|
292
|
-
const message =
|
|
343
|
+
const message = buf2.fromBinary(MessageSchema2, data);
|
|
293
344
|
log2("received", {
|
|
294
|
-
peerKey: this.
|
|
345
|
+
peerKey: this._peerKey,
|
|
295
346
|
payload: protocol.getPayloadType(message)
|
|
296
347
|
}, {
|
|
297
|
-
F:
|
|
298
|
-
L:
|
|
348
|
+
F: __dxlog_file3,
|
|
349
|
+
L: 141,
|
|
299
350
|
S: this,
|
|
300
351
|
C: (f, a) => f(...a)
|
|
301
352
|
});
|
|
@@ -308,8 +359,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
308
359
|
err,
|
|
309
360
|
payload: protocol.getPayloadType(message)
|
|
310
361
|
}, {
|
|
311
|
-
F:
|
|
312
|
-
L:
|
|
362
|
+
F: __dxlog_file3,
|
|
363
|
+
L: 147,
|
|
313
364
|
S: this,
|
|
314
365
|
C: (f, a) => f(...a)
|
|
315
366
|
});
|
|
@@ -320,18 +371,9 @@ var EdgeClient = class extends Resource2 {
|
|
|
320
371
|
await this._ready.wait({
|
|
321
372
|
timeout: this._config.timeout ?? DEFAULT_TIMEOUT
|
|
322
373
|
});
|
|
323
|
-
log2("Websocket is ready", {
|
|
324
|
-
identity: this._identity.identityKey,
|
|
325
|
-
peer: this._identity.peerKey
|
|
326
|
-
}, {
|
|
327
|
-
F: __dxlog_file2,
|
|
328
|
-
L: 194,
|
|
329
|
-
S: this,
|
|
330
|
-
C: (f, a) => f(...a)
|
|
331
|
-
});
|
|
332
374
|
this._keepaliveCtx = new Context(void 0, {
|
|
333
|
-
F:
|
|
334
|
-
L:
|
|
375
|
+
F: __dxlog_file3,
|
|
376
|
+
L: 154
|
|
335
377
|
});
|
|
336
378
|
scheduleTaskInterval(this._keepaliveCtx, async () => {
|
|
337
379
|
this._ws?.send("__ping__");
|
|
@@ -344,7 +386,7 @@ var EdgeClient = class extends Resource2 {
|
|
|
344
386
|
return;
|
|
345
387
|
}
|
|
346
388
|
try {
|
|
347
|
-
this._ready.throw(
|
|
389
|
+
this._ready.throw(new WebsocketClosedError());
|
|
348
390
|
this._ready.reset();
|
|
349
391
|
void this._keepaliveCtx?.dispose();
|
|
350
392
|
this._keepaliveCtx = void 0;
|
|
@@ -365,8 +407,8 @@ var EdgeClient = class extends Resource2 {
|
|
|
365
407
|
log2.warn("Error closing websocket", {
|
|
366
408
|
err
|
|
367
409
|
}, {
|
|
368
|
-
F:
|
|
369
|
-
L:
|
|
410
|
+
F: __dxlog_file3,
|
|
411
|
+
L: 190,
|
|
370
412
|
S: this,
|
|
371
413
|
C: (f, a) => f(...a)
|
|
372
414
|
});
|
|
@@ -378,32 +420,38 @@ var EdgeClient = class extends Resource2 {
|
|
|
378
420
|
*/
|
|
379
421
|
async send(message) {
|
|
380
422
|
if (this._ready.state !== TriggerState.RESOLVED) {
|
|
381
|
-
log2("waiting for websocket to become ready", void 0, {
|
|
382
|
-
F: __dxlog_file2,
|
|
383
|
-
L: 243,
|
|
384
|
-
S: this,
|
|
385
|
-
C: (f, a) => f(...a)
|
|
386
|
-
});
|
|
387
423
|
await this._ready.wait({
|
|
388
424
|
timeout: this._config.timeout ?? DEFAULT_TIMEOUT
|
|
389
425
|
});
|
|
390
426
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
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
|
+
});
|
|
397
445
|
log2("sending...", {
|
|
398
|
-
peerKey: this.
|
|
446
|
+
peerKey: this._peerKey,
|
|
399
447
|
payload: protocol.getPayloadType(message)
|
|
400
448
|
}, {
|
|
401
|
-
F:
|
|
402
|
-
L:
|
|
449
|
+
F: __dxlog_file3,
|
|
450
|
+
L: 204,
|
|
403
451
|
S: this,
|
|
404
452
|
C: (f, a) => f(...a)
|
|
405
453
|
});
|
|
406
|
-
this._ws.send(
|
|
454
|
+
this._ws.send(buf2.toBinary(MessageSchema2, message));
|
|
407
455
|
}
|
|
408
456
|
_onHeartbeat() {
|
|
409
457
|
if (this._lifecycleState !== LifecycleState2.OPEN) {
|
|
@@ -411,277 +459,17 @@ var EdgeClient = class extends Resource2 {
|
|
|
411
459
|
}
|
|
412
460
|
void this._heartBeatContext?.dispose();
|
|
413
461
|
this._heartBeatContext = new Context(void 0, {
|
|
414
|
-
F:
|
|
415
|
-
L:
|
|
462
|
+
F: __dxlog_file3,
|
|
463
|
+
L: 213
|
|
416
464
|
});
|
|
417
465
|
scheduleTask(this._heartBeatContext, () => {
|
|
418
466
|
this._persistentLifecycle.scheduleRestart();
|
|
419
467
|
}, 2 * SIGNAL_KEEPALIVE_INTERVAL);
|
|
420
468
|
}
|
|
421
469
|
};
|
|
422
|
-
var encodePresentationIntoAuthHeader = (presentation) => {
|
|
423
|
-
const encoded = schema.getCodecForType("dxos.halo.credentials.Presentation").encode(presentation);
|
|
424
|
-
const encodedToken = Buffer.from(encoded).toString("base64").replace(/=*$/, "").replaceAll("/", "|");
|
|
425
|
-
return `base64url.bearer.authorization.dxos.org.${encodedToken}`;
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
// packages/core/mesh/edge-client/src/auth.ts
|
|
429
|
-
import { createCredential, signPresentation } from "@dxos/credentials";
|
|
430
|
-
import { Keyring } from "@dxos/keyring";
|
|
431
|
-
import { PublicKey } from "@dxos/keys";
|
|
432
|
-
var createDeviceEdgeIdentity = async (signer, key) => {
|
|
433
|
-
return {
|
|
434
|
-
identityKey: key.toHex(),
|
|
435
|
-
peerKey: key.toHex(),
|
|
436
|
-
presentCredentials: async ({ challenge }) => {
|
|
437
|
-
return signPresentation({
|
|
438
|
-
presentation: {
|
|
439
|
-
credentials: [
|
|
440
|
-
// Verifier requires at least one credential in the presentation to establish the subject.
|
|
441
|
-
await createCredential({
|
|
442
|
-
assertion: {
|
|
443
|
-
"@type": "dxos.halo.credentials.Auth"
|
|
444
|
-
},
|
|
445
|
-
issuer: key,
|
|
446
|
-
subject: key,
|
|
447
|
-
signer
|
|
448
|
-
})
|
|
449
|
-
]
|
|
450
|
-
},
|
|
451
|
-
signer,
|
|
452
|
-
signerKey: key,
|
|
453
|
-
nonce: challenge
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
};
|
|
457
|
-
};
|
|
458
|
-
var createChainEdgeIdentity = async (signer, identityKey, peerKey, chain, credentials) => {
|
|
459
|
-
const credentialsToSign = credentials.length > 0 ? credentials : [
|
|
460
|
-
await createCredential({
|
|
461
|
-
assertion: {
|
|
462
|
-
"@type": "dxos.halo.credentials.Auth"
|
|
463
|
-
},
|
|
464
|
-
issuer: identityKey,
|
|
465
|
-
subject: identityKey,
|
|
466
|
-
signer,
|
|
467
|
-
chain,
|
|
468
|
-
signingKey: peerKey
|
|
469
|
-
})
|
|
470
|
-
];
|
|
471
|
-
return {
|
|
472
|
-
identityKey: identityKey.toHex(),
|
|
473
|
-
peerKey: peerKey.toHex(),
|
|
474
|
-
presentCredentials: async ({ challenge }) => {
|
|
475
|
-
return signPresentation({
|
|
476
|
-
presentation: {
|
|
477
|
-
credentials: credentialsToSign
|
|
478
|
-
},
|
|
479
|
-
signer,
|
|
480
|
-
nonce: challenge,
|
|
481
|
-
signerKey: peerKey,
|
|
482
|
-
chain
|
|
483
|
-
});
|
|
484
|
-
}
|
|
485
|
-
};
|
|
486
|
-
};
|
|
487
|
-
var createEphemeralEdgeIdentity = async () => {
|
|
488
|
-
const keyring = new Keyring();
|
|
489
|
-
const key = await keyring.createKey();
|
|
490
|
-
return createDeviceEdgeIdentity(keyring, key);
|
|
491
|
-
};
|
|
492
|
-
var createTestHaloEdgeIdentity = async (signer, identityKey, deviceKey) => {
|
|
493
|
-
const deviceAdmission = await createCredential({
|
|
494
|
-
assertion: {
|
|
495
|
-
"@type": "dxos.halo.credentials.AuthorizedDevice",
|
|
496
|
-
deviceKey,
|
|
497
|
-
identityKey
|
|
498
|
-
},
|
|
499
|
-
issuer: identityKey,
|
|
500
|
-
subject: deviceKey,
|
|
501
|
-
signer
|
|
502
|
-
});
|
|
503
|
-
return createChainEdgeIdentity(signer, identityKey, deviceKey, {
|
|
504
|
-
credential: deviceAdmission
|
|
505
|
-
}, [
|
|
506
|
-
await createCredential({
|
|
507
|
-
assertion: {
|
|
508
|
-
"@type": "dxos.halo.credentials.Auth"
|
|
509
|
-
},
|
|
510
|
-
issuer: identityKey,
|
|
511
|
-
subject: identityKey,
|
|
512
|
-
signer
|
|
513
|
-
})
|
|
514
|
-
]);
|
|
515
|
-
};
|
|
516
|
-
var createStubEdgeIdentity = () => {
|
|
517
|
-
const identityKey = PublicKey.random();
|
|
518
|
-
const deviceKey = PublicKey.random();
|
|
519
|
-
return {
|
|
520
|
-
identityKey: identityKey.toHex(),
|
|
521
|
-
peerKey: deviceKey.toHex(),
|
|
522
|
-
presentCredentials: async () => {
|
|
523
|
-
throw new Error("Stub identity does not support authentication.");
|
|
524
|
-
}
|
|
525
|
-
};
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
// packages/core/mesh/edge-client/src/edge-http-client.ts
|
|
529
|
-
import { sleep as sleep2 } from "@dxos/async";
|
|
530
|
-
import { Context as Context2 } from "@dxos/context";
|
|
531
|
-
import { log as log3 } from "@dxos/log";
|
|
532
|
-
import { EdgeCallFailedError, EdgeAuthChallengeError } from "@dxos/protocols";
|
|
533
|
-
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-http-client.ts";
|
|
534
|
-
var DEFAULT_RETRY_TIMEOUT = 1500;
|
|
535
|
-
var DEFAULT_RETRY_JITTER = 500;
|
|
536
|
-
var DEFAULT_MAX_RETRIES_COUNT = 3;
|
|
537
|
-
var EdgeHttpClient = class {
|
|
538
|
-
constructor(baseUrl) {
|
|
539
|
-
this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
|
|
540
|
-
log3("created", {
|
|
541
|
-
url: this._baseUrl
|
|
542
|
-
}, {
|
|
543
|
-
F: __dxlog_file3,
|
|
544
|
-
L: 33,
|
|
545
|
-
S: this,
|
|
546
|
-
C: (f, a) => f(...a)
|
|
547
|
-
});
|
|
548
|
-
}
|
|
549
|
-
createAgent(body, args) {
|
|
550
|
-
return this._call("/agents/create", {
|
|
551
|
-
...args,
|
|
552
|
-
method: "POST",
|
|
553
|
-
body
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
getAgentStatus(request, args) {
|
|
557
|
-
return this._call(`/users/${request.ownerIdentityKey.toHex()}/agent/status`, {
|
|
558
|
-
...args,
|
|
559
|
-
method: "GET"
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
getCredentialsForNotarization(spaceId, args) {
|
|
563
|
-
return this._call(`/spaces/${spaceId}/notarization`, {
|
|
564
|
-
...args,
|
|
565
|
-
method: "GET"
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
async notarizeCredentials(spaceId, body, args) {
|
|
569
|
-
await this._call(`/spaces/${spaceId}/notarization`, {
|
|
570
|
-
...args,
|
|
571
|
-
body,
|
|
572
|
-
method: "POST"
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
async joinSpaceByInvitation(spaceId, body, args) {
|
|
576
|
-
return this._call(`/spaces/${spaceId}/join`, {
|
|
577
|
-
...args,
|
|
578
|
-
body,
|
|
579
|
-
method: "POST"
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
async _call(path, args) {
|
|
583
|
-
const requestContext = args.context ?? new Context2(void 0, {
|
|
584
|
-
F: __dxlog_file3,
|
|
585
|
-
L: 68
|
|
586
|
-
});
|
|
587
|
-
const shouldRetry = createRetryHandler(args);
|
|
588
|
-
const request = createRequest(args);
|
|
589
|
-
const url = `${this._baseUrl}${path.startsWith("/") ? path.slice(1) : path}`;
|
|
590
|
-
log3.info("call", {
|
|
591
|
-
method: args.method,
|
|
592
|
-
path,
|
|
593
|
-
request: args.body
|
|
594
|
-
}, {
|
|
595
|
-
F: __dxlog_file3,
|
|
596
|
-
L: 73,
|
|
597
|
-
S: this,
|
|
598
|
-
C: (f, a) => f(...a)
|
|
599
|
-
});
|
|
600
|
-
while (true) {
|
|
601
|
-
let processingError;
|
|
602
|
-
let retryAfterHeaderValue = Number.NaN;
|
|
603
|
-
try {
|
|
604
|
-
const response = await fetch(url, request);
|
|
605
|
-
retryAfterHeaderValue = Number(response.headers.get("Retry-After"));
|
|
606
|
-
if (response.ok) {
|
|
607
|
-
const body = await response.json();
|
|
608
|
-
if (body.success) {
|
|
609
|
-
return body.data;
|
|
610
|
-
}
|
|
611
|
-
log3.info("unsuccessful edge response", {
|
|
612
|
-
path,
|
|
613
|
-
body
|
|
614
|
-
}, {
|
|
615
|
-
F: __dxlog_file3,
|
|
616
|
-
L: 89,
|
|
617
|
-
S: this,
|
|
618
|
-
C: (f, a) => f(...a)
|
|
619
|
-
});
|
|
620
|
-
if (body.errorData?.type === "auth_challenge" && typeof body.errorData?.challenge === "string") {
|
|
621
|
-
processingError = new EdgeAuthChallengeError(body.errorData.challenge, body.errorData);
|
|
622
|
-
} else {
|
|
623
|
-
processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);
|
|
624
|
-
}
|
|
625
|
-
} else {
|
|
626
|
-
processingError = EdgeCallFailedError.fromHttpFailure(response);
|
|
627
|
-
}
|
|
628
|
-
} catch (error) {
|
|
629
|
-
processingError = EdgeCallFailedError.fromProcessingFailureCause(error);
|
|
630
|
-
}
|
|
631
|
-
if (processingError.isRetryable && await shouldRetry(requestContext, retryAfterHeaderValue)) {
|
|
632
|
-
log3.info("retrying edge request", {
|
|
633
|
-
path,
|
|
634
|
-
processingError
|
|
635
|
-
}, {
|
|
636
|
-
F: __dxlog_file3,
|
|
637
|
-
L: 104,
|
|
638
|
-
S: this,
|
|
639
|
-
C: (f, a) => f(...a)
|
|
640
|
-
});
|
|
641
|
-
} else {
|
|
642
|
-
throw processingError;
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
};
|
|
647
|
-
var createRequest = (args) => {
|
|
648
|
-
return {
|
|
649
|
-
method: args.method,
|
|
650
|
-
body: args.body && JSON.stringify(args.body)
|
|
651
|
-
};
|
|
652
|
-
};
|
|
653
|
-
var createRetryHandler = (args) => {
|
|
654
|
-
if (!args.retry || args.retry.count < 1) {
|
|
655
|
-
return async () => false;
|
|
656
|
-
}
|
|
657
|
-
let retries = 0;
|
|
658
|
-
const maxRetries = args.retry.count ?? DEFAULT_MAX_RETRIES_COUNT;
|
|
659
|
-
const baseTimeout = args.retry.timeout ?? DEFAULT_RETRY_TIMEOUT;
|
|
660
|
-
const jitter = args.retry.jitter ?? DEFAULT_RETRY_JITTER;
|
|
661
|
-
return async (ctx, retryAfter) => {
|
|
662
|
-
if (++retries > maxRetries || ctx.disposed) {
|
|
663
|
-
return false;
|
|
664
|
-
}
|
|
665
|
-
if (retryAfter) {
|
|
666
|
-
await sleep2(retryAfter);
|
|
667
|
-
} else {
|
|
668
|
-
const timeout = baseTimeout + Math.random() * jitter;
|
|
669
|
-
await sleep2(timeout);
|
|
670
|
-
}
|
|
671
|
-
return true;
|
|
672
|
-
};
|
|
673
|
-
};
|
|
674
470
|
export {
|
|
675
471
|
EdgeClient,
|
|
676
|
-
EdgeConnectionClosedError,
|
|
677
|
-
EdgeHttpClient,
|
|
678
|
-
EdgeIdentityChangedError,
|
|
679
472
|
Protocol,
|
|
680
|
-
createChainEdgeIdentity,
|
|
681
|
-
createDeviceEdgeIdentity,
|
|
682
|
-
createEphemeralEdgeIdentity,
|
|
683
|
-
createStubEdgeIdentity,
|
|
684
|
-
createTestHaloEdgeIdentity,
|
|
685
473
|
getTypename,
|
|
686
474
|
protocol,
|
|
687
475
|
toUint8Array
|