@dxos/teleport-extension-object-sync 0.3.8-main.152ec6f → 0.3.8-main.1b6c849

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.
@@ -39,7 +39,7 @@ var BlobSyncExtension = class extends RpcExtension {
39
39
  this._ctx = new Context({
40
40
  onError: (err) => log.catch(err, void 0, {
41
41
  F: __dxlog_file,
42
- L: 33,
42
+ L: 34,
43
43
  S: this,
44
44
  C: (f, a) => f(...a)
45
45
  })
@@ -59,7 +59,7 @@ var BlobSyncExtension = class extends RpcExtension {
59
59
  list: this._localWantList
60
60
  }, {
61
61
  F: __dxlog_file,
62
- L: 47,
62
+ L: 48,
63
63
  S: this,
64
64
  C: (f, a) => f(...a)
65
65
  });
@@ -88,7 +88,7 @@ var BlobSyncExtension = class extends RpcExtension {
88
88
  err
89
89
  }, {
90
90
  F: __dxlog_file,
91
- L: 74,
91
+ L: 75,
92
92
  S: this,
93
93
  C: (f, a) => f(...a)
94
94
  });
@@ -105,7 +105,7 @@ var BlobSyncExtension = class extends RpcExtension {
105
105
  async onOpen(context) {
106
106
  log("open", void 0, {
107
107
  F: __dxlog_file,
108
- L: 106,
108
+ L: 107,
109
109
  S: this,
110
110
  C: (f, a) => f(...a)
111
111
  });
@@ -115,7 +115,7 @@ var BlobSyncExtension = class extends RpcExtension {
115
115
  async onClose(err) {
116
116
  log("close", void 0, {
117
117
  F: __dxlog_file,
118
- L: 112,
118
+ L: 113,
119
119
  S: this,
120
120
  C: (f, a) => f(...a)
121
121
  });
@@ -123,6 +123,17 @@ var BlobSyncExtension = class extends RpcExtension {
123
123
  await this._params.onClose();
124
124
  await super.onClose(err);
125
125
  }
126
+ async onAbort(err) {
127
+ log("abort", void 0, {
128
+ F: __dxlog_file,
129
+ L: 120,
130
+ S: this,
131
+ C: (f, a) => f(...a)
132
+ });
133
+ await this._ctx.dispose();
134
+ await this._params.onAbort();
135
+ await super.onAbort(err);
136
+ }
126
137
  async getHandlers() {
127
138
  return {
128
139
  BlobSyncService: {
@@ -131,7 +142,7 @@ var BlobSyncExtension = class extends RpcExtension {
131
142
  remoteWantList: wantList
132
143
  }, {
133
144
  F: __dxlog_file,
134
- L: 122,
145
+ L: 130,
135
146
  S: this,
136
147
  C: (f, a) => f(...a)
137
148
  });
@@ -143,7 +154,7 @@ var BlobSyncExtension = class extends RpcExtension {
143
154
  data
144
155
  }, {
145
156
  F: __dxlog_file,
146
- L: 127,
157
+ L: 135,
147
158
  S: this,
148
159
  C: (f, a) => f(...a)
149
160
  });
@@ -160,7 +171,7 @@ var BlobSyncExtension = class extends RpcExtension {
160
171
  data
161
172
  }, {
162
173
  F: __dxlog_file,
163
- L: 139,
174
+ L: 147,
164
175
  S: this,
165
176
  C: (f, a) => f(...a)
166
177
  });
@@ -197,7 +208,7 @@ var BlobSyncExtension = class extends RpcExtension {
197
208
  }
198
209
  invariant(meta.bitfield, void 0, {
199
210
  F: __dxlog_file,
200
- L: 178,
211
+ L: 186,
201
212
  S: this,
202
213
  A: [
203
214
  "meta.bitfield",
@@ -206,7 +217,7 @@ var BlobSyncExtension = class extends RpcExtension {
206
217
  });
207
218
  invariant(meta.chunkSize, void 0, {
208
219
  F: __dxlog_file,
209
- L: 179,
220
+ L: 187,
210
221
  S: this,
211
222
  A: [
212
223
  "meta.chunkSize",
@@ -215,7 +226,7 @@ var BlobSyncExtension = class extends RpcExtension {
215
226
  });
216
227
  invariant(meta.length, void 0, {
217
228
  F: __dxlog_file,
218
- L: 180,
229
+ L: 188,
219
230
  S: this,
220
231
  A: [
221
232
  "meta.length",
@@ -228,7 +239,7 @@ var BlobSyncExtension = class extends RpcExtension {
228
239
  meta
229
240
  }, {
230
241
  F: __dxlog_file,
231
- L: 183,
242
+ L: 191,
232
243
  S: this,
233
244
  C: (f, a) => f(...a)
234
245
  });
@@ -365,6 +376,15 @@ var BlobSync = class BlobSync2 {
365
376
  });
366
377
  this._extensions.delete(extension);
367
378
  },
379
+ onAbort: async () => {
380
+ log2("extension aborted", void 0, {
381
+ F: __dxlog_file2,
382
+ L: 114,
383
+ S: this,
384
+ C: (f, a) => f(...a)
385
+ });
386
+ this._extensions.delete(extension);
387
+ },
368
388
  onPush: async (blobChunk) => {
369
389
  if (!this._downloadRequests.has(blobChunk.id)) {
370
390
  return;
@@ -373,7 +393,7 @@ var BlobSync = class BlobSync2 {
373
393
  blobChunk
374
394
  }, {
375
395
  F: __dxlog_file2,
376
- L: 117,
396
+ L: 121,
377
397
  S: this,
378
398
  C: (f, a) => f(...a)
379
399
  });
@@ -384,7 +404,7 @@ var BlobSync = class BlobSync2 {
384
404
  } else {
385
405
  invariant2(meta.bitfield, void 0, {
386
406
  F: __dxlog_file2,
387
- L: 123,
407
+ L: 127,
388
408
  S: this,
389
409
  A: [
390
410
  "meta.bitfield",
@@ -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 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 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 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", "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", "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, 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": ";;;AAMA,SAASA,cAAcC,OAAOC,oBAAoB;AAClD,SAASC,eAAe;AACxB,SAASC,iBAAiB;AAC1B,SAASC,WAAW;AACpB,SAASC,gBAAgBC,cAAc;AAEvC,SAAgCC,oBAAoB;AACpD,SAASC,gBAAgB;;;;;;;;;;;;AAYzB,IAAMC,gCAAgCC,QAAkC,IAAI;AAE5E,IAAMC,yBAAyB;AAKxB,IAAMC,oBAAN,cAAgCL,aAAAA;EAwDrCM,YACmBC,SACjB;AACA,UAAM;MACJC,SAAS;QACPC,iBAAiBV,OAAOW,WAAW,6CAAA;MACrC;MACAC,WAAW;QACTF,iBAAiBV,OAAOW,WAAW,6CAAA;MACrC;MACAE,SAAS;MACTC,iBAAiB;QACfC,aAAa;MACf;IACF,CAAA;mBAbiBP;SAxDFQ,OAAO,IAAIpB,QAAQ;MAAEqB,SAAS,CAACC,QAAQpB,IAAIqB,MAAMD,KAAAA,QAAAA;;;;;;IAAK,CAAA;SAE/DE,sBAAsB;SACtBC,iBAA2B;MAAEC,OAAO,CAAA;IAAG;SAE9BC,kBAAkB,IAAI9B,aAAa,KAAKuB,MAAM,YAAA;AAE7D,UAAI,KAAKI,sBAAsBjB,gCAAgCqB,KAAKC,IAAG,GAAI;AACzE,cAAM/B,MAAM,KAAK0B,sBAAsBjB,gCAAgCqB,KAAKC,IAAG,CAAA;AAC/E,YAAI,KAAKT,KAAKU,UAAU;AACtB;QACF;MACF;AAEA5B,UAAI,QAAQ;QAAE6B,MAAM,KAAKN;MAAe,GAAA;;;;;;AACxC,YAAM,KAAKO,IAAIlB,gBAAgBmB,KAAK,KAAKR,cAAc;AACvD,WAAKD,sBAAsBI,KAAKC,IAAG;IACrC,CAAA;SAEQK,kBAAkB;SAETC,UAAU,IAAItC,aAAa,KAAKuB,MAAM,YAAA;AACrD,UAAI,KAAKc,mBAAmBzB,wBAAwB;AAClD;MACF;AACA,YAAM2B,aAAa,MAAM,KAAKC,gBAAgB5B,yBAAyB,KAAKyB,eAAe;AAC3F,UAAI,CAACE,YAAY;AACf;MACF;AACA,iBAAWE,aAAaF,YAAY;AAClC,YAAI,KAAKhB,KAAKU,UAAU;AACtB;QACF;AAEA,aAAKI;AAEL,aAAKK,KAAKD,SAAAA,EACPf,MAAM,CAACD,QAAAA;AACN,cAAIA,eAAenB,gBAAgB;AACjC;UACF;AACAD,cAAIsC,KAAK,eAAe;YAAElB;UAAI,GAAA;;;;;;QAChC,CAAA,EACCmB,QAAQ,MAAA;AACP,eAAKP;AACL,eAAKQ,iBAAgB;QACvB,CAAA;MACJ;IACF,CAAA;SAKOC,iBAA2B;MAAEjB,OAAO,CAAA;IAAG;EAiB9C;EAEA,MAAekB,OAAOC,SAA0C;AAC9D3C,QAAI,QAAA,QAAA;;;;;;AACJ,UAAM,MAAM0C,OAAOC,OAAAA;AACnB,UAAM,KAAKjC,QAAQgC,OAAM;EAC3B;EAEA,MAAeE,QAAQxB,KAAwC;AAC7DpB,QAAI,SAAA,QAAA;;;;;;AACJ,UAAM,KAAKkB,KAAK2B,QAAO;AACvB,UAAM,KAAKnC,QAAQkC,QAAO;AAC1B,UAAM,MAAMA,QAAQxB,GAAAA;EACtB;EAEA,MAAe0B,QAAQ1B,KAAwC;AAC7DpB,QAAI,SAAA,QAAA;;;;;;AACJ,UAAM,KAAKkB,KAAK2B,QAAO;AACvB,UAAM,KAAKnC,QAAQoC,QAAO;AAC1B,UAAM,MAAMA,QAAQ1B,GAAAA;EACtB;EAEA,MAAgB2B,cAAsC;AACpD,WAAO;MACLnC,iBAAiB;QACfmB,MAAM,OAAOiB,aAAAA;AACXhD,cAAI,eAAe;YAAEyC,gBAAgBO;UAAS,GAAA;;;;;;AAC9C,eAAKP,iBAAiBO;AACtB,eAAKR,iBAAgB;QACvB;QACAH,MAAM,OAAOY,SAAAA;AACXjD,cAAI,YAAY;YAAEiD;UAAK,GAAA;;;;;;AACvB,gBAAM,KAAKvC,QAAQwC,OAAOD,IAAAA;QAC5B;MACF;IACF;EACF;EAEA,MACMZ,KAAKY,MAAiB;AAC1B,QAAI,KAAK/B,KAAKU,UAAU;AACtB;IACF;AACA5B,QAAI,QAAQ;MAAEiD;IAAK,GAAA;;;;;;AACnB,UAAM,KAAKnB,IAAIlB,gBAAgByB,KAAKY,IAAAA;EACtC;EAEAE,eAAeH,UAAoB;AACjC,QAAI,KAAK9B,KAAKU,UAAU;AACtB;IACF;AACA,SAAKL,iBAAiByB;AACtB,SAAKvB,gBAAgB2B,SAAQ;EAC/B;EAEAZ,mBAAmB;AACjB,QAAI,KAAKtB,KAAKU,UAAU;AACtB;IACF;AACA,SAAKK,QAAQmB,SAAQ;EACvB;EAEA,MAAcjB,gBAAgBkB,SAAS,GAAgC;AACrE,QAAI,KAAKnC,KAAKU,UAAU;AACtB;IACF;AAEA,QAAI,CAAC,KAAKa,eAAejB,SAAS,KAAKiB,eAAejB,OAAO8B,WAAW,GAAG;AACzE;IACF;AAEA,UAAMC,WAAW;SAAI,KAAKd,eAAejB;MAAOgC,KAAK,MAAMC,KAAKC,OAAM,IAAK,GAAA;AAE3E,UAAMC,SAAsB,CAAA;AAE5B,eAAWC,UAAUL,UAAU;AAC7B,YAAMM,OAAO,MAAM,KAAKnD,QAAQoD,UAAUC,QAAQH,OAAOI,EAAE;AAE3D,UAAI,CAACH,MAAM;AAET;MACF;AACA9D,gBAAU8D,KAAKI,UAAQ,QAAA;;;;;;;;;AACvBlE,gBAAU8D,KAAKK,WAAS,QAAA;;;;;;;;;AACxBnE,gBAAU8D,KAAKP,QAAM,QAAA;;;;;;;;;AAErB,UAAIM,OAAOM,aAAaN,OAAOM,cAAcL,KAAKK,WAAW;AAC3DlE,YAAIsC,KAAK,sBAAsB;UAAEsB;UAAQC;QAAK,GAAA;;;;;;AAC9C;MACF;AAEA,YAAMM,kBAAkBP,OAAOK,YAAY7D,SAASgE,KAAKP,KAAKP,SAASO,KAAKK,SAAS;AAErF,YAAMG,cAAcjE,SAASkE,IAAIH,iBAAiBN,KAAKI,QAAQ;AAC/D,YAAMM,eAAenE,SAASoE,YAAYH,WAAAA,EAAab,KAAK,MAAMC,KAAKC,OAAM,IAAK,GAAA;AAElF,iBAAWe,OAAOF,cAAc;AAC9B,cAAMG,YAAY,MAAM,KAAKhE,QAAQoD,UAAUa,IAAIf,OAAOI,IAAI;UAC5DY,QAAQH,MAAMZ,KAAKK;UACnBZ,QAAQG,KAAKoB,IAAIhB,KAAKK,WAAWL,KAAKP,SAASmB,MAAMZ,KAAKK,SAAS;QACrE,CAAA;AACAP,eAAOtB,KAAK;UACV2B,IAAIJ,OAAOI;UACXc,aAAajB,KAAKP;UAClBY,WAAWL,KAAKK;UAChBa,aAAaN,MAAMZ,KAAKK;UACxBc,SAASN;QACX,CAAA;AAEA,YAAIf,OAAOL,UAAUD,QAAQ;AAC3B,iBAAOM;QACT;MACF;IACF;AAEA,WAAOA;EACT;AACF;;EA/EG9D;GA7GUW,kBAAAA,WAAAA,QAAAA,IAAAA;;;AC5Bb,SAASyE,YAAYC,SAASC,YAAY;AAC1C,SAASC,mBAAmBC,WAAAA,gBAAe;AAC3C,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,iBAAiB;AAC1B,SAASC,OAAAA,YAAW;AACpB,SAASC,gBAAgB;AAEzB,SAASC,YAAAA,WAAUC,kBAAkB;;;;;;;;;;;;AAiBrC,IAAaC,WAAN,MAAAA,UAAA;EAULC,YAA6BC,SAAyB;mBAAzBA;SATZC,OAAO,IAAIC,SAAAA;SACXC,QAAQ,IAAIC,KAAAA;SAEZC,oBAAoB,IAAIC,WAAwC,CAACC,QAChFC,UAAUC,KAAKF,GAAAA,EAAKG,MAAK,CAAA;SAGVC,cAAc,oBAAIC,IAAAA;EAEoB;EAEvD,MAAMC,OAAO;EAAC;EAEd,MAAMC,QAAQ;AACZ,UAAM,KAAKb,KAAKc,QAAO;EACzB;;;;;;EAOA,MAAMC,SAASC,KAAcC,IAA+B;AAC1DC,IAAAA,KAAI,YAAY;MAAED;IAAG,GAAA;;;;;;AACrB,UAAME,UAAU,MAAM,KAAKjB,MAAMkB,oBAAoB,YAAA;AACnD,YAAMC,kBAAkB,KAAKjB,kBAAkBkB,IAAIL,EAAAA;AAEnD,UAAII,iBAAiB;AACnBA,wBAAgBE;AAChB,eAAOF;MACT;AAEA,YAAMG,OAAO,MAAM,KAAKzB,QAAQ0B,UAAUC,QAAQT,EAAAA;AAClD,YAAME,WAA2B;QAC/BQ,SAAS,IAAIC,QAAAA;QACbL,SAAS;QACTM,MAAM;UACJZ;UACAa,WAAWN,MAAMM;UACjBC,UAAUP,MAAMO,YAAYC,WAAWxB,KAAKyB,UAASC,OAAOV,KAAKO,QAAQ,CAAA;QAC3E;MACF;AAGA,UAAIP,MAAMW,UAAUC,SAASC,MAAMC,eAAe;AAChDnB,QAAAA,SAAQQ,QAAQY,KAAI;MACtB,OAAO;AACL,aAAKnC,kBAAkBoC,IAAIvB,IAAIE,QAAAA;AAC/B,aAAKsB,0BAAyB;MAChC;AAEA,aAAOtB;IACT,CAAA;AAEAH,SAAK0B,UAAU,MACb,KAAKxC,MAAMkB,oBAAoB,YAAA;AAE7B,YAAMD,WAAU,KAAKf,kBAAkBkB,IAAIL,EAAAA;AAC3C,UAAI,CAACE,UAAS;AACZ;MACF;AACA,UAAI,EAAEA,SAAQI,YAAY,GAAG;AAC3B,aAAKnB,kBAAkBuC,OAAO1B,EAAAA;MAChC;AACA,WAAKwB,0BAAyB;IAChC,CAAA,CAAA;AAGF,WAAOzB,MAAM4B,kBAAkB5B,KAAKG,QAAQQ,QAAQkB,KAAI,CAAA,IAAM1B,QAAQQ,QAAQkB,KAAI;EACpF;EAEAC,kBAAkB;AAChB,UAAMC,YAAY,IAAIC,kBAAkB;MACtCvB,WAAW,KAAK1B,QAAQ0B;MACxBwB,QAAQ,YAAA;AACN/B,QAAAA,KAAI,oBAAA,QAAA;;;;;;AACJ,aAAKR,YAAYwC,IAAIH,SAAAA;AACrBA,kBAAUI,eAAe,KAAKC,aAAY,CAAA;MAC5C;MACAC,SAAS,YAAA;AACPnC,QAAAA,KAAI,oBAAA,QAAA;;;;;;AACJ,aAAKR,YAAYiC,OAAOI,SAAAA;MAC1B;MACAO,SAAS,YAAA;AACPpC,QAAAA,KAAI,qBAAA,QAAA;;;;;;AACJ,aAAKR,YAAYiC,OAAOI,SAAAA;MAC1B;MACAQ,QAAQ,OAAOC,cAAAA;AACb,YAAI,CAAC,KAAKpD,kBAAkBqD,IAAID,UAAUvC,EAAE,GAAG;AAC7C;QACF;AACAC,QAAAA,KAAI,YAAY;UAAEsC;QAAU,GAAA;;;;;;AAC5B,cAAMhC,OAAO,MAAM,KAAKzB,QAAQ0B,UAAUiC,SAASF,SAAAA;AACnD,YAAIhC,KAAKW,UAAUC,SAASC,MAAMC,eAAe;AAC/C,eAAKlC,kBAAkBkB,IAAIkC,UAAUvC,EAAE,GAAGU,QAAQY,KAAAA;AAClD,eAAKnC,kBAAkBuC,OAAOa,UAAUvC,EAAE;QAC5C,OAAO;AACL0C,UAAAA,WAAUnC,KAAKO,UAAQ,QAAA;;;;;;;;;AACvB,eAAK3B,kBAAkBkB,IAAIkC,UAAUvC,EAAE,EAAGY,KAAKE,WAAWE,UAASC,OAAOV,KAAKO,QAAQ;QACzF;AAEA,aAAKU,0BAAyB;AAC9B,aAAKmB,kBAAiB;MACxB;IACF,CAAA;AACA,WAAOb;EACT;;;;EAKA,MAAMc,gBAAgBC,KAAiB;AACrC,SAAKF,kBAAiB;EACxB;EAEQR,eAAyB;AAC/B,WAAO;MACLW,OAAOC,MAAMxD,KAAK,KAAKJ,kBAAkB6D,OAAM,CAAA,EAAIC,IAAI,CAAC/C,YAAYA,QAAQU,IAAI;IAClF;EACF;EAEQ+B,oBAAoB;AAC1B,eAAWb,aAAa,KAAKrC,aAAa;AACxCqC,gBAAUoB,iBAAgB;IAC5B;EACF;EAEQ1B,4BAA4B;AAClC,eAAWM,aAAa,KAAKrC,aAAa;AACxCqC,gBAAUI,eAAe,KAAKC,aAAY,CAAA;IAC5C;EACF;AACF;AArIavD,WAAAA,cAAAA;EADZuE,WAAW,QAAQ,OAAA;GACPvE,QAAAA;;;ACxBb,OAAOwE,UAAU;AAEjB,SAASC,gBAAAA,qBAAoB;AAC7B,SAASC,oBAAoB;AAC7B,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,UAAAA,eAAc;AACvB,SAASC,YAAAA,iBAAgB;AAGzB,SAASC,YAAAA,WAAUC,qBAAqB;;;;;;;;;;;;AAOjC,IAAMC,qBAAqB;AAElC,IAAMC,gBAAgBL,QAAOM,gBAAgB,yBAAA;AAEtC,IAAMC,YAAN,MAAMA;EACXC,YAA6BC,YAAuB;sBAAvBA;EAAwB;EAErD,MACMC,QAAQC,IAA+C;AAC3D,WAAO,KAAKC,SAASD,EAAAA;EACvB;;;;EAKA,MACME,IAAIF,IAAgBG,UAAsB,CAAC,GAAwB;AACvE,UAAMC,WAAW,MAAM,KAAKH,SAASD,EAAAA;AAErC,QAAI,CAACI,UAAU;AACb,YAAM,IAAIC,MAAM,oBAAA;IAClB;AAEA,UAAM,EAAEC,SAAS,GAAGC,SAASH,SAASG,OAAM,IAAKJ;AAEjD,QAAIG,SAASC,SAASH,SAASG,QAAQ;AACrC,YAAM,IAAIF,MAAM,eAAA;IAClB;AAEA,QAAID,SAASI,UAAUlB,UAASmB,MAAMC,eAAe;AACnD,YAAMC,QAAO,KAAKC,aAAaZ,EAAAA;AAC/B,aAAOW,MAAKE,KAAKP,QAAQC,MAAAA;IAC3B,WAAWJ,QAAQG,WAAWQ,UAAaX,QAAQI,WAAWO,QAAW;AACvE,YAAM,IAAIT,MAAM,oBAAA;IAClB;AAEA,UAAMU,aAAaC,KAAKC,MAAMX,SAASF,SAASc,SAAS;AACzD,UAAMC,WAAWH,KAAKI,MAAMd,SAASC,UAAUH,SAASc,SAAS;AAEjE/B,IAAAA,WAAUiB,SAASiB,UAAU,wBAAA;;;;;;;;;AAC7BlC,IAAAA,WAAUiB,SAASiB,SAASd,SAAS,KAAKY,UAAU,2BAAA;;;;;;;;;AAEpD,UAAMG,UAAU/B,UAASgC,MAAMnB,SAASiB,UAAUN,YAAYI,QAAAA,MAAcA,WAAWJ;AAEvF,QAAI,CAACO,SAAS;AACZ,YAAM,IAAIjB,MAAM,oBAAA;IAClB;AAEA,UAAMM,OAAO,KAAKC,aAAaZ,EAAAA;AAC/B,WAAOW,KAAKE,KAAKP,QAAQC,MAAAA;EAC3B;EAEA,MACMiB,OAA4B;AAQhC,UAAMC,QAAQ,IAAIC,KAAK,MAAM,KAAK5B,WAAW0B,KAAI,GAAIG,IAAI,CAACC,MAAMA,EAAEC,MAAM,GAAA,EAAK,CAAA,CAAE,CAAA;AAE/E,UAAMC,MAAkB,CAAA;AAExB,eAAWnB,QAAQc,OAAO;AACxB,YAAMzB,KAAKZ,WAAU2C,KAAKpB,IAAAA,EAAMqB,aAAY;AAC5C,YAAMC,OAAO,MAAM,KAAKhC,SAASD,EAAAA;AACjC,UAAIiC,MAAM;AACRH,YAAII,KAAKD,IAAAA;MACX;IACF;AAEA,WAAOH;EACT;EAEA,MACMK,IAAIC,MAAqC;AAC7C,UAAMpC,KAAK,IAAIqC,WAAW,MAAMnD,aAAaoD,OAAO,WAAWF,IAAAA,CAAAA;AAC/D,UAAMf,WAAW9B,UAASgD,KAAKH,KAAK7B,SAASd,kBAAAA;AAE7C,UAAMwC,OAAiB;MACrBjC;MACAQ,OAAOlB,UAASmB,MAAMC;MACtBH,QAAQ6B,KAAK7B;MACbW,WAAWzB;MACX4B;MACAmB,SAAS,oBAAIC,KAAAA;MACbC,SAAS,oBAAID,KAAAA;IACf;AAEA,UAAM,KAAK7B,aAAaZ,EAAAA,EAAI2C,MAAM,GAAGnD,cAAc4C,IAAAA,CAAAA;AACnD,UAAM,KAAKQ,WAAW5C,IAAIiC,IAAAA;AAC1B,WAAOA;EACT;;EAGA,MACMY,SAASC,OAAqC;AAElD,QAAIb,OAAO,MAAM,KAAKhC,SAAS6C,MAAM9C,EAAE;AACvC,QAAI,CAACiC,MAAM;AACT9C,MAAAA,WAAU2D,MAAMC,aAAa,8BAAA;;;;;;;;;AAC7Bd,aAAO;QACLjC,IAAI8C,MAAM9C;QACVQ,OAAOlB,UAASmB,MAAMuC;QACtBzC,QAAQuC,MAAMC;QACd7B,WAAW4B,MAAM5B,aAAazB;QAC9B+C,SAAS,oBAAIC,KAAAA;MACf;AACAR,WAAKZ,WAAW9B,UAAS0D,MAAMhB,KAAK1B,SAAS0B,KAAKf,SAAS;IAC7D;AAEA,QAAI4B,MAAM5B,aAAa4B,MAAM5B,cAAce,KAAKf,WAAW;AACzD,YAAM,IAAIb,MAAM,oBAAA;IAClB;AAEAlB,IAAAA,WAAU8C,KAAKZ,UAAU,wBAAA;;;;;;;;;AACzBlC,IAAAA,WAAU2D,MAAMI,gBAAgBpC,QAAW,8BAAA;;;;;;;;;AAG3C,UAAM,KAAKF,aAAakC,MAAM9C,EAAE,EAAE2C,MAAMG,MAAMI,aAAa1D,cAAcsD,MAAMK,OAAO,CAAA;AAGtF5D,IAAAA,UAAS4C,IAAIF,KAAKZ,UAAUL,KAAKC,MAAM6B,MAAMI,cAAcjB,KAAKf,SAAS,GAAG,IAAA;AAG5E,QAAI3B,UAASgC,MAAMU,KAAKZ,UAAU,GAAGY,KAAK1B,MAAM,IAAI0B,KAAKf,aAAae,KAAK1B,QAAQ;AACjF0B,WAAKzB,QAAQlB,UAASmB,MAAMC;IAC9B;AACAuB,SAAKS,UAAU,oBAAID,KAAAA;AAEnB,UAAM,KAAKG,WAAWE,MAAM9C,IAAIiC,IAAAA;AAEhC,WAAOA;EACT;EAEA,MAAcW,WAAW5C,IAAgBiC,MAA+B;AACtE,UAAMmB,UAAU5D,cAAcE,cAAc2D,OAAOpB,IAAAA,CAAAA;AACnD,UAAMG,OAAOkB,OAAOC,MAAMH,QAAQ7C,SAAS,CAAA;AAC3C6B,SAAKoB,cAAcJ,QAAQ7C,QAAQ,CAAA;AACnC6C,YAAQK,KAAKrB,MAAM,CAAA;AAGnB,UAAM,KAAKsB,aAAa1D,EAAAA,EAAI2C,MAAM,GAAGP,IAAAA;EACvC;EAEA,MAAcnC,SAASD,IAA+C;AACpE,UAAMW,OAAO,KAAK+C,aAAa1D,EAAAA;AAC/B,UAAM2D,QAAQ,MAAMhD,KAAKiD,KAAI,GAAID;AACjC,QAAIA,SAAS,GAAG;AACd;IACF;AACA,UAAMvB,OAAO,MAAMzB,KAAKE,KAAK,GAAG8C,IAAAA;AAChC,UAAME,YAAYzB,KAAK0B,aAAa,CAAA;AACpC,WAAOpE,cAAcqE,OAAO3B,KAAK4B,SAAS,GAAGH,YAAY,CAAA,CAAA;EAC3D;EAEQH,aAAa1D,IAAgB;AACnC,WAAO,KAAKF,WAAWmE,gBAAgBjF,KAAKkF,KAAK1E,cAAcQ,EAAAA,EAAImE,SAAS,KAAA,GAAQ,MAAA,CAAA;EACtF;EAEQvD,aAAaZ,IAAgB;AACnC,WAAO,KAAKF,WAAWmE,gBAAgBjF,KAAKkF,KAAK1E,cAAcQ,EAAAA,EAAImE,SAAS,KAAA,GAAQ,MAAA,CAAA;EACtF;AACF;;EA9JGlF;GAHUW,UAAAA,WAAAA,WAAAA,IAAAA;;EAWVX;GAXUW,UAAAA,WAAAA,OAAAA,IAAAA;;EAgDVX;GAhDUW,UAAAA,WAAAA,QAAAA,IAAAA;;EAwEVX;GAxEUW,UAAAA,WAAAA,OAAAA,IAAAA;;EA6FVX;GA7FUW,UAAAA,WAAAA,YAAAA,IAAAA;",
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"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytes":24384,"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":17817,"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":"@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}],"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/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":29905},"packages/core/mesh/teleport-extension-object-sync/dist/lib/browser/index.mjs":{"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":"@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":{"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytesInOutput":7121},"packages/core/mesh/teleport-extension-object-sync/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts":{"bytesInOutput":5176},"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts":{"bytesInOutput":6547}},"bytes":19215}}}
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":"@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}],"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/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":30506},"packages/core/mesh/teleport-extension-object-sync/dist/lib/browser/index.mjs":{"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":"@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":{"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":19685}}}
@@ -87,7 +87,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
87
87
  this._ctx = new import_context.Context({
88
88
  onError: (err) => import_log.log.catch(err, void 0, {
89
89
  F: __dxlog_file,
90
- L: 33,
90
+ L: 34,
91
91
  S: this,
92
92
  C: (f, a) => f(...a)
93
93
  })
@@ -107,7 +107,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
107
107
  list: this._localWantList
108
108
  }, {
109
109
  F: __dxlog_file,
110
- L: 47,
110
+ L: 48,
111
111
  S: this,
112
112
  C: (f, a) => f(...a)
113
113
  });
@@ -136,7 +136,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
136
136
  err
137
137
  }, {
138
138
  F: __dxlog_file,
139
- L: 74,
139
+ L: 75,
140
140
  S: this,
141
141
  C: (f, a) => f(...a)
142
142
  });
@@ -153,7 +153,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
153
153
  async onOpen(context) {
154
154
  (0, import_log.log)("open", void 0, {
155
155
  F: __dxlog_file,
156
- L: 106,
156
+ L: 107,
157
157
  S: this,
158
158
  C: (f, a) => f(...a)
159
159
  });
@@ -163,7 +163,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
163
163
  async onClose(err) {
164
164
  (0, import_log.log)("close", void 0, {
165
165
  F: __dxlog_file,
166
- L: 112,
166
+ L: 113,
167
167
  S: this,
168
168
  C: (f, a) => f(...a)
169
169
  });
@@ -171,6 +171,17 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
171
171
  await this._params.onClose();
172
172
  await super.onClose(err);
173
173
  }
174
+ async onAbort(err) {
175
+ (0, import_log.log)("abort", void 0, {
176
+ F: __dxlog_file,
177
+ L: 120,
178
+ S: this,
179
+ C: (f, a) => f(...a)
180
+ });
181
+ await this._ctx.dispose();
182
+ await this._params.onAbort();
183
+ await super.onAbort(err);
184
+ }
174
185
  async getHandlers() {
175
186
  return {
176
187
  BlobSyncService: {
@@ -179,7 +190,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
179
190
  remoteWantList: wantList
180
191
  }, {
181
192
  F: __dxlog_file,
182
- L: 122,
193
+ L: 130,
183
194
  S: this,
184
195
  C: (f, a) => f(...a)
185
196
  });
@@ -191,7 +202,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
191
202
  data
192
203
  }, {
193
204
  F: __dxlog_file,
194
- L: 127,
205
+ L: 135,
195
206
  S: this,
196
207
  C: (f, a) => f(...a)
197
208
  });
@@ -208,7 +219,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
208
219
  data
209
220
  }, {
210
221
  F: __dxlog_file,
211
- L: 139,
222
+ L: 147,
212
223
  S: this,
213
224
  C: (f, a) => f(...a)
214
225
  });
@@ -245,7 +256,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
245
256
  }
246
257
  (0, import_invariant.invariant)(meta.bitfield, void 0, {
247
258
  F: __dxlog_file,
248
- L: 178,
259
+ L: 186,
249
260
  S: this,
250
261
  A: [
251
262
  "meta.bitfield",
@@ -254,7 +265,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
254
265
  });
255
266
  (0, import_invariant.invariant)(meta.chunkSize, void 0, {
256
267
  F: __dxlog_file,
257
- L: 179,
268
+ L: 187,
258
269
  S: this,
259
270
  A: [
260
271
  "meta.chunkSize",
@@ -263,7 +274,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
263
274
  });
264
275
  (0, import_invariant.invariant)(meta.length, void 0, {
265
276
  F: __dxlog_file,
266
- L: 180,
277
+ L: 188,
267
278
  S: this,
268
279
  A: [
269
280
  "meta.length",
@@ -276,7 +287,7 @@ var BlobSyncExtension = class extends import_teleport.RpcExtension {
276
287
  meta
277
288
  }, {
278
289
  F: __dxlog_file,
279
- L: 183,
290
+ L: 191,
280
291
  S: this,
281
292
  C: (f, a) => f(...a)
282
293
  });
@@ -404,6 +415,15 @@ var BlobSync = class BlobSync2 {
404
415
  });
405
416
  this._extensions.delete(extension);
406
417
  },
418
+ onAbort: async () => {
419
+ (0, import_log2.log)("extension aborted", void 0, {
420
+ F: __dxlog_file2,
421
+ L: 114,
422
+ S: this,
423
+ C: (f, a) => f(...a)
424
+ });
425
+ this._extensions.delete(extension);
426
+ },
407
427
  onPush: async (blobChunk) => {
408
428
  if (!this._downloadRequests.has(blobChunk.id)) {
409
429
  return;
@@ -412,7 +432,7 @@ var BlobSync = class BlobSync2 {
412
432
  blobChunk
413
433
  }, {
414
434
  F: __dxlog_file2,
415
- L: 117,
435
+ L: 121,
416
436
  S: this,
417
437
  C: (f, a) => f(...a)
418
438
  });
@@ -423,7 +443,7 @@ var BlobSync = class BlobSync2 {
423
443
  } else {
424
444
  (0, import_invariant2.invariant)(meta.bitfield, void 0, {
425
445
  F: __dxlog_file2,
426
- L: 123,
446
+ L: 127,
427
447
  S: this,
428
448
  A: [
429
449
  "meta.bitfield",
@@ -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 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 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 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": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,mBAAkD;AAClD,qBAAwB;AACxB,uBAA0B;AAC1B,iBAAoB;AACpB,uBAAuC;AAEvC,sBAAoD;AACpD,kBAAyB;ACTzB,IAAAA,gBAA0C;AAC1C,IAAAC,kBAA2C;AAC3C,IAAAC,oBAA0B;AAC1B,kBAA0B;AAC1B,IAAAC,cAAoB;AACpB,kBAAyB;AAEzB,IAAAC,eAAqC;ACPrC,uBAAiB;AAEjB,IAAAJ,gBAA6B;AAC7B,oBAA6B;AAC7B,IAAAE,oBAA0B;AAC1B,IAAAG,eAA0B;AAC1B,IAAAC,oBAAuB;AACvB,IAAAC,eAAyB;AAGzB,IAAAH,eAAwC;;;;;;;;;;;;AFUxC,IAAMI,gCAAgCC,QAAQC,IAAIC,aAAa,SAAS,IAAI;AAE5E,IAAMC,yBAAyB;AAKxB,IAAMC,oBAAN,cAAgCC,6BAAAA;EAwDrCC,YACmBC,SACjB;AACA,UAAM;MACJC,SAAS;QACPC,iBAAiBC,wBAAOC,WAAW,6CAAA;MACrC;MACAC,WAAW;QACTH,iBAAiBC,wBAAOC,WAAW,6CAAA;MACrC;MACAE,SAAS;MACTC,iBAAiB;QACfC,aAAa;MACf;IACF,CAAA;mBAbiBR;SAxDFS,OAAO,IAAIC,uBAAQ;MAAEC,SAAS,CAACC,QAAQC,eAAIC,MAAMF,KAAAA,QAAAA;;;;;;IAAK,CAAA;SAE/DG,sBAAsB;SACtBC,iBAA2B;MAAEC,OAAO,CAAA;IAAG;SAE9BC,kBAAkB,IAAIC,0BAAa,KAAKV,MAAM,YAAA;AAE7D,UAAI,KAAKM,sBAAsBvB,gCAAgC4B,KAAKC,IAAG,GAAI;AACzE,kBAAMC,oBAAM,KAAKP,sBAAsBvB,gCAAgC4B,KAAKC,IAAG,CAAA;AAC/E,YAAI,KAAKZ,KAAKc,UAAU;AACtB;QACF;MACF;AAEAV,0BAAI,QAAQ;QAAEW,MAAM,KAAKR;MAAe,GAAA;;;;;;AACxC,YAAM,KAAKS,IAAIvB,gBAAgBwB,KAAK,KAAKV,cAAc;AACvD,WAAKD,sBAAsBK,KAAKC,IAAG;IACrC,CAAA;SAEQM,kBAAkB;SAETC,UAAU,IAAIT,0BAAa,KAAKV,MAAM,YAAA;AACrD,UAAI,KAAKkB,mBAAmB/B,wBAAwB;AAClD;MACF;AACA,YAAMiC,aAAa,MAAM,KAAKC,gBAAgBlC,yBAAyB,KAAK+B,eAAe;AAC3F,UAAI,CAACE,YAAY;AACf;MACF;AACA,iBAAWE,aAAaF,YAAY;AAClC,YAAI,KAAKpB,KAAKc,UAAU;AACtB;QACF;AAEA,aAAKI;AAEL,aAAKK,KAAKD,SAAAA,EACPjB,MAAM,CAACF,QAAAA;AACN,cAAIA,eAAeqB,iCAAgB;AACjC;UACF;AACApB,yBAAIqB,KAAK,eAAe;YAAEtB;UAAI,GAAA;;;;;;QAChC,CAAA,EACCuB,QAAQ,MAAA;AACP,eAAKR;AACL,eAAKS,iBAAgB;QACvB,CAAA;MACJ;IACF,CAAA;SAKOC,iBAA2B;MAAEpB,OAAO,CAAA;IAAG;EAiB9C;EAEA,MAAeqB,OAAOC,SAA0C;AAC9D1B,wBAAI,QAAA,QAAA;;;;;;AACJ,UAAM,MAAMyB,OAAOC,OAAAA;AACnB,UAAM,KAAKvC,QAAQsC,OAAM;EAC3B;EAEA,MAAeE,QAAQ5B,KAAwC;AAC7DC,wBAAI,SAAA,QAAA;;;;;;AACJ,UAAM,KAAKJ,KAAKgC,QAAO;AACvB,UAAM,KAAKzC,QAAQwC,QAAO;AAC1B,UAAM,MAAMA,QAAQ5B,GAAAA;EACtB;EAEA,MAAgB8B,cAAsC;AACpD,WAAO;MACLxC,iBAAiB;QACfwB,MAAM,OAAOiB,aAAAA;AACX9B,8BAAI,eAAe;YAAEwB,gBAAgBM;UAAS,GAAA;;;;;;AAC9C,eAAKN,iBAAiBM;AACtB,eAAKP,iBAAgB;QACvB;QACAJ,MAAM,OAAOY,SAAAA;AACX/B,8BAAI,YAAY;YAAE+B;UAAK,GAAA;;;;;;AACvB,gBAAM,KAAK5C,QAAQ6C,OAAOD,IAAAA;QAC5B;MACF;IACF;EACF;EAEA,MACMZ,KAAKY,MAAiB;AAC1B,QAAI,KAAKnC,KAAKc,UAAU;AACtB;IACF;AACAV,wBAAI,QAAQ;MAAE+B;IAAK,GAAA;;;;;;AACnB,UAAM,KAAKnB,IAAIvB,gBAAgB8B,KAAKY,IAAAA;EACtC;EAEAE,eAAeH,UAAoB;AACjC,QAAI,KAAKlC,KAAKc,UAAU;AACtB;IACF;AACA,SAAKP,iBAAiB2B;AACtB,SAAKzB,gBAAgB6B,SAAQ;EAC/B;EAEAX,mBAAmB;AACjB,QAAI,KAAK3B,KAAKc,UAAU;AACtB;IACF;AACA,SAAKK,QAAQmB,SAAQ;EACvB;EAEA,MAAcjB,gBAAgBkB,SAAS,GAAgC;AACrE,QAAI,KAAKvC,KAAKc,UAAU;AACtB;IACF;AAEA,QAAI,CAAC,KAAKc,eAAepB,SAAS,KAAKoB,eAAepB,OAAOgC,WAAW,GAAG;AACzE;IACF;AAEA,UAAMC,WAAW;SAAI,KAAKb,eAAepB;MAAOkC,KAAK,MAAMC,KAAKC,OAAM,IAAK,GAAA;AAE3E,UAAMC,SAAsB,CAAA;AAE5B,eAAWC,UAAUL,UAAU;AAC7B,YAAMM,OAAO,MAAM,KAAKxD,QAAQyD,UAAUC,QAAQH,OAAOI,EAAE;AAE3D,UAAI,CAACH,MAAM;AAET;MACF;AACAI,sCAAUJ,KAAKK,UAAQ,QAAA;;;;;;;;;AACvBD,sCAAUJ,KAAKM,WAAS,QAAA;;;;;;;;;AACxBF,sCAAUJ,KAAKP,QAAM,QAAA;;;;;;;;;AAErB,UAAIM,OAAOO,aAAaP,OAAOO,cAAcN,KAAKM,WAAW;AAC3DjD,uBAAIqB,KAAK,sBAAsB;UAAEqB;UAAQC;QAAK,GAAA;;;;;;AAC9C;MACF;AAEA,YAAMO,kBAAkBR,OAAOM,YAAYG,qBAASC,KAAKT,KAAKP,SAASO,KAAKM,SAAS;AAErF,YAAMI,cAAcF,qBAASG,IAAIJ,iBAAiBP,KAAKK,QAAQ;AAC/D,YAAMO,eAAeJ,qBAASK,YAAYH,WAAAA,EAAaf,KAAK,MAAMC,KAAKC,OAAM,IAAK,GAAA;AAElF,iBAAWiB,OAAOF,cAAc;AAC9B,cAAMG,YAAY,MAAM,KAAKvE,QAAQyD,UAAUe,IAAIjB,OAAOI,IAAI;UAC5Dc,QAAQH,MAAMd,KAAKM;UACnBb,QAAQG,KAAKsB,IAAIlB,KAAKM,WAAWN,KAAKP,SAASqB,MAAMd,KAAKM,SAAS;QACrE,CAAA;AACAR,eAAOtB,KAAK;UACV2B,IAAIJ,OAAOI;UACXgB,aAAanB,KAAKP;UAClBa,WAAWN,KAAKM;UAChBc,aAAaN,MAAMd,KAAKM;UACxBe,SAASN;QACX,CAAA;AAEA,YAAIjB,OAAOL,UAAUD,QAAQ;AAC3B,iBAAOM;QACT;MACF;IACF;AAEA,WAAOA;EACT;AACF;;EA/EGwB;GAtGUjF,kBAAAA,WAAAA,QAAAA,IAAAA;;;;;;;;;;;;ACHb,IAAakF,WAAN,MAAAA,UAAA;EAULhF,YAA6BC,SAAyB;mBAAzBA;SATZS,OAAO,IAAIC,gBAAAA,QAAAA;SACXsE,QAAQ,IAAIC,mBAAAA;SAEZC,oBAAoB,IAAIC,wBAAwC,CAACC,QAChFC,sBAAUC,KAAKF,GAAAA,EAAKG,MAAK,CAAA;SAGVC,cAAc,oBAAIC,IAAAA;EAEoB;EAEvD,MAAMC,OAAO;EAAC;EAEd,MAAMC,QAAQ;AACZ,UAAM,KAAKlF,KAAKgC,QAAO;EACzB;;;;;;EAOA,MAAMmD,SAASC,KAAclC,IAA+B;AAC1D9C,oBAAAA,KAAI,YAAY;MAAE8C;IAAG,GAAA;;;;;;AACrB,UAAMmC,UAAU,MAAM,KAAKd,MAAMe,oBAAoB,YAAA;AACnD,YAAMC,kBAAkB,KAAKd,kBAAkBV,IAAIb,EAAAA;AAEnD,UAAIqC,iBAAiB;AACnBA,wBAAgBC;AAChB,eAAOD;MACT;AAEA,YAAMxC,OAAO,MAAM,KAAKxD,QAAQyD,UAAUC,QAAQC,EAAAA;AAClD,YAAMmC,WAA2B;QAC/BI,SAAS,IAAIC,sBAAAA;QACbF,SAAS;QACTvE,MAAM;UACJiC;UACAG,WAAWN,MAAMM;UACjBD,UAAUL,MAAMK,YAAYuC,WAAWd,KAAKtB,aAAAA,SAASqC,OAAO7C,KAAKK,QAAQ,CAAA;QAC3E;MACF;AAGA,UAAIL,MAAM8C,UAAUC,qBAASC,MAAMC,eAAe;AAChDX,iBAAQI,QAAQQ,KAAI;MACtB,OAAO;AACL,aAAKxB,kBAAkByB,IAAIhD,IAAImC,QAAAA;AAC/B,aAAKc,0BAAyB;MAChC;AAEA,aAAOd;IACT,CAAA;AAEAD,SAAKgB,UAAU,MACb,KAAK7B,MAAMe,oBAAoB,YAAA;AAE7B,YAAMD,WAAU,KAAKZ,kBAAkBV,IAAIb,EAAAA;AAC3C,UAAI,CAACmC,UAAS;AACZ;MACF;AACA,UAAI,EAAEA,SAAQG,YAAY,GAAG;AAC3B,aAAKf,kBAAkB4B,OAAOnD,EAAAA;MAChC;AACA,WAAKiD,0BAAyB;IAChC,CAAA,CAAA;AAGF,WAAOf,UAAMkB,mCAAkBlB,KAAKC,QAAQI,QAAQc,KAAI,CAAA,IAAMlB,QAAQI,QAAQc,KAAI;EACpF;EAEAC,kBAAkB;AAChB,UAAMC,YAAY,IAAIrH,kBAAkB;MACtC4D,WAAW,KAAKzD,QAAQyD;MACxBnB,QAAQ,YAAA;AACNzB,wBAAAA,KAAI,oBAAA,QAAA;;;;;;AACJ,aAAK2E,YAAY2B,IAAID,SAAAA;AACrBA,kBAAUpE,eAAe,KAAKsE,aAAY,CAAA;MAC5C;MACA5E,SAAS,YAAA;AACP3B,wBAAAA,KAAI,oBAAA,QAAA;;;;;;AACJ,aAAK2E,YAAYsB,OAAOI,SAAAA;MAC1B;MACArE,QAAQ,OAAOd,cAAAA;AACb,YAAI,CAAC,KAAKmD,kBAAkBmC,IAAItF,UAAU4B,EAAE,GAAG;AAC7C;QACF;AACA9C,wBAAAA,KAAI,YAAY;UAAEkB;QAAU,GAAA;;;;;;AAC5B,cAAMyB,OAAO,MAAM,KAAKxD,QAAQyD,UAAU6D,SAASvF,SAAAA;AACnD,YAAIyB,KAAK8C,UAAUC,qBAASC,MAAMC,eAAe;AAC/C,eAAKvB,kBAAkBV,IAAIzC,UAAU4B,EAAE,GAAGuC,QAAQQ,KAAAA;AAClD,eAAKxB,kBAAkB4B,OAAO/E,UAAU4B,EAAE;QAC5C,OAAO;AACLC,gCAAAA,WAAUJ,KAAKK,UAAQ,QAAA;;;;;;;;;AACvB,eAAKqB,kBAAkBV,IAAIzC,UAAU4B,EAAE,EAAGjC,KAAKmC,WAAWG,aAAAA,SAASqC,OAAO7C,KAAKK,QAAQ;QACzF;AAEA,aAAK+C,0BAAyB;AAC9B,aAAKW,kBAAiB;MACxB;IACF,CAAA;AACA,WAAOL;EACT;;;;EAKA,MAAMM,gBAAgBC,KAAiB;AACrC,SAAKF,kBAAiB;EACxB;EAEQH,eAAyB;AAC/B,WAAO;MACLnG,OAAOyG,MAAMpC,KAAK,KAAKJ,kBAAkByC,OAAM,CAAA,EAAIC,IAAI,CAAC9B,YAAYA,QAAQpE,IAAI;IAClF;EACF;EAEQ6F,oBAAoB;AAC1B,eAAWL,aAAa,KAAK1B,aAAa;AACxC0B,gBAAU9E,iBAAgB;IAC5B;EACF;EAEQwE,4BAA4B;AAClC,eAAWM,aAAa,KAAK1B,aAAa;AACxC0B,gBAAUpE,eAAe,KAAKsE,aAAY,CAAA;IAC5C;EACF;AACF;AAjIarC,WAAAA,cAAAA;MADZ8C,0BAAW,QAAQ,OAAA;GACP9C,QAAAA;;;;;;;;;;;;ACPN,IAAM+C,qBAAqB;AAElC,IAAMC,gBAAgB5H,kBAAAA,OAAO6H,gBAAgB,yBAAA;AAEtC,IAAMC,YAAN,MAAMA;EACXlI,YAA6BmI,YAAuB;sBAAvBA;EAAwB;EAErD,MACMxE,QAAQC,IAA+C;AAC3D,WAAO,KAAKwE,SAASxE,EAAAA;EACvB;;;;EAKA,MACMa,IAAIb,IAAgByE,UAAsB,CAAC,GAAwB;AACvE,UAAMC,WAAW,MAAM,KAAKF,SAASxE,EAAAA;AAErC,QAAI,CAAC0E,UAAU;AACb,YAAM,IAAIC,MAAM,oBAAA;IAClB;AAEA,UAAM,EAAE7D,SAAS,GAAGxB,SAASoF,SAASpF,OAAM,IAAKmF;AAEjD,QAAI3D,SAASxB,SAASoF,SAASpF,QAAQ;AACrC,YAAM,IAAIqF,MAAM,eAAA;IAClB;AAEA,QAAID,SAAS/B,UAAUC,aAAAA,SAASC,MAAMC,eAAe;AACnD,YAAM8B,QAAO,KAAKC,aAAa7E,EAAAA;AAC/B,aAAO4E,MAAKE,KAAKhE,QAAQxB,MAAAA;IAC3B,WAAWmF,QAAQ3D,WAAWiE,UAAaN,QAAQnF,WAAWyF,QAAW;AACvE,YAAM,IAAIJ,MAAM,oBAAA;IAClB;AAEA,UAAMK,aAAavF,KAAKwF,MAAMnE,SAAS4D,SAASvE,SAAS;AACzD,UAAM+E,WAAWzF,KAAK0F,MAAMrE,SAASxB,UAAUoF,SAASvE,SAAS;AAEjEF,0BAAAA,WAAUyE,SAASxE,UAAU,wBAAA;;;;;;;;;AAC7BD,0BAAAA,WAAUyE,SAASxE,SAASZ,SAAS,KAAK4F,UAAU,2BAAA;;;;;;;;;AAEpD,UAAME,UAAU/E,aAAAA,SAASgF,MAAMX,SAASxE,UAAU8E,YAAYE,QAAAA,MAAcA,WAAWF;AAEvF,QAAI,CAACI,SAAS;AACZ,YAAM,IAAIT,MAAM,oBAAA;IAClB;AAEA,UAAMC,OAAO,KAAKC,aAAa7E,EAAAA;AAC/B,WAAO4E,KAAKE,KAAKhE,QAAQxB,MAAAA;EAC3B;EAEA,MACMzB,OAA4B;AAQhC,UAAMyH,QAAQ,IAAIxD,KAAK,MAAM,KAAKyC,WAAW1G,KAAI,GAAIoG,IAAI,CAACsB,MAAMA,EAAEC,MAAM,GAAA,EAAK,CAAA,CAAE,CAAA;AAE/E,UAAMC,MAAkB,CAAA;AAExB,eAAWb,QAAQU,OAAO;AACxB,YAAMtF,KAAK0B,aAAAA,UAAUC,KAAKiD,IAAAA,EAAMc,aAAY;AAC5C,YAAM7F,OAAO,MAAM,KAAK2E,SAASxE,EAAAA;AACjC,UAAIH,MAAM;AACR4F,YAAIpH,KAAKwB,IAAAA;MACX;IACF;AAEA,WAAO4F;EACT;EAEA,MACMzC,IAAI/D,MAAqC;AAC7C,UAAMe,KAAK,IAAIyC,WAAW,MAAMkD,2BAAaC,OAAO,WAAW3G,IAAAA,CAAAA;AAC/D,UAAMiB,WAAWG,aAAAA,SAASC,KAAKrB,KAAKK,SAAS6E,kBAAAA;AAE7C,UAAMtE,OAAiB;MACrBG;MACA2C,OAAOC,aAAAA,SAASC,MAAMC;MACtBxD,QAAQL,KAAKK;MACba,WAAWgE;MACXjE;MACA2F,SAAS,oBAAIpI,KAAAA;MACbqI,SAAS,oBAAIrI,KAAAA;IACf;AAEA,UAAM,KAAKoH,aAAa7E,EAAAA,EAAI+F,MAAM,OAAGC,4BAAc/G,IAAAA,CAAAA;AACnD,UAAM,KAAKgH,WAAWjG,IAAIH,IAAAA;AAC1B,WAAOA;EACT;;EAGA,MACM8D,SAASuC,OAAqC;AAElD,QAAIrG,OAAO,MAAM,KAAK2E,SAAS0B,MAAMlG,EAAE;AACvC,QAAI,CAACH,MAAM;AACTI,4BAAAA,WAAUiG,MAAMlF,aAAa,8BAAA;;;;;;;;;AAC7BnB,aAAO;QACLG,IAAIkG,MAAMlG;QACV2C,OAAOC,aAAAA,SAASC,MAAMsD;QACtB7G,QAAQ4G,MAAMlF;QACdb,WAAW+F,MAAM/F,aAAagE;QAC9B0B,SAAS,oBAAIpI,KAAAA;MACf;AACAoC,WAAKK,WAAWG,aAAAA,SAAS+F,MAAMvG,KAAKP,SAASO,KAAKM,SAAS;IAC7D;AAEA,QAAI+F,MAAM/F,aAAa+F,MAAM/F,cAAcN,KAAKM,WAAW;AACzD,YAAM,IAAIwE,MAAM,oBAAA;IAClB;AAEA1E,0BAAAA,WAAUJ,KAAKK,UAAU,wBAAA;;;;;;;;;AACzBD,0BAAAA,WAAUiG,MAAMjF,gBAAgB8D,QAAW,8BAAA;;;;;;;;;AAG3C,UAAM,KAAKF,aAAaqB,MAAMlG,EAAE,EAAE+F,MAAMG,MAAMjF,iBAAa+E,4BAAcE,MAAMhF,OAAO,CAAA;AAGtFb,iBAAAA,SAAS2C,IAAInD,KAAKK,UAAUT,KAAKwF,MAAMiB,MAAMjF,cAAcpB,KAAKM,SAAS,GAAG,IAAA;AAG5E,QAAIE,aAAAA,SAASgF,MAAMxF,KAAKK,UAAU,GAAGL,KAAKP,MAAM,IAAIO,KAAKM,aAAaN,KAAKP,QAAQ;AACjFO,WAAK8C,QAAQC,aAAAA,SAASC,MAAMC;IAC9B;AACAjD,SAAKiG,UAAU,oBAAIrI,KAAAA;AAEnB,UAAM,KAAKwI,WAAWC,MAAMlG,IAAIH,IAAAA;AAEhC,WAAOA;EACT;EAEA,MAAcoG,WAAWjG,IAAgBH,MAA+B;AACtE,UAAMwG,cAAUL,4BAAc5B,cAAckC,OAAOzG,IAAAA,CAAAA;AACnD,UAAMZ,OAAOsH,OAAOC,MAAMH,QAAQ/G,SAAS,CAAA;AAC3CL,SAAKwH,cAAcJ,QAAQ/G,QAAQ,CAAA;AACnC+G,YAAQK,KAAKzH,MAAM,CAAA;AAGnB,UAAM,KAAK0H,aAAa3G,EAAAA,EAAI+F,MAAM,GAAG9G,IAAAA;EACvC;EAEA,MAAcuF,SAASxE,IAA+C;AACpE,UAAM4E,OAAO,KAAK+B,aAAa3G,EAAAA;AAC/B,UAAM4G,QAAQ,MAAMhC,KAAKiC,KAAI,GAAID;AACjC,QAAIA,SAAS,GAAG;AACd;IACF;AACA,UAAM3H,OAAO,MAAM2F,KAAKE,KAAK,GAAG8B,IAAAA;AAChC,UAAME,YAAY7H,KAAK8H,aAAa,CAAA;AACpC,WAAO3C,cAAc4C,OAAO/H,KAAKgI,SAAS,GAAGH,YAAY,CAAA,CAAA;EAC3D;EAEQH,aAAa3G,IAAgB;AACnC,WAAO,KAAKuE,WAAW2C,gBAAgBC,iBAAAA,QAAKC,SAAKpB,4BAAchG,EAAAA,EAAIqH,SAAS,KAAA,GAAQ,MAAA,CAAA;EACtF;EAEQxC,aAAa7E,IAAgB;AACnC,WAAO,KAAKuE,WAAW2C,gBAAgBC,iBAAAA,QAAKC,SAAKpB,4BAAchG,EAAAA,EAAIqH,SAAS,KAAA,GAAQ,MAAA,CAAA;EACtF;AACF;;EA9JGlG,cAAAA;GAHUmD,UAAAA,WAAAA,WAAAA,IAAAA;;EAWVnD,cAAAA;GAXUmD,UAAAA,WAAAA,OAAAA,IAAAA;;EAgDVnD,cAAAA;GAhDUmD,UAAAA,WAAAA,QAAAA,IAAAA;;EAwEVnD,cAAAA;GAxEUmD,UAAAA,WAAAA,OAAAA,IAAAA;;EA6FVnD,cAAAA;GA7FUmD,UAAAA,WAAAA,YAAAA,IAAAA;",
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", "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, 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"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts":{"bytes":24384,"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":17817,"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":29938},"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":7147},"packages/core/mesh/teleport-extension-object-sync/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts":{"bytesInOutput":5176},"packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts":{"bytesInOutput":6537}},"bytes":19197}}}
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}}}
@@ -5,6 +5,7 @@ export type BlobSyncExtensionParams = {
5
5
  blobStore: BlobStore;
6
6
  onOpen: () => Promise<void>;
7
7
  onClose: () => Promise<void>;
8
+ onAbort: () => Promise<void>;
8
9
  onPush: (data: BlobChunk) => Promise<void>;
9
10
  };
10
11
  /**
@@ -25,6 +26,7 @@ export declare class BlobSyncExtension extends RpcExtension<ServiceBundle, Servi
25
26
  constructor(_params: BlobSyncExtensionParams);
26
27
  onOpen(context: ExtensionContext): Promise<void>;
27
28
  onClose(err?: Error | undefined): Promise<void>;
29
+ onAbort(err?: Error | undefined): Promise<void>;
28
30
  protected getHandlers(): Promise<ServiceBundle>;
29
31
  push(data: BlobChunk): Promise<void>;
30
32
  updateWantList(wantList: WantList): void;
@@ -1 +1 @@
1
- {"version":3,"file":"blob-sync-extension.d.ts","sourceRoot":"","sources":["../../../src/blob-sync-extension.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,mDAAmD,CAAC;AACxH,OAAO,EAAE,KAAK,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C,CAAC;AAMF;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,YAAY,CAAC,aAAa,EAAE,aAAa,CAAC;IAyD7E,OAAO,CAAC,QAAQ,CAAC,OAAO;IAxD1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqD;IAE1E,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,cAAc,CAA2B;IAEjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAY7B;IAEH,OAAO,CAAC,eAAe,CAAK;IAE5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CA2BrB;IAEH;;OAEG;IACI,cAAc,EAAE,QAAQ,CAAiB;gBAG7B,OAAO,EAAE,uBAAuB;IAgBpC,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;cAO9C,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC;IAiB/C,IAAI,CAAC,IAAI,EAAE,SAAS;IAQ1B,cAAc,CAAC,QAAQ,EAAE,QAAQ;IAQjC,gBAAgB;YAOF,eAAe;CAuD9B;AAED,KAAK,aAAa,GAAG;IACnB,eAAe,EAAE,eAAe,CAAC;CAClC,CAAC"}
1
+ {"version":3,"file":"blob-sync-extension.d.ts","sourceRoot":"","sources":["../../../src/blob-sync-extension.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,mDAAmD,CAAC;AACxH,OAAO,EAAE,KAAK,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C,CAAC;AAMF;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,YAAY,CAAC,aAAa,EAAE,aAAa,CAAC;IAyD7E,OAAO,CAAC,QAAQ,CAAC,OAAO;IAxD1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqD;IAE1E,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,cAAc,CAA2B;IAEjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAY7B;IAEH,OAAO,CAAC,eAAe,CAAK;IAE5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CA2BrB;IAEH;;OAEG;IACI,cAAc,EAAE,QAAQ,CAAiB;gBAG7B,OAAO,EAAE,uBAAuB;IAgBpC,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/C,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;cAO9C,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC;IAiB/C,IAAI,CAAC,IAAI,EAAE,SAAS;IAQ1B,cAAc,CAAC,QAAQ,EAAE,QAAQ;IAQjC,gBAAgB;YAOF,eAAe;CAuD9B;AAED,KAAK,aAAa,GAAG;IACnB,eAAe,EAAE,eAAe,CAAC;CAClC,CAAC"}
@@ -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;IAiCf;;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,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/teleport-extension-object-sync",
3
- "version": "0.3.8-main.152ec6f",
3
+ "version": "0.3.8-main.1b6c849",
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.8-main.152ec6f",
20
- "@dxos/crypto": "0.3.8-main.152ec6f",
21
- "@dxos/context": "0.3.8-main.152ec6f",
22
- "@dxos/debug": "0.3.8-main.152ec6f",
23
- "@dxos/invariant": "0.3.8-main.152ec6f",
24
- "@dxos/keys": "0.3.8-main.152ec6f",
25
- "@dxos/log": "0.3.8-main.152ec6f",
26
- "@dxos/node-std": "0.3.8-main.152ec6f",
27
- "@dxos/protocols": "0.3.8-main.152ec6f",
28
- "@dxos/random-access-storage": "0.3.8-main.152ec6f",
29
- "@dxos/rpc": "0.3.8-main.152ec6f",
30
- "@dxos/teleport": "0.3.8-main.152ec6f",
31
- "@dxos/util": "0.3.8-main.152ec6f"
19
+ "@dxos/async": "0.3.8-main.1b6c849",
20
+ "@dxos/context": "0.3.8-main.1b6c849",
21
+ "@dxos/crypto": "0.3.8-main.1b6c849",
22
+ "@dxos/invariant": "0.3.8-main.1b6c849",
23
+ "@dxos/debug": "0.3.8-main.1b6c849",
24
+ "@dxos/log": "0.3.8-main.1b6c849",
25
+ "@dxos/keys": "0.3.8-main.1b6c849",
26
+ "@dxos/protocols": "0.3.8-main.1b6c849",
27
+ "@dxos/node-std": "0.3.8-main.1b6c849",
28
+ "@dxos/random-access-storage": "0.3.8-main.1b6c849",
29
+ "@dxos/rpc": "0.3.8-main.1b6c849",
30
+ "@dxos/teleport": "0.3.8-main.1b6c849",
31
+ "@dxos/util": "0.3.8-main.1b6c849"
32
32
  },
33
33
  "devDependencies": {
34
34
  "typescript": "^5.2.2"
@@ -19,6 +19,7 @@ export type BlobSyncExtensionParams = {
19
19
  blobStore: BlobStore;
20
20
  onOpen: () => Promise<void>;
21
21
  onClose: () => Promise<void>;
22
+ onAbort: () => Promise<void>;
22
23
  onPush: (data: BlobChunk) => Promise<void>;
23
24
  };
24
25
 
@@ -115,6 +116,13 @@ export class BlobSyncExtension extends RpcExtension<ServiceBundle, ServiceBundle
115
116
  await super.onClose(err);
116
117
  }
117
118
 
119
+ override async onAbort(err?: Error | undefined): Promise<void> {
120
+ log('abort');
121
+ await this._ctx.dispose();
122
+ await this._params.onAbort();
123
+ await super.onAbort(err);
124
+ }
125
+
118
126
  protected async getHandlers(): Promise<ServiceBundle> {
119
127
  return {
120
128
  BlobSyncService: {
package/src/blob-sync.ts CHANGED
@@ -110,6 +110,10 @@ export class BlobSync {
110
110
  log('extension closed');
111
111
  this._extensions.delete(extension);
112
112
  },
113
+ onAbort: async () => {
114
+ log('extension aborted');
115
+ this._extensions.delete(extension);
116
+ },
113
117
  onPush: async (blobChunk) => {
114
118
  if (!this._downloadRequests.has(blobChunk.id)) {
115
119
  return;