@dxos/teleport 0.1.53 → 0.1.54-main.270ec56
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-XWWASTDK.mjs → chunk-7TGKNWZQ.mjs} +265 -146
- package/dist/lib/browser/chunk-7TGKNWZQ.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +204 -6
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +24 -23
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/index.cjs +461 -143
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +279 -159
- package/dist/lib/node/testing/index.cjs.map +4 -4
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/muxing/balancer.d.ts +23 -0
- package/dist/types/src/muxing/balancer.d.ts.map +1 -0
- package/dist/types/src/muxing/framer.d.ts +3 -0
- package/dist/types/src/muxing/framer.d.ts.map +1 -1
- package/dist/types/src/muxing/muxer.d.ts +5 -3
- package/dist/types/src/muxing/muxer.d.ts.map +1 -1
- package/dist/types/src/teleport.d.ts +2 -2
- package/dist/types/src/teleport.d.ts.map +1 -1
- package/dist/types/src/testing/test-extension-with-streams.d.ts +42 -0
- package/dist/types/src/testing/test-extension-with-streams.d.ts.map +1 -0
- package/package.json +12 -12
- package/src/index.ts +1 -0
- package/src/muxing/balancer.ts +106 -0
- package/src/muxing/framer.ts +23 -4
- package/src/muxing/muxer.test.ts +12 -8
- package/src/muxing/muxer.ts +119 -71
- package/src/rpc-extension.ts +3 -3
- package/src/teleport.ts +15 -15
- package/src/testing/test-builder.ts +11 -11
- package/src/testing/test-extension-with-streams.ts +244 -0
- package/src/testing/test-extension.ts +6 -6
- package/dist/lib/browser/chunk-XWWASTDK.mjs.map +0 -7
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import "@dxos/node-std/globals"
|
|
1
|
+
import "@dxos/node-std/globals";
|
|
2
2
|
|
|
3
3
|
// packages/core/mesh/teleport/src/muxing/framer.ts
|
|
4
|
-
import assert from "@dxos/node-std/assert";
|
|
5
4
|
import { Duplex } from "@dxos/node-std/stream";
|
|
5
|
+
import invariant from "tiny-invariant";
|
|
6
6
|
import * as varint from "varint";
|
|
7
7
|
var Framer = class {
|
|
8
8
|
constructor() {
|
|
9
|
+
this._responseQueue = [];
|
|
9
10
|
this._stream = new Duplex({
|
|
10
11
|
objectMode: false,
|
|
11
12
|
read: () => {
|
|
12
13
|
},
|
|
13
14
|
write: (chunk, encoding, callback) => {
|
|
14
|
-
|
|
15
|
+
invariant(!this._subscribeCb, "Internal Framer bug. Concurrent writes detected.");
|
|
15
16
|
if (this._buffer && this._buffer.length > 0) {
|
|
16
17
|
this._buffer = Buffer.concat([
|
|
17
18
|
this._buffer,
|
|
@@ -34,11 +35,18 @@ var Framer = class {
|
|
|
34
35
|
});
|
|
35
36
|
this.port = {
|
|
36
37
|
send: (message) => {
|
|
37
|
-
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
const canContinue = this._stream.push(encodeFrame(message));
|
|
40
|
+
if (!canContinue) {
|
|
41
|
+
this._responseQueue.push(resolve);
|
|
42
|
+
} else {
|
|
43
|
+
process.nextTick(resolve);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
38
46
|
},
|
|
39
47
|
subscribe: (callback) => {
|
|
40
48
|
var _a;
|
|
41
|
-
|
|
49
|
+
invariant(!this._messageCb, "Rpc port already has a message listener.");
|
|
42
50
|
this._messageCb = callback;
|
|
43
51
|
(_a = this._subscribeCb) == null ? void 0 : _a.call(this);
|
|
44
52
|
return () => {
|
|
@@ -46,10 +54,16 @@ var Framer = class {
|
|
|
46
54
|
};
|
|
47
55
|
}
|
|
48
56
|
};
|
|
57
|
+
this.stream.on("drain", this._processResponseQueue.bind(this));
|
|
49
58
|
}
|
|
50
59
|
get stream() {
|
|
51
60
|
return this._stream;
|
|
52
61
|
}
|
|
62
|
+
_processResponseQueue() {
|
|
63
|
+
const responseQueue = this._responseQueue;
|
|
64
|
+
this._responseQueue = [];
|
|
65
|
+
responseQueue.forEach((cb) => cb());
|
|
66
|
+
}
|
|
53
67
|
/**
|
|
54
68
|
* Attempts to pop frames from the buffer and call the message callback.
|
|
55
69
|
*/
|
|
@@ -70,6 +84,7 @@ var Framer = class {
|
|
|
70
84
|
}
|
|
71
85
|
}
|
|
72
86
|
destroy() {
|
|
87
|
+
this._stream.removeAllListeners("drain");
|
|
73
88
|
this._stream.destroy();
|
|
74
89
|
}
|
|
75
90
|
};
|
|
@@ -102,18 +117,96 @@ var encodeFrame = (payload) => {
|
|
|
102
117
|
};
|
|
103
118
|
|
|
104
119
|
// packages/core/mesh/teleport/src/muxing/muxer.ts
|
|
105
|
-
import assert2 from "@dxos/node-std/assert";
|
|
106
120
|
import { Duplex as Duplex2 } from "@dxos/node-std/stream";
|
|
107
|
-
import
|
|
121
|
+
import invariant2 from "tiny-invariant";
|
|
122
|
+
import { scheduleTaskInterval, Event, Trigger } from "@dxos/async";
|
|
108
123
|
import { Context } from "@dxos/context";
|
|
109
124
|
import { failUndefined } from "@dxos/debug";
|
|
110
125
|
import { log } from "@dxos/log";
|
|
111
126
|
import { schema } from "@dxos/protocols";
|
|
112
|
-
|
|
113
|
-
|
|
127
|
+
|
|
128
|
+
// packages/core/mesh/teleport/src/muxing/balancer.ts
|
|
129
|
+
var Balancer = class {
|
|
130
|
+
constructor(_port, _sysChannelId) {
|
|
131
|
+
this._port = _port;
|
|
132
|
+
this._sysChannelId = _sysChannelId;
|
|
133
|
+
this._lastCallerIndex = 0;
|
|
134
|
+
this._channels = [];
|
|
135
|
+
this._calls = /* @__PURE__ */ new Map();
|
|
136
|
+
this._channels.push(_sysChannelId);
|
|
137
|
+
}
|
|
138
|
+
addChannel(channel) {
|
|
139
|
+
this._channels.push(channel);
|
|
140
|
+
}
|
|
141
|
+
pushChunk(msg, trigger, channelId) {
|
|
142
|
+
const noCalls = this._calls.size === 0;
|
|
143
|
+
if (!this._channels.includes(channelId)) {
|
|
144
|
+
throw new Error(`Unknown channel ${channelId}`);
|
|
145
|
+
}
|
|
146
|
+
if (!this._calls.has(channelId)) {
|
|
147
|
+
this._calls.set(channelId, []);
|
|
148
|
+
}
|
|
149
|
+
const channelCalls = this._calls.get(channelId);
|
|
150
|
+
channelCalls.push({
|
|
151
|
+
msg,
|
|
152
|
+
trigger
|
|
153
|
+
});
|
|
154
|
+
if (noCalls) {
|
|
155
|
+
process.nextTick(async () => {
|
|
156
|
+
await this._processCalls();
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
destroy() {
|
|
161
|
+
this._calls.clear();
|
|
162
|
+
}
|
|
163
|
+
_getNextCallerId() {
|
|
164
|
+
if (this._calls.has(this._sysChannelId)) {
|
|
165
|
+
return this._sysChannelId;
|
|
166
|
+
}
|
|
167
|
+
const index = this._lastCallerIndex;
|
|
168
|
+
this._lastCallerIndex = (this._lastCallerIndex + 1) % this._channels.length;
|
|
169
|
+
return this._channels[index];
|
|
170
|
+
}
|
|
171
|
+
_getNextCall() {
|
|
172
|
+
let call;
|
|
173
|
+
while (!call) {
|
|
174
|
+
const channelId = this._getNextCallerId();
|
|
175
|
+
const channelCalls = this._calls.get(channelId);
|
|
176
|
+
if (!channelCalls) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
call = channelCalls.shift();
|
|
180
|
+
if (channelCalls.length === 0) {
|
|
181
|
+
this._calls.delete(channelId);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return call;
|
|
185
|
+
}
|
|
186
|
+
async _processCalls() {
|
|
187
|
+
if (this._calls.size === 0) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const call = this._getNextCall();
|
|
191
|
+
try {
|
|
192
|
+
await this._port.send(call.msg);
|
|
193
|
+
call.trigger.wake();
|
|
194
|
+
} catch (err) {
|
|
195
|
+
call.trigger.throw(err);
|
|
196
|
+
}
|
|
197
|
+
await this._processCalls();
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// packages/core/mesh/teleport/src/muxing/muxer.ts
|
|
202
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/muxing/muxer.ts";
|
|
203
|
+
var Command = schema.getCodecForType("dxos.mesh.muxer.Command");
|
|
204
|
+
var STATS_INTERVAL = 1e3;
|
|
205
|
+
var SYSTEM_CHANNEL_ID = -1;
|
|
114
206
|
var Muxer = class {
|
|
115
207
|
constructor() {
|
|
116
208
|
this._framer = new Framer();
|
|
209
|
+
this._balancer = new Balancer(this._framer.port, SYSTEM_CHANNEL_ID);
|
|
117
210
|
this.stream = this._framer.stream;
|
|
118
211
|
this._channelsByLocalId = /* @__PURE__ */ new Map();
|
|
119
212
|
this._channelsByTag = /* @__PURE__ */ new Map();
|
|
@@ -123,21 +216,10 @@ var Muxer = class {
|
|
|
123
216
|
this.close = new Event();
|
|
124
217
|
this.statsUpdated = new Event();
|
|
125
218
|
this._ctx = new Context();
|
|
126
|
-
this.
|
|
127
|
-
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
this.statsUpdated.emit(Array.from(this._channelsByTag.values()).map((channel) => ({
|
|
131
|
-
id: channel.id,
|
|
132
|
-
tag: channel.tag,
|
|
133
|
-
bytesSent: channel.stats.bytesSent,
|
|
134
|
-
bytesReceived: channel.stats.bytesReceived
|
|
135
|
-
})));
|
|
136
|
-
await sleep(DEBOUNCE_STATS_INTERVAL);
|
|
137
|
-
});
|
|
138
|
-
this._framer.port.subscribe((msg) => {
|
|
139
|
-
this._handleCommand(codec.decode(msg));
|
|
219
|
+
this._framer.port.subscribe(async (msg) => {
|
|
220
|
+
await this._handleCommand(Command.decode(msg));
|
|
140
221
|
});
|
|
222
|
+
scheduleTaskInterval(this._ctx, async () => this._emitStats(), STATS_INTERVAL);
|
|
141
223
|
}
|
|
142
224
|
/**
|
|
143
225
|
* Creates a duplex Node.js-style stream.
|
|
@@ -145,35 +227,38 @@ var Muxer = class {
|
|
|
145
227
|
* The stream is immediately readable and writable.
|
|
146
228
|
* NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).
|
|
147
229
|
*/
|
|
148
|
-
createStream(tag, opts = {}) {
|
|
230
|
+
async createStream(tag, opts = {}) {
|
|
149
231
|
const channel = this._getOrCreateStream({
|
|
150
232
|
tag,
|
|
151
233
|
contentType: opts.contentType
|
|
152
234
|
});
|
|
153
|
-
|
|
235
|
+
invariant2(!channel.push, `Channel already open: ${tag}`);
|
|
154
236
|
const stream = new Duplex2({
|
|
155
237
|
write: (data, encoding, callback) => {
|
|
156
|
-
this._sendData(channel, data);
|
|
157
|
-
callback();
|
|
238
|
+
this._sendData(channel, data).then(() => callback()).catch(callback);
|
|
158
239
|
},
|
|
159
240
|
read: () => {
|
|
160
241
|
}
|
|
161
242
|
});
|
|
162
243
|
channel.push = (data) => {
|
|
163
244
|
channel.stats.bytesReceived += data.length;
|
|
164
|
-
this._emitStats.schedule();
|
|
165
245
|
stream.push(data);
|
|
166
246
|
};
|
|
167
247
|
channel.destroy = (err) => {
|
|
168
248
|
stream.destroy(err);
|
|
169
249
|
};
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
250
|
+
try {
|
|
251
|
+
await this._sendCommand({
|
|
252
|
+
openChannel: {
|
|
253
|
+
id: channel.id,
|
|
254
|
+
tag: channel.tag,
|
|
255
|
+
contentType: channel.contentType
|
|
256
|
+
}
|
|
257
|
+
}, SYSTEM_CHANNEL_ID);
|
|
258
|
+
} catch (err) {
|
|
259
|
+
this._destroyChannel(channel, err);
|
|
260
|
+
throw err;
|
|
261
|
+
}
|
|
177
262
|
return stream;
|
|
178
263
|
}
|
|
179
264
|
/**
|
|
@@ -182,17 +267,16 @@ var Muxer = class {
|
|
|
182
267
|
* The port is immediately usable.
|
|
183
268
|
* NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).
|
|
184
269
|
*/
|
|
185
|
-
createPort(tag, opts = {}) {
|
|
270
|
+
async createPort(tag, opts = {}) {
|
|
186
271
|
const channel = this._getOrCreateStream({
|
|
187
272
|
tag,
|
|
188
273
|
contentType: opts.contentType
|
|
189
274
|
});
|
|
190
|
-
|
|
275
|
+
invariant2(!channel.push, `Channel already open: ${tag}`);
|
|
191
276
|
let inboundBuffer = [];
|
|
192
277
|
let callback;
|
|
193
278
|
channel.push = (data) => {
|
|
194
279
|
channel.stats.bytesReceived += data.length;
|
|
195
|
-
this._emitStats.schedule();
|
|
196
280
|
if (callback) {
|
|
197
281
|
callback(data);
|
|
198
282
|
} else {
|
|
@@ -200,11 +284,11 @@ var Muxer = class {
|
|
|
200
284
|
}
|
|
201
285
|
};
|
|
202
286
|
const port = {
|
|
203
|
-
send: (data) => {
|
|
204
|
-
this._sendData(channel, data);
|
|
287
|
+
send: async (data) => {
|
|
288
|
+
await this._sendData(channel, data);
|
|
205
289
|
},
|
|
206
290
|
subscribe: (cb) => {
|
|
207
|
-
|
|
291
|
+
invariant2(!callback, "Only one subscriber is allowed");
|
|
208
292
|
callback = cb;
|
|
209
293
|
for (const data of inboundBuffer) {
|
|
210
294
|
cb(data);
|
|
@@ -212,13 +296,18 @@ var Muxer = class {
|
|
|
212
296
|
inboundBuffer = [];
|
|
213
297
|
}
|
|
214
298
|
};
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
299
|
+
try {
|
|
300
|
+
await this._sendCommand({
|
|
301
|
+
openChannel: {
|
|
302
|
+
id: channel.id,
|
|
303
|
+
tag: channel.tag,
|
|
304
|
+
contentType: channel.contentType
|
|
305
|
+
}
|
|
306
|
+
}, SYSTEM_CHANNEL_ID);
|
|
307
|
+
} catch (err) {
|
|
308
|
+
this._destroyChannel(channel, err);
|
|
309
|
+
throw err;
|
|
310
|
+
}
|
|
222
311
|
return port;
|
|
223
312
|
}
|
|
224
313
|
/**
|
|
@@ -229,12 +318,16 @@ var Muxer = class {
|
|
|
229
318
|
return;
|
|
230
319
|
}
|
|
231
320
|
this._destroying = true;
|
|
232
|
-
this._sendCommand({
|
|
321
|
+
Promise.resolve(this._sendCommand({
|
|
233
322
|
destroy: {
|
|
234
323
|
error: err == null ? void 0 : err.message
|
|
235
324
|
}
|
|
325
|
+
}, SYSTEM_CHANNEL_ID)).then(() => {
|
|
326
|
+
this._dispose();
|
|
327
|
+
}).catch((err2) => {
|
|
328
|
+
this._dispose(err2);
|
|
236
329
|
});
|
|
237
|
-
this.
|
|
330
|
+
void this._ctx.dispose();
|
|
238
331
|
}
|
|
239
332
|
_dispose(err) {
|
|
240
333
|
var _a;
|
|
@@ -242,6 +335,7 @@ var Muxer = class {
|
|
|
242
335
|
return;
|
|
243
336
|
}
|
|
244
337
|
this._destroyed = true;
|
|
338
|
+
this._balancer.destroy();
|
|
245
339
|
this._framer.destroy();
|
|
246
340
|
for (const channel of this._channelsByTag.values()) {
|
|
247
341
|
(_a = channel.destroy) == null ? void 0 : _a.call(channel, err);
|
|
@@ -249,24 +343,25 @@ var Muxer = class {
|
|
|
249
343
|
this.close.emit(err);
|
|
250
344
|
this._channelsByLocalId.clear();
|
|
251
345
|
this._channelsByTag.clear();
|
|
252
|
-
void this._ctx.dispose();
|
|
253
346
|
}
|
|
254
|
-
_handleCommand(cmd) {
|
|
347
|
+
async _handleCommand(cmd) {
|
|
255
348
|
var _a;
|
|
256
349
|
log("Received command", {
|
|
257
350
|
cmd
|
|
258
351
|
}, {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
352
|
+
F: __dxlog_file,
|
|
353
|
+
L: 239,
|
|
354
|
+
S: this,
|
|
355
|
+
C: (f, a) => f(...a)
|
|
263
356
|
});
|
|
264
357
|
if (this._destroyed || this._destroying) {
|
|
265
|
-
log.warn("Received command after destroy", {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
358
|
+
log.warn("Received command after destroy", {
|
|
359
|
+
cmd
|
|
360
|
+
}, {
|
|
361
|
+
F: __dxlog_file,
|
|
362
|
+
L: 242,
|
|
363
|
+
S: this,
|
|
364
|
+
C: (f, a) => f(...a)
|
|
270
365
|
});
|
|
271
366
|
return;
|
|
272
367
|
}
|
|
@@ -277,12 +372,12 @@ var Muxer = class {
|
|
|
277
372
|
});
|
|
278
373
|
channel.remoteId = cmd.openChannel.id;
|
|
279
374
|
for (const data of channel.buffer) {
|
|
280
|
-
this._sendCommand({
|
|
375
|
+
await this._sendCommand({
|
|
281
376
|
data: {
|
|
282
377
|
channelId: channel.remoteId,
|
|
283
378
|
data
|
|
284
379
|
}
|
|
285
|
-
});
|
|
380
|
+
}, channel.id);
|
|
286
381
|
}
|
|
287
382
|
channel.buffer = [];
|
|
288
383
|
} else if (cmd.data) {
|
|
@@ -291,10 +386,10 @@ var Muxer = class {
|
|
|
291
386
|
log.warn("Received data for channel before it was opened", {
|
|
292
387
|
tag: stream.tag
|
|
293
388
|
}, {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
389
|
+
F: __dxlog_file,
|
|
390
|
+
L: 269,
|
|
391
|
+
S: this,
|
|
392
|
+
C: (f, a) => f(...a)
|
|
298
393
|
});
|
|
299
394
|
return;
|
|
300
395
|
}
|
|
@@ -303,10 +398,14 @@ var Muxer = class {
|
|
|
303
398
|
this._dispose();
|
|
304
399
|
}
|
|
305
400
|
}
|
|
306
|
-
_sendCommand(cmd) {
|
|
307
|
-
|
|
401
|
+
async _sendCommand(cmd, channelId = -1) {
|
|
402
|
+
try {
|
|
403
|
+
const trigger = new Trigger();
|
|
404
|
+
this._balancer.pushChunk(Command.encode(cmd), trigger, channelId);
|
|
405
|
+
await trigger.wait();
|
|
406
|
+
} catch (err) {
|
|
308
407
|
this.destroy(err);
|
|
309
|
-
}
|
|
408
|
+
}
|
|
310
409
|
}
|
|
311
410
|
_getOrCreateStream(params) {
|
|
312
411
|
let channel = this._channelsByTag.get(params.tag);
|
|
@@ -326,28 +425,46 @@ var Muxer = class {
|
|
|
326
425
|
};
|
|
327
426
|
this._channelsByTag.set(channel.tag, channel);
|
|
328
427
|
this._channelsByLocalId.set(channel.id, channel);
|
|
428
|
+
this._balancer.addChannel(channel.id);
|
|
329
429
|
}
|
|
330
430
|
return channel;
|
|
331
431
|
}
|
|
332
|
-
_sendData(channel, data) {
|
|
432
|
+
async _sendData(channel, data) {
|
|
333
433
|
channel.stats.bytesSent += data.length;
|
|
334
|
-
this._emitStats.schedule();
|
|
335
434
|
if (channel.remoteId === null) {
|
|
336
435
|
channel.buffer.push(data);
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
await this._sendCommand({
|
|
439
|
+
data: {
|
|
440
|
+
channelId: channel.remoteId,
|
|
441
|
+
data
|
|
442
|
+
}
|
|
443
|
+
}, channel.id);
|
|
444
|
+
}
|
|
445
|
+
_destroyChannel(channel, err) {
|
|
446
|
+
if (channel.destroy) {
|
|
447
|
+
channel.destroy(err);
|
|
344
448
|
}
|
|
449
|
+
this._channelsByLocalId.delete(channel.id);
|
|
450
|
+
this._channelsByTag.delete(channel.tag);
|
|
451
|
+
}
|
|
452
|
+
async _emitStats() {
|
|
453
|
+
if (this._destroyed || this._destroying) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
this.statsUpdated.emit(Array.from(this._channelsByTag.values()).map((channel) => ({
|
|
457
|
+
id: channel.id,
|
|
458
|
+
tag: channel.tag,
|
|
459
|
+
bytesSent: channel.stats.bytesSent,
|
|
460
|
+
bytesReceived: channel.stats.bytesReceived
|
|
461
|
+
})));
|
|
345
462
|
}
|
|
346
463
|
};
|
|
347
464
|
|
|
348
465
|
// packages/core/mesh/teleport/src/teleport.ts
|
|
349
|
-
import
|
|
350
|
-
import { asyncTimeout, scheduleTaskInterval, runInContextAsync, synchronized, scheduleTask } from "@dxos/async";
|
|
466
|
+
import invariant3 from "tiny-invariant";
|
|
467
|
+
import { asyncTimeout, scheduleTaskInterval as scheduleTaskInterval2, runInContextAsync, synchronized, scheduleTask } from "@dxos/async";
|
|
351
468
|
import { Context as Context2 } from "@dxos/context";
|
|
352
469
|
import { failUndefined as failUndefined2 } from "@dxos/debug";
|
|
353
470
|
import { PublicKey } from "@dxos/keys";
|
|
@@ -355,7 +472,7 @@ import { log as log2 } from "@dxos/log";
|
|
|
355
472
|
import { schema as schema2, RpcClosedError } from "@dxos/protocols";
|
|
356
473
|
import { createProtoRpcPeer } from "@dxos/rpc";
|
|
357
474
|
import { Callback } from "@dxos/util";
|
|
358
|
-
|
|
475
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
359
476
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
360
477
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
361
478
|
r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -364,17 +481,18 @@ var __decorate = function(decorators, target, key, desc) {
|
|
|
364
481
|
if (d = decorators[i])
|
|
365
482
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
366
483
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
367
|
-
}
|
|
484
|
+
}
|
|
485
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/teleport.ts";
|
|
368
486
|
var Teleport = class {
|
|
369
487
|
constructor({ initiator, localPeerId, remotePeerId }) {
|
|
370
488
|
this._ctx = new Context2({
|
|
371
489
|
onError: (err) => {
|
|
372
490
|
void this.destroy(err).catch(() => {
|
|
373
491
|
log2.error("Error during destroy", err, {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
492
|
+
F: __dxlog_file2,
|
|
493
|
+
L: 35,
|
|
494
|
+
S: this,
|
|
495
|
+
C: (f, a) => f(...a)
|
|
378
496
|
});
|
|
379
497
|
});
|
|
380
498
|
}
|
|
@@ -384,21 +502,21 @@ var Teleport = class {
|
|
|
384
502
|
heartbeatInterval: 1e4,
|
|
385
503
|
heartbeatTimeout: 1e4,
|
|
386
504
|
onTimeout: () => {
|
|
387
|
-
this.destroy(new Error("Connection timed out")).catch((err) => log2.catch(err,
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
505
|
+
this.destroy(new Error("Connection timed out")).catch((err) => log2.catch(err, void 0, {
|
|
506
|
+
F: __dxlog_file2,
|
|
507
|
+
L: 46,
|
|
508
|
+
S: this,
|
|
509
|
+
C: (f, a) => f(...a)
|
|
392
510
|
}));
|
|
393
511
|
}
|
|
394
512
|
});
|
|
395
513
|
this._extensions = /* @__PURE__ */ new Map();
|
|
396
514
|
this._remoteExtensions = /* @__PURE__ */ new Set();
|
|
397
515
|
this._open = false;
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
516
|
+
invariant3(typeof initiator === "boolean");
|
|
517
|
+
invariant3(PublicKey.isPublicKey(localPeerId));
|
|
518
|
+
invariant3(PublicKey.isPublicKey(remotePeerId));
|
|
519
|
+
invariant3(typeof initiator === "boolean");
|
|
402
520
|
this.initiator = initiator;
|
|
403
521
|
this.localPeerId = localPeerId;
|
|
404
522
|
this.remotePeerId = remotePeerId;
|
|
@@ -406,12 +524,12 @@ var Teleport = class {
|
|
|
406
524
|
log2("remote extension", {
|
|
407
525
|
name
|
|
408
526
|
}, {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
527
|
+
F: __dxlog_file2,
|
|
528
|
+
L: 65,
|
|
529
|
+
S: this,
|
|
530
|
+
C: (f, a) => f(...a)
|
|
413
531
|
});
|
|
414
|
-
|
|
532
|
+
invariant3(!this._remoteExtensions.has(name), "Remote extension already exists");
|
|
415
533
|
this._remoteExtensions.add(name);
|
|
416
534
|
if (this._extensions.has(name)) {
|
|
417
535
|
try {
|
|
@@ -455,12 +573,12 @@ var Teleport = class {
|
|
|
455
573
|
for (const extension of this._extensions.values()) {
|
|
456
574
|
try {
|
|
457
575
|
await extension.onClose(err);
|
|
458
|
-
} catch (
|
|
459
|
-
log2.catch(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
576
|
+
} catch (err2) {
|
|
577
|
+
log2.catch(err2, void 0, {
|
|
578
|
+
F: __dxlog_file2,
|
|
579
|
+
L: 125,
|
|
580
|
+
S: this,
|
|
581
|
+
C: (f, a) => f(...a)
|
|
464
582
|
});
|
|
465
583
|
}
|
|
466
584
|
}
|
|
@@ -473,10 +591,10 @@ var Teleport = class {
|
|
|
473
591
|
log2("addExtension", {
|
|
474
592
|
name
|
|
475
593
|
}, {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
594
|
+
F: __dxlog_file2,
|
|
595
|
+
L: 137,
|
|
596
|
+
S: this,
|
|
597
|
+
C: (f, a) => f(...a)
|
|
480
598
|
});
|
|
481
599
|
this._setExtension(name, extension);
|
|
482
600
|
scheduleTask(this._ctx, async () => {
|
|
@@ -496,8 +614,8 @@ var Teleport = class {
|
|
|
496
614
|
}
|
|
497
615
|
}
|
|
498
616
|
_setExtension(extensionName, extension) {
|
|
499
|
-
|
|
500
|
-
|
|
617
|
+
invariant3(!extensionName.includes("/"), "Invalid extension name");
|
|
618
|
+
invariant3(!this._extensions.has(extensionName), "Extension already exists");
|
|
501
619
|
this._extensions.set(extensionName, extension);
|
|
502
620
|
}
|
|
503
621
|
async _openExtension(extensionName) {
|
|
@@ -505,22 +623,22 @@ var Teleport = class {
|
|
|
505
623
|
log2("open extension", {
|
|
506
624
|
extensionName
|
|
507
625
|
}, {
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
626
|
+
F: __dxlog_file2,
|
|
627
|
+
L: 167,
|
|
628
|
+
S: this,
|
|
629
|
+
C: (f, a) => f(...a)
|
|
512
630
|
});
|
|
513
631
|
const extension = (_a = this._extensions.get(extensionName)) != null ? _a : failUndefined2();
|
|
514
632
|
const context = {
|
|
515
633
|
initiator: this.initiator,
|
|
516
634
|
localPeerId: this.localPeerId,
|
|
517
635
|
remotePeerId: this.remotePeerId,
|
|
518
|
-
createPort: (channelName, opts) => {
|
|
519
|
-
|
|
636
|
+
createPort: async (channelName, opts) => {
|
|
637
|
+
invariant3(!channelName.includes("/"), "Invalid channel name");
|
|
520
638
|
return this._muxer.createPort(`${extensionName}/${channelName}`, opts);
|
|
521
639
|
},
|
|
522
|
-
createStream: (channelName, opts) => {
|
|
523
|
-
|
|
640
|
+
createStream: async (channelName, opts) => {
|
|
641
|
+
invariant3(!channelName.includes("/"), "Invalid channel name");
|
|
524
642
|
return this._muxer.createStream(`${extensionName}/${channelName}`, opts);
|
|
525
643
|
},
|
|
526
644
|
close: (err) => {
|
|
@@ -533,14 +651,14 @@ var Teleport = class {
|
|
|
533
651
|
log2("extension opened", {
|
|
534
652
|
extensionName
|
|
535
653
|
}, {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
654
|
+
F: __dxlog_file2,
|
|
655
|
+
L: 190,
|
|
656
|
+
S: this,
|
|
657
|
+
C: (f, a) => f(...a)
|
|
540
658
|
});
|
|
541
659
|
}
|
|
542
660
|
};
|
|
543
|
-
|
|
661
|
+
_ts_decorate([
|
|
544
662
|
synchronized
|
|
545
663
|
], Teleport.prototype, "destroy", null);
|
|
546
664
|
var ControlExtension = class {
|
|
@@ -571,12 +689,12 @@ var ControlExtension = class {
|
|
|
571
689
|
}
|
|
572
690
|
}
|
|
573
691
|
},
|
|
574
|
-
port: extensionContext.createPort("rpc", {
|
|
692
|
+
port: await extensionContext.createPort("rpc", {
|
|
575
693
|
contentType: 'application/x-protobuf; messagType="dxos.rpc.Message"'
|
|
576
694
|
})
|
|
577
695
|
});
|
|
578
696
|
await this._rpc.open();
|
|
579
|
-
|
|
697
|
+
scheduleTaskInterval2(this._ctx, async () => {
|
|
580
698
|
try {
|
|
581
699
|
await asyncTimeout(this._rpc.rpc.Control.heartbeat(), this.opts.heartbeatTimeout);
|
|
582
700
|
} catch (err) {
|
|
@@ -596,16 +714,17 @@ var ControlExtension = class {
|
|
|
596
714
|
};
|
|
597
715
|
|
|
598
716
|
// packages/core/mesh/teleport/src/testing/test-extension.ts
|
|
599
|
-
import
|
|
600
|
-
import { asyncTimeout as asyncTimeout2, Trigger } from "@dxos/async";
|
|
717
|
+
import invariant4 from "tiny-invariant";
|
|
718
|
+
import { asyncTimeout as asyncTimeout2, Trigger as Trigger2 } from "@dxos/async";
|
|
601
719
|
import { log as log3 } from "@dxos/log";
|
|
602
720
|
import { schema as schema3 } from "@dxos/protocols";
|
|
603
721
|
import { createProtoRpcPeer as createProtoRpcPeer2 } from "@dxos/rpc";
|
|
722
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/testing/test-extension.ts";
|
|
604
723
|
var TestExtension = class {
|
|
605
724
|
constructor(callbacks = {}) {
|
|
606
725
|
this.callbacks = callbacks;
|
|
607
|
-
this.open = new
|
|
608
|
-
this.closed = new
|
|
726
|
+
this.open = new Trigger2();
|
|
727
|
+
this.closed = new Trigger2();
|
|
609
728
|
}
|
|
610
729
|
get remotePeerId() {
|
|
611
730
|
var _a;
|
|
@@ -617,14 +736,14 @@ var TestExtension = class {
|
|
|
617
736
|
localPeerId: context.localPeerId,
|
|
618
737
|
remotePeerId: context.remotePeerId
|
|
619
738
|
}, {
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
739
|
+
F: __dxlog_file3,
|
|
740
|
+
L: 33,
|
|
741
|
+
S: this,
|
|
742
|
+
C: (f, a) => f(...a)
|
|
624
743
|
});
|
|
625
744
|
this.extensionContext = context;
|
|
626
745
|
this._rpc = createProtoRpcPeer2({
|
|
627
|
-
port: context.createPort("rpc", {
|
|
746
|
+
port: await context.createPort("rpc", {
|
|
628
747
|
contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
|
|
629
748
|
}),
|
|
630
749
|
requested: {
|
|
@@ -644,7 +763,7 @@ var TestExtension = class {
|
|
|
644
763
|
}
|
|
645
764
|
}
|
|
646
765
|
},
|
|
647
|
-
timeout:
|
|
766
|
+
timeout: 2e3
|
|
648
767
|
});
|
|
649
768
|
await this._rpc.open();
|
|
650
769
|
await ((_b = (_a = this.callbacks).onOpen) == null ? void 0 : _b.call(_a));
|
|
@@ -655,10 +774,10 @@ var TestExtension = class {
|
|
|
655
774
|
log3("onClose", {
|
|
656
775
|
err
|
|
657
776
|
}, {
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
777
|
+
F: __dxlog_file3,
|
|
778
|
+
L: 67,
|
|
779
|
+
S: this,
|
|
780
|
+
C: (f, a) => f(...a)
|
|
662
781
|
});
|
|
663
782
|
await ((_b = (_a = this.callbacks).onClose) == null ? void 0 : _b.call(_a));
|
|
664
783
|
this.closed.wake();
|
|
@@ -666,12 +785,12 @@ var TestExtension = class {
|
|
|
666
785
|
}
|
|
667
786
|
async test(message = "test") {
|
|
668
787
|
await this.open.wait({
|
|
669
|
-
timeout:
|
|
788
|
+
timeout: 1500
|
|
670
789
|
});
|
|
671
790
|
const res = await asyncTimeout2(this._rpc.rpc.TestService.testCall({
|
|
672
791
|
data: message
|
|
673
|
-
}),
|
|
674
|
-
|
|
792
|
+
}), 1500);
|
|
793
|
+
invariant4(res.data === message);
|
|
675
794
|
}
|
|
676
795
|
/**
|
|
677
796
|
* Force-close the connection.
|
|
@@ -690,4 +809,4 @@ export {
|
|
|
690
809
|
Teleport,
|
|
691
810
|
TestExtension
|
|
692
811
|
};
|
|
693
|
-
//# sourceMappingURL=chunk-
|
|
812
|
+
//# sourceMappingURL=chunk-7TGKNWZQ.mjs.map
|