@dxos/teleport 0.1.23 → 0.1.24
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-F3DXMBSX.mjs +657 -0
- package/dist/lib/browser/chunk-F3DXMBSX.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +15 -653
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +95 -694
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node/index.cjs +3 -3
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +95 -47
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/types/src/rpc-extension.d.ts +2 -2
- package/dist/types/src/rpc-extension.d.ts.map +1 -1
- package/dist/types/src/testing/test-builder.d.ts +22 -15
- package/dist/types/src/testing/test-builder.d.ts.map +1 -1
- package/package.json +10 -10
- package/src/rpc-extension.ts +2 -2
- package/src/teleport.test.ts +13 -10
- package/src/testing/test-builder.ts +94 -39
|
@@ -1,657 +1,19 @@
|
|
|
1
1
|
import "@dxos/node-std/globals"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
objectMode: false,
|
|
11
|
-
read: () => {
|
|
12
|
-
},
|
|
13
|
-
write: (chunk, encoding, callback) => {
|
|
14
|
-
assert(!this._subscribeCb, "Internal Framer bug. Concurrent writes detected.");
|
|
15
|
-
if (this._buffer && this._buffer.length > 0) {
|
|
16
|
-
this._buffer = Buffer.concat([
|
|
17
|
-
this._buffer,
|
|
18
|
-
chunk
|
|
19
|
-
]);
|
|
20
|
-
} else {
|
|
21
|
-
this._buffer = chunk;
|
|
22
|
-
}
|
|
23
|
-
if (this._messageCb) {
|
|
24
|
-
this._popFrames();
|
|
25
|
-
callback();
|
|
26
|
-
} else {
|
|
27
|
-
this._subscribeCb = () => {
|
|
28
|
-
this._popFrames();
|
|
29
|
-
this._subscribeCb = void 0;
|
|
30
|
-
callback();
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
this.port = {
|
|
36
|
-
send: (message) => {
|
|
37
|
-
this._stream.push(encodeFrame(message));
|
|
38
|
-
},
|
|
39
|
-
subscribe: (callback) => {
|
|
40
|
-
var _a;
|
|
41
|
-
assert(!this._messageCb, "Rpc port already has a message listener.");
|
|
42
|
-
this._messageCb = callback;
|
|
43
|
-
(_a = this._subscribeCb) == null ? void 0 : _a.call(this);
|
|
44
|
-
return () => {
|
|
45
|
-
this._messageCb = void 0;
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
get stream() {
|
|
51
|
-
return this._stream;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Attempts to pop frames from the buffer and call the message callback.
|
|
55
|
-
*/
|
|
56
|
-
_popFrames() {
|
|
57
|
-
let offset = 0;
|
|
58
|
-
while (offset < this._buffer.length) {
|
|
59
|
-
const frame = decodeFrame(this._buffer, offset);
|
|
60
|
-
if (!frame) {
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
offset += frame.bytesConsumed;
|
|
64
|
-
this._messageCb(frame.payload);
|
|
65
|
-
}
|
|
66
|
-
if (offset < this._buffer.length) {
|
|
67
|
-
this._buffer = this._buffer.subarray(offset);
|
|
68
|
-
} else {
|
|
69
|
-
this._buffer = void 0;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
destroy() {
|
|
73
|
-
this._stream.destroy();
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
var decodeFrame = (buffer, offset) => {
|
|
77
|
-
try {
|
|
78
|
-
const frameLength = varint.decode(buffer, offset);
|
|
79
|
-
const tagLength = varint.decode.bytes;
|
|
80
|
-
if (buffer.length < offset + tagLength + frameLength) {
|
|
81
|
-
return void 0;
|
|
82
|
-
}
|
|
83
|
-
const payload = buffer.subarray(offset + tagLength, offset + tagLength + frameLength);
|
|
84
|
-
return {
|
|
85
|
-
payload,
|
|
86
|
-
bytesConsumed: tagLength + frameLength
|
|
87
|
-
};
|
|
88
|
-
} catch (err) {
|
|
89
|
-
if (err instanceof RangeError) {
|
|
90
|
-
return void 0;
|
|
91
|
-
} else {
|
|
92
|
-
throw err;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
var encodeFrame = (payload) => {
|
|
97
|
-
const tagLength = varint.encodingLength(payload.length);
|
|
98
|
-
const frame = Buffer.allocUnsafe(tagLength + payload.length);
|
|
99
|
-
varint.encode(payload.length, frame);
|
|
100
|
-
frame.set(payload, tagLength);
|
|
101
|
-
return frame;
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// packages/core/mesh/teleport/src/muxing/muxer.ts
|
|
105
|
-
import assert2 from "@dxos/node-std/assert";
|
|
106
|
-
import { Duplex as Duplex2 } from "@dxos/node-std/stream";
|
|
107
|
-
import { Event } from "@dxos/async";
|
|
108
|
-
import { failUndefined } from "@dxos/debug";
|
|
109
|
-
import { log } from "@dxos/log";
|
|
110
|
-
import { schema } from "@dxos/protocols";
|
|
111
|
-
var codec = schema.getCodecForType("dxos.mesh.muxer.Command");
|
|
112
|
-
var Muxer = class {
|
|
113
|
-
constructor() {
|
|
114
|
-
this._framer = new Framer();
|
|
115
|
-
this.stream = this._framer.stream;
|
|
116
|
-
this._channelsByLocalId = /* @__PURE__ */ new Map();
|
|
117
|
-
this._channelsByTag = /* @__PURE__ */ new Map();
|
|
118
|
-
this._nextId = 0;
|
|
119
|
-
this._destroyed = false;
|
|
120
|
-
this._destroying = false;
|
|
121
|
-
this.close = new Event();
|
|
122
|
-
this._framer.port.subscribe((msg) => {
|
|
123
|
-
this._handleCommand(codec.decode(msg));
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Creates a duplex Node.js-style stream.
|
|
128
|
-
* The remote peer is expected to call `createStream` with the same tag.
|
|
129
|
-
* The stream is immediately readable and writable.
|
|
130
|
-
* NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).
|
|
131
|
-
*/
|
|
132
|
-
createStream(tag, opts = {}) {
|
|
133
|
-
const channel = this._getOrCreateStream({
|
|
134
|
-
tag,
|
|
135
|
-
contentType: opts.contentType
|
|
136
|
-
});
|
|
137
|
-
assert2(!channel.push, `Channel already open: ${tag}`);
|
|
138
|
-
const stream = new Duplex2({
|
|
139
|
-
write: (data, encoding, callback) => {
|
|
140
|
-
this._sendData(channel, data);
|
|
141
|
-
callback();
|
|
142
|
-
},
|
|
143
|
-
read: () => {
|
|
144
|
-
}
|
|
145
|
-
// No-op. We will push data when we receive it.
|
|
146
|
-
});
|
|
147
|
-
channel.push = (data) => {
|
|
148
|
-
stream.push(data);
|
|
149
|
-
};
|
|
150
|
-
channel.destroy = (err) => {
|
|
151
|
-
stream.destroy(err);
|
|
152
|
-
};
|
|
153
|
-
this._sendCommand({
|
|
154
|
-
openChannel: {
|
|
155
|
-
id: channel.id,
|
|
156
|
-
tag: channel.tag,
|
|
157
|
-
contentType: channel.contentType
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
return stream;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Creates an RPC port.
|
|
164
|
-
* The remote peer is expected to call `createPort` with the same tag.
|
|
165
|
-
* The port is immediately usable.
|
|
166
|
-
* NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).
|
|
167
|
-
*/
|
|
168
|
-
createPort(tag, opts = {}) {
|
|
169
|
-
const channel = this._getOrCreateStream({
|
|
170
|
-
tag,
|
|
171
|
-
contentType: opts.contentType
|
|
172
|
-
});
|
|
173
|
-
assert2(!channel.push, `Channel already open: ${tag}`);
|
|
174
|
-
let inboundBuffer = [];
|
|
175
|
-
let callback;
|
|
176
|
-
channel.push = (data) => {
|
|
177
|
-
if (callback) {
|
|
178
|
-
callback(data);
|
|
179
|
-
} else {
|
|
180
|
-
inboundBuffer.push(data);
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
const port = {
|
|
184
|
-
send: (data) => {
|
|
185
|
-
this._sendData(channel, data);
|
|
186
|
-
},
|
|
187
|
-
subscribe: (cb) => {
|
|
188
|
-
assert2(!callback, "Only one subscriber is allowed");
|
|
189
|
-
callback = cb;
|
|
190
|
-
for (const data of inboundBuffer) {
|
|
191
|
-
cb(data);
|
|
192
|
-
}
|
|
193
|
-
inboundBuffer = [];
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
this._sendCommand({
|
|
197
|
-
openChannel: {
|
|
198
|
-
id: channel.id,
|
|
199
|
-
tag: channel.tag,
|
|
200
|
-
contentType: channel.contentType
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
return port;
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Force-close with optional error.
|
|
207
|
-
*/
|
|
208
|
-
destroy(err) {
|
|
209
|
-
if (this._destroying) {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
this._destroying = true;
|
|
213
|
-
this._sendCommand({
|
|
214
|
-
destroy: {
|
|
215
|
-
error: err == null ? void 0 : err.message
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
this._dispose();
|
|
219
|
-
}
|
|
220
|
-
_dispose(err) {
|
|
221
|
-
var _a;
|
|
222
|
-
if (this._destroyed) {
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
this._destroyed = true;
|
|
226
|
-
this._framer.destroy();
|
|
227
|
-
for (const channel of this._channelsByTag.values()) {
|
|
228
|
-
(_a = channel.destroy) == null ? void 0 : _a.call(channel, err);
|
|
229
|
-
}
|
|
230
|
-
this.close.emit(err);
|
|
231
|
-
this._channelsByLocalId.clear();
|
|
232
|
-
this._channelsByTag.clear();
|
|
233
|
-
}
|
|
234
|
-
_handleCommand(cmd) {
|
|
235
|
-
var _a;
|
|
236
|
-
log("Received command", {
|
|
237
|
-
cmd
|
|
238
|
-
}, {
|
|
239
|
-
file: "muxer.ts",
|
|
240
|
-
line: 194,
|
|
241
|
-
scope: this,
|
|
242
|
-
callSite: (f, a) => f(...a)
|
|
243
|
-
});
|
|
244
|
-
if (this._destroyed || this._destroying) {
|
|
245
|
-
log.warn("Received command after destroy", {}, {
|
|
246
|
-
file: "muxer.ts",
|
|
247
|
-
line: 197,
|
|
248
|
-
scope: this,
|
|
249
|
-
callSite: (f, a) => f(...a)
|
|
250
|
-
});
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
if (cmd.openChannel) {
|
|
254
|
-
const channel = this._getOrCreateStream({
|
|
255
|
-
tag: cmd.openChannel.tag,
|
|
256
|
-
contentType: cmd.openChannel.contentType
|
|
257
|
-
});
|
|
258
|
-
channel.remoteId = cmd.openChannel.id;
|
|
259
|
-
for (const data of channel.buffer) {
|
|
260
|
-
this._sendCommand({
|
|
261
|
-
data: {
|
|
262
|
-
channelId: channel.remoteId,
|
|
263
|
-
data
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
channel.buffer = [];
|
|
268
|
-
} else if (cmd.data) {
|
|
269
|
-
const stream = (_a = this._channelsByLocalId.get(cmd.data.channelId)) != null ? _a : failUndefined();
|
|
270
|
-
if (!stream.push) {
|
|
271
|
-
log.warn("Received data for channel before it was opened", {
|
|
272
|
-
tag: stream.tag
|
|
273
|
-
}, {
|
|
274
|
-
file: "muxer.ts",
|
|
275
|
-
line: 221,
|
|
276
|
-
scope: this,
|
|
277
|
-
callSite: (f, a) => f(...a)
|
|
278
|
-
});
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
stream.push(cmd.data.data);
|
|
282
|
-
} else if (cmd.destroy) {
|
|
283
|
-
this._dispose();
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
_sendCommand(cmd) {
|
|
287
|
-
Promise.resolve(this._framer.port.send(codec.encode(cmd))).catch((err) => {
|
|
288
|
-
this.destroy(err);
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
_getOrCreateStream(params) {
|
|
292
|
-
let channel = this._channelsByTag.get(params.tag);
|
|
293
|
-
if (!channel) {
|
|
294
|
-
channel = {
|
|
295
|
-
id: this._nextId++,
|
|
296
|
-
remoteId: null,
|
|
297
|
-
tag: params.tag,
|
|
298
|
-
contentType: params.contentType,
|
|
299
|
-
buffer: [],
|
|
300
|
-
push: null,
|
|
301
|
-
destroy: null
|
|
302
|
-
};
|
|
303
|
-
this._channelsByTag.set(channel.tag, channel);
|
|
304
|
-
this._channelsByLocalId.set(channel.id, channel);
|
|
305
|
-
}
|
|
306
|
-
return channel;
|
|
307
|
-
}
|
|
308
|
-
_sendData(channel, data) {
|
|
309
|
-
if (channel.remoteId === null) {
|
|
310
|
-
channel.buffer.push(data);
|
|
311
|
-
} else {
|
|
312
|
-
this._sendCommand({
|
|
313
|
-
data: {
|
|
314
|
-
channelId: channel.remoteId,
|
|
315
|
-
data
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
// packages/core/mesh/teleport/src/teleport.ts
|
|
323
|
-
import assert3 from "@dxos/node-std/assert";
|
|
324
|
-
import { asyncTimeout, scheduleTaskInterval, runInContextAsync, synchronized, scheduleTask } from "@dxos/async";
|
|
325
|
-
import { Context } from "@dxos/context";
|
|
326
|
-
import { failUndefined as failUndefined2 } from "@dxos/debug";
|
|
327
|
-
import { PublicKey } from "@dxos/keys";
|
|
328
|
-
import { log as log2 } from "@dxos/log";
|
|
329
|
-
import { schema as schema2 } from "@dxos/protocols";
|
|
330
|
-
import { createProtoRpcPeer, RpcClosedError } from "@dxos/rpc";
|
|
331
|
-
import { Callback } from "@dxos/util";
|
|
332
|
-
var __decorate = function(decorators, target, key, desc) {
|
|
333
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
334
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
335
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
336
|
-
else
|
|
337
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
338
|
-
if (d = decorators[i])
|
|
339
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
340
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
341
|
-
};
|
|
342
|
-
var Teleport = class {
|
|
343
|
-
constructor({ initiator, localPeerId, remotePeerId }) {
|
|
344
|
-
this._ctx = new Context({
|
|
345
|
-
onError: (err) => {
|
|
346
|
-
void this.destroy(err).catch(() => {
|
|
347
|
-
log2.error("Error during destroy", err, {
|
|
348
|
-
file: "teleport.ts",
|
|
349
|
-
line: 34,
|
|
350
|
-
scope: this,
|
|
351
|
-
callSite: (f, a) => f(...a)
|
|
352
|
-
});
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
});
|
|
356
|
-
this._muxer = new Muxer();
|
|
357
|
-
this._control = new ControlExtension({
|
|
358
|
-
heartbeatInterval: 3e3,
|
|
359
|
-
heartbeatTimeout: 3e3,
|
|
360
|
-
onTimeout: () => {
|
|
361
|
-
this.destroy(new Error("Connection timed out")).catch((err) => log2.catch(err, {}, {
|
|
362
|
-
file: "teleport.ts",
|
|
363
|
-
line: 45,
|
|
364
|
-
scope: this,
|
|
365
|
-
callSite: (f, a) => f(...a)
|
|
366
|
-
}));
|
|
367
|
-
}
|
|
368
|
-
});
|
|
369
|
-
this._extensions = /* @__PURE__ */ new Map();
|
|
370
|
-
this._remoteExtensions = /* @__PURE__ */ new Set();
|
|
371
|
-
this._open = false;
|
|
372
|
-
assert3(typeof initiator === "boolean");
|
|
373
|
-
assert3(PublicKey.isPublicKey(localPeerId));
|
|
374
|
-
assert3(PublicKey.isPublicKey(remotePeerId));
|
|
375
|
-
assert3(typeof initiator === "boolean");
|
|
376
|
-
this.initiator = initiator;
|
|
377
|
-
this.localPeerId = localPeerId;
|
|
378
|
-
this.remotePeerId = remotePeerId;
|
|
379
|
-
this._control.onExtensionRegistered.set(async (name) => {
|
|
380
|
-
log2("remote extension", {
|
|
381
|
-
name
|
|
382
|
-
}, {
|
|
383
|
-
file: "teleport.ts",
|
|
384
|
-
line: 64,
|
|
385
|
-
scope: this,
|
|
386
|
-
callSite: (f, a) => f(...a)
|
|
387
|
-
});
|
|
388
|
-
assert3(!this._remoteExtensions.has(name), "Remote extension already exists");
|
|
389
|
-
this._remoteExtensions.add(name);
|
|
390
|
-
if (this._extensions.has(name)) {
|
|
391
|
-
try {
|
|
392
|
-
await this._openExtension(name);
|
|
393
|
-
} catch (err) {
|
|
394
|
-
await this.destroy(err);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
|
-
{
|
|
399
|
-
this._muxer.stream.on("close", async () => {
|
|
400
|
-
await this.destroy();
|
|
401
|
-
});
|
|
402
|
-
this._muxer.stream.on("error", async (err) => {
|
|
403
|
-
await this.destroy(err);
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
get stream() {
|
|
408
|
-
return this._muxer.stream;
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Blocks until the handshake is complete.
|
|
412
|
-
*/
|
|
413
|
-
async open() {
|
|
414
|
-
this._setExtension("dxos.mesh.teleport.control", this._control);
|
|
415
|
-
await this._openExtension("dxos.mesh.teleport.control");
|
|
416
|
-
this._open = true;
|
|
417
|
-
}
|
|
418
|
-
async close(err) {
|
|
419
|
-
await this.destroy(err);
|
|
420
|
-
}
|
|
421
|
-
async destroy(err) {
|
|
422
|
-
if (this._ctx.disposed) {
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
await this._ctx.dispose();
|
|
426
|
-
for (const extension of this._extensions.values()) {
|
|
427
|
-
try {
|
|
428
|
-
await extension.onClose(err);
|
|
429
|
-
} catch (err1) {
|
|
430
|
-
log2.catch(err1, {}, {
|
|
431
|
-
file: "teleport.ts",
|
|
432
|
-
line: 120,
|
|
433
|
-
scope: this,
|
|
434
|
-
callSite: (f, a) => f(...a)
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
this._muxer.destroy(err);
|
|
439
|
-
}
|
|
440
|
-
addExtension(name, extension) {
|
|
441
|
-
if (!this._open) {
|
|
442
|
-
throw new Error("Not open");
|
|
443
|
-
}
|
|
444
|
-
log2("addExtension", {
|
|
445
|
-
name
|
|
446
|
-
}, {
|
|
447
|
-
file: "teleport.ts",
|
|
448
|
-
line: 132,
|
|
449
|
-
scope: this,
|
|
450
|
-
callSite: (f, a) => f(...a)
|
|
451
|
-
});
|
|
452
|
-
this._setExtension(name, extension);
|
|
453
|
-
scheduleTask(this._ctx, async () => {
|
|
454
|
-
try {
|
|
455
|
-
await this._control.registerExtension(name);
|
|
456
|
-
} catch (err) {
|
|
457
|
-
if (err instanceof RpcClosedError) {
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
throw err;
|
|
461
|
-
}
|
|
462
|
-
});
|
|
463
|
-
if (this._remoteExtensions.has(name)) {
|
|
464
|
-
scheduleTask(this._ctx, async () => {
|
|
465
|
-
await this._openExtension(name);
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
_setExtension(extensionName, extension) {
|
|
470
|
-
assert3(!extensionName.includes("/"), "Invalid extension name");
|
|
471
|
-
assert3(!this._extensions.has(extensionName), "Extension already exists");
|
|
472
|
-
this._extensions.set(extensionName, extension);
|
|
473
|
-
}
|
|
474
|
-
async _openExtension(extensionName) {
|
|
475
|
-
var _a;
|
|
476
|
-
log2("open extension", {
|
|
477
|
-
extensionName
|
|
478
|
-
}, {
|
|
479
|
-
file: "teleport.ts",
|
|
480
|
-
line: 162,
|
|
481
|
-
scope: this,
|
|
482
|
-
callSite: (f, a) => f(...a)
|
|
483
|
-
});
|
|
484
|
-
const extension = (_a = this._extensions.get(extensionName)) != null ? _a : failUndefined2();
|
|
485
|
-
const context = {
|
|
486
|
-
initiator: this.initiator,
|
|
487
|
-
localPeerId: this.localPeerId,
|
|
488
|
-
remotePeerId: this.remotePeerId,
|
|
489
|
-
createPort: (channelName, opts) => {
|
|
490
|
-
assert3(!channelName.includes("/"), "Invalid channel name");
|
|
491
|
-
return this._muxer.createPort(`${extensionName}/${channelName}`, opts);
|
|
492
|
-
},
|
|
493
|
-
createStream: (channelName, opts) => {
|
|
494
|
-
assert3(!channelName.includes("/"), "Invalid channel name");
|
|
495
|
-
return this._muxer.createStream(`${extensionName}/${channelName}`, opts);
|
|
496
|
-
},
|
|
497
|
-
close: (err) => {
|
|
498
|
-
void runInContextAsync(this._ctx, async () => {
|
|
499
|
-
await this.close(err);
|
|
500
|
-
});
|
|
501
|
-
}
|
|
502
|
-
};
|
|
503
|
-
await extension.onOpen(context);
|
|
504
|
-
log2("extension opened", {
|
|
505
|
-
extensionName
|
|
506
|
-
}, {
|
|
507
|
-
file: "teleport.ts",
|
|
508
|
-
line: 185,
|
|
509
|
-
scope: this,
|
|
510
|
-
callSite: (f, a) => f(...a)
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
};
|
|
514
|
-
__decorate([
|
|
515
|
-
synchronized
|
|
516
|
-
], Teleport.prototype, "destroy", null);
|
|
517
|
-
var ControlExtension = class {
|
|
518
|
-
constructor(opts) {
|
|
519
|
-
this.opts = opts;
|
|
520
|
-
this._ctx = new Context({
|
|
521
|
-
onError: (err) => {
|
|
522
|
-
this._extensionContext.close(err);
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
this.onExtensionRegistered = new Callback();
|
|
526
|
-
}
|
|
527
|
-
async onOpen(extensionContext) {
|
|
528
|
-
this._extensionContext = extensionContext;
|
|
529
|
-
this._rpc = createProtoRpcPeer({
|
|
530
|
-
requested: {
|
|
531
|
-
Control: schema2.getService("dxos.mesh.teleport.control.ControlService")
|
|
532
|
-
},
|
|
533
|
-
exposed: {
|
|
534
|
-
Control: schema2.getService("dxos.mesh.teleport.control.ControlService")
|
|
535
|
-
},
|
|
536
|
-
handlers: {
|
|
537
|
-
Control: {
|
|
538
|
-
registerExtension: async (request) => {
|
|
539
|
-
this.onExtensionRegistered.call(request.name);
|
|
540
|
-
},
|
|
541
|
-
heartbeat: async (request) => {
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
},
|
|
545
|
-
port: extensionContext.createPort("rpc", {
|
|
546
|
-
contentType: 'application/x-protobuf; messagType="dxos.rpc.Message"'
|
|
547
|
-
})
|
|
548
|
-
});
|
|
549
|
-
await this._rpc.open();
|
|
550
|
-
scheduleTaskInterval(this._ctx, async () => {
|
|
551
|
-
try {
|
|
552
|
-
await asyncTimeout(this._rpc.rpc.Control.heartbeat(), this.opts.heartbeatTimeout);
|
|
553
|
-
} catch (err) {
|
|
554
|
-
this.opts.onTimeout();
|
|
555
|
-
}
|
|
556
|
-
}, this.opts.heartbeatInterval);
|
|
557
|
-
}
|
|
558
|
-
async onClose(err) {
|
|
559
|
-
await this._ctx.dispose();
|
|
560
|
-
await this._rpc.close();
|
|
561
|
-
}
|
|
562
|
-
async registerExtension(name) {
|
|
563
|
-
await this._rpc.rpc.Control.registerExtension({
|
|
564
|
-
name
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
// packages/core/mesh/teleport/src/testing/test-extension.ts
|
|
570
|
-
import assert4 from "@dxos/node-std/assert";
|
|
571
|
-
import { asyncTimeout as asyncTimeout2, Trigger } from "@dxos/async";
|
|
572
|
-
import { log as log3 } from "@dxos/log";
|
|
573
|
-
import { schema as schema3 } from "@dxos/protocols";
|
|
574
|
-
import { createProtoRpcPeer as createProtoRpcPeer2 } from "@dxos/rpc";
|
|
575
|
-
var TestExtension = class {
|
|
576
|
-
constructor(callbacks = {}) {
|
|
577
|
-
this.callbacks = callbacks;
|
|
578
|
-
this.open = new Trigger();
|
|
579
|
-
this.closed = new Trigger();
|
|
580
|
-
}
|
|
581
|
-
get remotePeerId() {
|
|
582
|
-
var _a;
|
|
583
|
-
return (_a = this.extensionContext) == null ? void 0 : _a.remotePeerId;
|
|
584
|
-
}
|
|
585
|
-
async onOpen(context) {
|
|
586
|
-
var _a, _b;
|
|
587
|
-
log3("onOpen", {
|
|
588
|
-
localPeerId: context.localPeerId,
|
|
589
|
-
remotePeerId: context.remotePeerId
|
|
590
|
-
}, {
|
|
591
|
-
file: "test-extension.ts",
|
|
592
|
-
line: 33,
|
|
593
|
-
scope: this,
|
|
594
|
-
callSite: (f, a) => f(...a)
|
|
595
|
-
});
|
|
596
|
-
this.extensionContext = context;
|
|
597
|
-
this._rpc = createProtoRpcPeer2({
|
|
598
|
-
port: context.createPort("rpc", {
|
|
599
|
-
contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
|
|
600
|
-
}),
|
|
601
|
-
requested: {
|
|
602
|
-
TestService: schema3.getService("example.testing.rpc.TestService")
|
|
603
|
-
},
|
|
604
|
-
exposed: {
|
|
605
|
-
TestService: schema3.getService("example.testing.rpc.TestService")
|
|
606
|
-
},
|
|
607
|
-
handlers: {
|
|
608
|
-
TestService: {
|
|
609
|
-
voidCall: async (request) => {
|
|
610
|
-
},
|
|
611
|
-
testCall: async (request) => {
|
|
612
|
-
return {
|
|
613
|
-
data: request.data
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
},
|
|
618
|
-
timeout: 1e3
|
|
619
|
-
});
|
|
620
|
-
await this._rpc.open();
|
|
621
|
-
await ((_b = (_a = this.callbacks).onOpen) == null ? void 0 : _b.call(_a));
|
|
622
|
-
this.open.wake();
|
|
623
|
-
}
|
|
624
|
-
async onClose(err) {
|
|
625
|
-
var _a, _b, _c;
|
|
626
|
-
log3("onClose", {
|
|
627
|
-
err
|
|
628
|
-
}, {
|
|
629
|
-
file: "test-extension.ts",
|
|
630
|
-
line: 67,
|
|
631
|
-
scope: this,
|
|
632
|
-
callSite: (f, a) => f(...a)
|
|
633
|
-
});
|
|
634
|
-
await ((_b = (_a = this.callbacks).onClose) == null ? void 0 : _b.call(_a));
|
|
635
|
-
this.closed.wake();
|
|
636
|
-
await ((_c = this._rpc) == null ? void 0 : _c.close());
|
|
637
|
-
}
|
|
638
|
-
async test() {
|
|
639
|
-
await this.open.wait({
|
|
640
|
-
timeout: 500
|
|
641
|
-
});
|
|
642
|
-
const res = await asyncTimeout2(this._rpc.rpc.TestService.testCall({
|
|
643
|
-
data: "test"
|
|
644
|
-
}), 500);
|
|
645
|
-
assert4(res.data === "test");
|
|
646
|
-
}
|
|
647
|
-
};
|
|
2
|
+
import {
|
|
3
|
+
Framer,
|
|
4
|
+
Muxer,
|
|
5
|
+
Teleport,
|
|
6
|
+
TestExtension,
|
|
7
|
+
decodeFrame,
|
|
8
|
+
encodeFrame
|
|
9
|
+
} from "./chunk-F3DXMBSX.mjs";
|
|
648
10
|
|
|
649
11
|
// packages/core/mesh/teleport/src/rpc-extension.ts
|
|
650
|
-
import
|
|
651
|
-
import { createProtoRpcPeer
|
|
12
|
+
import assert from "@dxos/node-std/assert";
|
|
13
|
+
import { createProtoRpcPeer } from "@dxos/rpc";
|
|
652
14
|
var RpcExtension = class {
|
|
653
|
-
constructor(
|
|
654
|
-
this.
|
|
15
|
+
constructor(_rpcParams) {
|
|
16
|
+
this._rpcParams = _rpcParams;
|
|
655
17
|
this._isClosed = false;
|
|
656
18
|
}
|
|
657
19
|
get initiator() {
|
|
@@ -664,7 +26,7 @@ var RpcExtension = class {
|
|
|
664
26
|
return this._extensionContext.remotePeerId;
|
|
665
27
|
}
|
|
666
28
|
get rpc() {
|
|
667
|
-
|
|
29
|
+
assert(this._rpc);
|
|
668
30
|
return this._rpc.rpc;
|
|
669
31
|
}
|
|
670
32
|
async onOpen(context) {
|
|
@@ -676,8 +38,8 @@ var RpcExtension = class {
|
|
|
676
38
|
const port = context.createPort("rpc", {
|
|
677
39
|
contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
|
|
678
40
|
});
|
|
679
|
-
this._rpc =
|
|
680
|
-
...this.
|
|
41
|
+
this._rpc = createProtoRpcPeer({
|
|
42
|
+
...this._rpcParams,
|
|
681
43
|
handlers,
|
|
682
44
|
port
|
|
683
45
|
});
|