@dxos/teleport 0.1.14
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/LICENSE +8 -0
- package/README.md +0 -0
- package/dist/lib/browser/index.mjs +544 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/testing.mjs +621 -0
- package/dist/lib/browser/testing.mjs.map +7 -0
- package/dist/lib/node/index.cjs +580 -0
- package/dist/lib/node/index.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -0
- package/dist/lib/node/testing.cjs +653 -0
- package/dist/lib/node/testing.cjs.map +7 -0
- package/dist/types/src/index.d.ts +3 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/muxing/framer.d.ts +29 -0
- package/dist/types/src/muxing/framer.d.ts.map +1 -0
- package/dist/types/src/muxing/framer.test.d.ts +2 -0
- package/dist/types/src/muxing/framer.test.d.ts.map +1 -0
- package/dist/types/src/muxing/index.d.ts +4 -0
- package/dist/types/src/muxing/index.d.ts.map +1 -0
- package/dist/types/src/muxing/muxer.d.ts +60 -0
- package/dist/types/src/muxing/muxer.d.ts.map +1 -0
- package/dist/types/src/muxing/muxer.test.d.ts +2 -0
- package/dist/types/src/muxing/muxer.test.d.ts.map +1 -0
- package/dist/types/src/muxing/rpc-port.d.ts +11 -0
- package/dist/types/src/muxing/rpc-port.d.ts.map +1 -0
- package/dist/types/src/muxing/rpc-port.test.d.ts +2 -0
- package/dist/types/src/muxing/rpc-port.test.d.ts.map +1 -0
- package/dist/types/src/teleport.d.ts +47 -0
- package/dist/types/src/teleport.d.ts.map +1 -0
- package/dist/types/src/teleport.test.d.ts +2 -0
- package/dist/types/src/teleport.test.d.ts.map +1 -0
- package/dist/types/src/test-extension.d.ts +12 -0
- package/dist/types/src/test-extension.d.ts.map +1 -0
- package/dist/types/src/testing.d.ts +29 -0
- package/dist/types/src/testing.d.ts.map +1 -0
- package/package.json +47 -0
- package/src/index.ts +6 -0
- package/src/muxing/framer.test.ts +160 -0
- package/src/muxing/framer.ts +132 -0
- package/src/muxing/index.ts +7 -0
- package/src/muxing/muxer.test.ts +185 -0
- package/src/muxing/muxer.ts +301 -0
- package/src/muxing/rpc-port.test.ts +18 -0
- package/src/muxing/rpc-port.ts +15 -0
- package/src/teleport.test.ts +81 -0
- package/src/teleport.ts +277 -0
- package/src/test-extension.ts +65 -0
- package/src/testing.ts +75 -0
- package/testing.d.ts +11 -0
- package/testing.js +5 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
Copyright (c) 2022 DXOS
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
5
|
+
|
|
6
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
7
|
+
|
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
// packages/core/mesh/teleport/src/muxing/framer.ts
|
|
2
|
+
import assert from "@dxos/node-std/assert";
|
|
3
|
+
import { Duplex } from "@dxos/node-std/stream";
|
|
4
|
+
import * as varint from "varint";
|
|
5
|
+
var Framer = class {
|
|
6
|
+
constructor() {
|
|
7
|
+
this._stream = new Duplex({
|
|
8
|
+
objectMode: false,
|
|
9
|
+
read: () => {
|
|
10
|
+
},
|
|
11
|
+
write: (chunk, encoding, callback) => {
|
|
12
|
+
assert(!this._subscribeCb, "Internal Framer bug. Concurrent writes detected.");
|
|
13
|
+
if (this._buffer && this._buffer.length > 0) {
|
|
14
|
+
this._buffer = Buffer.concat([
|
|
15
|
+
this._buffer,
|
|
16
|
+
chunk
|
|
17
|
+
]);
|
|
18
|
+
} else {
|
|
19
|
+
this._buffer = chunk;
|
|
20
|
+
}
|
|
21
|
+
if (this._messageCb) {
|
|
22
|
+
this._popFrames();
|
|
23
|
+
callback();
|
|
24
|
+
} else {
|
|
25
|
+
this._subscribeCb = () => {
|
|
26
|
+
this._popFrames();
|
|
27
|
+
this._subscribeCb = void 0;
|
|
28
|
+
callback();
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
this.port = {
|
|
34
|
+
send: (message) => {
|
|
35
|
+
this._stream.push(encodeLength(message.length));
|
|
36
|
+
this._stream.push(message);
|
|
37
|
+
},
|
|
38
|
+
subscribe: (callback) => {
|
|
39
|
+
var _a;
|
|
40
|
+
assert(!this._messageCb, "Rpc port already has a message listener.");
|
|
41
|
+
this._messageCb = callback;
|
|
42
|
+
(_a = this._subscribeCb) == null ? void 0 : _a.call(this);
|
|
43
|
+
return () => {
|
|
44
|
+
this._messageCb = void 0;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
get stream() {
|
|
50
|
+
return this._stream;
|
|
51
|
+
}
|
|
52
|
+
_popFrames() {
|
|
53
|
+
let offset = 0;
|
|
54
|
+
while (offset < this._buffer.length) {
|
|
55
|
+
const frame = readFrame(this._buffer, offset);
|
|
56
|
+
if (!frame) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
offset += frame.bytesConsumed;
|
|
60
|
+
this._messageCb(frame.payload);
|
|
61
|
+
}
|
|
62
|
+
if (offset < this._buffer.length) {
|
|
63
|
+
this._buffer = this._buffer.subarray(offset);
|
|
64
|
+
} else {
|
|
65
|
+
this._buffer = void 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
destroy() {
|
|
69
|
+
this._stream.destroy();
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var readFrame = (buffer, offset) => {
|
|
73
|
+
try {
|
|
74
|
+
const frameLength = varint.decode(buffer, offset);
|
|
75
|
+
const tagLength = varint.decode.bytes;
|
|
76
|
+
if (buffer.length < offset + tagLength + frameLength) {
|
|
77
|
+
return void 0;
|
|
78
|
+
}
|
|
79
|
+
const payload = buffer.subarray(offset + tagLength, offset + tagLength + frameLength);
|
|
80
|
+
return {
|
|
81
|
+
payload,
|
|
82
|
+
bytesConsumed: tagLength + frameLength
|
|
83
|
+
};
|
|
84
|
+
} catch (err) {
|
|
85
|
+
if (err instanceof RangeError) {
|
|
86
|
+
return void 0;
|
|
87
|
+
} else {
|
|
88
|
+
throw err;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
var encodeLength = (length) => {
|
|
93
|
+
const res = varint.encode(length, Buffer.allocUnsafe(4)).subarray(0, varint.encode.bytes);
|
|
94
|
+
if (varint.encode.bytes > 4) {
|
|
95
|
+
throw new Error("Frame too large");
|
|
96
|
+
}
|
|
97
|
+
return res;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// packages/core/mesh/teleport/src/muxing/muxer.ts
|
|
101
|
+
import assert2 from "@dxos/node-std/assert";
|
|
102
|
+
import { Duplex as Duplex2 } from "@dxos/node-std/stream";
|
|
103
|
+
import { Event } from "@dxos/async";
|
|
104
|
+
import { failUndefined } from "@dxos/debug";
|
|
105
|
+
import { log } from "@dxos/log";
|
|
106
|
+
import { schema } from "@dxos/protocols";
|
|
107
|
+
var codec = schema.getCodecForType("dxos.mesh.muxer.Command");
|
|
108
|
+
var Muxer = class {
|
|
109
|
+
constructor() {
|
|
110
|
+
this._framer = new Framer();
|
|
111
|
+
this.stream = this._framer.stream;
|
|
112
|
+
this._channelsByLocalId = /* @__PURE__ */ new Map();
|
|
113
|
+
this._channelsByTag = /* @__PURE__ */ new Map();
|
|
114
|
+
this._nextId = 0;
|
|
115
|
+
this._destroyed = false;
|
|
116
|
+
this._destroying = false;
|
|
117
|
+
this.close = new Event();
|
|
118
|
+
this._framer.port.subscribe((msg) => {
|
|
119
|
+
this._handleCommand(codec.decode(msg));
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
createStream(tag, opts = {}) {
|
|
123
|
+
const channel = this._getOrCreateStream({
|
|
124
|
+
tag,
|
|
125
|
+
contentType: opts.contentType
|
|
126
|
+
});
|
|
127
|
+
assert2(!channel.push, `Channel already open: ${tag}`);
|
|
128
|
+
const stream = new Duplex2({
|
|
129
|
+
write: (data, encoding, callback) => {
|
|
130
|
+
this._sendData(channel, data);
|
|
131
|
+
callback();
|
|
132
|
+
},
|
|
133
|
+
read: () => {
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
channel.push = (data) => {
|
|
137
|
+
stream.push(data);
|
|
138
|
+
};
|
|
139
|
+
channel.destroy = (err) => {
|
|
140
|
+
stream.destroy(err);
|
|
141
|
+
};
|
|
142
|
+
this._sendCommand({
|
|
143
|
+
openChannel: {
|
|
144
|
+
id: channel.id,
|
|
145
|
+
tag: channel.tag,
|
|
146
|
+
contentType: channel.contentType
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
return stream;
|
|
150
|
+
}
|
|
151
|
+
createPort(tag, opts = {}) {
|
|
152
|
+
const channel = this._getOrCreateStream({
|
|
153
|
+
tag,
|
|
154
|
+
contentType: opts.contentType
|
|
155
|
+
});
|
|
156
|
+
assert2(!channel.push, `Channel already open: ${tag}`);
|
|
157
|
+
let inboundBuffer = [];
|
|
158
|
+
let callback;
|
|
159
|
+
channel.push = (data) => {
|
|
160
|
+
if (callback) {
|
|
161
|
+
callback(data);
|
|
162
|
+
} else {
|
|
163
|
+
inboundBuffer.push(data);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const port = {
|
|
167
|
+
send: (data) => {
|
|
168
|
+
this._sendData(channel, data);
|
|
169
|
+
},
|
|
170
|
+
subscribe: (cb) => {
|
|
171
|
+
assert2(!callback, "Only one subscriber is allowed");
|
|
172
|
+
callback = cb;
|
|
173
|
+
for (const data of inboundBuffer) {
|
|
174
|
+
cb(data);
|
|
175
|
+
}
|
|
176
|
+
inboundBuffer = [];
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
this._sendCommand({
|
|
180
|
+
openChannel: {
|
|
181
|
+
id: channel.id,
|
|
182
|
+
tag: channel.tag,
|
|
183
|
+
contentType: channel.contentType
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
return port;
|
|
187
|
+
}
|
|
188
|
+
destroy(err) {
|
|
189
|
+
if (this._destroying) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
this._destroying = true;
|
|
193
|
+
this._sendCommand({
|
|
194
|
+
destroy: {
|
|
195
|
+
error: err == null ? void 0 : err.message
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
this._dispose();
|
|
199
|
+
}
|
|
200
|
+
_dispose(err) {
|
|
201
|
+
var _a;
|
|
202
|
+
if (this._destroyed) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
this._destroyed = true;
|
|
206
|
+
this._framer.destroy();
|
|
207
|
+
for (const channel of this._channelsByTag.values()) {
|
|
208
|
+
(_a = channel.destroy) == null ? void 0 : _a.call(channel, err);
|
|
209
|
+
}
|
|
210
|
+
this.close.emit(err);
|
|
211
|
+
this._channelsByLocalId.clear();
|
|
212
|
+
this._channelsByTag.clear();
|
|
213
|
+
}
|
|
214
|
+
_handleCommand(cmd) {
|
|
215
|
+
var _a;
|
|
216
|
+
log("Received command", {
|
|
217
|
+
cmd
|
|
218
|
+
}, {
|
|
219
|
+
file: "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/muxing/muxer.ts",
|
|
220
|
+
line: 194,
|
|
221
|
+
scope: this,
|
|
222
|
+
callSite: (f, a) => f(...a)
|
|
223
|
+
});
|
|
224
|
+
if (this._destroyed || this._destroying) {
|
|
225
|
+
log.warn("Received command after destroy", {}, {
|
|
226
|
+
file: "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/muxing/muxer.ts",
|
|
227
|
+
line: 197,
|
|
228
|
+
scope: this,
|
|
229
|
+
callSite: (f, a) => f(...a)
|
|
230
|
+
});
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (cmd.openChannel) {
|
|
234
|
+
const channel = this._getOrCreateStream({
|
|
235
|
+
tag: cmd.openChannel.tag,
|
|
236
|
+
contentType: cmd.openChannel.contentType
|
|
237
|
+
});
|
|
238
|
+
channel.remoteId = cmd.openChannel.id;
|
|
239
|
+
for (const data of channel.buffer) {
|
|
240
|
+
this._sendCommand({
|
|
241
|
+
data: {
|
|
242
|
+
channelId: channel.remoteId,
|
|
243
|
+
data
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
channel.buffer = [];
|
|
248
|
+
} else if (cmd.data) {
|
|
249
|
+
const stream = (_a = this._channelsByLocalId.get(cmd.data.channelId)) != null ? _a : failUndefined();
|
|
250
|
+
if (!stream.push) {
|
|
251
|
+
log.warn("Received data for channel before it was opened", {
|
|
252
|
+
tag: stream.tag
|
|
253
|
+
}, {
|
|
254
|
+
file: "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/muxing/muxer.ts",
|
|
255
|
+
line: 221,
|
|
256
|
+
scope: this,
|
|
257
|
+
callSite: (f, a) => f(...a)
|
|
258
|
+
});
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
stream.push(cmd.data.data);
|
|
262
|
+
} else if (cmd.destroy) {
|
|
263
|
+
this._dispose();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
_sendCommand(cmd) {
|
|
267
|
+
Promise.resolve(this._framer.port.send(codec.encode(cmd))).catch((err) => {
|
|
268
|
+
this.destroy(err);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
_getOrCreateStream(params) {
|
|
272
|
+
let channel = this._channelsByTag.get(params.tag);
|
|
273
|
+
if (!channel) {
|
|
274
|
+
channel = {
|
|
275
|
+
id: this._nextId++,
|
|
276
|
+
remoteId: null,
|
|
277
|
+
tag: params.tag,
|
|
278
|
+
contentType: params.contentType,
|
|
279
|
+
buffer: [],
|
|
280
|
+
push: null,
|
|
281
|
+
destroy: null
|
|
282
|
+
};
|
|
283
|
+
this._channelsByTag.set(channel.tag, channel);
|
|
284
|
+
this._channelsByLocalId.set(channel.id, channel);
|
|
285
|
+
}
|
|
286
|
+
return channel;
|
|
287
|
+
}
|
|
288
|
+
_sendData(channel, data) {
|
|
289
|
+
if (channel.remoteId === null) {
|
|
290
|
+
channel.buffer.push(data);
|
|
291
|
+
} else {
|
|
292
|
+
this._sendCommand({
|
|
293
|
+
data: {
|
|
294
|
+
channelId: channel.remoteId,
|
|
295
|
+
data
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// packages/core/mesh/teleport/src/teleport.ts
|
|
303
|
+
import assert3 from "@dxos/node-std/assert";
|
|
304
|
+
import { asyncTimeout, scheduleTaskInterval, runInContextAsync, synchronized, scheduleTask } from "@dxos/async";
|
|
305
|
+
import { Context } from "@dxos/context";
|
|
306
|
+
import { failUndefined as failUndefined2 } from "@dxos/debug";
|
|
307
|
+
import { PublicKey } from "@dxos/keys";
|
|
308
|
+
import { log as log2 } from "@dxos/log";
|
|
309
|
+
import { schema as schema2 } from "@dxos/protocols";
|
|
310
|
+
import { createProtoRpcPeer, RpcClosedError } from "@dxos/rpc";
|
|
311
|
+
import { Callback } from "@dxos/util";
|
|
312
|
+
var __decorate = function(decorators, target, key, desc) {
|
|
313
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
314
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
315
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
316
|
+
else
|
|
317
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
318
|
+
if (d = decorators[i])
|
|
319
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
320
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
321
|
+
};
|
|
322
|
+
var Teleport = class {
|
|
323
|
+
constructor({ initiator, localPeerId, remotePeerId }) {
|
|
324
|
+
this._ctx = new Context({
|
|
325
|
+
onError: (err) => {
|
|
326
|
+
void this.destroy(err).catch(() => {
|
|
327
|
+
log2.error("Error during destroy", err, {
|
|
328
|
+
file: "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/teleport.ts",
|
|
329
|
+
line: 34,
|
|
330
|
+
scope: this,
|
|
331
|
+
callSite: (f, a) => f(...a)
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
this._muxer = new Muxer();
|
|
337
|
+
this._control = new ControlExtension({
|
|
338
|
+
heartbeatInterval: 3e3,
|
|
339
|
+
heartbeatTimeout: 3e3
|
|
340
|
+
});
|
|
341
|
+
this._extensions = /* @__PURE__ */ new Map();
|
|
342
|
+
this._remoteExtensions = /* @__PURE__ */ new Set();
|
|
343
|
+
this._open = false;
|
|
344
|
+
assert3(typeof initiator === "boolean");
|
|
345
|
+
assert3(PublicKey.isPublicKey(localPeerId));
|
|
346
|
+
assert3(PublicKey.isPublicKey(remotePeerId));
|
|
347
|
+
assert3(typeof initiator === "boolean");
|
|
348
|
+
this.initiator = initiator;
|
|
349
|
+
this.localPeerId = localPeerId;
|
|
350
|
+
this.remotePeerId = remotePeerId;
|
|
351
|
+
this._control.onExtensionRegistered.set(async (name) => {
|
|
352
|
+
log2("remote extension", {
|
|
353
|
+
name
|
|
354
|
+
}, {
|
|
355
|
+
file: "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/teleport.ts",
|
|
356
|
+
line: 61,
|
|
357
|
+
scope: this,
|
|
358
|
+
callSite: (f, a) => f(...a)
|
|
359
|
+
});
|
|
360
|
+
assert3(!this._remoteExtensions.has(name), "Remote extension already exists");
|
|
361
|
+
this._remoteExtensions.add(name);
|
|
362
|
+
if (this._extensions.has(name)) {
|
|
363
|
+
try {
|
|
364
|
+
await this._openExtension(name);
|
|
365
|
+
} catch (err) {
|
|
366
|
+
await this.destroy(err);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
{
|
|
371
|
+
this._muxer.stream.on("close", async () => {
|
|
372
|
+
await this.destroy();
|
|
373
|
+
});
|
|
374
|
+
this._muxer.stream.on("error", async (err) => {
|
|
375
|
+
await this.destroy(err);
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
get stream() {
|
|
380
|
+
return this._muxer.stream;
|
|
381
|
+
}
|
|
382
|
+
async open() {
|
|
383
|
+
this._setExtension("dxos.mesh.teleport.control", this._control);
|
|
384
|
+
await this._openExtension("dxos.mesh.teleport.control");
|
|
385
|
+
this._open = true;
|
|
386
|
+
}
|
|
387
|
+
async close(err) {
|
|
388
|
+
await this.destroy(err);
|
|
389
|
+
}
|
|
390
|
+
async destroy(err) {
|
|
391
|
+
if (this._ctx.disposed) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
await this._ctx.dispose();
|
|
395
|
+
for (const extension of this._extensions.values()) {
|
|
396
|
+
try {
|
|
397
|
+
await extension.onClose(err);
|
|
398
|
+
} catch (err1) {
|
|
399
|
+
log2.catch(err1, {}, {
|
|
400
|
+
file: "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/teleport.ts",
|
|
401
|
+
line: 117,
|
|
402
|
+
scope: this,
|
|
403
|
+
callSite: (f, a) => f(...a)
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
this._muxer.destroy(err);
|
|
408
|
+
}
|
|
409
|
+
addExtension(name, extension) {
|
|
410
|
+
if (!this._open) {
|
|
411
|
+
throw new Error("Not open");
|
|
412
|
+
}
|
|
413
|
+
log2("addExtension", {
|
|
414
|
+
name
|
|
415
|
+
}, {
|
|
416
|
+
file: "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/teleport.ts",
|
|
417
|
+
line: 129,
|
|
418
|
+
scope: this,
|
|
419
|
+
callSite: (f, a) => f(...a)
|
|
420
|
+
});
|
|
421
|
+
this._setExtension(name, extension);
|
|
422
|
+
scheduleTask(this._ctx, async () => {
|
|
423
|
+
try {
|
|
424
|
+
await this._control.registerExtension(name);
|
|
425
|
+
} catch (err) {
|
|
426
|
+
if (err instanceof RpcClosedError) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
throw err;
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
if (this._remoteExtensions.has(name)) {
|
|
433
|
+
scheduleTask(this._ctx, async () => {
|
|
434
|
+
await this._openExtension(name);
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
_setExtension(extensionName, extension) {
|
|
439
|
+
assert3(!extensionName.includes("/"), "Invalid extension name");
|
|
440
|
+
assert3(!this._extensions.has(extensionName), "Extension already exists");
|
|
441
|
+
this._extensions.set(extensionName, extension);
|
|
442
|
+
}
|
|
443
|
+
async _openExtension(extensionName) {
|
|
444
|
+
var _a;
|
|
445
|
+
log2("open extension", {
|
|
446
|
+
extensionName
|
|
447
|
+
}, {
|
|
448
|
+
file: "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/teleport.ts",
|
|
449
|
+
line: 159,
|
|
450
|
+
scope: this,
|
|
451
|
+
callSite: (f, a) => f(...a)
|
|
452
|
+
});
|
|
453
|
+
const extension = (_a = this._extensions.get(extensionName)) != null ? _a : failUndefined2();
|
|
454
|
+
const context = {
|
|
455
|
+
initiator: this.initiator,
|
|
456
|
+
localPeerId: this.localPeerId,
|
|
457
|
+
remotePeerId: this.remotePeerId,
|
|
458
|
+
createPort: (channelName, opts) => {
|
|
459
|
+
assert3(!channelName.includes("/"), "Invalid channel name");
|
|
460
|
+
return this._muxer.createPort(`${extensionName}/${channelName}`, opts);
|
|
461
|
+
},
|
|
462
|
+
createStream: (channelName, opts) => {
|
|
463
|
+
assert3(!channelName.includes("/"), "Invalid channel name");
|
|
464
|
+
return this._muxer.createStream(`${extensionName}/${channelName}`, opts);
|
|
465
|
+
},
|
|
466
|
+
close: (err) => {
|
|
467
|
+
void runInContextAsync(this._ctx, async () => {
|
|
468
|
+
await this.close(err);
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
await extension.onOpen(context);
|
|
473
|
+
log2("extension opened", {
|
|
474
|
+
extensionName
|
|
475
|
+
}, {
|
|
476
|
+
file: "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/teleport.ts",
|
|
477
|
+
line: 182,
|
|
478
|
+
scope: this,
|
|
479
|
+
callSite: (f, a) => f(...a)
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
__decorate([
|
|
484
|
+
synchronized
|
|
485
|
+
], Teleport.prototype, "destroy", null);
|
|
486
|
+
var ControlExtension = class {
|
|
487
|
+
constructor(opts) {
|
|
488
|
+
this.opts = opts;
|
|
489
|
+
this._ctx = new Context({
|
|
490
|
+
onError: (err) => {
|
|
491
|
+
this._extensionContext.close(err);
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
this.onExtensionRegistered = new Callback();
|
|
495
|
+
this.onTimeout = new Callback();
|
|
496
|
+
}
|
|
497
|
+
async onOpen(extensionContext) {
|
|
498
|
+
this._extensionContext = extensionContext;
|
|
499
|
+
this._rpc = createProtoRpcPeer({
|
|
500
|
+
requested: {
|
|
501
|
+
Control: schema2.getService("dxos.mesh.teleport.control.ControlService")
|
|
502
|
+
},
|
|
503
|
+
exposed: {
|
|
504
|
+
Control: schema2.getService("dxos.mesh.teleport.control.ControlService")
|
|
505
|
+
},
|
|
506
|
+
handlers: {
|
|
507
|
+
Control: {
|
|
508
|
+
registerExtension: async (request) => {
|
|
509
|
+
this.onExtensionRegistered.call(request.name);
|
|
510
|
+
},
|
|
511
|
+
heartbeat: async (request) => {
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
port: extensionContext.createPort("rpc", {
|
|
516
|
+
contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
|
|
517
|
+
})
|
|
518
|
+
});
|
|
519
|
+
await this._rpc.open();
|
|
520
|
+
scheduleTaskInterval(this._ctx, async () => {
|
|
521
|
+
try {
|
|
522
|
+
await asyncTimeout(this._rpc.rpc.Control.heartbeat(), this.opts.heartbeatTimeout);
|
|
523
|
+
} catch (err) {
|
|
524
|
+
this.onTimeout.call();
|
|
525
|
+
}
|
|
526
|
+
}, this.opts.heartbeatInterval);
|
|
527
|
+
}
|
|
528
|
+
async onClose(err) {
|
|
529
|
+
await this._ctx.dispose();
|
|
530
|
+
await this._rpc.close();
|
|
531
|
+
}
|
|
532
|
+
async registerExtension(name) {
|
|
533
|
+
await this._rpc.rpc.Control.registerExtension({
|
|
534
|
+
name
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
export {
|
|
539
|
+
Framer,
|
|
540
|
+
Muxer,
|
|
541
|
+
Teleport,
|
|
542
|
+
readFrame
|
|
543
|
+
};
|
|
544
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/muxing/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/muxing/framer.ts", "../../../src/muxing/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/muxing/muxer.ts", "../../../src/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/teleport.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\nimport { Duplex } from 'node:stream';\nimport * as varint from 'varint';\n\nimport { RpcPort } from './rpc-port';\n\n/**\n * Framer that turns a stream of binary messages into a framed RpcPort.\n *\n * Buffers are written prefixed by their length encoded as a varint.\n */\nexport class Framer {\n // private readonly _tagBuffer = Buffer.alloc(4)\n private _messageCb?: (msg: Uint8Array) => void;\n private _subscribeCb?: () => void;\n private _buffer?: Buffer; // The rest of the bytes from the previous write call.\n\n private readonly _stream = new Duplex({\n objectMode: false,\n read: () => {},\n write: (chunk, encoding, callback) => {\n assert(!this._subscribeCb, 'Internal Framer bug. Concurrent writes detected.');\n\n if (this._buffer && this._buffer.length > 0) {\n this._buffer = Buffer.concat([this._buffer, chunk]);\n } else {\n this._buffer = chunk;\n }\n\n if (this._messageCb) {\n this._popFrames();\n callback();\n } else {\n this._subscribeCb = () => {\n // Schedule the processing of the chunk after the peer subscribes to the messages.\n this._popFrames();\n this._subscribeCb = undefined;\n callback();\n };\n }\n }\n });\n\n public readonly port: RpcPort = {\n send: (message) => {\n this._stream.push(encodeLength(message.length));\n this._stream.push(message);\n },\n subscribe: (callback) => {\n assert(!this._messageCb, 'Rpc port already has a message listener.');\n this._messageCb = callback;\n this._subscribeCb?.();\n return () => {\n this._messageCb = undefined;\n };\n }\n };\n\n get stream(): Duplex {\n return this._stream;\n }\n\n /**\n * Attempts to pop frames from the buffer and call the message callback.\n */\n private _popFrames() {\n let offset = 0;\n while (offset < this._buffer!.length) {\n const frame = readFrame(this._buffer!, offset);\n\n if (!frame) {\n break; // Couldn't read frame but there are still bytes left in the buffer.\n }\n offset += frame.bytesConsumed;\n // TODO(dmaretskyi): Possible bug if the peer unsubscribes while we're reading frames.\n this._messageCb!(frame.payload);\n }\n\n if (offset < this._buffer!.length) {\n // Save the rest of the bytes for the next write call.\n this._buffer = this._buffer!.subarray(offset);\n } else {\n this._buffer = undefined;\n }\n }\n\n destroy() {\n // TODO(dmaretskyi): Call stream.end() instead?\n this._stream.destroy();\n }\n}\n\n/**\n * Attempts to read a frame from the input buffer.\n */\nexport const readFrame = (buffer: Buffer, offset: number): { payload: Buffer; bytesConsumed: number } | undefined => {\n try {\n const frameLength = varint.decode(buffer, offset);\n const tagLength = varint.decode.bytes;\n\n if (buffer.length < offset + tagLength + frameLength) {\n // Not enough bytes to read the frame.\n return undefined;\n }\n\n const payload = buffer.subarray(offset + tagLength, offset + tagLength + frameLength);\n\n return {\n payload,\n bytesConsumed: tagLength + frameLength\n };\n } catch (err) {\n if (err instanceof RangeError) {\n // Not enough bytes to read the tag.\n return undefined;\n } else {\n throw err;\n }\n }\n};\n\nconst encodeLength = (length: number) => {\n const res = varint.encode(length, Buffer.allocUnsafe(4)).subarray(0, varint.encode.bytes);\n if (varint.encode.bytes > 4) {\n throw new Error('Frame too large');\n }\n return res;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\nimport { Duplex } from 'node:stream';\n\nimport { Event } from '@dxos/async';\nimport { failUndefined } from '@dxos/debug';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { Command } from '@dxos/protocols/proto/dxos/mesh/muxer';\n\nimport { Framer } from './framer';\nimport { RpcPort } from './rpc-port';\n\nconst codec = schema.getCodecForType('dxos.mesh.muxer.Command');\n\nexport type CleanupCb = void | (() => void);\n\nexport type CreateChannelOpts = {\n /**\n * MIME type of the wire content.\n *\n * Examples:\n * - application/octet-stream\n * - application/x-protobuf; messageType=\"dxos.rpc.Message\"\n */\n contentType?: string;\n};\n\n/**\n * Channel based multiplexer.\n *\n * Can be used to open a number of channels represented by streams or RPC ports.\n * Performs framing for RPC ports.\n * Will buffer data until the remote peer opens the channel.\n *\n * The API will not advertise channels that as they are opened by the remote peer.\n * A higher level API (could be build on top of this muxer) for channel discovery is required.\n */\nexport class Muxer {\n private readonly _framer = new Framer();\n public readonly stream = this._framer.stream;\n\n private readonly _channelsByLocalId = new Map<number, Channel>();\n private readonly _channelsByTag = new Map<string, Channel>();\n\n private _nextId = 0;\n private _destroyed = false;\n private _destroying = false;\n\n public close = new Event<Error | undefined>();\n\n constructor() {\n this._framer.port.subscribe((msg) => {\n this._handleCommand(codec.decode(msg));\n });\n }\n\n /**\n * Creates a duplex Node.js-style stream.\n * The remote peer is expected to call `createStream` with the same tag.\n * The stream is immediately readable and writable.\n * NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).\n */\n createStream(tag: string, opts: CreateChannelOpts = {}): Duplex {\n const channel = this._getOrCreateStream({\n tag,\n contentType: opts.contentType\n });\n assert(!channel.push, `Channel already open: ${tag}`);\n\n const stream = new Duplex({\n write: (data, encoding, callback) => {\n this._sendData(channel, data);\n // TODO(dmaretskyi): Should we error if sending data has errored?\n callback();\n },\n read: () => {} // No-op. We will push data when we receive it.\n });\n\n channel.push = (data) => {\n stream.push(data);\n };\n channel.destroy = (err) => {\n // TODO(dmaretskyi): Call stream.end() instead?\n stream.destroy(err);\n };\n\n // NOTE: Make sure channel.push is set before sending the command.\n this._sendCommand({\n openChannel: {\n id: channel.id,\n tag: channel.tag,\n contentType: channel.contentType\n }\n });\n\n return stream;\n }\n\n /**\n * Creates an RPC port.\n * The remote peer is expected to call `createPort` with the same tag.\n * The port is immediately usable.\n * NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).\n */\n createPort(tag: string, opts: CreateChannelOpts = {}): RpcPort {\n const channel = this._getOrCreateStream({\n tag,\n contentType: opts.contentType\n });\n assert(!channel.push, `Channel already open: ${tag}`);\n\n // We need to buffer incoming data until the port is subscribed to.\n let inboundBuffer: Uint8Array[] = [];\n let callback: ((data: Uint8Array) => void) | undefined;\n\n channel.push = (data) => {\n if (callback) {\n callback(data);\n } else {\n inboundBuffer.push(data);\n }\n };\n\n const port: RpcPort = {\n send: (data: Uint8Array) => {\n this._sendData(channel, data); // TODO(dmaretskyi): Error propagation?\n\n // TODO(dmaretskyi): Debugging.\n // appendFileSync('log.json', JSON.stringify(schema.getCodecForType('dxos.rpc.RpcMessage').decode(data), null, 2) + '\\n')\n },\n subscribe: (cb: (data: Uint8Array) => void) => {\n assert(!callback, 'Only one subscriber is allowed');\n callback = cb;\n for (const data of inboundBuffer) {\n cb(data);\n }\n inboundBuffer = [];\n }\n };\n\n // NOTE: Make sure channel.push is set before sending the command.\n this._sendCommand({\n openChannel: {\n id: channel.id,\n tag: channel.tag,\n contentType: channel.contentType\n }\n });\n\n return port;\n }\n\n /**\n * Force-close with optional error.\n */\n destroy(err?: Error) {\n if (this._destroying) {\n return;\n }\n this._destroying = true;\n\n this._sendCommand({\n destroy: {\n error: err?.message\n }\n });\n this._dispose();\n }\n\n private _dispose(err?: Error) {\n if (this._destroyed) {\n return;\n }\n\n this._destroyed = true;\n this._framer.destroy();\n\n for (const channel of this._channelsByTag.values()) {\n channel.destroy?.(err);\n }\n\n this.close.emit(err);\n\n // Make it easy for GC.\n this._channelsByLocalId.clear();\n this._channelsByTag.clear();\n }\n\n private _handleCommand(cmd: Command) {\n log('Received command', { cmd });\n\n if (this._destroyed || this._destroying) {\n log.warn('Received command after destroy');\n return;\n }\n\n if (cmd.openChannel) {\n const channel = this._getOrCreateStream({\n tag: cmd.openChannel.tag,\n contentType: cmd.openChannel.contentType\n });\n channel.remoteId = cmd.openChannel.id;\n\n // Flush any buffered data.\n for (const data of channel.buffer) {\n this._sendCommand({\n data: {\n channelId: channel.remoteId,\n data\n }\n });\n }\n channel.buffer = [];\n } else if (cmd.data) {\n const stream = this._channelsByLocalId.get(cmd.data.channelId) ?? failUndefined();\n if (!stream.push) {\n log.warn('Received data for channel before it was opened', { tag: stream.tag });\n return;\n }\n stream.push(cmd.data.data);\n } else if (cmd.destroy) {\n this._dispose();\n }\n }\n\n private _sendCommand(cmd: Command) {\n Promise.resolve(this._framer.port.send(codec.encode(cmd))).catch((err) => {\n this.destroy(err);\n });\n }\n\n private _getOrCreateStream(params: CreateChannelInternalParams): Channel {\n let channel = this._channelsByTag.get(params.tag);\n if (!channel) {\n channel = {\n id: this._nextId++,\n remoteId: null,\n tag: params.tag,\n contentType: params.contentType,\n buffer: [],\n push: null,\n destroy: null\n };\n this._channelsByTag.set(channel.tag, channel);\n this._channelsByLocalId.set(channel.id, channel);\n }\n return channel;\n }\n\n private _sendData(channel: Channel, data: Uint8Array) {\n if (channel.remoteId === null) {\n // Remote side has not opened the channel yet.\n channel.buffer.push(data);\n } else {\n this._sendCommand({\n data: {\n channelId: channel.remoteId,\n data\n }\n });\n }\n }\n}\n\ntype Channel = {\n /**\n * Our local channel ID.\n * Incoming Data commands will have this ID.\n */\n id: number;\n tag: string;\n\n /**\n * Remote id is set when we receive an OpenChannel command.\n * The originating Data commands should carry this id.\n */\n remoteId: null | number;\n\n contentType?: string;\n\n /**\n * Send buffer.\n */\n buffer: Uint8Array[];\n\n /**\n * Set when we initialize a NodeJS stream or an RPC port consuming the channel.\n */\n push: null | ((data: Uint8Array) => void);\n\n destroy: null | ((err?: Error) => void);\n};\n\ntype CreateChannelInternalParams = {\n tag: string;\n contentType?: string;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\nimport { Duplex } from 'node:stream';\n\nimport { asyncTimeout, scheduleTaskInterval, runInContextAsync, synchronized, scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { failUndefined } from '@dxos/debug';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { ControlService } from '@dxos/protocols/proto/dxos/mesh/teleport/control';\nimport { createProtoRpcPeer, ProtoRpcPeer, RpcClosedError } from '@dxos/rpc';\nimport { Callback } from '@dxos/util';\n\nimport { CreateChannelOpts, Muxer, RpcPort } from './muxing';\n\nexport type TeleportParams = {\n initiator: boolean;\n localPeerId: PublicKey;\n remotePeerId: PublicKey;\n};\n\nexport class Teleport {\n public readonly initiator: boolean;\n public readonly localPeerId: PublicKey;\n public readonly remotePeerId: PublicKey;\n\n private readonly _ctx = new Context({\n onError: (err) => {\n void this.destroy(err).catch(() => {\n log.error('Error during destroy', err);\n });\n }\n });\n\n private readonly _muxer = new Muxer();\n\n private readonly _control = new ControlExtension({\n heartbeatInterval: 3000,\n heartbeatTimeout: 3000\n });\n\n private readonly _extensions = new Map<string, TeleportExtension>();\n private readonly _remoteExtensions = new Set<string>();\n\n private _open = false;\n\n constructor({ initiator, localPeerId, remotePeerId }: TeleportParams) {\n assert(typeof initiator === 'boolean');\n assert(PublicKey.isPublicKey(localPeerId));\n assert(PublicKey.isPublicKey(remotePeerId));\n assert(typeof initiator === 'boolean');\n this.initiator = initiator;\n this.localPeerId = localPeerId;\n this.remotePeerId = remotePeerId;\n\n this._control.onExtensionRegistered.set(async (name) => {\n log('remote extension', { name });\n assert(!this._remoteExtensions.has(name), 'Remote extension already exists');\n this._remoteExtensions.add(name);\n\n if (this._extensions.has(name)) {\n try {\n await this._openExtension(name);\n } catch (err: any) {\n await this.destroy(err);\n }\n }\n });\n\n {\n // Destroy Teleport when the stream is closed.\n this._muxer.stream.on('close', async () => {\n await this.destroy();\n });\n\n this._muxer.stream.on('error', async (err) => {\n await this.destroy(err);\n });\n }\n }\n\n get stream(): Duplex {\n return this._muxer.stream;\n }\n\n /**\n * Blocks until the handshake is complete.\n */\n async open() {\n this._setExtension('dxos.mesh.teleport.control', this._control);\n await this._openExtension('dxos.mesh.teleport.control');\n this._open = true;\n }\n\n async close(err?: Error) {\n // TODO(dmaretskyi): Try soft close.\n\n await this.destroy(err);\n }\n\n @synchronized\n async destroy(err?: Error) {\n if (this._ctx.disposed) {\n return;\n }\n\n await this._ctx.dispose();\n\n for (const extension of this._extensions.values()) {\n try {\n await extension.onClose(err);\n } catch (err: any) {\n log.catch(err);\n }\n }\n\n this._muxer.destroy(err);\n }\n\n addExtension(name: string, extension: TeleportExtension) {\n if (!this._open) {\n throw new Error('Not open');\n }\n\n log('addExtension', { name });\n this._setExtension(name, extension);\n\n // Perform the registration in a separate tick as this might block while the remote side is opening the extension.\n scheduleTask(this._ctx, async () => {\n try {\n await this._control.registerExtension(name);\n } catch (err) {\n if (err instanceof RpcClosedError) {\n return;\n }\n throw err;\n }\n });\n\n if (this._remoteExtensions.has(name)) {\n // Open the extension in a separate tick.\n scheduleTask(this._ctx, async () => {\n await this._openExtension(name);\n });\n }\n }\n\n private _setExtension(extensionName: string, extension: TeleportExtension) {\n assert(!extensionName.includes('/'), 'Invalid extension name');\n assert(!this._extensions.has(extensionName), 'Extension already exists');\n this._extensions.set(extensionName, extension);\n }\n\n private async _openExtension(extensionName: string) {\n log('open extension', { extensionName });\n const extension = this._extensions.get(extensionName) ?? failUndefined();\n\n const context: ExtensionContext = {\n initiator: this.initiator,\n localPeerId: this.localPeerId,\n remotePeerId: this.remotePeerId,\n createPort: (channelName: string, opts?: CreateChannelOpts) => {\n assert(!channelName.includes('/'), 'Invalid channel name');\n return this._muxer.createPort(`${extensionName}/${channelName}`, opts);\n },\n createStream: (channelName: string, opts?: CreateChannelOpts) => {\n assert(!channelName.includes('/'), 'Invalid channel name');\n return this._muxer.createStream(`${extensionName}/${channelName}`, opts);\n },\n close: (err) => {\n void runInContextAsync(this._ctx, async () => {\n await this.close(err);\n });\n }\n };\n\n await extension.onOpen(context);\n log('extension opened', { extensionName });\n }\n}\n\nexport type ExtensionContext = {\n /**\n * One of the peers will be designated an initiator.\n */\n initiator: boolean;\n localPeerId: PublicKey;\n remotePeerId: PublicKey;\n createStream(tag: string, opts?: CreateChannelOpts): Duplex;\n createPort(tag: string, opts?: CreateChannelOpts): RpcPort;\n close(err?: Error): void;\n};\n\nexport interface TeleportExtension {\n onOpen(context: ExtensionContext): Promise<void>;\n onClose(err?: Error): Promise<void>;\n}\n\ntype ControlExtensionOpts = {\n heartbeatInterval: number;\n heartbeatTimeout: number;\n};\n\nclass ControlExtension implements TeleportExtension {\n private readonly _ctx = new Context({\n onError: (err) => {\n this._extensionContext.close(err);\n }\n });\n\n private _extensionContext!: ExtensionContext;\n private _rpc!: ProtoRpcPeer<{ Control: ControlService }>;\n\n public readonly onExtensionRegistered = new Callback<(extensionName: string) => void>();\n public readonly onTimeout = new Callback<() => void>();\n\n constructor(private readonly opts: ControlExtensionOpts) {}\n\n async onOpen(extensionContext: ExtensionContext): Promise<void> {\n this._extensionContext = extensionContext;\n\n // NOTE: Make sure that RPC timeout is greater than the heartbeat timeout.\n // TODO(dmaretskyi): Allow overwriting the timeout on individual RPC calls?\n this._rpc = createProtoRpcPeer<ControlRpcBundle, ControlRpcBundle>({\n requested: {\n Control: schema.getService('dxos.mesh.teleport.control.ControlService')\n },\n exposed: {\n Control: schema.getService('dxos.mesh.teleport.control.ControlService')\n },\n handlers: {\n Control: {\n registerExtension: async (request) => {\n this.onExtensionRegistered.call(request.name);\n },\n heartbeat: async (request) => {\n // Ok.\n }\n }\n },\n port: extensionContext.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"dxos.rpc.Message\"'\n })\n });\n\n await this._rpc.open();\n\n scheduleTaskInterval(\n this._ctx,\n async () => {\n try {\n await asyncTimeout(this._rpc.rpc.Control.heartbeat(), this.opts.heartbeatTimeout);\n } catch (err: any) {\n this.onTimeout.call();\n }\n },\n this.opts.heartbeatInterval\n );\n }\n\n async onClose(err?: Error): Promise<void> {\n await this._ctx.dispose();\n await this._rpc.close();\n }\n\n async registerExtension(name: string) {\n await this._rpc.rpc.Control.registerExtension({ name });\n }\n}\n\ntype ControlRpcBundle = {\n Control: ControlService;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["assert", "Duplex", "varint", "Framer", "_stream", "objectMode", "read", "write", "chunk", "encoding", "callback", "_subscribeCb", "_buffer", "length", "Buffer", "concat", "_messageCb", "_popFrames", "undefined", "port", "send", "message", "push", "encodeLength", "subscribe", "stream", "offset", "frame", "readFrame", "bytesConsumed", "payload", "subarray", "destroy", "buffer", "frameLength", "decode", "tagLength", "bytes", "err", "RangeError", "res", "encode", "allocUnsafe", "Error", "assert", "Duplex", "Event", "failUndefined", "log", "schema", "codec", "schema", "getCodecForType", "Muxer", "constructor", "_framer", "Framer", "stream", "_channelsByLocalId", "Map", "_channelsByTag", "_nextId", "_destroyed", "_destroying", "close", "Event", "port", "subscribe", "msg", "_handleCommand", "decode", "createStream", "tag", "opts", "channel", "_getOrCreateStream", "contentType", "assert", "push", "Duplex", "write", "data", "encoding", "callback", "_sendData", "read", "destroy", "err", "_sendCommand", "openChannel", "id", "createPort", "inboundBuffer", "send", "cb", "error", "message", "_dispose", "values", "emit", "clear", "cmd", "log", "warn", "remoteId", "buffer", "channelId", "get", "failUndefined", "Promise", "resolve", "encode", "catch", "params", "set", "assert", "asyncTimeout", "scheduleTaskInterval", "runInContextAsync", "synchronized", "scheduleTask", "Context", "failUndefined", "PublicKey", "log", "schema", "createProtoRpcPeer", "RpcClosedError", "Callback", "Teleport", "constructor", "initiator", "localPeerId", "remotePeerId", "_ctx", "Context", "onError", "err", "destroy", "catch", "log", "error", "_muxer", "Muxer", "_control", "ControlExtension", "heartbeatInterval", "heartbeatTimeout", "_extensions", "Map", "_remoteExtensions", "Set", "_open", "assert", "PublicKey", "isPublicKey", "onExtensionRegistered", "set", "name", "has", "add", "_openExtension", "stream", "on", "open", "_setExtension", "close", "disposed", "dispose", "extension", "values", "onClose", "addExtension", "Error", "scheduleTask", "registerExtension", "RpcClosedError", "extensionName", "includes", "get", "failUndefined", "context", "createPort", "channelName", "opts", "createStream", "runInContextAsync", "onOpen", "synchronized", "_extensionContext", "Callback", "onTimeout", "extensionContext", "_rpc", "createProtoRpcPeer", "requested", "Control", "schema", "getService", "exposed", "handlers", "request", "call", "heartbeat", "port", "contentType", "scheduleTaskInterval", "asyncTimeout", "rpc"]
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"inputs":{"packages/core/mesh/teleport/src/muxing/framer.ts":{"bytes":12433,"imports":[]},"packages/core/mesh/teleport/src/muxing/muxer.ts":{"bytes":25627,"imports":[{"path":"packages/core/mesh/teleport/src/muxing/framer.ts","kind":"import-statement"}]},"packages/core/mesh/teleport/src/muxing/rpc-port.ts":{"bytes":912,"imports":[]},"packages/core/mesh/teleport/src/muxing/index.ts":{"bytes":631,"imports":[{"path":"packages/core/mesh/teleport/src/muxing/framer.ts","kind":"import-statement"},{"path":"packages/core/mesh/teleport/src/muxing/muxer.ts","kind":"import-statement"},{"path":"packages/core/mesh/teleport/src/muxing/rpc-port.ts","kind":"import-statement"}]},"packages/core/mesh/teleport/src/teleport.ts":{"bytes":27881,"imports":[{"path":"packages/core/mesh/teleport/src/muxing/index.ts","kind":"import-statement"}]},"packages/core/mesh/teleport/src/index.ts":{"bytes":538,"imports":[{"path":"packages/core/mesh/teleport/src/muxing/index.ts","kind":"import-statement"},{"path":"packages/core/mesh/teleport/src/teleport.ts","kind":"import-statement"}]},"packages/core/mesh/teleport/src/testing.ts":{"bytes":7505,"imports":[{"path":"packages/core/mesh/teleport/src/teleport.ts","kind":"import-statement"}]}},"outputs":{"packages/core/mesh/teleport/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":32212},"packages/core/mesh/teleport/dist/lib/browser/index.mjs":{"imports":[],"exports":["Framer","Muxer","Teleport","readFrame"],"entryPoint":"packages/core/mesh/teleport/src/index.ts","inputs":{"packages/core/mesh/teleport/src/muxing/framer.ts":{"bytesInOutput":2572},"packages/core/mesh/teleport/src/muxing/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport/src/muxing/muxer.ts":{"bytesInOutput":5288},"packages/core/mesh/teleport/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport/src/teleport.ts":{"bytesInOutput":7504}},"bytes":15606},"packages/core/mesh/teleport/dist/lib/browser/testing.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":35936},"packages/core/mesh/teleport/dist/lib/browser/testing.mjs":{"imports":[],"exports":["TestBuilder","TestPeer"],"entryPoint":"packages/core/mesh/teleport/src/testing.ts","inputs":{"packages/core/mesh/teleport/src/testing.ts":{"bytesInOutput":1876},"packages/core/mesh/teleport/src/teleport.ts":{"bytesInOutput":7504},"packages/core/mesh/teleport/src/muxing/framer.ts":{"bytesInOutput":2572},"packages/core/mesh/teleport/src/muxing/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport/src/muxing/muxer.ts":{"bytesInOutput":5288}},"bytes":17609}}}
|