@dxos/teleport-extension-object-sync 0.3.11-main.f14932f → 0.3.11-main.f4c1077

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.
@@ -280,7 +280,7 @@ _ts_decorate([
280
280
  ], BlobSyncExtension.prototype, "push", null);
281
281
 
282
282
  // packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts
283
- import { trackLeaks, Trigger, Lock } from "@dxos/async";
283
+ import { trackLeaks, Trigger, Mutex } from "@dxos/async";
284
284
  import { cancelWithContext, Context as Context2 } from "@dxos/context";
285
285
  import { invariant as invariant2 } from "@dxos/invariant";
286
286
  import { PublicKey } from "@dxos/keys";
@@ -298,11 +298,11 @@ function _ts_decorate2(decorators, target, key, desc) {
298
298
  return c > 3 && r && Object.defineProperty(target, key, r), r;
299
299
  }
300
300
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts";
301
- var BlobSync = class BlobSync2 {
301
+ var BlobSync = class {
302
302
  constructor(_params) {
303
303
  this._params = _params;
304
304
  this._ctx = new Context2();
305
- this._lock = new Lock();
305
+ this._mutex = new Mutex();
306
306
  this._downloadRequests = new ComplexMap((key) => PublicKey.from(key).toHex());
307
307
  this._extensions = /* @__PURE__ */ new Set();
308
308
  }
@@ -325,7 +325,7 @@ var BlobSync = class BlobSync2 {
325
325
  S: this,
326
326
  C: (f, a) => f(...a)
327
327
  });
328
- const request = await this._lock.executeSynchronized(async () => {
328
+ const request = await this._mutex.executeSynchronized(async () => {
329
329
  const existingRequest = this._downloadRequests.get(id);
330
330
  if (existingRequest) {
331
331
  existingRequest.counter++;
@@ -349,7 +349,7 @@ var BlobSync = class BlobSync2 {
349
349
  }
350
350
  return request2;
351
351
  });
352
- ctx?.onDispose(() => this._lock.executeSynchronized(async () => {
352
+ ctx?.onDispose(() => this._mutex.executeSynchronized(async () => {
353
353
  const request2 = this._downloadRequests.get(id);
354
354
  if (!request2) {
355
355
  return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/blob-sync-extension.ts", "../../../src/blob-sync.ts", "../../../src/blob-store.ts"],
4
- "sourcesContent": ["//\n\n//\n// Copyright 2023 DXOS.org\n//\n\nimport { DeferredTask, sleep, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { RpcClosedError, schema } from '@dxos/protocols';\nimport { type BlobChunk, type BlobSyncService, type WantList } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\nimport { BitField } from '@dxos/util';\n\nimport { type BlobStore } from './blob-store';\n\nexport type BlobSyncExtensionParams = {\n blobStore: BlobStore;\n onOpen: () => Promise<void>;\n onClose: () => Promise<void>;\n onAbort: () => Promise<void>;\n onPush: (data: BlobChunk) => Promise<void>;\n};\n\nconst MIN_WANT_LIST_UPDATE_INTERVAL = process.env.NODE_ENV === 'test' ? 5 : 500;\n\nconst MAX_CONCURRENT_UPLOADS = 20;\n\n/**\n * Manages replication between a set of feeds for a single teleport session.\n */\nexport class BlobSyncExtension extends RpcExtension<ServiceBundle, ServiceBundle> {\n private readonly _ctx = new Context({ onError: (err) => log.catch(err) });\n\n private _lastWantListUpdate = 0;\n private _localWantList: WantList = { blobs: [] };\n\n private readonly _updateWantList = new DeferredTask(this._ctx, async () => {\n // Throttle want list updates.\n if (this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL > Date.now()) {\n await sleep(this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL - Date.now());\n if (this._ctx.disposed) {\n return;\n }\n }\n\n log('want', { list: this._localWantList });\n await this.rpc.BlobSyncService.want(this._localWantList);\n this._lastWantListUpdate = Date.now();\n });\n\n private _currentUploads = 0;\n\n private readonly _upload = new DeferredTask(this._ctx, async () => {\n if (this._currentUploads >= MAX_CONCURRENT_UPLOADS) {\n return;\n }\n const blobChunks = await this._pickBlobChunks(MAX_CONCURRENT_UPLOADS - this._currentUploads);\n if (!blobChunks) {\n return;\n }\n for (const blobChunk of blobChunks) {\n if (this._ctx.disposed) {\n break;\n }\n\n this._currentUploads++;\n\n this.push(blobChunk)\n .catch((err) => {\n if (err instanceof RpcClosedError) {\n return;\n }\n log.warn('push failed', { err });\n })\n .finally(() => {\n this._currentUploads--;\n this.reconcileUploads();\n });\n }\n });\n\n /**\n * Set of id's remote peer wants.\n */\n public remoteWantList: WantList = { blobs: [] };\n\n constructor(\n private readonly _params: BlobSyncExtensionParams, // to not conflict with the base class\n ) {\n super({\n exposed: {\n BlobSyncService: schema.getService('dxos.mesh.teleport.blobsync.BlobSyncService'),\n },\n requested: {\n BlobSyncService: schema.getService('dxos.mesh.teleport.blobsync.BlobSyncService'),\n },\n timeout: 20_000,\n encodingOptions: {\n preserveAny: true,\n },\n });\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n log('open');\n await super.onOpen(context);\n await this._params.onOpen();\n }\n\n override async onClose(err?: Error | undefined): Promise<void> {\n log('close');\n await this._ctx.dispose();\n await this._params.onClose();\n await super.onClose(err);\n }\n\n override async onAbort(err?: Error | undefined): Promise<void> {\n log('abort');\n await this._ctx.dispose();\n await this._params.onAbort();\n await super.onAbort(err);\n }\n\n protected async getHandlers(): Promise<ServiceBundle> {\n return {\n BlobSyncService: {\n want: async (wantList) => {\n log('remote want', { remoteWantList: wantList });\n this.remoteWantList = wantList;\n this.reconcileUploads();\n },\n push: async (data) => {\n log('received', { data });\n await this._params.onPush(data);\n },\n },\n };\n }\n\n @synchronized\n async push(data: BlobChunk) {\n if (this._ctx.disposed) {\n return;\n }\n log('push', { data });\n await this.rpc.BlobSyncService.push(data);\n }\n\n updateWantList(wantList: WantList) {\n if (this._ctx.disposed) {\n return;\n }\n this._localWantList = wantList;\n this._updateWantList.schedule();\n }\n\n reconcileUploads() {\n if (this._ctx.disposed) {\n return;\n }\n this._upload.schedule();\n }\n\n private async _pickBlobChunks(amount = 1): Promise<BlobChunk[] | void> {\n if (this._ctx.disposed) {\n return;\n }\n\n if (!this.remoteWantList.blobs || this.remoteWantList.blobs?.length === 0) {\n return;\n }\n\n const shuffled = [...this.remoteWantList.blobs].sort(() => Math.random() - 0.5);\n\n const chunks: BlobChunk[] = [];\n\n for (const header of shuffled) {\n const meta = await this._params.blobStore.getMeta(header.id);\n\n if (!meta) {\n // Skip this header\n continue;\n }\n invariant(meta.bitfield);\n invariant(meta.chunkSize);\n invariant(meta.length);\n\n if (header.chunkSize && header.chunkSize !== meta.chunkSize) {\n log.warn('Invalid chunk size', { header, meta });\n continue;\n }\n\n const requestBitfield = header.bitfield ?? BitField.ones(meta.length / meta.chunkSize);\n\n const presentData = BitField.and(requestBitfield, meta.bitfield);\n const chunkIndices = BitField.findIndexes(presentData).sort(() => Math.random() - 0.5);\n\n for (const idx of chunkIndices) {\n const chunkData = await this._params.blobStore.get(header.id, {\n offset: idx * meta.chunkSize,\n length: Math.min(meta.chunkSize, meta.length - idx * meta.chunkSize),\n });\n chunks.push({\n id: header.id,\n totalLength: meta.length,\n chunkSize: meta.chunkSize,\n chunkOffset: idx * meta.chunkSize,\n payload: chunkData,\n });\n\n if (chunks.length >= amount) {\n return chunks;\n }\n }\n }\n\n return chunks;\n }\n}\n\ntype ServiceBundle = {\n BlobSyncService: BlobSyncService;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { trackLeaks, Trigger, Lock } from '@dxos/async';\nimport { cancelWithContext, Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { BlobMeta } from '@dxos/protocols/proto/dxos/echo/blob';\nimport { type WantList } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { BitField, ComplexMap } from '@dxos/util';\n\nimport { type BlobStore } from './blob-store';\nimport { BlobSyncExtension } from './blob-sync-extension';\n\nexport type BlobSyncParams = {\n blobStore: BlobStore;\n};\n\ntype DownloadRequest = {\n trigger: Trigger<void>;\n counter: number;\n want: WantList.Entry;\n};\n\n// TODO(dmaretskyi): Rename to blob-sync.\n@trackLeaks('open', 'close')\nexport class BlobSync {\n private readonly _ctx = new Context();\n private readonly _lock = new Lock();\n\n private readonly _downloadRequests = new ComplexMap<Uint8Array, DownloadRequest>((key) =>\n PublicKey.from(key).toHex(),\n );\n\n private readonly _extensions = new Set<BlobSyncExtension>();\n\n constructor(private readonly _params: BlobSyncParams) {}\n\n async open() {}\n\n async close() {\n await this._ctx.dispose();\n }\n\n /**\n * Resolves when the object with the given id is fully downloaded in the blob store.\n *\n * @param id hex-encoded id of the object to download.\n */\n async download(ctx: Context, id: Uint8Array): Promise<void> {\n log('download', { id });\n const request = await this._lock.executeSynchronized(async () => {\n const existingRequest = this._downloadRequests.get(id);\n\n if (existingRequest) {\n existingRequest.counter++;\n return existingRequest;\n }\n\n const meta = await this._params.blobStore.getMeta(id);\n const request: DownloadRequest = {\n trigger: new Trigger(),\n counter: 1,\n want: {\n id,\n chunkSize: meta?.chunkSize,\n bitfield: meta?.bitfield && Uint8Array.from(BitField.invert(meta.bitfield)),\n },\n };\n\n // Check if the object is already fully downloaded.\n if (meta?.state === BlobMeta.State.FULLY_PRESENT) {\n request.trigger.wake();\n } else {\n this._downloadRequests.set(id, request);\n this._updateExtensionsWantList();\n }\n\n return request;\n });\n\n ctx?.onDispose(() =>\n this._lock.executeSynchronized(async () => {\n // Remove request if context is disposed and nobody else requests it.\n const request = this._downloadRequests.get(id);\n if (!request) {\n return;\n }\n if (--request.counter === 0) {\n this._downloadRequests.delete(id);\n }\n this._updateExtensionsWantList();\n }),\n );\n\n return ctx ? cancelWithContext(ctx, request.trigger.wait()) : request.trigger.wait();\n }\n\n createExtension() {\n const extension = new BlobSyncExtension({\n blobStore: this._params.blobStore,\n onOpen: async () => {\n log('extension opened');\n this._extensions.add(extension);\n extension.updateWantList(this._getWantList());\n },\n onClose: async () => {\n log('extension closed');\n this._extensions.delete(extension);\n },\n onAbort: async () => {\n log('extension aborted');\n this._extensions.delete(extension);\n },\n onPush: async (blobChunk) => {\n if (!this._downloadRequests.has(blobChunk.id)) {\n return;\n }\n log('received', { blobChunk });\n const meta = await this._params.blobStore.setChunk(blobChunk);\n if (meta.state === BlobMeta.State.FULLY_PRESENT) {\n this._downloadRequests.get(blobChunk.id)?.trigger.wake();\n this._downloadRequests.delete(blobChunk.id);\n } else {\n invariant(meta.bitfield);\n this._downloadRequests.get(blobChunk.id)!.want.bitfield = BitField.invert(meta.bitfield);\n }\n\n this._updateExtensionsWantList();\n this._reconcileUploads();\n },\n });\n return extension;\n }\n\n /**\n * Notify extensions that a blob with the given id was added to the blob store.\n */\n async notifyBlobAdded(_id: Uint8Array) {\n this._reconcileUploads();\n }\n\n private _getWantList(): WantList {\n return {\n blobs: Array.from(this._downloadRequests.values()).map((request) => request.want),\n };\n }\n\n private _reconcileUploads() {\n for (const extension of this._extensions) {\n extension.reconcileUploads();\n }\n }\n\n private _updateExtensionsWantList() {\n for (const extension of this._extensions) {\n extension.updateWantList(this._getWantList());\n }\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport path from 'node:path';\n\nimport { synchronized } from '@dxos/async';\nimport { subtleCrypto } from '@dxos/crypto';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { schema } from '@dxos/protocols';\nimport { BlobMeta } from '@dxos/protocols/proto/dxos/echo/blob';\nimport { type BlobChunk } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { type Directory } from '@dxos/random-access-storage';\nimport { BitField, arrayToBuffer } from '@dxos/util';\n\nexport type GetOptions = {\n offset?: number;\n length?: number;\n};\n\nexport const DEFAULT_CHUNK_SIZE = 4096;\n\nconst BlobMetaCodec = schema.getCodecForType('dxos.echo.blob.BlobMeta');\n\nexport class BlobStore {\n constructor(private readonly _directory: Directory) {}\n\n @synchronized\n async getMeta(id: Uint8Array): Promise<BlobMeta | undefined> {\n return this._getMeta(id);\n }\n\n /**\n * @throws If range is not available.\n */\n @synchronized\n async get(id: Uint8Array, options: GetOptions = {}): Promise<Uint8Array> {\n const metadata = await this._getMeta(id);\n\n if (!metadata) {\n throw new Error('Blob not available');\n }\n\n const { offset = 0, length = metadata.length } = options;\n\n if (offset + length > metadata.length) {\n throw new Error('Invalid range');\n }\n\n if (metadata.state === BlobMeta.State.FULLY_PRESENT) {\n const file = this._getDataFile(id);\n return file.read(offset, length);\n } else if (options.offset === undefined && options.length === undefined) {\n throw new Error('Blob not available');\n }\n\n const beginChunk = Math.floor(offset / metadata.chunkSize);\n const endChunk = Math.ceil((offset + length) / metadata.chunkSize);\n\n invariant(metadata.bitfield, 'Bitfield not present');\n invariant(metadata.bitfield.length * 8 >= endChunk, 'Invalid bitfield length');\n\n const present = BitField.count(metadata.bitfield, beginChunk, endChunk) === endChunk - beginChunk;\n\n if (!present) {\n throw new Error('Blob not available');\n }\n\n const file = this._getDataFile(id);\n return file.read(offset, length);\n }\n\n @synchronized\n async list(): Promise<BlobMeta[]> {\n /*\n Weird path formatting:\n\n \"e9b9aa7a21c2c55a9eca333cd59975633157562ca0a0f4f243d4778f192c291e_meta\"\n \"e9b9aa7a21c2c55a9eca333cd59975633157562ca0a0f4f243d4778f192c291e_data\"\n \"5001de5a47191357c075aeee6451c4cc323f3a8ada24dd1191e83403608a38d5_meta\n */\n const files = new Set((await this._directory.list()).map((f) => f.split('_')[0]));\n\n const res: BlobMeta[] = [];\n\n for (const file of files) {\n const id = PublicKey.from(file).asUint8Array();\n const meta = await this._getMeta(id);\n if (meta) {\n res.push(meta);\n }\n }\n\n return res;\n }\n\n @synchronized\n async set(data: Uint8Array): Promise<BlobMeta> {\n const id = new Uint8Array(await subtleCrypto.digest('SHA-256', data));\n const bitfield = BitField.ones(data.length / DEFAULT_CHUNK_SIZE);\n\n const meta: BlobMeta = {\n id,\n state: BlobMeta.State.FULLY_PRESENT,\n length: data.length,\n chunkSize: DEFAULT_CHUNK_SIZE,\n bitfield,\n created: new Date(),\n updated: new Date(),\n };\n\n await this._getDataFile(id).write(0, arrayToBuffer(data));\n await this._writeMeta(id, meta);\n return meta;\n }\n\n // TODO(dmaretskyi): Optimize locking.\n @synchronized\n async setChunk(chunk: BlobChunk): Promise<BlobMeta> {\n // Init metadata.\n let meta = await this._getMeta(chunk.id);\n if (!meta) {\n invariant(chunk.totalLength, 'totalLength is not present');\n meta = {\n id: chunk.id,\n state: BlobMeta.State.PARTIALLY_PRESENT,\n length: chunk.totalLength,\n chunkSize: chunk.chunkSize ?? DEFAULT_CHUNK_SIZE,\n created: new Date(),\n };\n meta.bitfield = BitField.zeros(meta.length / meta.chunkSize);\n }\n\n if (chunk.chunkSize && chunk.chunkSize !== meta.chunkSize) {\n throw new Error('Invalid chunk size');\n }\n\n invariant(meta.bitfield, 'Bitfield not present');\n invariant(chunk.chunkOffset !== undefined, 'chunkOffset is not present');\n\n // Write chunk.\n await this._getDataFile(chunk.id).write(chunk.chunkOffset, arrayToBuffer(chunk.payload));\n\n // Update bitfield.\n BitField.set(meta.bitfield, Math.floor(chunk.chunkOffset / meta.chunkSize), true);\n\n // Update metadata.\n if (BitField.count(meta.bitfield, 0, meta.length) * meta.chunkSize >= meta.length) {\n meta.state = BlobMeta.State.FULLY_PRESENT;\n }\n meta.updated = new Date();\n\n await this._writeMeta(chunk.id, meta);\n\n return meta;\n }\n\n private async _writeMeta(id: Uint8Array, meta: BlobMeta): Promise<void> {\n const encoded = arrayToBuffer(BlobMetaCodec.encode(meta));\n const data = Buffer.alloc(encoded.length + 4);\n data.writeUInt32LE(encoded.length, 0);\n encoded.copy(data, 4);\n\n // Write metadata.\n await this._getMetaFile(id).write(0, data);\n }\n\n private async _getMeta(id: Uint8Array): Promise<BlobMeta | undefined> {\n const file = this._getMetaFile(id);\n const size = (await file.stat()).size;\n if (size === 0) {\n return;\n }\n const data = await file.read(0, size);\n const protoSize = data.readUInt32LE(0);\n return BlobMetaCodec.decode(data.subarray(4, protoSize + 4));\n }\n\n private _getMetaFile(id: Uint8Array) {\n return this._directory.getOrCreateFile(path.join(arrayToBuffer(id).toString('hex'), 'meta'));\n }\n\n private _getDataFile(id: Uint8Array) {\n return this._directory.getOrCreateFile(path.join(arrayToBuffer(id).toString('hex'), 'data'));\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["DeferredTask", "sleep", "synchronized", "Context", "invariant", "log", "RpcClosedError", "schema", "RpcExtension", "BitField", "MIN_WANT_LIST_UPDATE_INTERVAL", "process", "MAX_CONCURRENT_UPLOADS", "BlobSyncExtension", "constructor", "_params", "exposed", "BlobSyncService", "getService", "requested", "timeout", "encodingOptions", "preserveAny", "_ctx", "onError", "err", "catch", "_lastWantListUpdate", "_localWantList", "blobs", "_updateWantList", "Date", "now", "disposed", "list", "rpc", "want", "_currentUploads", "_upload", "blobChunks", "_pickBlobChunks", "blobChunk", "push", "warn", "finally", "reconcileUploads", "remoteWantList", "onOpen", "context", "onClose", "dispose", "onAbort", "getHandlers", "wantList", "data", "onPush", "updateWantList", "schedule", "amount", "length", "shuffled", "sort", "Math", "random", "chunks", "header", "meta", "blobStore", "getMeta", "id", "bitfield", "chunkSize", "requestBitfield", "ones", "presentData", "and", "chunkIndices", "findIndexes", "idx", "chunkData", "get", "offset", "min", "totalLength", "chunkOffset", "payload", "trackLeaks", "Trigger", "Lock", "cancelWithContext", "Context", "invariant", "PublicKey", "log", "BlobMeta", "BitField", "ComplexMap", "BlobSync", "constructor", "_params", "_ctx", "Context", "_lock", "Lock", "_downloadRequests", "ComplexMap", "key", "PublicKey", "from", "toHex", "_extensions", "Set", "open", "close", "dispose", "download", "ctx", "id", "log", "request", "executeSynchronized", "existingRequest", "get", "counter", "meta", "blobStore", "getMeta", "trigger", "Trigger", "want", "chunkSize", "bitfield", "Uint8Array", "BitField", "invert", "state", "BlobMeta", "State", "FULLY_PRESENT", "wake", "set", "_updateExtensionsWantList", "onDispose", "delete", "cancelWithContext", "wait", "createExtension", "extension", "BlobSyncExtension", "onOpen", "add", "updateWantList", "_getWantList", "onClose", "onAbort", "onPush", "blobChunk", "has", "setChunk", "invariant", "_reconcileUploads", "notifyBlobAdded", "_id", "blobs", "Array", "values", "map", "reconcileUploads", "trackLeaks", "path", "synchronized", "subtleCrypto", "invariant", "PublicKey", "schema", "BlobMeta", "BitField", "arrayToBuffer", "DEFAULT_CHUNK_SIZE", "BlobMetaCodec", "getCodecForType", "BlobStore", "constructor", "_directory", "getMeta", "id", "_getMeta", "get", "options", "metadata", "Error", "offset", "length", "state", "State", "FULLY_PRESENT", "file", "_getDataFile", "read", "undefined", "beginChunk", "Math", "floor", "chunkSize", "endChunk", "ceil", "bitfield", "present", "count", "list", "files", "Set", "map", "f", "split", "res", "from", "asUint8Array", "meta", "push", "set", "data", "Uint8Array", "digest", "ones", "created", "Date", "updated", "write", "_writeMeta", "setChunk", "chunk", "totalLength", "PARTIALLY_PRESENT", "zeros", "chunkOffset", "payload", "encoded", "encode", "Buffer", "alloc", "writeUInt32LE", "copy", "_getMetaFile", "size", "stat", "protoSize", "readUInt32LE", "decode", "subarray", "getOrCreateFile", "join", "toString"]
4
+ "sourcesContent": ["//\n\n//\n// Copyright 2023 DXOS.org\n//\n\nimport { DeferredTask, sleep, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { RpcClosedError, schema } from '@dxos/protocols';\nimport { type BlobChunk, type BlobSyncService, type WantList } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\nimport { BitField } from '@dxos/util';\n\nimport { type BlobStore } from './blob-store';\n\nexport type BlobSyncExtensionParams = {\n blobStore: BlobStore;\n onOpen: () => Promise<void>;\n onClose: () => Promise<void>;\n onAbort: () => Promise<void>;\n onPush: (data: BlobChunk) => Promise<void>;\n};\n\nconst MIN_WANT_LIST_UPDATE_INTERVAL = process.env.NODE_ENV === 'test' ? 5 : 500;\n\nconst MAX_CONCURRENT_UPLOADS = 20;\n\n/**\n * Manages replication between a set of feeds for a single teleport session.\n */\nexport class BlobSyncExtension extends RpcExtension<ServiceBundle, ServiceBundle> {\n private readonly _ctx = new Context({ onError: (err) => log.catch(err) });\n\n private _lastWantListUpdate = 0;\n private _localWantList: WantList = { blobs: [] };\n\n private readonly _updateWantList = new DeferredTask(this._ctx, async () => {\n // Throttle want list updates.\n if (this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL > Date.now()) {\n await sleep(this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL - Date.now());\n if (this._ctx.disposed) {\n return;\n }\n }\n\n log('want', { list: this._localWantList });\n await this.rpc.BlobSyncService.want(this._localWantList);\n this._lastWantListUpdate = Date.now();\n });\n\n private _currentUploads = 0;\n\n private readonly _upload = new DeferredTask(this._ctx, async () => {\n if (this._currentUploads >= MAX_CONCURRENT_UPLOADS) {\n return;\n }\n const blobChunks = await this._pickBlobChunks(MAX_CONCURRENT_UPLOADS - this._currentUploads);\n if (!blobChunks) {\n return;\n }\n for (const blobChunk of blobChunks) {\n if (this._ctx.disposed) {\n break;\n }\n\n this._currentUploads++;\n\n this.push(blobChunk)\n .catch((err) => {\n if (err instanceof RpcClosedError) {\n return;\n }\n log.warn('push failed', { err });\n })\n .finally(() => {\n this._currentUploads--;\n this.reconcileUploads();\n });\n }\n });\n\n /**\n * Set of id's remote peer wants.\n */\n public remoteWantList: WantList = { blobs: [] };\n\n constructor(\n private readonly _params: BlobSyncExtensionParams, // to not conflict with the base class\n ) {\n super({\n exposed: {\n BlobSyncService: schema.getService('dxos.mesh.teleport.blobsync.BlobSyncService'),\n },\n requested: {\n BlobSyncService: schema.getService('dxos.mesh.teleport.blobsync.BlobSyncService'),\n },\n timeout: 20_000,\n encodingOptions: {\n preserveAny: true,\n },\n });\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n log('open');\n await super.onOpen(context);\n await this._params.onOpen();\n }\n\n override async onClose(err?: Error | undefined): Promise<void> {\n log('close');\n await this._ctx.dispose();\n await this._params.onClose();\n await super.onClose(err);\n }\n\n override async onAbort(err?: Error | undefined): Promise<void> {\n log('abort');\n await this._ctx.dispose();\n await this._params.onAbort();\n await super.onAbort(err);\n }\n\n protected async getHandlers(): Promise<ServiceBundle> {\n return {\n BlobSyncService: {\n want: async (wantList) => {\n log('remote want', { remoteWantList: wantList });\n this.remoteWantList = wantList;\n this.reconcileUploads();\n },\n push: async (data) => {\n log('received', { data });\n await this._params.onPush(data);\n },\n },\n };\n }\n\n @synchronized\n async push(data: BlobChunk) {\n if (this._ctx.disposed) {\n return;\n }\n log('push', { data });\n await this.rpc.BlobSyncService.push(data);\n }\n\n updateWantList(wantList: WantList) {\n if (this._ctx.disposed) {\n return;\n }\n this._localWantList = wantList;\n this._updateWantList.schedule();\n }\n\n reconcileUploads() {\n if (this._ctx.disposed) {\n return;\n }\n this._upload.schedule();\n }\n\n private async _pickBlobChunks(amount = 1): Promise<BlobChunk[] | void> {\n if (this._ctx.disposed) {\n return;\n }\n\n if (!this.remoteWantList.blobs || this.remoteWantList.blobs?.length === 0) {\n return;\n }\n\n const shuffled = [...this.remoteWantList.blobs].sort(() => Math.random() - 0.5);\n\n const chunks: BlobChunk[] = [];\n\n for (const header of shuffled) {\n const meta = await this._params.blobStore.getMeta(header.id);\n\n if (!meta) {\n // Skip this header\n continue;\n }\n invariant(meta.bitfield);\n invariant(meta.chunkSize);\n invariant(meta.length);\n\n if (header.chunkSize && header.chunkSize !== meta.chunkSize) {\n log.warn('Invalid chunk size', { header, meta });\n continue;\n }\n\n const requestBitfield = header.bitfield ?? BitField.ones(meta.length / meta.chunkSize);\n\n const presentData = BitField.and(requestBitfield, meta.bitfield);\n const chunkIndices = BitField.findIndexes(presentData).sort(() => Math.random() - 0.5);\n\n for (const idx of chunkIndices) {\n const chunkData = await this._params.blobStore.get(header.id, {\n offset: idx * meta.chunkSize,\n length: Math.min(meta.chunkSize, meta.length - idx * meta.chunkSize),\n });\n chunks.push({\n id: header.id,\n totalLength: meta.length,\n chunkSize: meta.chunkSize,\n chunkOffset: idx * meta.chunkSize,\n payload: chunkData,\n });\n\n if (chunks.length >= amount) {\n return chunks;\n }\n }\n }\n\n return chunks;\n }\n}\n\ntype ServiceBundle = {\n BlobSyncService: BlobSyncService;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { trackLeaks, Trigger, Mutex } from '@dxos/async';\nimport { cancelWithContext, Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { BlobMeta } from '@dxos/protocols/proto/dxos/echo/blob';\nimport { type WantList } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { BitField, ComplexMap } from '@dxos/util';\n\nimport { type BlobStore } from './blob-store';\nimport { BlobSyncExtension } from './blob-sync-extension';\n\nexport type BlobSyncParams = {\n blobStore: BlobStore;\n};\n\ntype DownloadRequest = {\n trigger: Trigger<void>;\n counter: number;\n want: WantList.Entry;\n};\n\n// TODO(dmaretskyi): Rename to blob-sync.\n@trackLeaks('open', 'close')\nexport class BlobSync {\n private readonly _ctx = new Context();\n private readonly _mutex = new Mutex();\n\n private readonly _downloadRequests = new ComplexMap<Uint8Array, DownloadRequest>((key) =>\n PublicKey.from(key).toHex(),\n );\n\n private readonly _extensions = new Set<BlobSyncExtension>();\n\n constructor(private readonly _params: BlobSyncParams) {}\n\n async open() {}\n\n async close() {\n await this._ctx.dispose();\n }\n\n /**\n * Resolves when the object with the given id is fully downloaded in the blob store.\n *\n * @param id hex-encoded id of the object to download.\n */\n async download(ctx: Context, id: Uint8Array): Promise<void> {\n log('download', { id });\n const request = await this._mutex.executeSynchronized(async () => {\n const existingRequest = this._downloadRequests.get(id);\n\n if (existingRequest) {\n existingRequest.counter++;\n return existingRequest;\n }\n\n const meta = await this._params.blobStore.getMeta(id);\n const request: DownloadRequest = {\n trigger: new Trigger(),\n counter: 1,\n want: {\n id,\n chunkSize: meta?.chunkSize,\n bitfield: meta?.bitfield && Uint8Array.from(BitField.invert(meta.bitfield)),\n },\n };\n\n // Check if the object is already fully downloaded.\n if (meta?.state === BlobMeta.State.FULLY_PRESENT) {\n request.trigger.wake();\n } else {\n this._downloadRequests.set(id, request);\n this._updateExtensionsWantList();\n }\n\n return request;\n });\n\n ctx?.onDispose(() =>\n this._mutex.executeSynchronized(async () => {\n // Remove request if context is disposed and nobody else requests it.\n const request = this._downloadRequests.get(id);\n if (!request) {\n return;\n }\n if (--request.counter === 0) {\n this._downloadRequests.delete(id);\n }\n this._updateExtensionsWantList();\n }),\n );\n\n return ctx ? cancelWithContext(ctx, request.trigger.wait()) : request.trigger.wait();\n }\n\n createExtension() {\n const extension = new BlobSyncExtension({\n blobStore: this._params.blobStore,\n onOpen: async () => {\n log('extension opened');\n this._extensions.add(extension);\n extension.updateWantList(this._getWantList());\n },\n onClose: async () => {\n log('extension closed');\n this._extensions.delete(extension);\n },\n onAbort: async () => {\n log('extension aborted');\n this._extensions.delete(extension);\n },\n onPush: async (blobChunk) => {\n if (!this._downloadRequests.has(blobChunk.id)) {\n return;\n }\n log('received', { blobChunk });\n const meta = await this._params.blobStore.setChunk(blobChunk);\n if (meta.state === BlobMeta.State.FULLY_PRESENT) {\n this._downloadRequests.get(blobChunk.id)?.trigger.wake();\n this._downloadRequests.delete(blobChunk.id);\n } else {\n invariant(meta.bitfield);\n this._downloadRequests.get(blobChunk.id)!.want.bitfield = BitField.invert(meta.bitfield);\n }\n\n this._updateExtensionsWantList();\n this._reconcileUploads();\n },\n });\n return extension;\n }\n\n /**\n * Notify extensions that a blob with the given id was added to the blob store.\n */\n async notifyBlobAdded(_id: Uint8Array) {\n this._reconcileUploads();\n }\n\n private _getWantList(): WantList {\n return {\n blobs: Array.from(this._downloadRequests.values()).map((request) => request.want),\n };\n }\n\n private _reconcileUploads() {\n for (const extension of this._extensions) {\n extension.reconcileUploads();\n }\n }\n\n private _updateExtensionsWantList() {\n for (const extension of this._extensions) {\n extension.updateWantList(this._getWantList());\n }\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport path from 'node:path';\n\nimport { synchronized } from '@dxos/async';\nimport { subtleCrypto } from '@dxos/crypto';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { schema } from '@dxos/protocols';\nimport { BlobMeta } from '@dxos/protocols/proto/dxos/echo/blob';\nimport { type BlobChunk } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { type Directory } from '@dxos/random-access-storage';\nimport { BitField, arrayToBuffer } from '@dxos/util';\n\nexport type GetOptions = {\n offset?: number;\n length?: number;\n};\n\nexport const DEFAULT_CHUNK_SIZE = 4096;\n\nconst BlobMetaCodec = schema.getCodecForType('dxos.echo.blob.BlobMeta');\n\nexport class BlobStore {\n constructor(private readonly _directory: Directory) {}\n\n @synchronized\n async getMeta(id: Uint8Array): Promise<BlobMeta | undefined> {\n return this._getMeta(id);\n }\n\n /**\n * @throws If range is not available.\n */\n @synchronized\n async get(id: Uint8Array, options: GetOptions = {}): Promise<Uint8Array> {\n const metadata = await this._getMeta(id);\n\n if (!metadata) {\n throw new Error('Blob not available');\n }\n\n const { offset = 0, length = metadata.length } = options;\n\n if (offset + length > metadata.length) {\n throw new Error('Invalid range');\n }\n\n if (metadata.state === BlobMeta.State.FULLY_PRESENT) {\n const file = this._getDataFile(id);\n return file.read(offset, length);\n } else if (options.offset === undefined && options.length === undefined) {\n throw new Error('Blob not available');\n }\n\n const beginChunk = Math.floor(offset / metadata.chunkSize);\n const endChunk = Math.ceil((offset + length) / metadata.chunkSize);\n\n invariant(metadata.bitfield, 'Bitfield not present');\n invariant(metadata.bitfield.length * 8 >= endChunk, 'Invalid bitfield length');\n\n const present = BitField.count(metadata.bitfield, beginChunk, endChunk) === endChunk - beginChunk;\n\n if (!present) {\n throw new Error('Blob not available');\n }\n\n const file = this._getDataFile(id);\n return file.read(offset, length);\n }\n\n @synchronized\n async list(): Promise<BlobMeta[]> {\n /*\n Weird path formatting:\n\n \"e9b9aa7a21c2c55a9eca333cd59975633157562ca0a0f4f243d4778f192c291e_meta\"\n \"e9b9aa7a21c2c55a9eca333cd59975633157562ca0a0f4f243d4778f192c291e_data\"\n \"5001de5a47191357c075aeee6451c4cc323f3a8ada24dd1191e83403608a38d5_meta\n */\n const files = new Set((await this._directory.list()).map((f) => f.split('_')[0]));\n\n const res: BlobMeta[] = [];\n\n for (const file of files) {\n const id = PublicKey.from(file).asUint8Array();\n const meta = await this._getMeta(id);\n if (meta) {\n res.push(meta);\n }\n }\n\n return res;\n }\n\n @synchronized\n async set(data: Uint8Array): Promise<BlobMeta> {\n const id = new Uint8Array(await subtleCrypto.digest('SHA-256', data));\n const bitfield = BitField.ones(data.length / DEFAULT_CHUNK_SIZE);\n\n const meta: BlobMeta = {\n id,\n state: BlobMeta.State.FULLY_PRESENT,\n length: data.length,\n chunkSize: DEFAULT_CHUNK_SIZE,\n bitfield,\n created: new Date(),\n updated: new Date(),\n };\n\n await this._getDataFile(id).write(0, arrayToBuffer(data));\n await this._writeMeta(id, meta);\n return meta;\n }\n\n // TODO(dmaretskyi): Optimize locking.\n @synchronized\n async setChunk(chunk: BlobChunk): Promise<BlobMeta> {\n // Init metadata.\n let meta = await this._getMeta(chunk.id);\n if (!meta) {\n invariant(chunk.totalLength, 'totalLength is not present');\n meta = {\n id: chunk.id,\n state: BlobMeta.State.PARTIALLY_PRESENT,\n length: chunk.totalLength,\n chunkSize: chunk.chunkSize ?? DEFAULT_CHUNK_SIZE,\n created: new Date(),\n };\n meta.bitfield = BitField.zeros(meta.length / meta.chunkSize);\n }\n\n if (chunk.chunkSize && chunk.chunkSize !== meta.chunkSize) {\n throw new Error('Invalid chunk size');\n }\n\n invariant(meta.bitfield, 'Bitfield not present');\n invariant(chunk.chunkOffset !== undefined, 'chunkOffset is not present');\n\n // Write chunk.\n await this._getDataFile(chunk.id).write(chunk.chunkOffset, arrayToBuffer(chunk.payload));\n\n // Update bitfield.\n BitField.set(meta.bitfield, Math.floor(chunk.chunkOffset / meta.chunkSize), true);\n\n // Update metadata.\n if (BitField.count(meta.bitfield, 0, meta.length) * meta.chunkSize >= meta.length) {\n meta.state = BlobMeta.State.FULLY_PRESENT;\n }\n meta.updated = new Date();\n\n await this._writeMeta(chunk.id, meta);\n\n return meta;\n }\n\n private async _writeMeta(id: Uint8Array, meta: BlobMeta): Promise<void> {\n const encoded = arrayToBuffer(BlobMetaCodec.encode(meta));\n const data = Buffer.alloc(encoded.length + 4);\n data.writeUInt32LE(encoded.length, 0);\n encoded.copy(data, 4);\n\n // Write metadata.\n await this._getMetaFile(id).write(0, data);\n }\n\n private async _getMeta(id: Uint8Array): Promise<BlobMeta | undefined> {\n const file = this._getMetaFile(id);\n const size = (await file.stat()).size;\n if (size === 0) {\n return;\n }\n const data = await file.read(0, size);\n const protoSize = data.readUInt32LE(0);\n return BlobMetaCodec.decode(data.subarray(4, protoSize + 4));\n }\n\n private _getMetaFile(id: Uint8Array) {\n return this._directory.getOrCreateFile(path.join(arrayToBuffer(id).toString('hex'), 'meta'));\n }\n\n private _getDataFile(id: Uint8Array) {\n return this._directory.getOrCreateFile(path.join(arrayToBuffer(id).toString('hex'), 'data'));\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["DeferredTask", "sleep", "synchronized", "Context", "invariant", "log", "RpcClosedError", "schema", "RpcExtension", "BitField", "MIN_WANT_LIST_UPDATE_INTERVAL", "process", "MAX_CONCURRENT_UPLOADS", "BlobSyncExtension", "constructor", "_params", "exposed", "BlobSyncService", "getService", "requested", "timeout", "encodingOptions", "preserveAny", "_ctx", "onError", "err", "catch", "_lastWantListUpdate", "_localWantList", "blobs", "_updateWantList", "Date", "now", "disposed", "list", "rpc", "want", "_currentUploads", "_upload", "blobChunks", "_pickBlobChunks", "blobChunk", "push", "warn", "finally", "reconcileUploads", "remoteWantList", "onOpen", "context", "onClose", "dispose", "onAbort", "getHandlers", "wantList", "data", "onPush", "updateWantList", "schedule", "amount", "length", "shuffled", "sort", "Math", "random", "chunks", "header", "meta", "blobStore", "getMeta", "id", "bitfield", "chunkSize", "requestBitfield", "ones", "presentData", "and", "chunkIndices", "findIndexes", "idx", "chunkData", "get", "offset", "min", "totalLength", "chunkOffset", "payload", "trackLeaks", "Trigger", "Mutex", "cancelWithContext", "Context", "invariant", "PublicKey", "log", "BlobMeta", "BitField", "ComplexMap", "BlobSync", "constructor", "_params", "_ctx", "Context", "_mutex", "Mutex", "_downloadRequests", "ComplexMap", "key", "PublicKey", "from", "toHex", "_extensions", "Set", "open", "close", "dispose", "download", "ctx", "id", "log", "request", "executeSynchronized", "existingRequest", "get", "counter", "meta", "blobStore", "getMeta", "trigger", "Trigger", "want", "chunkSize", "bitfield", "Uint8Array", "BitField", "invert", "state", "BlobMeta", "State", "FULLY_PRESENT", "wake", "set", "_updateExtensionsWantList", "onDispose", "delete", "cancelWithContext", "wait", "createExtension", "extension", "BlobSyncExtension", "onOpen", "add", "updateWantList", "_getWantList", "onClose", "onAbort", "onPush", "blobChunk", "has", "setChunk", "invariant", "_reconcileUploads", "notifyBlobAdded", "_id", "blobs", "Array", "values", "map", "reconcileUploads", "trackLeaks", "path", "synchronized", "subtleCrypto", "invariant", "PublicKey", "schema", "BlobMeta", "BitField", "arrayToBuffer", "DEFAULT_CHUNK_SIZE", "BlobMetaCodec", "getCodecForType", "BlobStore", "constructor", "_directory", "getMeta", "id", "_getMeta", "get", "options", "metadata", "Error", "offset", "length", "state", "State", "FULLY_PRESENT", "file", "_getDataFile", "read", "undefined", "beginChunk", "Math", "floor", "chunkSize", "endChunk", "ceil", "bitfield", "present", "count", "list", "files", "Set", "map", "f", "split", "res", "from", "asUint8Array", "meta", "push", "set", "data", "Uint8Array", "digest", "ones", "created", "Date", "updated", "write", "_writeMeta", "setChunk", "chunk", "totalLength", "PARTIALLY_PRESENT", "zeros", "chunkOffset", "payload", "encoded", "encode", "Buffer", "alloc", "writeUInt32LE", "copy", "_getMetaFile", "size", "stat", "protoSize", "readUInt32LE", "decode", "subarray", "getOrCreateFile", "join", "toString"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"inject-globals:@inject-globals":{"bytes":384,"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytes":25198,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/teleport","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts":{"bytes":18393,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","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/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts","kind":"import-statement","original":"./blob-sync-extension"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts":{"bytes":22281,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/crypto","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/index.ts":{"bytes":703,"imports":[{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts","kind":"import-statement","original":"./blob-sync-extension"},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts","kind":"import-statement","original":"./blob-sync"},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts","kind":"import-statement","original":"./blob-store"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"packages/core/mesh/teleport-extension-object-sync/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":30513},"packages/core/mesh/teleport-extension-object-sync/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/teleport","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","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/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/crypto","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["BlobStore","BlobSync","BlobSyncExtension","DEFAULT_CHUNK_SIZE"],"entryPoint":"packages/core/mesh/teleport-extension-object-sync/src/index.ts","inputs":{"inject-globals:@inject-globals":{"bytesInOutput":79},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytesInOutput":7357},"packages/core/mesh/teleport-extension-object-sync/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts":{"bytesInOutput":5410},"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts":{"bytesInOutput":6547}},"bytes":19799}}}
1
+ {"inputs":{"inject-globals:@inject-globals":{"bytes":384,"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytes":25214,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/teleport","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts":{"bytes":18411,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","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/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts","kind":"import-statement","original":"./blob-sync-extension"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts":{"bytes":22289,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/crypto","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/index.ts":{"bytes":703,"imports":[{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts","kind":"import-statement","original":"./blob-sync-extension"},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts","kind":"import-statement","original":"./blob-sync"},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts","kind":"import-statement","original":"./blob-store"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"packages/core/mesh/teleport-extension-object-sync/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":30531},"packages/core/mesh/teleport-extension-object-sync/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/teleport","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","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/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/crypto","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["BlobStore","BlobSync","BlobSyncExtension","DEFAULT_CHUNK_SIZE"],"entryPoint":"packages/core/mesh/teleport-extension-object-sync/src/index.ts","inputs":{"inject-globals:@inject-globals":{"bytesInOutput":79},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytesInOutput":7357},"packages/core/mesh/teleport-extension-object-sync/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts":{"bytesInOutput":5405},"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts":{"bytesInOutput":6547}},"bytes":19794}}}
@@ -330,11 +330,11 @@ function _ts_decorate2(decorators, target, key, desc) {
330
330
  return c > 3 && r && Object.defineProperty(target, key, r), r;
331
331
  }
332
332
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts";
333
- var BlobSync = class BlobSync2 {
333
+ var BlobSync = class {
334
334
  constructor(_params) {
335
335
  this._params = _params;
336
336
  this._ctx = new import_context2.Context();
337
- this._lock = new import_async2.Lock();
337
+ this._mutex = new import_async2.Mutex();
338
338
  this._downloadRequests = new import_util2.ComplexMap((key) => import_keys.PublicKey.from(key).toHex());
339
339
  this._extensions = /* @__PURE__ */ new Set();
340
340
  }
@@ -357,7 +357,7 @@ var BlobSync = class BlobSync2 {
357
357
  S: this,
358
358
  C: (f, a) => f(...a)
359
359
  });
360
- const request = await this._lock.executeSynchronized(async () => {
360
+ const request = await this._mutex.executeSynchronized(async () => {
361
361
  const existingRequest = this._downloadRequests.get(id);
362
362
  if (existingRequest) {
363
363
  existingRequest.counter++;
@@ -381,7 +381,7 @@ var BlobSync = class BlobSync2 {
381
381
  }
382
382
  return request2;
383
383
  });
384
- ctx?.onDispose(() => this._lock.executeSynchronized(async () => {
384
+ ctx?.onDispose(() => this._mutex.executeSynchronized(async () => {
385
385
  const request2 = this._downloadRequests.get(id);
386
386
  if (!request2) {
387
387
  return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/blob-sync-extension.ts", "../../../src/blob-sync.ts", "../../../src/blob-store.ts"],
4
- "sourcesContent": ["//\n\n//\n// Copyright 2023 DXOS.org\n//\n\nimport { DeferredTask, sleep, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { RpcClosedError, schema } from '@dxos/protocols';\nimport { type BlobChunk, type BlobSyncService, type WantList } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\nimport { BitField } from '@dxos/util';\n\nimport { type BlobStore } from './blob-store';\n\nexport type BlobSyncExtensionParams = {\n blobStore: BlobStore;\n onOpen: () => Promise<void>;\n onClose: () => Promise<void>;\n onAbort: () => Promise<void>;\n onPush: (data: BlobChunk) => Promise<void>;\n};\n\nconst MIN_WANT_LIST_UPDATE_INTERVAL = process.env.NODE_ENV === 'test' ? 5 : 500;\n\nconst MAX_CONCURRENT_UPLOADS = 20;\n\n/**\n * Manages replication between a set of feeds for a single teleport session.\n */\nexport class BlobSyncExtension extends RpcExtension<ServiceBundle, ServiceBundle> {\n private readonly _ctx = new Context({ onError: (err) => log.catch(err) });\n\n private _lastWantListUpdate = 0;\n private _localWantList: WantList = { blobs: [] };\n\n private readonly _updateWantList = new DeferredTask(this._ctx, async () => {\n // Throttle want list updates.\n if (this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL > Date.now()) {\n await sleep(this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL - Date.now());\n if (this._ctx.disposed) {\n return;\n }\n }\n\n log('want', { list: this._localWantList });\n await this.rpc.BlobSyncService.want(this._localWantList);\n this._lastWantListUpdate = Date.now();\n });\n\n private _currentUploads = 0;\n\n private readonly _upload = new DeferredTask(this._ctx, async () => {\n if (this._currentUploads >= MAX_CONCURRENT_UPLOADS) {\n return;\n }\n const blobChunks = await this._pickBlobChunks(MAX_CONCURRENT_UPLOADS - this._currentUploads);\n if (!blobChunks) {\n return;\n }\n for (const blobChunk of blobChunks) {\n if (this._ctx.disposed) {\n break;\n }\n\n this._currentUploads++;\n\n this.push(blobChunk)\n .catch((err) => {\n if (err instanceof RpcClosedError) {\n return;\n }\n log.warn('push failed', { err });\n })\n .finally(() => {\n this._currentUploads--;\n this.reconcileUploads();\n });\n }\n });\n\n /**\n * Set of id's remote peer wants.\n */\n public remoteWantList: WantList = { blobs: [] };\n\n constructor(\n private readonly _params: BlobSyncExtensionParams, // to not conflict with the base class\n ) {\n super({\n exposed: {\n BlobSyncService: schema.getService('dxos.mesh.teleport.blobsync.BlobSyncService'),\n },\n requested: {\n BlobSyncService: schema.getService('dxos.mesh.teleport.blobsync.BlobSyncService'),\n },\n timeout: 20_000,\n encodingOptions: {\n preserveAny: true,\n },\n });\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n log('open');\n await super.onOpen(context);\n await this._params.onOpen();\n }\n\n override async onClose(err?: Error | undefined): Promise<void> {\n log('close');\n await this._ctx.dispose();\n await this._params.onClose();\n await super.onClose(err);\n }\n\n override async onAbort(err?: Error | undefined): Promise<void> {\n log('abort');\n await this._ctx.dispose();\n await this._params.onAbort();\n await super.onAbort(err);\n }\n\n protected async getHandlers(): Promise<ServiceBundle> {\n return {\n BlobSyncService: {\n want: async (wantList) => {\n log('remote want', { remoteWantList: wantList });\n this.remoteWantList = wantList;\n this.reconcileUploads();\n },\n push: async (data) => {\n log('received', { data });\n await this._params.onPush(data);\n },\n },\n };\n }\n\n @synchronized\n async push(data: BlobChunk) {\n if (this._ctx.disposed) {\n return;\n }\n log('push', { data });\n await this.rpc.BlobSyncService.push(data);\n }\n\n updateWantList(wantList: WantList) {\n if (this._ctx.disposed) {\n return;\n }\n this._localWantList = wantList;\n this._updateWantList.schedule();\n }\n\n reconcileUploads() {\n if (this._ctx.disposed) {\n return;\n }\n this._upload.schedule();\n }\n\n private async _pickBlobChunks(amount = 1): Promise<BlobChunk[] | void> {\n if (this._ctx.disposed) {\n return;\n }\n\n if (!this.remoteWantList.blobs || this.remoteWantList.blobs?.length === 0) {\n return;\n }\n\n const shuffled = [...this.remoteWantList.blobs].sort(() => Math.random() - 0.5);\n\n const chunks: BlobChunk[] = [];\n\n for (const header of shuffled) {\n const meta = await this._params.blobStore.getMeta(header.id);\n\n if (!meta) {\n // Skip this header\n continue;\n }\n invariant(meta.bitfield);\n invariant(meta.chunkSize);\n invariant(meta.length);\n\n if (header.chunkSize && header.chunkSize !== meta.chunkSize) {\n log.warn('Invalid chunk size', { header, meta });\n continue;\n }\n\n const requestBitfield = header.bitfield ?? BitField.ones(meta.length / meta.chunkSize);\n\n const presentData = BitField.and(requestBitfield, meta.bitfield);\n const chunkIndices = BitField.findIndexes(presentData).sort(() => Math.random() - 0.5);\n\n for (const idx of chunkIndices) {\n const chunkData = await this._params.blobStore.get(header.id, {\n offset: idx * meta.chunkSize,\n length: Math.min(meta.chunkSize, meta.length - idx * meta.chunkSize),\n });\n chunks.push({\n id: header.id,\n totalLength: meta.length,\n chunkSize: meta.chunkSize,\n chunkOffset: idx * meta.chunkSize,\n payload: chunkData,\n });\n\n if (chunks.length >= amount) {\n return chunks;\n }\n }\n }\n\n return chunks;\n }\n}\n\ntype ServiceBundle = {\n BlobSyncService: BlobSyncService;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { trackLeaks, Trigger, Lock } from '@dxos/async';\nimport { cancelWithContext, Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { BlobMeta } from '@dxos/protocols/proto/dxos/echo/blob';\nimport { type WantList } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { BitField, ComplexMap } from '@dxos/util';\n\nimport { type BlobStore } from './blob-store';\nimport { BlobSyncExtension } from './blob-sync-extension';\n\nexport type BlobSyncParams = {\n blobStore: BlobStore;\n};\n\ntype DownloadRequest = {\n trigger: Trigger<void>;\n counter: number;\n want: WantList.Entry;\n};\n\n// TODO(dmaretskyi): Rename to blob-sync.\n@trackLeaks('open', 'close')\nexport class BlobSync {\n private readonly _ctx = new Context();\n private readonly _lock = new Lock();\n\n private readonly _downloadRequests = new ComplexMap<Uint8Array, DownloadRequest>((key) =>\n PublicKey.from(key).toHex(),\n );\n\n private readonly _extensions = new Set<BlobSyncExtension>();\n\n constructor(private readonly _params: BlobSyncParams) {}\n\n async open() {}\n\n async close() {\n await this._ctx.dispose();\n }\n\n /**\n * Resolves when the object with the given id is fully downloaded in the blob store.\n *\n * @param id hex-encoded id of the object to download.\n */\n async download(ctx: Context, id: Uint8Array): Promise<void> {\n log('download', { id });\n const request = await this._lock.executeSynchronized(async () => {\n const existingRequest = this._downloadRequests.get(id);\n\n if (existingRequest) {\n existingRequest.counter++;\n return existingRequest;\n }\n\n const meta = await this._params.blobStore.getMeta(id);\n const request: DownloadRequest = {\n trigger: new Trigger(),\n counter: 1,\n want: {\n id,\n chunkSize: meta?.chunkSize,\n bitfield: meta?.bitfield && Uint8Array.from(BitField.invert(meta.bitfield)),\n },\n };\n\n // Check if the object is already fully downloaded.\n if (meta?.state === BlobMeta.State.FULLY_PRESENT) {\n request.trigger.wake();\n } else {\n this._downloadRequests.set(id, request);\n this._updateExtensionsWantList();\n }\n\n return request;\n });\n\n ctx?.onDispose(() =>\n this._lock.executeSynchronized(async () => {\n // Remove request if context is disposed and nobody else requests it.\n const request = this._downloadRequests.get(id);\n if (!request) {\n return;\n }\n if (--request.counter === 0) {\n this._downloadRequests.delete(id);\n }\n this._updateExtensionsWantList();\n }),\n );\n\n return ctx ? cancelWithContext(ctx, request.trigger.wait()) : request.trigger.wait();\n }\n\n createExtension() {\n const extension = new BlobSyncExtension({\n blobStore: this._params.blobStore,\n onOpen: async () => {\n log('extension opened');\n this._extensions.add(extension);\n extension.updateWantList(this._getWantList());\n },\n onClose: async () => {\n log('extension closed');\n this._extensions.delete(extension);\n },\n onAbort: async () => {\n log('extension aborted');\n this._extensions.delete(extension);\n },\n onPush: async (blobChunk) => {\n if (!this._downloadRequests.has(blobChunk.id)) {\n return;\n }\n log('received', { blobChunk });\n const meta = await this._params.blobStore.setChunk(blobChunk);\n if (meta.state === BlobMeta.State.FULLY_PRESENT) {\n this._downloadRequests.get(blobChunk.id)?.trigger.wake();\n this._downloadRequests.delete(blobChunk.id);\n } else {\n invariant(meta.bitfield);\n this._downloadRequests.get(blobChunk.id)!.want.bitfield = BitField.invert(meta.bitfield);\n }\n\n this._updateExtensionsWantList();\n this._reconcileUploads();\n },\n });\n return extension;\n }\n\n /**\n * Notify extensions that a blob with the given id was added to the blob store.\n */\n async notifyBlobAdded(_id: Uint8Array) {\n this._reconcileUploads();\n }\n\n private _getWantList(): WantList {\n return {\n blobs: Array.from(this._downloadRequests.values()).map((request) => request.want),\n };\n }\n\n private _reconcileUploads() {\n for (const extension of this._extensions) {\n extension.reconcileUploads();\n }\n }\n\n private _updateExtensionsWantList() {\n for (const extension of this._extensions) {\n extension.updateWantList(this._getWantList());\n }\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport path from 'node:path';\n\nimport { synchronized } from '@dxos/async';\nimport { subtleCrypto } from '@dxos/crypto';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { schema } from '@dxos/protocols';\nimport { BlobMeta } from '@dxos/protocols/proto/dxos/echo/blob';\nimport { type BlobChunk } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { type Directory } from '@dxos/random-access-storage';\nimport { BitField, arrayToBuffer } from '@dxos/util';\n\nexport type GetOptions = {\n offset?: number;\n length?: number;\n};\n\nexport const DEFAULT_CHUNK_SIZE = 4096;\n\nconst BlobMetaCodec = schema.getCodecForType('dxos.echo.blob.BlobMeta');\n\nexport class BlobStore {\n constructor(private readonly _directory: Directory) {}\n\n @synchronized\n async getMeta(id: Uint8Array): Promise<BlobMeta | undefined> {\n return this._getMeta(id);\n }\n\n /**\n * @throws If range is not available.\n */\n @synchronized\n async get(id: Uint8Array, options: GetOptions = {}): Promise<Uint8Array> {\n const metadata = await this._getMeta(id);\n\n if (!metadata) {\n throw new Error('Blob not available');\n }\n\n const { offset = 0, length = metadata.length } = options;\n\n if (offset + length > metadata.length) {\n throw new Error('Invalid range');\n }\n\n if (metadata.state === BlobMeta.State.FULLY_PRESENT) {\n const file = this._getDataFile(id);\n return file.read(offset, length);\n } else if (options.offset === undefined && options.length === undefined) {\n throw new Error('Blob not available');\n }\n\n const beginChunk = Math.floor(offset / metadata.chunkSize);\n const endChunk = Math.ceil((offset + length) / metadata.chunkSize);\n\n invariant(metadata.bitfield, 'Bitfield not present');\n invariant(metadata.bitfield.length * 8 >= endChunk, 'Invalid bitfield length');\n\n const present = BitField.count(metadata.bitfield, beginChunk, endChunk) === endChunk - beginChunk;\n\n if (!present) {\n throw new Error('Blob not available');\n }\n\n const file = this._getDataFile(id);\n return file.read(offset, length);\n }\n\n @synchronized\n async list(): Promise<BlobMeta[]> {\n /*\n Weird path formatting:\n\n \"e9b9aa7a21c2c55a9eca333cd59975633157562ca0a0f4f243d4778f192c291e_meta\"\n \"e9b9aa7a21c2c55a9eca333cd59975633157562ca0a0f4f243d4778f192c291e_data\"\n \"5001de5a47191357c075aeee6451c4cc323f3a8ada24dd1191e83403608a38d5_meta\n */\n const files = new Set((await this._directory.list()).map((f) => f.split('_')[0]));\n\n const res: BlobMeta[] = [];\n\n for (const file of files) {\n const id = PublicKey.from(file).asUint8Array();\n const meta = await this._getMeta(id);\n if (meta) {\n res.push(meta);\n }\n }\n\n return res;\n }\n\n @synchronized\n async set(data: Uint8Array): Promise<BlobMeta> {\n const id = new Uint8Array(await subtleCrypto.digest('SHA-256', data));\n const bitfield = BitField.ones(data.length / DEFAULT_CHUNK_SIZE);\n\n const meta: BlobMeta = {\n id,\n state: BlobMeta.State.FULLY_PRESENT,\n length: data.length,\n chunkSize: DEFAULT_CHUNK_SIZE,\n bitfield,\n created: new Date(),\n updated: new Date(),\n };\n\n await this._getDataFile(id).write(0, arrayToBuffer(data));\n await this._writeMeta(id, meta);\n return meta;\n }\n\n // TODO(dmaretskyi): Optimize locking.\n @synchronized\n async setChunk(chunk: BlobChunk): Promise<BlobMeta> {\n // Init metadata.\n let meta = await this._getMeta(chunk.id);\n if (!meta) {\n invariant(chunk.totalLength, 'totalLength is not present');\n meta = {\n id: chunk.id,\n state: BlobMeta.State.PARTIALLY_PRESENT,\n length: chunk.totalLength,\n chunkSize: chunk.chunkSize ?? DEFAULT_CHUNK_SIZE,\n created: new Date(),\n };\n meta.bitfield = BitField.zeros(meta.length / meta.chunkSize);\n }\n\n if (chunk.chunkSize && chunk.chunkSize !== meta.chunkSize) {\n throw new Error('Invalid chunk size');\n }\n\n invariant(meta.bitfield, 'Bitfield not present');\n invariant(chunk.chunkOffset !== undefined, 'chunkOffset is not present');\n\n // Write chunk.\n await this._getDataFile(chunk.id).write(chunk.chunkOffset, arrayToBuffer(chunk.payload));\n\n // Update bitfield.\n BitField.set(meta.bitfield, Math.floor(chunk.chunkOffset / meta.chunkSize), true);\n\n // Update metadata.\n if (BitField.count(meta.bitfield, 0, meta.length) * meta.chunkSize >= meta.length) {\n meta.state = BlobMeta.State.FULLY_PRESENT;\n }\n meta.updated = new Date();\n\n await this._writeMeta(chunk.id, meta);\n\n return meta;\n }\n\n private async _writeMeta(id: Uint8Array, meta: BlobMeta): Promise<void> {\n const encoded = arrayToBuffer(BlobMetaCodec.encode(meta));\n const data = Buffer.alloc(encoded.length + 4);\n data.writeUInt32LE(encoded.length, 0);\n encoded.copy(data, 4);\n\n // Write metadata.\n await this._getMetaFile(id).write(0, data);\n }\n\n private async _getMeta(id: Uint8Array): Promise<BlobMeta | undefined> {\n const file = this._getMetaFile(id);\n const size = (await file.stat()).size;\n if (size === 0) {\n return;\n }\n const data = await file.read(0, size);\n const protoSize = data.readUInt32LE(0);\n return BlobMetaCodec.decode(data.subarray(4, protoSize + 4));\n }\n\n private _getMetaFile(id: Uint8Array) {\n return this._directory.getOrCreateFile(path.join(arrayToBuffer(id).toString('hex'), 'meta'));\n }\n\n private _getDataFile(id: Uint8Array) {\n return this._directory.getOrCreateFile(path.join(arrayToBuffer(id).toString('hex'), 'data'));\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_async", "import_context", "import_invariant", "import_log", "import_util", "import_keys", "import_protocols", "import_blob", "MIN_WANT_LIST_UPDATE_INTERVAL", "process", "env", "NODE_ENV", "MAX_CONCURRENT_UPLOADS", "BlobSyncExtension", "RpcExtension", "constructor", "_params", "exposed", "BlobSyncService", "schema", "getService", "requested", "timeout", "encodingOptions", "preserveAny", "_ctx", "Context", "onError", "err", "log", "catch", "_lastWantListUpdate", "_localWantList", "blobs", "_updateWantList", "DeferredTask", "Date", "now", "sleep", "disposed", "list", "rpc", "want", "_currentUploads", "_upload", "blobChunks", "_pickBlobChunks", "blobChunk", "push", "RpcClosedError", "warn", "finally", "reconcileUploads", "remoteWantList", "onOpen", "context", "onClose", "dispose", "onAbort", "getHandlers", "wantList", "data", "onPush", "updateWantList", "schedule", "amount", "length", "shuffled", "sort", "Math", "random", "chunks", "header", "meta", "blobStore", "getMeta", "id", "invariant", "bitfield", "chunkSize", "requestBitfield", "BitField", "ones", "presentData", "and", "chunkIndices", "findIndexes", "idx", "chunkData", "get", "offset", "min", "totalLength", "chunkOffset", "payload", "synchronized", "BlobSync", "_lock", "Lock", "_downloadRequests", "ComplexMap", "key", "PublicKey", "from", "toHex", "_extensions", "Set", "open", "close", "download", "ctx", "request", "executeSynchronized", "existingRequest", "counter", "trigger", "Trigger", "Uint8Array", "invert", "state", "BlobMeta", "State", "FULLY_PRESENT", "wake", "set", "_updateExtensionsWantList", "onDispose", "delete", "cancelWithContext", "wait", "createExtension", "extension", "add", "_getWantList", "has", "setChunk", "_reconcileUploads", "notifyBlobAdded", "_id", "Array", "values", "map", "trackLeaks", "DEFAULT_CHUNK_SIZE", "BlobMetaCodec", "getCodecForType", "BlobStore", "_directory", "_getMeta", "options", "metadata", "Error", "file", "_getDataFile", "read", "undefined", "beginChunk", "floor", "endChunk", "ceil", "present", "count", "files", "f", "split", "res", "asUint8Array", "subtleCrypto", "digest", "created", "updated", "write", "arrayToBuffer", "_writeMeta", "chunk", "PARTIALLY_PRESENT", "zeros", "encoded", "encode", "Buffer", "alloc", "writeUInt32LE", "copy", "_getMetaFile", "size", "stat", "protoSize", "readUInt32LE", "decode", "subarray", "getOrCreateFile", "path", "join", "toString"]
4
+ "sourcesContent": ["//\n\n//\n// Copyright 2023 DXOS.org\n//\n\nimport { DeferredTask, sleep, synchronized } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { RpcClosedError, schema } from '@dxos/protocols';\nimport { type BlobChunk, type BlobSyncService, type WantList } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { type ExtensionContext, RpcExtension } from '@dxos/teleport';\nimport { BitField } from '@dxos/util';\n\nimport { type BlobStore } from './blob-store';\n\nexport type BlobSyncExtensionParams = {\n blobStore: BlobStore;\n onOpen: () => Promise<void>;\n onClose: () => Promise<void>;\n onAbort: () => Promise<void>;\n onPush: (data: BlobChunk) => Promise<void>;\n};\n\nconst MIN_WANT_LIST_UPDATE_INTERVAL = process.env.NODE_ENV === 'test' ? 5 : 500;\n\nconst MAX_CONCURRENT_UPLOADS = 20;\n\n/**\n * Manages replication between a set of feeds for a single teleport session.\n */\nexport class BlobSyncExtension extends RpcExtension<ServiceBundle, ServiceBundle> {\n private readonly _ctx = new Context({ onError: (err) => log.catch(err) });\n\n private _lastWantListUpdate = 0;\n private _localWantList: WantList = { blobs: [] };\n\n private readonly _updateWantList = new DeferredTask(this._ctx, async () => {\n // Throttle want list updates.\n if (this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL > Date.now()) {\n await sleep(this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL - Date.now());\n if (this._ctx.disposed) {\n return;\n }\n }\n\n log('want', { list: this._localWantList });\n await this.rpc.BlobSyncService.want(this._localWantList);\n this._lastWantListUpdate = Date.now();\n });\n\n private _currentUploads = 0;\n\n private readonly _upload = new DeferredTask(this._ctx, async () => {\n if (this._currentUploads >= MAX_CONCURRENT_UPLOADS) {\n return;\n }\n const blobChunks = await this._pickBlobChunks(MAX_CONCURRENT_UPLOADS - this._currentUploads);\n if (!blobChunks) {\n return;\n }\n for (const blobChunk of blobChunks) {\n if (this._ctx.disposed) {\n break;\n }\n\n this._currentUploads++;\n\n this.push(blobChunk)\n .catch((err) => {\n if (err instanceof RpcClosedError) {\n return;\n }\n log.warn('push failed', { err });\n })\n .finally(() => {\n this._currentUploads--;\n this.reconcileUploads();\n });\n }\n });\n\n /**\n * Set of id's remote peer wants.\n */\n public remoteWantList: WantList = { blobs: [] };\n\n constructor(\n private readonly _params: BlobSyncExtensionParams, // to not conflict with the base class\n ) {\n super({\n exposed: {\n BlobSyncService: schema.getService('dxos.mesh.teleport.blobsync.BlobSyncService'),\n },\n requested: {\n BlobSyncService: schema.getService('dxos.mesh.teleport.blobsync.BlobSyncService'),\n },\n timeout: 20_000,\n encodingOptions: {\n preserveAny: true,\n },\n });\n }\n\n override async onOpen(context: ExtensionContext): Promise<void> {\n log('open');\n await super.onOpen(context);\n await this._params.onOpen();\n }\n\n override async onClose(err?: Error | undefined): Promise<void> {\n log('close');\n await this._ctx.dispose();\n await this._params.onClose();\n await super.onClose(err);\n }\n\n override async onAbort(err?: Error | undefined): Promise<void> {\n log('abort');\n await this._ctx.dispose();\n await this._params.onAbort();\n await super.onAbort(err);\n }\n\n protected async getHandlers(): Promise<ServiceBundle> {\n return {\n BlobSyncService: {\n want: async (wantList) => {\n log('remote want', { remoteWantList: wantList });\n this.remoteWantList = wantList;\n this.reconcileUploads();\n },\n push: async (data) => {\n log('received', { data });\n await this._params.onPush(data);\n },\n },\n };\n }\n\n @synchronized\n async push(data: BlobChunk) {\n if (this._ctx.disposed) {\n return;\n }\n log('push', { data });\n await this.rpc.BlobSyncService.push(data);\n }\n\n updateWantList(wantList: WantList) {\n if (this._ctx.disposed) {\n return;\n }\n this._localWantList = wantList;\n this._updateWantList.schedule();\n }\n\n reconcileUploads() {\n if (this._ctx.disposed) {\n return;\n }\n this._upload.schedule();\n }\n\n private async _pickBlobChunks(amount = 1): Promise<BlobChunk[] | void> {\n if (this._ctx.disposed) {\n return;\n }\n\n if (!this.remoteWantList.blobs || this.remoteWantList.blobs?.length === 0) {\n return;\n }\n\n const shuffled = [...this.remoteWantList.blobs].sort(() => Math.random() - 0.5);\n\n const chunks: BlobChunk[] = [];\n\n for (const header of shuffled) {\n const meta = await this._params.blobStore.getMeta(header.id);\n\n if (!meta) {\n // Skip this header\n continue;\n }\n invariant(meta.bitfield);\n invariant(meta.chunkSize);\n invariant(meta.length);\n\n if (header.chunkSize && header.chunkSize !== meta.chunkSize) {\n log.warn('Invalid chunk size', { header, meta });\n continue;\n }\n\n const requestBitfield = header.bitfield ?? BitField.ones(meta.length / meta.chunkSize);\n\n const presentData = BitField.and(requestBitfield, meta.bitfield);\n const chunkIndices = BitField.findIndexes(presentData).sort(() => Math.random() - 0.5);\n\n for (const idx of chunkIndices) {\n const chunkData = await this._params.blobStore.get(header.id, {\n offset: idx * meta.chunkSize,\n length: Math.min(meta.chunkSize, meta.length - idx * meta.chunkSize),\n });\n chunks.push({\n id: header.id,\n totalLength: meta.length,\n chunkSize: meta.chunkSize,\n chunkOffset: idx * meta.chunkSize,\n payload: chunkData,\n });\n\n if (chunks.length >= amount) {\n return chunks;\n }\n }\n }\n\n return chunks;\n }\n}\n\ntype ServiceBundle = {\n BlobSyncService: BlobSyncService;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { trackLeaks, Trigger, Mutex } from '@dxos/async';\nimport { cancelWithContext, Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { BlobMeta } from '@dxos/protocols/proto/dxos/echo/blob';\nimport { type WantList } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { BitField, ComplexMap } from '@dxos/util';\n\nimport { type BlobStore } from './blob-store';\nimport { BlobSyncExtension } from './blob-sync-extension';\n\nexport type BlobSyncParams = {\n blobStore: BlobStore;\n};\n\ntype DownloadRequest = {\n trigger: Trigger<void>;\n counter: number;\n want: WantList.Entry;\n};\n\n// TODO(dmaretskyi): Rename to blob-sync.\n@trackLeaks('open', 'close')\nexport class BlobSync {\n private readonly _ctx = new Context();\n private readonly _mutex = new Mutex();\n\n private readonly _downloadRequests = new ComplexMap<Uint8Array, DownloadRequest>((key) =>\n PublicKey.from(key).toHex(),\n );\n\n private readonly _extensions = new Set<BlobSyncExtension>();\n\n constructor(private readonly _params: BlobSyncParams) {}\n\n async open() {}\n\n async close() {\n await this._ctx.dispose();\n }\n\n /**\n * Resolves when the object with the given id is fully downloaded in the blob store.\n *\n * @param id hex-encoded id of the object to download.\n */\n async download(ctx: Context, id: Uint8Array): Promise<void> {\n log('download', { id });\n const request = await this._mutex.executeSynchronized(async () => {\n const existingRequest = this._downloadRequests.get(id);\n\n if (existingRequest) {\n existingRequest.counter++;\n return existingRequest;\n }\n\n const meta = await this._params.blobStore.getMeta(id);\n const request: DownloadRequest = {\n trigger: new Trigger(),\n counter: 1,\n want: {\n id,\n chunkSize: meta?.chunkSize,\n bitfield: meta?.bitfield && Uint8Array.from(BitField.invert(meta.bitfield)),\n },\n };\n\n // Check if the object is already fully downloaded.\n if (meta?.state === BlobMeta.State.FULLY_PRESENT) {\n request.trigger.wake();\n } else {\n this._downloadRequests.set(id, request);\n this._updateExtensionsWantList();\n }\n\n return request;\n });\n\n ctx?.onDispose(() =>\n this._mutex.executeSynchronized(async () => {\n // Remove request if context is disposed and nobody else requests it.\n const request = this._downloadRequests.get(id);\n if (!request) {\n return;\n }\n if (--request.counter === 0) {\n this._downloadRequests.delete(id);\n }\n this._updateExtensionsWantList();\n }),\n );\n\n return ctx ? cancelWithContext(ctx, request.trigger.wait()) : request.trigger.wait();\n }\n\n createExtension() {\n const extension = new BlobSyncExtension({\n blobStore: this._params.blobStore,\n onOpen: async () => {\n log('extension opened');\n this._extensions.add(extension);\n extension.updateWantList(this._getWantList());\n },\n onClose: async () => {\n log('extension closed');\n this._extensions.delete(extension);\n },\n onAbort: async () => {\n log('extension aborted');\n this._extensions.delete(extension);\n },\n onPush: async (blobChunk) => {\n if (!this._downloadRequests.has(blobChunk.id)) {\n return;\n }\n log('received', { blobChunk });\n const meta = await this._params.blobStore.setChunk(blobChunk);\n if (meta.state === BlobMeta.State.FULLY_PRESENT) {\n this._downloadRequests.get(blobChunk.id)?.trigger.wake();\n this._downloadRequests.delete(blobChunk.id);\n } else {\n invariant(meta.bitfield);\n this._downloadRequests.get(blobChunk.id)!.want.bitfield = BitField.invert(meta.bitfield);\n }\n\n this._updateExtensionsWantList();\n this._reconcileUploads();\n },\n });\n return extension;\n }\n\n /**\n * Notify extensions that a blob with the given id was added to the blob store.\n */\n async notifyBlobAdded(_id: Uint8Array) {\n this._reconcileUploads();\n }\n\n private _getWantList(): WantList {\n return {\n blobs: Array.from(this._downloadRequests.values()).map((request) => request.want),\n };\n }\n\n private _reconcileUploads() {\n for (const extension of this._extensions) {\n extension.reconcileUploads();\n }\n }\n\n private _updateExtensionsWantList() {\n for (const extension of this._extensions) {\n extension.updateWantList(this._getWantList());\n }\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport path from 'node:path';\n\nimport { synchronized } from '@dxos/async';\nimport { subtleCrypto } from '@dxos/crypto';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { schema } from '@dxos/protocols';\nimport { BlobMeta } from '@dxos/protocols/proto/dxos/echo/blob';\nimport { type BlobChunk } from '@dxos/protocols/proto/dxos/mesh/teleport/blobsync';\nimport { type Directory } from '@dxos/random-access-storage';\nimport { BitField, arrayToBuffer } from '@dxos/util';\n\nexport type GetOptions = {\n offset?: number;\n length?: number;\n};\n\nexport const DEFAULT_CHUNK_SIZE = 4096;\n\nconst BlobMetaCodec = schema.getCodecForType('dxos.echo.blob.BlobMeta');\n\nexport class BlobStore {\n constructor(private readonly _directory: Directory) {}\n\n @synchronized\n async getMeta(id: Uint8Array): Promise<BlobMeta | undefined> {\n return this._getMeta(id);\n }\n\n /**\n * @throws If range is not available.\n */\n @synchronized\n async get(id: Uint8Array, options: GetOptions = {}): Promise<Uint8Array> {\n const metadata = await this._getMeta(id);\n\n if (!metadata) {\n throw new Error('Blob not available');\n }\n\n const { offset = 0, length = metadata.length } = options;\n\n if (offset + length > metadata.length) {\n throw new Error('Invalid range');\n }\n\n if (metadata.state === BlobMeta.State.FULLY_PRESENT) {\n const file = this._getDataFile(id);\n return file.read(offset, length);\n } else if (options.offset === undefined && options.length === undefined) {\n throw new Error('Blob not available');\n }\n\n const beginChunk = Math.floor(offset / metadata.chunkSize);\n const endChunk = Math.ceil((offset + length) / metadata.chunkSize);\n\n invariant(metadata.bitfield, 'Bitfield not present');\n invariant(metadata.bitfield.length * 8 >= endChunk, 'Invalid bitfield length');\n\n const present = BitField.count(metadata.bitfield, beginChunk, endChunk) === endChunk - beginChunk;\n\n if (!present) {\n throw new Error('Blob not available');\n }\n\n const file = this._getDataFile(id);\n return file.read(offset, length);\n }\n\n @synchronized\n async list(): Promise<BlobMeta[]> {\n /*\n Weird path formatting:\n\n \"e9b9aa7a21c2c55a9eca333cd59975633157562ca0a0f4f243d4778f192c291e_meta\"\n \"e9b9aa7a21c2c55a9eca333cd59975633157562ca0a0f4f243d4778f192c291e_data\"\n \"5001de5a47191357c075aeee6451c4cc323f3a8ada24dd1191e83403608a38d5_meta\n */\n const files = new Set((await this._directory.list()).map((f) => f.split('_')[0]));\n\n const res: BlobMeta[] = [];\n\n for (const file of files) {\n const id = PublicKey.from(file).asUint8Array();\n const meta = await this._getMeta(id);\n if (meta) {\n res.push(meta);\n }\n }\n\n return res;\n }\n\n @synchronized\n async set(data: Uint8Array): Promise<BlobMeta> {\n const id = new Uint8Array(await subtleCrypto.digest('SHA-256', data));\n const bitfield = BitField.ones(data.length / DEFAULT_CHUNK_SIZE);\n\n const meta: BlobMeta = {\n id,\n state: BlobMeta.State.FULLY_PRESENT,\n length: data.length,\n chunkSize: DEFAULT_CHUNK_SIZE,\n bitfield,\n created: new Date(),\n updated: new Date(),\n };\n\n await this._getDataFile(id).write(0, arrayToBuffer(data));\n await this._writeMeta(id, meta);\n return meta;\n }\n\n // TODO(dmaretskyi): Optimize locking.\n @synchronized\n async setChunk(chunk: BlobChunk): Promise<BlobMeta> {\n // Init metadata.\n let meta = await this._getMeta(chunk.id);\n if (!meta) {\n invariant(chunk.totalLength, 'totalLength is not present');\n meta = {\n id: chunk.id,\n state: BlobMeta.State.PARTIALLY_PRESENT,\n length: chunk.totalLength,\n chunkSize: chunk.chunkSize ?? DEFAULT_CHUNK_SIZE,\n created: new Date(),\n };\n meta.bitfield = BitField.zeros(meta.length / meta.chunkSize);\n }\n\n if (chunk.chunkSize && chunk.chunkSize !== meta.chunkSize) {\n throw new Error('Invalid chunk size');\n }\n\n invariant(meta.bitfield, 'Bitfield not present');\n invariant(chunk.chunkOffset !== undefined, 'chunkOffset is not present');\n\n // Write chunk.\n await this._getDataFile(chunk.id).write(chunk.chunkOffset, arrayToBuffer(chunk.payload));\n\n // Update bitfield.\n BitField.set(meta.bitfield, Math.floor(chunk.chunkOffset / meta.chunkSize), true);\n\n // Update metadata.\n if (BitField.count(meta.bitfield, 0, meta.length) * meta.chunkSize >= meta.length) {\n meta.state = BlobMeta.State.FULLY_PRESENT;\n }\n meta.updated = new Date();\n\n await this._writeMeta(chunk.id, meta);\n\n return meta;\n }\n\n private async _writeMeta(id: Uint8Array, meta: BlobMeta): Promise<void> {\n const encoded = arrayToBuffer(BlobMetaCodec.encode(meta));\n const data = Buffer.alloc(encoded.length + 4);\n data.writeUInt32LE(encoded.length, 0);\n encoded.copy(data, 4);\n\n // Write metadata.\n await this._getMetaFile(id).write(0, data);\n }\n\n private async _getMeta(id: Uint8Array): Promise<BlobMeta | undefined> {\n const file = this._getMetaFile(id);\n const size = (await file.stat()).size;\n if (size === 0) {\n return;\n }\n const data = await file.read(0, size);\n const protoSize = data.readUInt32LE(0);\n return BlobMetaCodec.decode(data.subarray(4, protoSize + 4));\n }\n\n private _getMetaFile(id: Uint8Array) {\n return this._directory.getOrCreateFile(path.join(arrayToBuffer(id).toString('hex'), 'meta'));\n }\n\n private _getDataFile(id: Uint8Array) {\n return this._directory.getOrCreateFile(path.join(arrayToBuffer(id).toString('hex'), 'data'));\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_async", "import_context", "import_invariant", "import_log", "import_util", "import_keys", "import_protocols", "import_blob", "MIN_WANT_LIST_UPDATE_INTERVAL", "process", "env", "NODE_ENV", "MAX_CONCURRENT_UPLOADS", "BlobSyncExtension", "RpcExtension", "constructor", "_params", "exposed", "BlobSyncService", "schema", "getService", "requested", "timeout", "encodingOptions", "preserveAny", "_ctx", "Context", "onError", "err", "log", "catch", "_lastWantListUpdate", "_localWantList", "blobs", "_updateWantList", "DeferredTask", "Date", "now", "sleep", "disposed", "list", "rpc", "want", "_currentUploads", "_upload", "blobChunks", "_pickBlobChunks", "blobChunk", "push", "RpcClosedError", "warn", "finally", "reconcileUploads", "remoteWantList", "onOpen", "context", "onClose", "dispose", "onAbort", "getHandlers", "wantList", "data", "onPush", "updateWantList", "schedule", "amount", "length", "shuffled", "sort", "Math", "random", "chunks", "header", "meta", "blobStore", "getMeta", "id", "invariant", "bitfield", "chunkSize", "requestBitfield", "BitField", "ones", "presentData", "and", "chunkIndices", "findIndexes", "idx", "chunkData", "get", "offset", "min", "totalLength", "chunkOffset", "payload", "synchronized", "BlobSync", "_mutex", "Mutex", "_downloadRequests", "ComplexMap", "key", "PublicKey", "from", "toHex", "_extensions", "Set", "open", "close", "download", "ctx", "request", "executeSynchronized", "existingRequest", "counter", "trigger", "Trigger", "Uint8Array", "invert", "state", "BlobMeta", "State", "FULLY_PRESENT", "wake", "set", "_updateExtensionsWantList", "onDispose", "delete", "cancelWithContext", "wait", "createExtension", "extension", "add", "_getWantList", "has", "setChunk", "_reconcileUploads", "notifyBlobAdded", "_id", "Array", "values", "map", "trackLeaks", "DEFAULT_CHUNK_SIZE", "BlobMetaCodec", "getCodecForType", "BlobStore", "_directory", "_getMeta", "options", "metadata", "Error", "file", "_getDataFile", "read", "undefined", "beginChunk", "floor", "endChunk", "ceil", "present", "count", "files", "f", "split", "res", "asUint8Array", "subtleCrypto", "digest", "created", "updated", "write", "arrayToBuffer", "_writeMeta", "chunk", "PARTIALLY_PRESENT", "zeros", "encoded", "encode", "Buffer", "alloc", "writeUInt32LE", "copy", "_getMetaFile", "size", "stat", "protoSize", "readUInt32LE", "decode", "subarray", "getOrCreateFile", "path", "join", "toString"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytes":25198,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/teleport","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts":{"bytes":18393,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","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/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts","kind":"import-statement","original":"./blob-sync-extension"}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts":{"bytes":22281,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/crypto","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/index.ts":{"bytes":703,"imports":[{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts","kind":"import-statement","original":"./blob-sync-extension"},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts","kind":"import-statement","original":"./blob-sync"},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts","kind":"import-statement","original":"./blob-store"}],"format":"esm"}},"outputs":{"packages/core/mesh/teleport-extension-object-sync/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":30539},"packages/core/mesh/teleport-extension-object-sync/dist/lib/node/index.cjs":{"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/teleport","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","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/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/crypto","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["BlobStore","BlobSync","BlobSyncExtension","DEFAULT_CHUNK_SIZE"],"entryPoint":"packages/core/mesh/teleport-extension-object-sync/src/index.ts","inputs":{"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytesInOutput":7383},"packages/core/mesh/teleport-extension-object-sync/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts":{"bytesInOutput":5410},"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts":{"bytesInOutput":6537}},"bytes":19667}}}
1
+ {"inputs":{"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytes":25214,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/teleport","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts":{"bytes":18411,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","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/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts","kind":"import-statement","original":"./blob-sync-extension"}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts":{"bytes":22289,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/crypto","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/teleport-extension-object-sync/src/index.ts":{"bytes":703,"imports":[{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts","kind":"import-statement","original":"./blob-sync-extension"},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts","kind":"import-statement","original":"./blob-sync"},{"path":"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts","kind":"import-statement","original":"./blob-store"}],"format":"esm"}},"outputs":{"packages/core/mesh/teleport-extension-object-sync/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":30557},"packages/core/mesh/teleport-extension-object-sync/dist/lib/node/index.cjs":{"imports":[{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/teleport","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","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/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/crypto","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/protocols/proto/dxos/echo/blob","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["BlobStore","BlobSync","BlobSyncExtension","DEFAULT_CHUNK_SIZE"],"entryPoint":"packages/core/mesh/teleport-extension-object-sync/src/index.ts","inputs":{"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytesInOutput":7383},"packages/core/mesh/teleport-extension-object-sync/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts":{"bytesInOutput":5405},"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts":{"bytesInOutput":6537}},"bytes":19662}}}
@@ -7,7 +7,7 @@ export type BlobSyncParams = {
7
7
  export declare class BlobSync {
8
8
  private readonly _params;
9
9
  private readonly _ctx;
10
- private readonly _lock;
10
+ private readonly _mutex;
11
11
  private readonly _downloadRequests;
12
12
  private readonly _extensions;
13
13
  constructor(_params: BlobSyncParams);
@@ -1 +1 @@
1
- {"version":3,"file":"blob-sync.d.ts","sourceRoot":"","sources":["../../../src/blob-sync.ts"],"names":[],"mappings":"AAKA,OAAO,EAAqB,OAAO,EAAE,MAAM,eAAe,CAAC;AAQ3D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AASF,qBACa,QAAQ;IAUP,OAAO,CAAC,QAAQ,CAAC,OAAO;IATpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IAEpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAEhC;IAEF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;gBAE/B,OAAO,EAAE,cAAc;IAE9C,IAAI;IAEJ,KAAK;IAIX;;;;OAIG;IACG,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAiD3D,eAAe;IAqCf;;OAEG;IACG,eAAe,CAAC,GAAG,EAAE,UAAU;IAIrC,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,yBAAyB;CAKlC"}
1
+ {"version":3,"file":"blob-sync.d.ts","sourceRoot":"","sources":["../../../src/blob-sync.ts"],"names":[],"mappings":"AAKA,OAAO,EAAqB,OAAO,EAAE,MAAM,eAAe,CAAC;AAQ3D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AASF,qBACa,QAAQ;IAUP,OAAO,CAAC,QAAQ,CAAC,OAAO;IATpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IAEtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAEhC;IAEF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;gBAE/B,OAAO,EAAE,cAAc;IAE9C,IAAI;IAEJ,KAAK;IAIX;;;;OAIG;IACG,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAiD3D,eAAe;IAqCf;;OAEG;IACG,eAAe,CAAC,GAAG,EAAE,UAAU;IAIrC,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,yBAAyB;CAKlC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/teleport-extension-object-sync",
3
- "version": "0.3.11-main.f14932f",
3
+ "version": "0.3.11-main.f4c1077",
4
4
  "description": "Teleport extension to synchronize opaque data objects.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -16,19 +16,19 @@
16
16
  "src"
17
17
  ],
18
18
  "dependencies": {
19
- "@dxos/async": "0.3.11-main.f14932f",
20
- "@dxos/context": "0.3.11-main.f14932f",
21
- "@dxos/crypto": "0.3.11-main.f14932f",
22
- "@dxos/debug": "0.3.11-main.f14932f",
23
- "@dxos/keys": "0.3.11-main.f14932f",
24
- "@dxos/invariant": "0.3.11-main.f14932f",
25
- "@dxos/log": "0.3.11-main.f14932f",
26
- "@dxos/node-std": "0.3.11-main.f14932f",
27
- "@dxos/protocols": "0.3.11-main.f14932f",
28
- "@dxos/random-access-storage": "0.3.11-main.f14932f",
29
- "@dxos/rpc": "0.3.11-main.f14932f",
30
- "@dxos/teleport": "0.3.11-main.f14932f",
31
- "@dxos/util": "0.3.11-main.f14932f"
19
+ "@dxos/async": "0.3.11-main.f4c1077",
20
+ "@dxos/context": "0.3.11-main.f4c1077",
21
+ "@dxos/crypto": "0.3.11-main.f4c1077",
22
+ "@dxos/invariant": "0.3.11-main.f4c1077",
23
+ "@dxos/keys": "0.3.11-main.f4c1077",
24
+ "@dxos/log": "0.3.11-main.f4c1077",
25
+ "@dxos/node-std": "0.3.11-main.f4c1077",
26
+ "@dxos/protocols": "0.3.11-main.f4c1077",
27
+ "@dxos/debug": "0.3.11-main.f4c1077",
28
+ "@dxos/random-access-storage": "0.3.11-main.f4c1077",
29
+ "@dxos/rpc": "0.3.11-main.f4c1077",
30
+ "@dxos/teleport": "0.3.11-main.f4c1077",
31
+ "@dxos/util": "0.3.11-main.f4c1077"
32
32
  },
33
33
  "devDependencies": {
34
34
  "typescript": "^5.2.2"
package/src/blob-sync.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { trackLeaks, Trigger, Lock } from '@dxos/async';
5
+ import { trackLeaks, Trigger, Mutex } from '@dxos/async';
6
6
  import { cancelWithContext, Context } from '@dxos/context';
7
7
  import { invariant } from '@dxos/invariant';
8
8
  import { PublicKey } from '@dxos/keys';
@@ -28,7 +28,7 @@ type DownloadRequest = {
28
28
  @trackLeaks('open', 'close')
29
29
  export class BlobSync {
30
30
  private readonly _ctx = new Context();
31
- private readonly _lock = new Lock();
31
+ private readonly _mutex = new Mutex();
32
32
 
33
33
  private readonly _downloadRequests = new ComplexMap<Uint8Array, DownloadRequest>((key) =>
34
34
  PublicKey.from(key).toHex(),
@@ -51,7 +51,7 @@ export class BlobSync {
51
51
  */
52
52
  async download(ctx: Context, id: Uint8Array): Promise<void> {
53
53
  log('download', { id });
54
- const request = await this._lock.executeSynchronized(async () => {
54
+ const request = await this._mutex.executeSynchronized(async () => {
55
55
  const existingRequest = this._downloadRequests.get(id);
56
56
 
57
57
  if (existingRequest) {
@@ -82,7 +82,7 @@ export class BlobSync {
82
82
  });
83
83
 
84
84
  ctx?.onDispose(() =>
85
- this._lock.executeSynchronized(async () => {
85
+ this._mutex.executeSynchronized(async () => {
86
86
  // Remove request if context is disposed and nobody else requests it.
87
87
  const request = this._downloadRequests.get(id);
88
88
  if (!request) {