@dxos/teleport-extension-replicator 0.8.3 → 0.8.4-main.2e9d522

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/teleport-extension-replicator",
3
- "version": "0.8.3",
3
+ "version": "0.8.4-main.2e9d522",
4
4
  "description": "Replicator extension for teleport.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -24,23 +24,23 @@
24
24
  "src"
25
25
  ],
26
26
  "dependencies": {
27
- "@dxos/async": "0.8.3",
28
- "@dxos/feed-store": "0.8.3",
29
- "@dxos/context": "0.8.3",
30
- "@dxos/debug": "0.8.3",
31
- "@dxos/keys": "0.8.3",
32
- "@dxos/invariant": "0.8.3",
33
- "@dxos/log": "0.8.3",
34
- "@dxos/node-std": "0.8.3",
35
- "@dxos/protocols": "0.8.3",
36
- "@dxos/rpc": "0.8.3",
37
- "@dxos/teleport": "0.8.3",
38
- "@dxos/util": "0.8.3"
27
+ "@dxos/async": "0.8.4-main.2e9d522",
28
+ "@dxos/context": "0.8.4-main.2e9d522",
29
+ "@dxos/debug": "0.8.4-main.2e9d522",
30
+ "@dxos/feed-store": "0.8.4-main.2e9d522",
31
+ "@dxos/invariant": "0.8.4-main.2e9d522",
32
+ "@dxos/log": "0.8.4-main.2e9d522",
33
+ "@dxos/keys": "0.8.4-main.2e9d522",
34
+ "@dxos/node-std": "0.8.4-main.2e9d522",
35
+ "@dxos/protocols": "0.8.4-main.2e9d522",
36
+ "@dxos/rpc": "0.8.4-main.2e9d522",
37
+ "@dxos/teleport": "0.8.4-main.2e9d522",
38
+ "@dxos/util": "0.8.4-main.2e9d522"
39
39
  },
40
40
  "devDependencies": {
41
41
  "fast-check": "^3.19.0",
42
- "@dxos/keyring": "0.8.3",
43
- "@dxos/random-access-storage": "0.8.3"
42
+ "@dxos/keyring": "0.8.4-main.2e9d522",
43
+ "@dxos/random-access-storage": "0.8.4-main.2e9d522"
44
44
  },
45
45
  "publishConfig": {
46
46
  "access": "public"
@@ -131,7 +131,6 @@ describe('ReplicatorExtension', () => {
131
131
  });
132
132
 
133
133
  // TODO: not working yet.
134
- // eslint-disable-next-line mocha/no-skipped-tests
135
134
  test.skip('enabling upload mid replication', async () => {
136
135
  const builder = new TestBuilder();
137
136
  const agent1 = builder.createAgent();
@@ -1,439 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var node_exports = {};
20
- __export(node_exports, {
21
- ReplicatorExtension: () => ReplicatorExtension
22
- });
23
- module.exports = __toCommonJS(node_exports);
24
- var import_async = require("@dxos/async");
25
- var import_context = require("@dxos/context");
26
- var import_debug = require("@dxos/debug");
27
- var import_invariant = require("@dxos/invariant");
28
- var import_keys = require("@dxos/keys");
29
- var import_log = require("@dxos/log");
30
- var import_protocols = require("@dxos/protocols");
31
- var import_proto = require("@dxos/protocols/proto");
32
- var import_rpc = require("@dxos/rpc");
33
- var import_util = require("@dxos/util");
34
- function _ts_decorate(decorators, target, key, desc) {
35
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
36
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
37
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
38
- return c > 3 && r && Object.defineProperty(target, key, r), r;
39
- }
40
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts";
41
- var ReplicatorExtension = class {
42
- constructor() {
43
- this._ctx = new import_context.Context({
44
- onError: (err) => {
45
- this._extensionContext?.close(err);
46
- }
47
- }, {
48
- F: __dxlog_file,
49
- L: 30
50
- });
51
- this._feeds = new import_util.ComplexMap(import_keys.PublicKey.hash);
52
- this._streams = new import_util.ComplexMap(import_keys.PublicKey.hash);
53
- this._options = {
54
- upload: false
55
- };
56
- this._updateTask = new import_async.DeferredTask(this._ctx, async () => {
57
- try {
58
- if (this._extensionContext.initiator === false) {
59
- await this._rpc.rpc.ReplicatorService.updateFeeds({
60
- feeds: Array.from(this._feeds.values()).map((feed) => ({
61
- feedKey: feed.key,
62
- download: true,
63
- upload: this._options.upload
64
- }))
65
- });
66
- } else if (this._extensionContext.initiator === true) {
67
- await this._reevaluateFeeds();
68
- }
69
- } catch (err) {
70
- if (err instanceof import_protocols.RpcClosedError) {
71
- return;
72
- }
73
- throw err;
74
- }
75
- });
76
- }
77
- get extensionInfo() {
78
- return {
79
- initiator: this._extensionContext?.initiator,
80
- localPeerId: this._extensionContext?.localPeerId,
81
- remotePeerId: this._extensionContext?.remotePeerId,
82
- feeds: Array.from(this._feeds.keys())
83
- };
84
- }
85
- setOptions(options) {
86
- this._options = options;
87
- (0, import_log.log)("setOptions", {
88
- options
89
- }, {
90
- F: __dxlog_file,
91
- L: 79,
92
- S: this,
93
- C: (f, a) => f(...a)
94
- });
95
- if (this._extensionContext) {
96
- this._updateTask.schedule();
97
- }
98
- return this;
99
- }
100
- addFeed(feed) {
101
- this._feeds.set(feed.key, feed);
102
- (0, import_log.log)("addFeed", {
103
- feedKey: feed.key
104
- }, {
105
- F: __dxlog_file,
106
- L: 88,
107
- S: this,
108
- C: (f, a) => f(...a)
109
- });
110
- if (this._extensionContext) {
111
- this._updateTask.schedule();
112
- }
113
- }
114
- async onOpen(context) {
115
- this._extensionContext = context;
116
- (0, import_log.log)("open", void 0, {
117
- F: __dxlog_file,
118
- L: 96,
119
- S: this,
120
- C: (f, a) => f(...a)
121
- });
122
- this._rpc = (0, import_rpc.createProtoRpcPeer)({
123
- requested: {
124
- ReplicatorService: import_proto.schema.getService("dxos.mesh.teleport.replicator.ReplicatorService")
125
- },
126
- exposed: {
127
- ReplicatorService: import_proto.schema.getService("dxos.mesh.teleport.replicator.ReplicatorService")
128
- },
129
- handlers: {
130
- ReplicatorService: {
131
- updateFeeds: async ({ feeds }) => {
132
- (0, import_log.log)("received feed info", {
133
- feeds
134
- }, {
135
- F: __dxlog_file,
136
- L: 108,
137
- S: this,
138
- C: (f, a) => f(...a)
139
- });
140
- (0, import_invariant.invariant)(this._extensionContext.initiator === true, "Invalid call", {
141
- F: __dxlog_file,
142
- L: 109,
143
- S: this,
144
- A: [
145
- "this._extensionContext!.initiator === true",
146
- "'Invalid call'"
147
- ]
148
- });
149
- this._updateTask.schedule();
150
- },
151
- startReplication: async ({ info }) => {
152
- (0, import_log.log)("starting replication...", {
153
- info
154
- }, {
155
- F: __dxlog_file,
156
- L: 113,
157
- S: this,
158
- C: (f, a) => f(...a)
159
- });
160
- (0, import_invariant.invariant)(this._extensionContext.initiator === false, "Invalid call", {
161
- F: __dxlog_file,
162
- L: 114,
163
- S: this,
164
- A: [
165
- "this._extensionContext!.initiator === false",
166
- "'Invalid call'"
167
- ]
168
- });
169
- const streamTag = await this._acceptReplication(info);
170
- return {
171
- streamTag
172
- };
173
- },
174
- stopReplication: async ({ info }) => {
175
- (0, import_log.log)("stopping replication...", {
176
- info
177
- }, {
178
- F: __dxlog_file,
179
- L: 122,
180
- S: this,
181
- C: (f, a) => f(...a)
182
- });
183
- (0, import_invariant.invariant)(this._extensionContext.initiator === false, "Invalid call", {
184
- F: __dxlog_file,
185
- L: 124,
186
- S: this,
187
- A: [
188
- "this._extensionContext!.initiator === false",
189
- "'Invalid call'"
190
- ]
191
- });
192
- await this._stopReplication(info.feedKey);
193
- }
194
- }
195
- },
196
- port: await context.createPort("rpc", {
197
- contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
198
- }),
199
- timeout: 1e4
200
- });
201
- await this._rpc.open();
202
- this._updateTask.schedule();
203
- }
204
- async onClose(err) {
205
- (0, import_log.log)("close", {
206
- err
207
- }, {
208
- F: __dxlog_file,
209
- L: 141,
210
- S: this,
211
- C: (f, a) => f(...a)
212
- });
213
- await this._ctx.dispose();
214
- await this._rpc?.close();
215
- for (const feedKey of this._streams.keys()) {
216
- await this._stopReplication(feedKey);
217
- }
218
- }
219
- async onAbort(err) {
220
- (0, import_log.log)("abort", {
221
- err
222
- }, {
223
- F: __dxlog_file,
224
- L: 150,
225
- S: this,
226
- C: (f, a) => f(...a)
227
- });
228
- await this._ctx.dispose();
229
- await this._rpc?.abort();
230
- for (const feedKey of this._streams.keys()) {
231
- await this._stopReplication(feedKey);
232
- }
233
- }
234
- async _reevaluateFeeds() {
235
- (0, import_log.log)("_reevaluateFeeds", void 0, {
236
- F: __dxlog_file,
237
- L: 161,
238
- S: this,
239
- C: (f, a) => f(...a)
240
- });
241
- for (const feedKey of this._feeds.keys()) {
242
- if (this._ctx.disposed) {
243
- return;
244
- }
245
- if (this._streams.has(feedKey) && this._options.upload !== this._streams.get(feedKey)?.info.upload) {
246
- try {
247
- await (0, import_async.asyncTimeout)(this._stopReplication(feedKey), 1e3);
248
- } catch (err) {
249
- import_log.log.catch(err, void 0, {
250
- F: __dxlog_file,
251
- L: 170,
252
- S: this,
253
- C: (f, a) => f(...a)
254
- });
255
- }
256
- }
257
- if (this._ctx.disposed) {
258
- return;
259
- }
260
- if (!this._streams.has(feedKey)) {
261
- await this._initiateReplication({
262
- feedKey,
263
- download: true,
264
- upload: this._options.upload
265
- });
266
- }
267
- }
268
- }
269
- /**
270
- * Try to initiate feed replication.
271
- */
272
- async _initiateReplication(feedInfo) {
273
- (0, import_log.log)("initiating replication", {
274
- feedInfo
275
- }, {
276
- F: __dxlog_file,
277
- L: 191,
278
- S: this,
279
- C: (f, a) => f(...a)
280
- });
281
- (0, import_invariant.invariant)(this._extensionContext.initiator === true, "Invalid call", {
282
- F: __dxlog_file,
283
- L: 192,
284
- S: this,
285
- A: [
286
- "this._extensionContext!.initiator === true",
287
- "'Invalid call'"
288
- ]
289
- });
290
- (0, import_invariant.invariant)(!this._streams.has(feedInfo.feedKey), `Replication already in progress for feed: ${feedInfo.feedKey}`, {
291
- F: __dxlog_file,
292
- L: 193,
293
- S: this,
294
- A: [
295
- "!this._streams.has(feedInfo.feedKey)",
296
- "`Replication already in progress for feed: ${feedInfo.feedKey}`"
297
- ]
298
- });
299
- const { streamTag } = await this._rpc.rpc.ReplicatorService.startReplication({
300
- info: feedInfo
301
- });
302
- if (!streamTag) {
303
- return;
304
- }
305
- await this._replicateFeed(feedInfo, streamTag);
306
- }
307
- /**
308
- * Respond to a remote request to replicate a feed.
309
- * @returns A stream tag for the replication stream or `undefined` if we don't want to replicate.
310
- */
311
- async _acceptReplication(feedInfo) {
312
- (0, import_invariant.invariant)(this._extensionContext.initiator === false, "Invalid call", {
313
- F: __dxlog_file,
314
- L: 208,
315
- S: this,
316
- A: [
317
- "this._extensionContext!.initiator === false",
318
- "'Invalid call'"
319
- ]
320
- });
321
- if (!this._feeds.has(feedInfo.feedKey) || this._streams.has(feedInfo.feedKey)) {
322
- return void 0;
323
- }
324
- const tag = `feed-${feedInfo.feedKey.toHex()}-${import_keys.PublicKey.random().toHex().slice(0, 8)}`;
325
- await this._replicateFeed(feedInfo, tag);
326
- return tag;
327
- }
328
- async _replicateFeed(info, streamTag) {
329
- (0, import_log.log)("replicate", {
330
- info,
331
- streamTag
332
- }, {
333
- F: __dxlog_file,
334
- L: 220,
335
- S: this,
336
- C: (f, a) => f(...a)
337
- });
338
- (0, import_invariant.invariant)(!this._streams.has(info.feedKey), `Replication already in progress for feed: ${info.feedKey}`, {
339
- F: __dxlog_file,
340
- L: 221,
341
- S: this,
342
- A: [
343
- "!this._streams.has(info.feedKey)",
344
- "`Replication already in progress for feed: ${info.feedKey}`"
345
- ]
346
- });
347
- const feed = this._feeds.get(info.feedKey) ?? (0, import_debug.failUndefined)();
348
- const networkStream = await this._extensionContext.createStream(streamTag, {
349
- contentType: "application/x-hypercore"
350
- });
351
- let replicationStreamErrors = 0;
352
- const replicationStream = feed.replicate(true, {
353
- live: true,
354
- upload: info.upload,
355
- download: info.download,
356
- noise: false,
357
- encrypted: false,
358
- maxRequests: 1024
359
- });
360
- replicationStream.on("error", (err) => {
361
- if (err instanceof import_protocols.TimeoutError) {
362
- import_log.log.info("replication stream timeout", {
363
- err,
364
- info
365
- }, {
366
- F: __dxlog_file,
367
- L: 257,
368
- S: this,
369
- C: (f, a) => f(...a)
370
- });
371
- return;
372
- }
373
- if (err?.message === "Writable stream closed prematurely" || err?.message === "Cannot call write after a stream was destroyed") {
374
- (0, import_log.log)("replication stream closed", {
375
- err,
376
- info
377
- }, {
378
- F: __dxlog_file,
379
- L: 265,
380
- S: this,
381
- C: (f, a) => f(...a)
382
- });
383
- return;
384
- }
385
- if (replicationStreamErrors === 0) {
386
- import_log.log.info("replication stream error", {
387
- err,
388
- info
389
- }, {
390
- F: __dxlog_file,
391
- L: 271,
392
- S: this,
393
- C: (f, a) => f(...a)
394
- });
395
- } else {
396
- import_log.log.info("replication stream error", {
397
- err,
398
- feedKey: info.feedKey,
399
- count: replicationStreamErrors
400
- }, {
401
- F: __dxlog_file,
402
- L: 273,
403
- S: this,
404
- C: (f, a) => f(...a)
405
- });
406
- }
407
- replicationStreamErrors++;
408
- });
409
- this._streams.set(info.feedKey, {
410
- streamTag,
411
- networkStream,
412
- replicationStream,
413
- info
414
- });
415
- networkStream.pipe(replicationStream).pipe(networkStream);
416
- }
417
- async _stopReplication(feedKey) {
418
- const stream = this._streams.get(feedKey);
419
- if (!stream) {
420
- return;
421
- }
422
- stream.networkStream.destroy();
423
- this._streams.delete(feedKey);
424
- }
425
- };
426
- _ts_decorate([
427
- import_log.logInfo
428
- ], ReplicatorExtension.prototype, "extensionInfo", null);
429
- _ts_decorate([
430
- import_async.synchronized
431
- ], ReplicatorExtension.prototype, "_reevaluateFeeds", null);
432
- _ts_decorate([
433
- import_async.synchronized
434
- ], ReplicatorExtension.prototype, "_acceptReplication", null);
435
- // Annotate the CommonJS export names for ESM import in node:
436
- 0 && (module.exports = {
437
- ReplicatorExtension
438
- });
439
- //# sourceMappingURL=index.cjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/replicator-extension.ts"],
4
- "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport type { ProtocolStream } from 'hypercore-protocol';\nimport { type Duplex } from 'node:stream';\n\nimport { asyncTimeout, DeferredTask, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { failUndefined } from '@dxos/debug';\nimport { type FeedWrapper } from '@dxos/feed-store';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { RpcClosedError, TimeoutError } from '@dxos/protocols';\nimport { schema } from '@dxos/protocols/proto';\nimport { type FeedInfo, type ReplicatorService } from '@dxos/protocols/proto/dxos/mesh/teleport/replicator';\nimport { createProtoRpcPeer, type ProtoRpcPeer } from '@dxos/rpc';\nimport { type ExtensionContext, type TeleportExtension } from '@dxos/teleport';\nimport { ComplexMap } from '@dxos/util';\n\nexport type ReplicationOptions = {\n upload: boolean;\n};\n\n/**\n * Manages replication between a set of feeds for a single teleport session.\n */\nexport class ReplicatorExtension implements TeleportExtension {\n private readonly _ctx = new Context({\n onError: (err) => {\n this._extensionContext?.close(err);\n },\n });\n\n private readonly _feeds = new ComplexMap<PublicKey, FeedWrapper<any>>(PublicKey.hash);\n private readonly _streams = new ComplexMap<PublicKey, ActiveStream>(PublicKey.hash);\n\n private _rpc?: ProtoRpcPeer<ServiceBundle>;\n private _extensionContext?: ExtensionContext;\n\n private _options: ReplicationOptions = {\n upload: false,\n };\n\n private readonly _updateTask = new DeferredTask(this._ctx, async () => {\n try {\n if (this._extensionContext!.initiator === false) {\n await this._rpc!.rpc.ReplicatorService.updateFeeds({\n feeds: Array.from(this._feeds.values()).map((feed) => ({\n feedKey: feed.key,\n download: true,\n upload: this._options.upload,\n })),\n });\n } else if (this._extensionContext!.initiator === true) {\n await this._reevaluateFeeds();\n }\n } catch (err) {\n if (err instanceof RpcClosedError) {\n return; // Some RPC requests might be pending while closing.\n }\n throw err;\n }\n });\n\n @logInfo\n private get extensionInfo() {\n return {\n initiator: this._extensionContext?.initiator,\n localPeerId: this._extensionContext?.localPeerId,\n remotePeerId: this._extensionContext?.remotePeerId,\n feeds: Array.from(this._feeds.keys()),\n };\n }\n\n setOptions(options: ReplicationOptions): this {\n this._options = options;\n log('setOptions', { options });\n if (this._extensionContext) {\n this._updateTask.schedule();\n }\n return this;\n }\n\n addFeed(feed: FeedWrapper<any>): void {\n this._feeds.set(feed.key, feed);\n log('addFeed', { feedKey: feed.key });\n if (this._extensionContext) {\n this._updateTask.schedule();\n }\n }\n\n async onOpen(context: ExtensionContext): Promise<void> {\n this._extensionContext = context;\n log('open');\n\n this._rpc = createProtoRpcPeer<ServiceBundle, ServiceBundle>({\n requested: {\n ReplicatorService: schema.getService('dxos.mesh.teleport.replicator.ReplicatorService'),\n },\n exposed: {\n ReplicatorService: schema.getService('dxos.mesh.teleport.replicator.ReplicatorService'),\n },\n handlers: {\n ReplicatorService: {\n updateFeeds: async ({ feeds }) => {\n log('received feed info', { feeds });\n invariant(this._extensionContext!.initiator === true, 'Invalid call');\n this._updateTask.schedule();\n },\n startReplication: async ({ info }) => {\n log('starting replication...', { info });\n invariant(this._extensionContext!.initiator === false, 'Invalid call');\n\n const streamTag = await this._acceptReplication(info);\n return {\n streamTag,\n };\n },\n stopReplication: async ({ info }) => {\n log('stopping replication...', { info });\n // TODO(dmaretskyi): Make sure any peer can stop replication.\n invariant(this._extensionContext!.initiator === false, 'Invalid call');\n\n await this._stopReplication(info.feedKey);\n },\n },\n },\n port: await context.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"dxos.rpc.Message\"',\n }),\n timeout: 10_000,\n });\n await this._rpc.open();\n\n this._updateTask.schedule();\n }\n\n async onClose(err?: Error | undefined): Promise<void> {\n log('close', { err });\n await this._ctx.dispose();\n await this._rpc?.close();\n for (const feedKey of this._streams.keys()) {\n await this._stopReplication(feedKey);\n }\n }\n\n async onAbort(err?: Error | undefined): Promise<void> {\n log('abort', { err });\n\n await this._ctx.dispose();\n await this._rpc?.abort();\n for (const feedKey of this._streams.keys()) {\n await this._stopReplication(feedKey);\n }\n }\n\n @synchronized\n private async _reevaluateFeeds(): Promise<void> {\n log('_reevaluateFeeds');\n for (const feedKey of this._feeds.keys()) {\n if (this._ctx.disposed) {\n return;\n }\n if (this._streams.has(feedKey) && this._options.upload !== this._streams.get(feedKey)?.info.upload) {\n try {\n await asyncTimeout(this._stopReplication(feedKey), 1000);\n } catch (err) {\n log.catch(err);\n }\n }\n\n if (this._ctx.disposed) {\n return;\n }\n if (!this._streams.has(feedKey)) {\n await this._initiateReplication({\n feedKey,\n download: true,\n upload: this._options.upload,\n });\n }\n }\n }\n\n /**\n * Try to initiate feed replication.\n */\n private async _initiateReplication(feedInfo: FeedInfo): Promise<void> {\n log('initiating replication', { feedInfo });\n invariant(this._extensionContext!.initiator === true, 'Invalid call');\n invariant(!this._streams.has(feedInfo.feedKey), `Replication already in progress for feed: ${feedInfo.feedKey}`);\n const { streamTag } = await this._rpc!.rpc.ReplicatorService.startReplication({ info: feedInfo });\n if (!streamTag) {\n return;\n }\n\n await this._replicateFeed(feedInfo, streamTag);\n }\n\n /**\n * Respond to a remote request to replicate a feed.\n * @returns A stream tag for the replication stream or `undefined` if we don't want to replicate.\n */\n @synchronized\n private async _acceptReplication(feedInfo: FeedInfo): Promise<string | undefined> {\n invariant(this._extensionContext!.initiator === false, 'Invalid call');\n\n if (!this._feeds.has(feedInfo.feedKey) || this._streams.has(feedInfo.feedKey)) {\n return undefined; // We don't have the feed or we are already replicating it.\n }\n\n const tag = `feed-${feedInfo.feedKey.toHex()}-${PublicKey.random().toHex().slice(0, 8)}`; // Generate a unique tag for the stream.\n await this._replicateFeed(feedInfo, tag);\n return tag;\n }\n\n private async _replicateFeed(info: FeedInfo, streamTag: string): Promise<void> {\n log('replicate', { info, streamTag });\n invariant(!this._streams.has(info.feedKey), `Replication already in progress for feed: ${info.feedKey}`);\n\n const feed = this._feeds.get(info.feedKey) ?? failUndefined();\n const networkStream = await this._extensionContext!.createStream(streamTag, {\n contentType: 'application/x-hypercore',\n });\n let replicationStreamErrors = 0;\n\n // https://github.com/holepunchto/hypercore/tree/v9.12.0#var-stream--feedreplicateisinitiator-options\n const replicationStream = feed.replicate(true, {\n live: true,\n upload: info.upload,\n download: info.download,\n noise: false,\n encrypted: false,\n maxRequests: 1024,\n });\n\n // Left for testing.\n // const debug = true;\n // if (debug) {\n // feed.on('sync', () => {\n // log.info('sync', { key: feed.key, length: feed.length });\n // });\n // feed.on('download', (index: number, data: any) => {\n // log.info('download', {\n // key: feed.key,\n // index,\n // length: feed.length,\n // data: data.length,\n // });\n // });\n // }\n\n replicationStream.on('error', (err) => {\n if (err instanceof TimeoutError) {\n log.info('replication stream timeout', { err, info });\n return;\n }\n // TODO(nf): use sentinel errors\n if (\n err?.message === 'Writable stream closed prematurely' ||\n err?.message === 'Cannot call write after a stream was destroyed'\n ) {\n log('replication stream closed', { err, info });\n return;\n }\n\n // TODO(nf): WARN on first error? log full info on some subsequent errors?\n if (replicationStreamErrors === 0) {\n log.info('replication stream error', { err, info });\n } else {\n log.info('replication stream error', { err, feedKey: info.feedKey, count: replicationStreamErrors });\n }\n replicationStreamErrors++;\n });\n\n this._streams.set(info.feedKey, {\n streamTag,\n networkStream,\n replicationStream,\n info,\n });\n\n networkStream.pipe(replicationStream as any).pipe(networkStream);\n }\n\n private async _stopReplication(feedKey: PublicKey): Promise<void> {\n const stream = this._streams.get(feedKey);\n if (!stream) {\n return;\n }\n\n stream.networkStream.destroy();\n this._streams.delete(feedKey);\n }\n}\n\ntype ServiceBundle = {\n ReplicatorService: ReplicatorService;\n};\n\ntype ActiveStream = {\n streamTag: string;\n networkStream: Duplex;\n replicationStream: ProtocolStream;\n info: FeedInfo;\n};\n"],
5
- "mappings": "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",
6
- "names": ["ReplicatorExtension", "_ctx", "Context", "onError", "err", "_extensionContext", "close", "_feeds", "ComplexMap", "PublicKey", "hash", "_streams", "_options", "upload", "_updateTask", "DeferredTask", "initiator", "_rpc", "rpc", "ReplicatorService", "updateFeeds", "feeds", "Array", "from", "values", "map", "feed", "feedKey", "key", "download", "_reevaluateFeeds", "RpcClosedError", "extensionInfo", "localPeerId", "remotePeerId", "keys", "setOptions", "options", "log", "schedule", "addFeed", "set", "onOpen", "context", "createProtoRpcPeer", "requested", "schema", "getService", "exposed", "handlers", "invariant", "startReplication", "info", "streamTag", "_acceptReplication", "stopReplication", "_stopReplication", "port", "createPort", "contentType", "timeout", "open", "onClose", "dispose", "onAbort", "abort", "disposed", "has", "get", "asyncTimeout", "catch", "_initiateReplication", "feedInfo", "_replicateFeed", "undefined", "tag", "toHex", "random", "slice", "failUndefined", "networkStream", "createStream", "replicationStreamErrors", "replicationStream", "replicate", "live", "noise", "encrypted", "maxRequests", "on", "TimeoutError", "message", "count", "pipe", "stream", "destroy", "delete"]
7
- }
@@ -1 +0,0 @@
1
- {"inputs":{"packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts":{"bytes":38844,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-replicator/src/index.ts":{"bytes":520,"imports":[{"path":"packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts","kind":"import-statement","original":"./replicator-extension"}],"format":"esm"}},"outputs":{"packages/core/mesh/teleport-extension-replicator/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":16528},"packages/core/mesh/teleport-extension-replicator/dist/lib/node/index.cjs":{"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["ReplicatorExtension"],"entryPoint":"packages/core/mesh/teleport-extension-replicator/src/index.ts","inputs":{"packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts":{"bytesInOutput":11707},"packages/core/mesh/teleport-extension-replicator/src/index.ts":{"bytesInOutput":0}},"bytes":11856}}}