@dxos/teleport-extension-replicator 0.3.7 → 0.3.8-main.36d5c2a

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.
@@ -20,7 +20,7 @@ function _ts_decorate(decorators, target, key, desc) {
20
20
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
21
21
  return c > 3 && r && Object.defineProperty(target, key, r), r;
22
22
  }
23
- var __dxlog_file = "/home/circleci/project/packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts";
23
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts";
24
24
  var ReplicatorExtension = class {
25
25
  constructor() {
26
26
  this._ctx = new Context({
@@ -366,12 +366,12 @@ var ReplicatorExtension = class {
366
366
  });
367
367
  return;
368
368
  }
369
- log.warn("replication stream error", {
369
+ log.info("replication stream error", {
370
370
  err,
371
371
  info
372
372
  }, {
373
373
  F: __dxlog_file,
374
- L: 267,
374
+ L: 268,
375
375
  S: this,
376
376
  C: (f, a) => f(...a)
377
377
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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 { schema, RpcClosedError, TimeoutError } from '@dxos/protocols';\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 log.catch(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>) {\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) {\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 });\n await this._rpc.open();\n\n this._updateTask.schedule();\n }\n\n async onClose(err?: Error | undefined) {\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) {\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() {\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) {\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) {\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\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 log.warn('replication stream error', { err, info });\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) {\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": ["asyncTimeout", "DeferredTask", "synchronized", "Context", "failUndefined", "invariant", "PublicKey", "log", "logInfo", "schema", "RpcClosedError", "TimeoutError", "createProtoRpcPeer", "ComplexMap", "ReplicatorExtension", "_ctx", "onError", "err", "catch", "_extensionContext", "close", "_feeds", "hash", "_streams", "_options", "upload", "_updateTask", "initiator", "_rpc", "rpc", "ReplicatorService", "updateFeeds", "feeds", "Array", "from", "values", "map", "feed", "feedKey", "key", "download", "_reevaluateFeeds", "extensionInfo", "localPeerId", "remotePeerId", "keys", "setOptions", "options", "schedule", "addFeed", "set", "onOpen", "context", "requested", "getService", "exposed", "handlers", "startReplication", "info", "streamTag", "_acceptReplication", "stopReplication", "_stopReplication", "port", "createPort", "contentType", "open", "onClose", "dispose", "onAbort", "abort", "disposed", "has", "get", "_initiateReplication", "feedInfo", "_replicateFeed", "undefined", "tag", "toHex", "random", "slice", "networkStream", "createStream", "replicationStream", "replicate", "live", "noise", "encrypted", "maxRequests", "on", "message", "warn", "pipe", "stream", "destroy", "delete"]
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 { schema, RpcClosedError, TimeoutError } from '@dxos/protocols';\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 log.catch(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>) {\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) {\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 });\n await this._rpc.open();\n\n this._updateTask.schedule();\n }\n\n async onClose(err?: Error | undefined) {\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) {\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() {\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) {\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) {\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\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?\n log.info('replication stream error', { err, info });\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) {\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": ["asyncTimeout", "DeferredTask", "synchronized", "Context", "failUndefined", "invariant", "PublicKey", "log", "logInfo", "schema", "RpcClosedError", "TimeoutError", "createProtoRpcPeer", "ComplexMap", "ReplicatorExtension", "_ctx", "onError", "err", "catch", "_extensionContext", "close", "_feeds", "hash", "_streams", "_options", "upload", "_updateTask", "initiator", "_rpc", "rpc", "ReplicatorService", "updateFeeds", "feeds", "Array", "from", "values", "map", "feed", "feedKey", "key", "download", "_reevaluateFeeds", "extensionInfo", "localPeerId", "remotePeerId", "keys", "setOptions", "options", "schedule", "addFeed", "set", "onOpen", "context", "requested", "getService", "exposed", "handlers", "startReplication", "info", "streamTag", "_acceptReplication", "stopReplication", "_stopReplication", "port", "createPort", "contentType", "open", "onClose", "dispose", "onAbort", "abort", "disposed", "has", "get", "_initiateReplication", "feedInfo", "_replicateFeed", "undefined", "tag", "toHex", "random", "slice", "networkStream", "createStream", "replicationStream", "replicate", "live", "noise", "encrypted", "maxRequests", "on", "message", "pipe", "stream", "destroy", "delete"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts":{"bytes":37392,"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/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":515,"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/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":15981},"packages/core/mesh/teleport-extension-replicator/dist/lib/browser/index.mjs":{"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/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":11349},"packages/core/mesh/teleport-extension-replicator/src/index.ts":{"bytesInOutput":0}},"bytes":11532}}}
1
+ {"inputs":{"packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts":{"bytes":37503,"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/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/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":16014},"packages/core/mesh/teleport-extension-replicator/dist/lib/browser/index.mjs":{"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/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":11354},"packages/core/mesh/teleport-extension-replicator/src/index.ts":{"bytesInOutput":0}},"bytes":11537}}}
@@ -16,15 +16,11 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // packages/core/mesh/teleport-extension-replicator/src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
19
+ var node_exports = {};
20
+ __export(node_exports, {
23
21
  ReplicatorExtension: () => ReplicatorExtension
24
22
  });
25
- module.exports = __toCommonJS(src_exports);
26
-
27
- // packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts
23
+ module.exports = __toCommonJS(node_exports);
28
24
  var import_async = require("@dxos/async");
29
25
  var import_context = require("@dxos/context");
30
26
  var import_debug = require("@dxos/debug");
@@ -44,7 +40,7 @@ function _ts_decorate(decorators, target, key, desc) {
44
40
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
45
41
  return c > 3 && r && Object.defineProperty(target, key, r), r;
46
42
  }
47
- var __dxlog_file = "/home/circleci/project/packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts";
43
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts";
48
44
  var ReplicatorExtension = class {
49
45
  constructor() {
50
46
  this._ctx = new import_context.Context({
@@ -390,12 +386,12 @@ var ReplicatorExtension = class {
390
386
  });
391
387
  return;
392
388
  }
393
- import_log.log.warn("replication stream error", {
389
+ import_log.log.info("replication stream error", {
394
390
  err,
395
391
  info
396
392
  }, {
397
393
  F: __dxlog_file,
398
- L: 267,
394
+ L: 268,
399
395
  S: this,
400
396
  C: (f, a) => f(...a)
401
397
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/index.ts", "../../../src/replicator-extension.ts"],
4
- "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nexport * from './replicator-extension';\n", "//\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 { schema, RpcClosedError, TimeoutError } from '@dxos/protocols';\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 log.catch(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>) {\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) {\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 });\n await this._rpc.open();\n\n this._updateTask.schedule();\n }\n\n async onClose(err?: Error | undefined) {\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) {\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() {\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) {\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) {\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\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 log.warn('replication stream error', { err, info });\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) {\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", "log", "catch", "_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", "schedule", "addFeed", "set", "onOpen", "context", "createProtoRpcPeer", "requested", "schema", "getService", "exposed", "handlers", "invariant", "startReplication", "info", "streamTag", "_acceptReplication", "stopReplication", "_stopReplication", "port", "createPort", "contentType", "open", "onClose", "dispose", "onAbort", "abort", "disposed", "has", "get", "asyncTimeout", "_initiateReplication", "feedInfo", "_replicateFeed", "undefined", "tag", "toHex", "random", "slice", "failUndefined", "networkStream", "createStream", "replicationStream", "replicate", "live", "noise", "encrypted", "maxRequests", "on", "TimeoutError", "message", "warn", "pipe", "stream", "destroy", "delete", "logInfo", "synchronized"]
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 { schema, RpcClosedError, TimeoutError } from '@dxos/protocols';\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 log.catch(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>) {\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) {\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 });\n await this._rpc.open();\n\n this._updateTask.schedule();\n }\n\n async onClose(err?: Error | undefined) {\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) {\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() {\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) {\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) {\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\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?\n log.info('replication stream error', { err, info });\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) {\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", "log", "catch", "_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", "schedule", "addFeed", "set", "onOpen", "context", "createProtoRpcPeer", "requested", "schema", "getService", "exposed", "handlers", "invariant", "startReplication", "info", "streamTag", "_acceptReplication", "stopReplication", "_stopReplication", "port", "createPort", "contentType", "open", "onClose", "dispose", "onAbort", "abort", "disposed", "has", "get", "asyncTimeout", "_initiateReplication", "feedInfo", "_replicateFeed", "undefined", "tag", "toHex", "random", "slice", "failUndefined", "networkStream", "createStream", "replicationStream", "replicate", "live", "noise", "encrypted", "maxRequests", "on", "TimeoutError", "message", "pipe", "stream", "destroy", "delete", "logInfo", "synchronized"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts":{"bytes":37392,"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/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":515,"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":16078},"packages/core/mesh/teleport-extension-replicator/dist/lib/node/index.cjs":{"imports":[{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/context","kind":"require-call","external":true},{"path":"@dxos/debug","kind":"require-call","external":true},{"path":"@dxos/invariant","kind":"require-call","external":true},{"path":"@dxos/keys","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"@dxos/protocols","kind":"require-call","external":true},{"path":"@dxos/rpc","kind":"require-call","external":true},{"path":"@dxos/util","kind":"require-call","external":true}],"exports":[],"entryPoint":"packages/core/mesh/teleport-extension-replicator/src/index.ts","inputs":{"packages/core/mesh/teleport-extension-replicator/src/index.ts":{"bytesInOutput":143},"packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts":{"bytesInOutput":11933}},"bytes":13170}}}
1
+ {"inputs":{"packages/core/mesh/teleport-extension-replicator/src/replicator-extension.ts":{"bytes":37503,"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/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":16012},"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/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":11354},"packages/core/mesh/teleport-extension-replicator/src/index.ts":{"bytesInOutput":0}},"bytes":11503}}}
@@ -1 +1 @@
1
- {"version":3,"file":"replicator-extension.d.ts","sourceRoot":"","sources":["../../../src/replicator-extension.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAOpD,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAG/E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,qBAAa,mBAAoB,YAAW,iBAAiB;IAC3D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAKlB;IAEH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+D;IACtF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2D;IAEpF,OAAO,CAAC,IAAI,CAAC,CAA8B;IAC3C,OAAO,CAAC,iBAAiB,CAAC,CAAmB;IAE7C,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAmBzB;IAGH,OAAO,KAAK,aAAa,GAOxB;IAED,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAS7C,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC;IAQxB,MAAM,CAAC,OAAO,EAAE,gBAAgB;IA6ChC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS;IAS/B,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS;YAWvB,gBAAgB;IA2B9B;;OAEG;YACW,oBAAoB;IAYlC;;;OAGG;YAEW,kBAAkB;YAYlB,cAAc;YA8Dd,gBAAgB;CAS/B"}
1
+ {"version":3,"file":"replicator-extension.d.ts","sourceRoot":"","sources":["../../../src/replicator-extension.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAOpD,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAG/E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,qBAAa,mBAAoB,YAAW,iBAAiB;IAC3D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAKlB;IAEH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+D;IACtF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2D;IAEpF,OAAO,CAAC,IAAI,CAAC,CAA8B;IAC3C,OAAO,CAAC,iBAAiB,CAAC,CAAmB;IAE7C,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAmBzB;IAGH,OAAO,KAAK,aAAa,GAOxB;IAED,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAS7C,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC;IAQxB,MAAM,CAAC,OAAO,EAAE,gBAAgB;IA6ChC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS;IAS/B,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS;YAWvB,gBAAgB;IA2B9B;;OAEG;YACW,oBAAoB;IAYlC;;;OAGG;YAEW,kBAAkB;YAYlB,cAAc;YA+Dd,gBAAgB;CAS/B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/teleport-extension-replicator",
3
- "version": "0.3.7",
3
+ "version": "0.3.8-main.36d5c2a",
4
4
  "description": "Replicator extension for teleport.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -16,25 +16,25 @@
16
16
  "src"
17
17
  ],
18
18
  "dependencies": {
19
- "@dxos/async": "0.3.7",
20
- "@dxos/context": "0.3.7",
21
- "@dxos/debug": "0.3.7",
22
- "@dxos/feed-store": "0.3.7",
23
- "@dxos/invariant": "0.3.7",
24
- "@dxos/keys": "0.3.7",
25
- "@dxos/log": "0.3.7",
26
- "@dxos/node-std": "0.3.7",
27
- "@dxos/protocols": "0.3.7",
28
- "@dxos/rpc": "0.3.7",
29
- "@dxos/teleport": "0.3.7",
30
- "@dxos/util": "0.3.7"
19
+ "@dxos/async": "0.3.8-main.36d5c2a",
20
+ "@dxos/context": "0.3.8-main.36d5c2a",
21
+ "@dxos/debug": "0.3.8-main.36d5c2a",
22
+ "@dxos/invariant": "0.3.8-main.36d5c2a",
23
+ "@dxos/keys": "0.3.8-main.36d5c2a",
24
+ "@dxos/feed-store": "0.3.8-main.36d5c2a",
25
+ "@dxos/log": "0.3.8-main.36d5c2a",
26
+ "@dxos/node-std": "0.3.8-main.36d5c2a",
27
+ "@dxos/protocols": "0.3.8-main.36d5c2a",
28
+ "@dxos/teleport": "0.3.8-main.36d5c2a",
29
+ "@dxos/rpc": "0.3.8-main.36d5c2a",
30
+ "@dxos/util": "0.3.8-main.36d5c2a"
31
31
  },
32
32
  "devDependencies": {
33
33
  "add": "^2.0.6",
34
34
  "fast-check": "~3.3.0",
35
35
  "typescript": "^5.2.2",
36
- "@dxos/keyring": "0.3.7",
37
- "@dxos/random-access-storage": "0.3.7"
36
+ "@dxos/keyring": "0.3.8-main.36d5c2a",
37
+ "@dxos/random-access-storage": "0.3.8-main.36d5c2a"
38
38
  },
39
39
  "publishConfig": {
40
40
  "access": "public"
@@ -264,7 +264,8 @@ export class ReplicatorExtension implements TeleportExtension {
264
264
  return;
265
265
  }
266
266
 
267
- log.warn('replication stream error', { err, info });
267
+ // TODO(nf): WARN on first error?
268
+ log.info('replication stream error', { err, info });
268
269
  });
269
270
 
270
271
  this._streams.set(info.feedKey, {