@dxos/random-access-storage 0.3.11-main.8be6c8a → 0.3.11-main.8feb6a5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,13 +20,13 @@ var getFullPath = (root, path) => join(root, stringDiff(path, root));
20
20
 
21
21
  // packages/common/random-access-storage/src/common/directory.ts
22
22
  var Directory = class _Directory {
23
- constructor(type, path, _list, _getOrCreateFile, _delete, _onFlush) {
23
+ constructor({ type, path, list, getOrCreateFile, remove, onFlush }) {
24
24
  this.type = type;
25
25
  this.path = path;
26
- this._list = _list;
27
- this._getOrCreateFile = _getOrCreateFile;
28
- this._delete = _delete;
29
- this._onFlush = _onFlush;
26
+ this._list = list;
27
+ this._getOrCreateFile = getOrCreateFile;
28
+ this._remove = remove;
29
+ this._onFlush = onFlush;
30
30
  }
31
31
  toString() {
32
32
  return `Directory(${JSON.stringify({
@@ -38,7 +38,13 @@ var Directory = class _Directory {
38
38
  * Create a new sub-directory.
39
39
  */
40
40
  createDirectory(path) {
41
- return new _Directory(this.type, getFullPath(this.path, path), this._list, this._getOrCreateFile, this._delete);
41
+ return new _Directory({
42
+ type: this.type,
43
+ path: getFullPath(this.path, path),
44
+ list: this._list,
45
+ getOrCreateFile: this._getOrCreateFile,
46
+ remove: this._remove
47
+ });
42
48
  }
43
49
  /**
44
50
  * Get all files in the current directory.
@@ -59,7 +65,7 @@ var Directory = class _Directory {
59
65
  * Close and delete all files in the directory and all its sub-directories.
60
66
  */
61
67
  async delete() {
62
- await this._delete();
68
+ await this._remove();
63
69
  }
64
70
  };
65
71
 
@@ -133,7 +139,13 @@ var AbstractStorage = class {
133
139
  }
134
140
  // TODO(burdon): Make required.
135
141
  createDirectory(sub = "") {
136
- return new Directory(this.type, getFullPath(this.path, sub), this._list.bind(this), (...args) => this.getOrCreateFile(...args), () => this._delete(sub));
142
+ return new Directory({
143
+ type: this.type,
144
+ path: getFullPath(this.path, sub),
145
+ list: this._list.bind(this),
146
+ getOrCreateFile: (...args) => this.getOrCreateFile(...args),
147
+ remove: () => this._remove(sub)
148
+ });
137
149
  }
138
150
  /**
139
151
  * Delete all files.
@@ -147,7 +159,7 @@ var AbstractStorage = class {
147
159
  C: (f, a) => f(...a)
148
160
  });
149
161
  await this._closeFilesInPath("");
150
- await this._delete("");
162
+ await this._remove("");
151
163
  await this._destroy();
152
164
  log2("Erased...", void 0, {
153
165
  F: __dxlog_file2,
@@ -165,7 +177,7 @@ var AbstractStorage = class {
165
177
  }
166
178
  }
167
179
  async _list(path) {
168
- return Array.from(this._getFiles(path).keys()).map((filename) => {
180
+ return Array.from((await this._getFiles(path)).keys()).map((filename) => {
169
181
  let name = filename.replace(path, "");
170
182
  if (name.startsWith("/")) {
171
183
  name = name.substring(1);
@@ -207,14 +219,14 @@ var AbstractStorage = class {
207
219
  }
208
220
  }
209
221
  }
210
- _getFiles(path) {
222
+ async _getFiles(path) {
211
223
  const fullPath = getFullPath(this.path, path);
212
224
  return new Map([
213
225
  ...this._files.entries()
214
226
  ].filter(([path2, file]) => path2.includes(fullPath) && file.destroyed !== true));
215
227
  }
216
228
  async _closeFilesInPath(path) {
217
- await Promise.all(Array.from(this._getFiles(path).values()).map((file) => file.close().catch((err) => log2.catch(err, void 0, {
229
+ await Promise.all(Array.from((await this._getFiles(path)).values()).map((file) => file.close().catch((err) => log2.catch(err, void 0, {
218
230
  F: __dxlog_file2,
219
231
  L: 133,
220
232
  S: this,
@@ -222,8 +234,8 @@ var AbstractStorage = class {
222
234
  }))));
223
235
  }
224
236
  // TODO(burdon): Delete directory (not just listed files).
225
- async _delete(path) {
226
- await Promise.all(Array.from(this._getFiles(path)).map(([path2, file]) => {
237
+ async _remove(path) {
238
+ await Promise.all(Array.from(await this._getFiles(path)).map(([path2, file]) => {
227
239
  return file.destroy().then(() => this._files.delete(path2)).catch((err) => log2.error(err.message, void 0, {
228
240
  F: __dxlog_file2,
229
241
  L: 144,
@@ -280,14 +292,13 @@ var MemoryStorage = class extends AbstractStorage {
280
292
  import raw from "random-access-web/mutable-file-wrapper.js";
281
293
 
282
294
  // packages/common/random-access-storage/src/browser/browser-storage.ts
283
- import { join as join3 } from "@dxos/node-std/path";
284
295
  var BrowserStorage = class extends AbstractStorage {
285
296
  constructor(path) {
286
297
  super(path);
287
298
  this._fileStorage = this._createFileStorage(path);
288
299
  }
289
300
  _createFile(path, filename) {
290
- const fullPath = join3(path, filename);
301
+ const fullPath = getFullPath(path, filename);
291
302
  return this._fileStorage(fullPath);
292
303
  }
293
304
  async _destroy() {
@@ -395,8 +406,15 @@ var WebFS = class {
395
406
  return this._root;
396
407
  }
397
408
  createDirectory(sub = "") {
398
- return new Directory(this.type, getFullPath(this.path, sub), (path) => this._list(path), (...args) => this.getOrCreateFile(...args), () => this._delete(sub), async () => {
399
- await Promise.all(Array.from(this._getFiles(sub)).map(([path, file]) => file.flush()));
409
+ return new Directory({
410
+ type: this.type,
411
+ path: getFullPath(this.path, sub),
412
+ list: (path) => this._list(path),
413
+ getOrCreateFile: (...args) => this.getOrCreateFile(...args),
414
+ remove: () => this._delete(sub),
415
+ onFlush: async () => {
416
+ await Promise.all(Array.from(this._getFiles(sub)).map(([path, file]) => file.flush()));
417
+ }
400
418
  });
401
419
  }
402
420
  getOrCreateFile(path, filename, opts) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/common/abstract-storage.ts", "../../../src/common/utils.ts", "../../../src/common/directory.ts", "../../../src/common/file.ts", "../../../src/common/memory-storage.ts", "../../../src/common/storage.ts", "../../../src/browser/firefox-storage.ts", "../../../src/browser/browser-storage.ts", "../../../src/browser/idb-storage.ts", "../../../src/browser/web-fs.ts", "../../../src/browser/storage.ts"],
4
- "sourcesContent": ["//\n// Copyright 2021 DXOS.org\n//\n\nimport { join } from 'node:path';\nimport { inspect } from 'node:util';\nimport type { RandomAccessStorage } from 'random-access-storage';\n\nimport { inspectObject } from '@dxos/debug';\nimport { log } from '@dxos/log';\n\nimport { Directory } from './directory';\nimport { type File, wrapFile } from './file';\nimport { type Storage, type StorageType } from './storage';\nimport { getFullPath } from './utils';\n\n/**\n * Base class for all storage implementations.\n * https://github.com/random-access-storage\n * https://github.com/random-access-storage/random-access-storage\n */\nexport abstract class AbstractStorage implements Storage {\n protected readonly _files = new Map<string, File>();\n\n public abstract readonly type: StorageType;\n\n // TODO(burdon): Make required.\n constructor(public readonly path: string) {}\n\n [inspect.custom]() {\n return inspectObject(this);\n }\n\n toJSON() {\n return { type: this.type, path: this.path };\n }\n\n public get size() {\n return this._files.size;\n }\n\n // TODO(burdon): Make required.\n public createDirectory(sub = ''): Directory {\n // invariant(sub.length);\n return new Directory(\n this.type,\n getFullPath(this.path, sub),\n this._list.bind(this),\n (...args) => this.getOrCreateFile(...args),\n () => this._delete(sub),\n );\n }\n\n /**\n * Delete all files.\n */\n async reset() {\n try {\n log.info('Erasing all data...');\n await this._closeFilesInPath('');\n await this._delete('');\n await this._destroy();\n log('Erased...');\n } catch (err: any) {\n log.catch(err);\n }\n }\n\n protected async _list(path: string): Promise<string[]> {\n // TODO(dmaretskyi): Fix me.\n return Array.from(this._getFiles(path).keys()).map((filename) => {\n let name = filename.replace(path, '');\n if (name.startsWith('/')) {\n name = name.substring(1);\n }\n return name;\n });\n }\n\n protected getOrCreateFile(path: string, filename: string, opts?: any): File {\n const fullPath = join(path, filename);\n\n let native;\n let file = this._getFileIfExists(fullPath);\n if (file) {\n if (!file.closed) {\n return file;\n }\n\n native = this._openFile(file.native);\n }\n\n if (!native) {\n native = this._createFile(path, filename, opts);\n }\n\n file = wrapFile(native, this.type);\n this._files.set(fullPath, file);\n return file;\n }\n\n protected _destroy(): Promise<void> | undefined {\n return undefined;\n }\n\n /**\n * Attempt to reopen file.\n */\n protected _openFile(file: RandomAccessStorage): RandomAccessStorage | undefined {\n return undefined;\n }\n\n protected abstract _createFile(path: string, filename: string, opts?: any): RandomAccessStorage;\n\n private _getFileIfExists(filename: string): File | undefined {\n if (this._files.has(filename)) {\n const file = this._files.get(filename);\n if (file && !file.destroyed) {\n return file;\n }\n }\n }\n\n private _getFiles(path: string): Map<string, File> {\n const fullPath = getFullPath(this.path, path);\n return new Map(\n [...this._files.entries()].filter(([path, file]) => path.includes(fullPath) && file.destroyed !== true),\n );\n }\n\n private async _closeFilesInPath(path: string): Promise<void> {\n await Promise.all(\n Array.from(this._getFiles(path).values()).map((file) => file.close().catch((err: any) => log.catch(err))),\n );\n }\n\n // TODO(burdon): Delete directory (not just listed files).\n protected async _delete(path: string): Promise<void> {\n await Promise.all(\n Array.from(this._getFiles(path)).map(([path, file]) => {\n return file\n .destroy()\n .then(() => this._files.delete(path))\n .catch((err: any) => log.error(err.message));\n }),\n );\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { join } from 'node:path';\n\n// TODO(burdon): Document.\nexport const stringDiff = (first: string, second: string) => first.split(second).join('');\n\nexport const getFullPath = (root: string, path: string) => join(root, stringDiff(path, root));\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type File } from './file';\nimport { type StorageType } from './storage';\nimport { getFullPath } from './utils';\n\n/**\n * Wraps a directory in the storage file system.\n */\nexport class Directory {\n constructor(\n public readonly type: StorageType,\n public readonly path: string,\n // TODO(burdon): Create interface for these methods (shared with AbstractStorage).\n private readonly _list: (path: string) => Promise<string[]>,\n private readonly _getOrCreateFile: (path: string, filename: string, opts?: any) => File,\n private readonly _delete: () => Promise<void>,\n private readonly _onFlush?: () => Promise<void>,\n ) {}\n\n toString() {\n return `Directory(${JSON.stringify({ type: this.type, path: this.path })})`;\n }\n\n /**\n * Create a new sub-directory.\n */\n createDirectory(path: string): Directory {\n return new Directory(this.type, getFullPath(this.path, path), this._list, this._getOrCreateFile, this._delete);\n }\n\n /**\n * Get all files in the current directory.\n */\n list(): Promise<string[]> {\n return this._list(this.path);\n }\n\n /**\n * Get or create a new file.\n */\n getOrCreateFile(filename: string, opts?: any): File {\n return this._getOrCreateFile(this.path, filename, opts);\n }\n\n async flush() {\n await this._onFlush?.();\n }\n\n /**\n * Close and delete all files in the directory and all its sub-directories.\n */\n async delete() {\n await this._delete();\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport pify from 'pify';\nimport type { FileStat, RandomAccessStorage, RandomAccessStorageProperties } from 'random-access-storage';\n\nimport { log } from '@dxos/log';\n\nimport { type StorageType } from './storage';\n\nconst MAX_STORAGE_OPERATION_TIME = 50;\n\n/**\n * Random access file wrapper.\n * https://github.com/random-access-storage/random-access-storage\n */\nexport interface File extends RandomAccessStorageProperties {\n readonly destroyed: boolean;\n\n // TODO(burdon): Can we remove these since they are not standard across implementations?\n readonly directory: string;\n readonly filename: string;\n\n // Added by factory.\n readonly type: StorageType;\n readonly native: RandomAccessStorage;\n\n write(offset: number, data: Buffer): Promise<void>;\n read(offset: number, size: number): Promise<Buffer>;\n del(offset: number, size: number): Promise<void>;\n stat(): Promise<FileStat>;\n close(): Promise<Error | void>;\n destroy(): Promise<Error | void>;\n\n /**\n * Save changes to disk.\n */\n flush?(): Promise<void>;\n\n // Not supported in node, memory.\n truncate?(offset: number): Promise<void>;\n\n // random-access-memory only.\n clone?(): RandomAccessStorage;\n}\n\nconst pifyFields = (object: any, type: StorageType, fields: string[]) => {\n for (const field of fields) {\n if (!object[field]) {\n // TODO(burdon): Suppress warning and throw error if used.\n // console.warn(`Field not supported for type: ${JSON.stringify({ type, field })}`);\n } else {\n const fn = pify(object[field].bind(object));\n object[field] = async (...args: any) => {\n const before = performance.now();\n\n const res = await fn(...args);\n\n const elapsed = performance.now() - before;\n if (elapsed > MAX_STORAGE_OPERATION_TIME) {\n log.warn('Slow storage operation', { type, operation: field, elapsed });\n }\n\n return res;\n };\n }\n }\n\n return object;\n};\n\n/**\n * Construct async File wrapper.\n * NOTE: This is safe since these are interface methods only (not used internally).\n */\nexport const wrapFile = (native: RandomAccessStorage, type: StorageType): File => {\n const file = pifyFields(native, type, ['write', 'read', 'del', 'stat', 'close', 'destroy', 'truncate']);\n return Object.assign(file, { type, native });\n};\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport ram from 'random-access-memory';\nimport { type Callback, type RandomAccessStorage } from 'random-access-storage';\n\nimport { arrayToBuffer } from '@dxos/util';\n\nimport { AbstractStorage } from './abstract-storage';\nimport { StorageType } from './storage';\n\n/**\n * Storage interface implementation for RAM.\n * https://github.com/random-access-storage/random-access-memory\n */\nexport class MemoryStorage extends AbstractStorage {\n public override type: StorageType = StorageType.RAM;\n\n protected override _createFile(path: string, filename: string): RandomAccessStorage {\n return this._patchFile(ram());\n }\n\n protected override _openFile(file: RandomAccessStorage): RandomAccessStorage {\n const newFile = file.clone!();\n (newFile as any).closed = false;\n return this._patchFile(newFile);\n }\n\n private _patchFile(file: RandomAccessStorage): RandomAccessStorage {\n // Patch required to make consistent across platforms.\n const trueRead = file.read.bind(file);\n\n file.read = (offset: number, size: number, cb: Callback<Buffer>) =>\n trueRead(offset, size, (err: Error | null, data?: Buffer) => {\n if (err) {\n return cb(err);\n } else {\n return cb(err, arrayToBuffer(data!));\n }\n });\n\n return file;\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { type Directory } from './directory';\n\n// TODO(burdon): Reconcile with ConfigProto.\nexport enum StorageType {\n RAM = 'ram',\n IDB = 'idb',\n CHROME = 'chrome',\n FIREFOX = 'firefox',\n NODE = 'node',\n WEBFS = 'webfs',\n}\n\nexport type DiskInfo = {\n /**\n * Bytes.\n */\n used: number;\n};\n\nexport interface Storage {\n readonly path: string;\n readonly type: StorageType;\n readonly size: number;\n\n getDiskInfo?(): Promise<DiskInfo>;\n\n // TODO(burdon): Make required.\n createDirectory: (path?: string) => Directory;\n reset: () => Promise<void>;\n}\n\nexport type StorageConstructor = (params?: { type?: StorageType; root?: string }) => Storage;\n", "//\n// Copyright 2021 DXOS.org\n//\n\n// NOTE: Removing the .js extension here breaks usage in create-react-app.\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport raw from 'random-access-web/mutable-file-wrapper.js';\n\nimport { BrowserStorage } from './browser-storage';\nimport { StorageType } from '../common';\n\n/**\n * Storage interface implementation for Firefox browser.\n * https://github.com/random-access-storage/random-access-web\n */\nexport class FirefoxStorage extends BrowserStorage {\n public override type: StorageType = StorageType.FIREFOX;\n\n protected override _createFileStorage(path: string) {\n return raw({ name: path });\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { join } from 'node:path';\nimport type { RandomAccessStorage } from 'random-access-storage';\n\nimport { AbstractStorage } from '../common';\n\n/**\n * Base class for random access files based on IDB.\n */\nexport abstract class BrowserStorage extends AbstractStorage {\n private readonly _fileStorage: (filename: string, opts?: {}) => RandomAccessStorage;\n\n constructor(path: string) {\n super(path);\n this._fileStorage = this._createFileStorage(path);\n }\n\n protected _createFile(path: string, filename: string): RandomAccessStorage {\n const fullPath = join(path, filename);\n return this._fileStorage(fullPath);\n }\n\n protected abstract _createFileStorage(path: string): (filename: string, opts?: {}) => RandomAccessStorage;\n\n protected override async _destroy() {\n // eslint-disable-next-line no-undef\n return new Promise<void>((resolve, reject) => {\n const request = indexedDB.deleteDatabase(this.path);\n request.onsuccess = () => {\n resolve();\n };\n request.onupgradeneeded = () => {\n reject(new Error('Upgrade needed.'));\n };\n request.onblocked = () => {\n reject(new Error('Blocked.'));\n };\n request.onerror = (err: any) => {\n reject(err);\n };\n });\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport idb from 'random-access-idb';\n\nimport { BrowserStorage } from './browser-storage';\nimport { StorageType } from '../common';\n\n/**\n * Storage interface implementation for index DB.\n * https://github.com/random-access-storage/random-access-idb\n */\nexport class IDbStorage extends BrowserStorage {\n public override type: StorageType = StorageType.IDB;\n\n protected override _createFileStorage(path: string) {\n return idb(path);\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { EventEmitter } from 'node:events';\nimport { callbackify } from 'node:util';\nimport { type RandomAccessStorage } from 'random-access-storage';\n\nimport { synchronized } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { TimeSeriesCounter, trace } from '@dxos/tracing';\n\nimport { Directory, type DiskInfo, type File, type Storage, StorageType, getFullPath } from '../common';\n\n/**\n * Web file systems.\n */\nexport class WebFS implements Storage {\n readonly type = StorageType.WEBFS;\n\n protected readonly _files = new Map<string, WebFile>();\n protected _root?: FileSystemDirectoryHandle;\n\n constructor(public readonly path: string) {}\n\n public get size() {\n return this._files.size;\n }\n\n private _getFiles(path: string): Map<string, WebFile> {\n const fullName = this._getFullFilename(this.path, path);\n return new Map(\n [...this._files.entries()].filter(([path, file]) => path.includes(fullName) && file.destroyed !== true),\n );\n }\n\n private async _list(path: string): Promise<string[]> {\n const fullName = this._getFullFilename(path);\n\n const root = await this._initialize();\n\n // TODO(dmaretskyi): While we're storing all files in flat namespace we just iterate the root.\n // console.log({ path, fullName })\n // let dir: FileSystemDirectoryHandle;\n // if (path === '') {\n // dir = root;\n // } else {\n // dir = await root.getDirectoryHandle(fullName, { create: true });\n // }\n const entries: string[] = [];\n\n for await (const entry of (root as any).keys()) {\n if (entry.startsWith(fullName + '_')) {\n entries.push(entry.slice(fullName.length + 1));\n }\n }\n return entries;\n }\n\n @synchronized\n private async _initialize() {\n if (this._root) {\n return this._root;\n }\n this._root = await navigator.storage.getDirectory();\n invariant(this._root, 'Root is undefined');\n return this._root;\n }\n\n createDirectory(sub = '') {\n return new Directory(\n this.type,\n getFullPath(this.path, sub),\n (path) => this._list(path),\n (...args) => this.getOrCreateFile(...args),\n () => this._delete(sub),\n async () => {\n await Promise.all(Array.from(this._getFiles(sub)).map(([path, file]) => file.flush()));\n },\n );\n }\n\n getOrCreateFile(path: string, filename: string, opts?: any): File {\n const fullName = this._getFullFilename(path, filename);\n const existingFile = this._files.get(fullName);\n if (existingFile) {\n return existingFile;\n }\n const file = this._createFile(fullName);\n this._files.set(fullName, file);\n return file;\n }\n\n private _createFile(fullName: string) {\n return new WebFile({\n fileName: fullName,\n file: this._initialize().then((root) => root.getFileHandle(fullName, { create: true })),\n destroy: async () => {\n this._files.delete(fullName);\n const root = await this._initialize();\n return root.removeEntry(fullName);\n },\n });\n }\n\n private async _delete(path: string): Promise<void> {\n await Promise.all(\n Array.from(this._getFiles(path)).map(async ([path, file]) => {\n await file.destroy().catch((err: any) => log.warn(err));\n this._files.delete(path);\n }),\n );\n }\n\n async reset() {\n await this._initialize();\n for await (const filename of await (this._root as any).keys()) {\n this._files.delete(filename);\n await this._root!.removeEntry(filename, { recursive: true }).catch((err: any) => log.warn(err));\n }\n this._root = undefined;\n }\n\n private _getFullFilename(path: string, filename?: string) {\n // Replace slashes with underscores. Because we can't have slashes in filenames in Browser File Handle API.\n if (filename) {\n return getFullPath(path, filename).split('/').join('_');\n } else {\n return path.split('/').join('_');\n }\n }\n\n async getDiskInfo(): Promise<DiskInfo> {\n let used = 0;\n\n const recurse = async (handle: FileSystemDirectoryHandle) => {\n const promises = [];\n\n for await (const entry of (handle as any).values()) {\n promises.push(\n (async () => {\n switch (entry.kind) {\n case 'file':\n used += await (entry as FileSystemFileHandle).getFile().then((f) => (used += f.size));\n break;\n case 'directory':\n await recurse(entry as FileSystemDirectoryHandle);\n break;\n }\n })(),\n );\n }\n await Promise.all(promises);\n };\n\n await recurse(this._root!);\n\n return {\n used,\n };\n }\n}\n\n// TODO(mykola): Remove EventEmitter.\n@trace.resource()\nexport class WebFile extends EventEmitter implements File {\n @trace.info()\n private readonly _fileName: string;\n\n private readonly _fileHandle: Promise<FileSystemFileHandle>;\n private readonly _destroy: () => Promise<void>;\n\n /**\n * Current view of the file contents.\n */\n private _buffer: Uint8Array | null = null;\n\n private _loadBufferPromise: Promise<void> | null = null;\n\n private _flushScheduled = false;\n\n private _flushPromise: Promise<void> | null = null;\n\n //\n // Metrics\n //\n\n @trace.metricsCounter()\n private _flushes = new TimeSeriesCounter();\n\n @trace.metricsCounter()\n private _operations = new TimeSeriesCounter();\n\n @trace.metricsCounter()\n private _reads = new TimeSeriesCounter();\n\n @trace.metricsCounter()\n private _readBytes = new TimeSeriesCounter();\n\n @trace.metricsCounter()\n private _writes = new TimeSeriesCounter();\n\n @trace.metricsCounter()\n private _writeBytes = new TimeSeriesCounter();\n\n @trace.info()\n get _bufferSize() {\n return this._buffer?.length;\n }\n\n constructor({\n fileName,\n file,\n destroy,\n }: {\n file: Promise<FileSystemFileHandle>;\n fileName: string;\n destroy: () => Promise<void>;\n }) {\n super();\n this._fileName = fileName;\n this._fileHandle = file;\n this._destroy = destroy;\n\n void this._loadBufferGuarded();\n }\n\n type: StorageType = StorageType.WEBFS;\n\n //\n // random-access-storage library compatibility\n //\n\n // TODO(dmaretskyi): Are those all needed?\n readonly opened: boolean = true;\n readonly suspended: boolean = false;\n readonly closed: boolean = false;\n readonly unlinked: boolean = false;\n readonly writing: boolean = false;\n readonly readable: boolean = true;\n readonly writable: boolean = true;\n readonly deletable: boolean = true;\n readonly truncatable: boolean = true;\n readonly statable: boolean = true;\n\n destroyed = false;\n directory = '';\n // TODO(dmaretskyi): is this used?\n filename = '';\n native: RandomAccessStorage = {\n write: callbackify(this.write.bind(this)),\n read: callbackify(this.read.bind(this)),\n del: callbackify(this.del.bind(this)),\n stat: callbackify(this.stat.bind(this)),\n destroy: callbackify(this.destroy.bind(this)),\n truncate: callbackify(this.truncate?.bind(this)),\n } as RandomAccessStorage;\n\n private async _loadBuffer() {\n const fileHandle = await this._fileHandle;\n const file = await fileHandle.getFile();\n this._buffer = new Uint8Array(await file.arrayBuffer());\n }\n\n private async _loadBufferGuarded() {\n await (this._loadBufferPromise ??= this._loadBuffer());\n }\n\n // Do not call directly, use _flushLater or _flushNow.\n private async _flushCache() {\n if (this.destroyed) {\n return;\n }\n\n this._flushes.inc();\n\n await this._loadBufferGuarded();\n invariant(this._buffer);\n\n const fileHandle = await this._fileHandle;\n const writable = await fileHandle.createWritable({ keepExistingData: true });\n await writable.write({ type: 'write', data: this._buffer, position: 0 });\n await writable.close();\n }\n\n private _flushLater() {\n if (this._flushScheduled) {\n return;\n }\n\n setTimeout(async () => {\n // Making sure only one flush can run at a time.\n const promiseBefore = this._flushPromise;\n await this._flushPromise;\n this._flushScheduled = false;\n\n // _flushNow might have been called. In that case we don't want to run the flush again.\n if (promiseBefore !== this._flushPromise) {\n return;\n }\n\n this._flushPromise = this._flushCache().catch((err) => log.warn(err));\n });\n\n this._flushScheduled = true;\n }\n\n private async _flushNow() {\n this._flushPromise = (this._flushPromise ?? Promise.resolve())\n .then(() => this._flushCache())\n .catch((err) => log.warn(err));\n\n await this._flushPromise;\n }\n\n async read(offset: number, size: number) {\n this._operations.inc();\n this._reads.inc();\n this._readBytes.inc(size);\n\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n\n if (offset + size > this._buffer.length) {\n throw new Error('Read out of bounds');\n }\n\n // Copy data into a new buffer.\n return Buffer.from(this._buffer.slice(offset, offset + size));\n }\n\n async write(offset: number, data: Buffer) {\n this._operations.inc();\n this._writes.inc();\n this._writeBytes.inc(data.length);\n\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n\n if (offset + data.length <= this._buffer.length) {\n this._buffer.set(data, offset);\n } else {\n // TODO(dmaretskyi): Optimize re-allocations.\n const newCache = new Uint8Array(offset + data.length);\n newCache.set(this._buffer);\n newCache.set(data, offset);\n this._buffer = newCache;\n }\n\n this._flushLater();\n }\n\n async del(offset: number, size: number) {\n this._operations.inc();\n\n if (offset < 0 || size < 0) {\n return;\n }\n\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n\n let leftoverSize = 0;\n if (offset + size < this._buffer.length) {\n leftoverSize = this._buffer.length - (offset + size);\n this._buffer.set(this._buffer.slice(offset + size, offset + size + leftoverSize), offset);\n }\n\n this._buffer = this._buffer.slice(0, offset + leftoverSize);\n\n this._flushLater();\n }\n\n async stat() {\n this._operations.inc();\n\n // NOTE: This will load all data from the file just to get it's size. While this is a lot of overhead, this works ok for out use cases.\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n\n return {\n size: this._buffer.length,\n };\n }\n\n async truncate(offset: number) {\n this._operations.inc();\n\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n\n this._buffer = this._buffer.slice(0, offset);\n\n this._flushLater();\n }\n\n async flush() {\n await this._flushNow();\n }\n\n async close(): Promise<void> {\n await this._flushNow();\n }\n\n @synchronized\n async destroy() {\n this.destroyed = true;\n return await this._destroy();\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { FirefoxStorage } from './firefox-storage';\nimport { IDbStorage } from './idb-storage';\nimport { WebFS } from './web-fs';\nimport { MemoryStorage, type Storage, type StorageConstructor, StorageType } from '../common';\n\nexport const createStorage: StorageConstructor = ({ type, root = '' } = {}): Storage => {\n if (type === undefined) {\n if (\n navigator &&\n navigator.storage &&\n typeof navigator.storage.getDirectory === 'function' &&\n FileSystemFileHandle &&\n typeof (FileSystemFileHandle.prototype as any).createWritable === 'function'\n ) {\n return new WebFS(root);\n } else {\n return new IDbStorage(root);\n }\n }\n\n switch (type) {\n case StorageType.RAM: {\n return new MemoryStorage(root);\n }\n\n case StorageType.IDB:\n case StorageType.CHROME: {\n return new IDbStorage(root);\n }\n\n case StorageType.FIREFOX: {\n return new FirefoxStorage(root);\n }\n\n case StorageType.WEBFS: {\n return new WebFS(root);\n }\n\n default: {\n throw new Error(`Invalid type: ${type}`);\n }\n }\n};\n"],
5
- "mappings": "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",
6
- "names": ["join", "inspect", "inspectObject", "log", "join", "stringDiff", "first", "second", "split", "join", "getFullPath", "root", "path", "Directory", "constructor", "type", "path", "_list", "_getOrCreateFile", "_delete", "_onFlush", "toString", "JSON", "stringify", "createDirectory", "getFullPath", "list", "getOrCreateFile", "filename", "opts", "flush", "delete", "pify", "log", "MAX_STORAGE_OPERATION_TIME", "pifyFields", "object", "type", "fields", "field", "fn", "bind", "args", "before", "performance", "now", "res", "elapsed", "warn", "operation", "wrapFile", "native", "file", "Object", "assign", "AbstractStorage", "constructor", "path", "_files", "Map", "inspect", "custom", "inspectObject", "toJSON", "type", "size", "createDirectory", "sub", "Directory", "getFullPath", "_list", "bind", "args", "getOrCreateFile", "_delete", "reset", "log", "info", "_closeFilesInPath", "_destroy", "err", "catch", "Array", "from", "_getFiles", "keys", "map", "filename", "name", "replace", "startsWith", "substring", "opts", "fullPath", "join", "native", "file", "_getFileIfExists", "closed", "_openFile", "_createFile", "wrapFile", "set", "undefined", "has", "get", "destroyed", "entries", "filter", "includes", "Promise", "all", "values", "close", "destroy", "then", "delete", "error", "message", "ram", "arrayToBuffer", "StorageType", "RAM", "IDB", "CHROME", "FIREFOX", "NODE", "WEBFS", "MemoryStorage", "AbstractStorage", "type", "StorageType", "RAM", "_createFile", "path", "filename", "_patchFile", "ram", "_openFile", "file", "newFile", "clone", "closed", "trueRead", "read", "bind", "offset", "size", "cb", "err", "data", "arrayToBuffer", "raw", "join", "BrowserStorage", "AbstractStorage", "constructor", "path", "_fileStorage", "_createFileStorage", "_createFile", "filename", "fullPath", "join", "_destroy", "Promise", "resolve", "reject", "request", "indexedDB", "deleteDatabase", "onsuccess", "onupgradeneeded", "Error", "onblocked", "onerror", "err", "FirefoxStorage", "BrowserStorage", "type", "StorageType", "FIREFOX", "_createFileStorage", "path", "raw", "name", "idb", "IDbStorage", "BrowserStorage", "type", "StorageType", "IDB", "_createFileStorage", "path", "idb", "EventEmitter", "callbackify", "synchronized", "invariant", "log", "TimeSeriesCounter", "trace", "WebFS", "constructor", "path", "type", "StorageType", "WEBFS", "_files", "Map", "size", "_getFiles", "fullName", "_getFullFilename", "entries", "filter", "file", "includes", "destroyed", "_list", "root", "_initialize", "entry", "keys", "startsWith", "push", "slice", "length", "_root", "navigator", "storage", "getDirectory", "invariant", "createDirectory", "sub", "Directory", "getFullPath", "args", "getOrCreateFile", "_delete", "Promise", "all", "Array", "from", "map", "flush", "filename", "opts", "existingFile", "get", "_createFile", "set", "WebFile", "fileName", "then", "getFileHandle", "create", "destroy", "delete", "removeEntry", "catch", "err", "log", "warn", "reset", "recursive", "undefined", "split", "join", "getDiskInfo", "used", "recurse", "handle", "promises", "values", "kind", "getFile", "f", "synchronized", "EventEmitter", "_buffer", "_loadBufferPromise", "_flushScheduled", "_flushPromise", "_flushes", "TimeSeriesCounter", "_operations", "_reads", "_readBytes", "_writes", "_writeBytes", "opened", "suspended", "closed", "unlinked", "writing", "readable", "writable", "deletable", "truncatable", "statable", "directory", "native", "write", "callbackify", "bind", "read", "del", "stat", "truncate", "_fileName", "_fileHandle", "_destroy", "_loadBufferGuarded", "_bufferSize", "_loadBuffer", "fileHandle", "Uint8Array", "arrayBuffer", "_flushCache", "inc", "createWritable", "keepExistingData", "data", "position", "close", "_flushLater", "setTimeout", "promiseBefore", "_flushNow", "resolve", "offset", "Error", "Buffer", "newCache", "leftoverSize", "trace", "info", "metricsCounter", "resource", "createStorage", "type", "root", "undefined", "navigator", "storage", "getDirectory", "FileSystemFileHandle", "prototype", "createWritable", "WebFS", "IDbStorage", "StorageType", "RAM", "MemoryStorage", "IDB", "CHROME", "FIREFOX", "FirefoxStorage", "WEBFS", "Error"]
4
+ "sourcesContent": ["//\n// Copyright 2021 DXOS.org\n//\n\nimport { join } from 'node:path';\nimport { inspect } from 'node:util';\nimport type { RandomAccessStorage } from 'random-access-storage';\n\nimport { inspectObject } from '@dxos/debug';\nimport { log } from '@dxos/log';\n\nimport { Directory } from './directory';\nimport { type File, wrapFile } from './file';\nimport { type Storage, type StorageType } from './storage';\nimport { getFullPath } from './utils';\n\n/**\n * Base class for all storage implementations.\n * https://github.com/random-access-storage\n * https://github.com/random-access-storage/random-access-storage\n */\nexport abstract class AbstractStorage implements Storage {\n protected readonly _files = new Map<string, File>();\n\n public abstract readonly type: StorageType;\n\n // TODO(burdon): Make required.\n constructor(public readonly path: string) {}\n\n [inspect.custom]() {\n return inspectObject(this);\n }\n\n toJSON() {\n return { type: this.type, path: this.path };\n }\n\n public get size() {\n return this._files.size;\n }\n\n // TODO(burdon): Make required.\n public createDirectory(sub = ''): Directory {\n // invariant(sub.length);\n return new Directory({\n type: this.type,\n path: getFullPath(this.path, sub),\n list: this._list.bind(this),\n getOrCreateFile: (...args) => this.getOrCreateFile(...args),\n remove: () => this._remove(sub),\n });\n }\n\n /**\n * Delete all files.\n */\n async reset() {\n try {\n log.info('Erasing all data...');\n await this._closeFilesInPath('');\n await this._remove('');\n await this._destroy();\n log('Erased...');\n } catch (err: any) {\n log.catch(err);\n }\n }\n\n protected async _list(path: string): Promise<string[]> {\n // TODO(dmaretskyi): Fix me.\n return Array.from((await this._getFiles(path)).keys()).map((filename) => {\n let name = filename.replace(path, '');\n if (name.startsWith('/')) {\n name = name.substring(1);\n }\n return name;\n });\n }\n\n protected getOrCreateFile(path: string, filename: string, opts?: any): File {\n const fullPath = join(path, filename);\n\n let native;\n let file = this._getFileIfExists(fullPath);\n if (file) {\n if (!file.closed) {\n return file;\n }\n\n native = this._openFile(file.native);\n }\n\n if (!native) {\n native = this._createFile(path, filename, opts);\n }\n\n file = wrapFile(native, this.type);\n this._files.set(fullPath, file);\n return file;\n }\n\n protected _destroy(): Promise<void> | undefined {\n return undefined;\n }\n\n /**\n * Attempt to reopen file.\n */\n protected _openFile(file: RandomAccessStorage): RandomAccessStorage | undefined {\n return undefined;\n }\n\n protected abstract _createFile(path: string, filename: string, opts?: any): RandomAccessStorage;\n\n private _getFileIfExists(filename: string): File | undefined {\n if (this._files.has(filename)) {\n const file = this._files.get(filename);\n if (file && !file.destroyed) {\n return file;\n }\n }\n }\n\n protected async _getFiles(path: string): Promise<Map<string, File>> {\n const fullPath = getFullPath(this.path, path);\n return new Map(\n [...this._files.entries()].filter(([path, file]) => path.includes(fullPath) && file.destroyed !== true),\n );\n }\n\n private async _closeFilesInPath(path: string): Promise<void> {\n await Promise.all(\n Array.from((await this._getFiles(path)).values()).map((file) => file.close().catch((err: any) => log.catch(err))),\n );\n }\n\n // TODO(burdon): Delete directory (not just listed files).\n protected async _remove(path: string): Promise<void> {\n await Promise.all(\n Array.from(await this._getFiles(path)).map(([path, file]) => {\n return file\n .destroy()\n .then(() => this._files.delete(path))\n .catch((err: any) => log.error(err.message));\n }),\n );\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { join } from 'node:path';\n\n// TODO(burdon): Document.\nexport const stringDiff = (first: string, second: string) => first.split(second).join('');\n\nexport const getFullPath = (root: string, path: string) => join(root, stringDiff(path, root));\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type File } from './file';\nimport { type StorageType } from './storage';\nimport { getFullPath } from './utils';\n\nexport type DirectoryParams = {\n type: StorageType;\n path: string;\n // TODO(burdon): Create interface for these methods (shared with AbstractStorage).\n list: (path: string) => Promise<string[]>;\n getOrCreateFile: (path: string, filename: string, opts?: any) => File;\n remove: () => Promise<void>;\n onFlush?: () => Promise<void>;\n};\n\n/**\n * Wraps a directory in the storage file system.\n */\nexport class Directory {\n public readonly type: StorageType;\n public readonly path: string;\n // TODO(burdon): Create interface for these methods (shared with AbstractStorage).\n private readonly _list: (path: string) => Promise<string[]>;\n private readonly _getOrCreateFile: (path: string, filename: string, opts?: any) => File;\n private readonly _remove: () => Promise<void>;\n private readonly _onFlush?: () => Promise<void>;\n\n constructor({ type, path, list, getOrCreateFile, remove, onFlush }: DirectoryParams) {\n this.type = type;\n this.path = path;\n this._list = list;\n this._getOrCreateFile = getOrCreateFile;\n this._remove = remove;\n this._onFlush = onFlush;\n }\n\n toString() {\n return `Directory(${JSON.stringify({ type: this.type, path: this.path })})`;\n }\n\n /**\n * Create a new sub-directory.\n */\n createDirectory(path: string): Directory {\n return new Directory({\n type: this.type,\n path: getFullPath(this.path, path),\n list: this._list,\n getOrCreateFile: this._getOrCreateFile,\n remove: this._remove,\n });\n }\n\n /**\n * Get all files in the current directory.\n */\n list(): Promise<string[]> {\n return this._list(this.path);\n }\n\n /**\n * Get or create a new file.\n */\n getOrCreateFile(filename: string, opts?: any): File {\n return this._getOrCreateFile(this.path, filename, opts);\n }\n\n async flush() {\n await this._onFlush?.();\n }\n\n /**\n * Close and delete all files in the directory and all its sub-directories.\n */\n async delete() {\n await this._remove();\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport pify from 'pify';\nimport type { FileStat, RandomAccessStorage, RandomAccessStorageProperties } from 'random-access-storage';\n\nimport { log } from '@dxos/log';\n\nimport { type StorageType } from './storage';\n\nconst MAX_STORAGE_OPERATION_TIME = 50;\n\n/**\n * Random access file wrapper.\n * https://github.com/random-access-storage/random-access-storage\n */\nexport interface File extends RandomAccessStorageProperties {\n readonly destroyed: boolean;\n\n // TODO(burdon): Can we remove these since they are not standard across implementations?\n readonly directory: string;\n readonly filename: string;\n\n // Added by factory.\n readonly type: StorageType;\n readonly native: RandomAccessStorage;\n\n write(offset: number, data: Buffer): Promise<void>;\n read(offset: number, size: number): Promise<Buffer>;\n del(offset: number, size: number): Promise<void>;\n stat(): Promise<FileStat>;\n close(): Promise<Error | void>;\n destroy(): Promise<Error | void>;\n\n /**\n * Save changes to disk.\n */\n flush?(): Promise<void>;\n\n // Not supported in node, memory.\n truncate?(offset: number): Promise<void>;\n\n // random-access-memory only.\n clone?(): RandomAccessStorage;\n}\n\nconst pifyFields = (object: any, type: StorageType, fields: string[]) => {\n for (const field of fields) {\n if (!object[field]) {\n // TODO(burdon): Suppress warning and throw error if used.\n // console.warn(`Field not supported for type: ${JSON.stringify({ type, field })}`);\n } else {\n const fn = pify(object[field].bind(object));\n object[field] = async (...args: any) => {\n const before = performance.now();\n\n const res = await fn(...args);\n\n const elapsed = performance.now() - before;\n if (elapsed > MAX_STORAGE_OPERATION_TIME) {\n log.warn('Slow storage operation', { type, operation: field, elapsed });\n }\n\n return res;\n };\n }\n }\n\n return object;\n};\n\n/**\n * Construct async File wrapper.\n * NOTE: This is safe since these are interface methods only (not used internally).\n */\nexport const wrapFile = (native: RandomAccessStorage, type: StorageType): File => {\n const file = pifyFields(native, type, ['write', 'read', 'del', 'stat', 'close', 'destroy', 'truncate']);\n return Object.assign(file, { type, native });\n};\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport ram from 'random-access-memory';\nimport { type Callback, type RandomAccessStorage } from 'random-access-storage';\n\nimport { arrayToBuffer } from '@dxos/util';\n\nimport { AbstractStorage } from './abstract-storage';\nimport { StorageType } from './storage';\n\n/**\n * Storage interface implementation for RAM.\n * https://github.com/random-access-storage/random-access-memory\n */\nexport class MemoryStorage extends AbstractStorage {\n public override type: StorageType = StorageType.RAM;\n\n protected override _createFile(path: string, filename: string): RandomAccessStorage {\n return this._patchFile(ram());\n }\n\n protected override _openFile(file: RandomAccessStorage): RandomAccessStorage {\n const newFile = file.clone!();\n (newFile as any).closed = false;\n return this._patchFile(newFile);\n }\n\n private _patchFile(file: RandomAccessStorage): RandomAccessStorage {\n // Patch required to make consistent across platforms.\n const trueRead = file.read.bind(file);\n\n file.read = (offset: number, size: number, cb: Callback<Buffer>) =>\n trueRead(offset, size, (err: Error | null, data?: Buffer) => {\n if (err) {\n return cb(err);\n } else {\n return cb(err, arrayToBuffer(data!));\n }\n });\n\n return file;\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { type Directory } from './directory';\n\n// TODO(burdon): Reconcile with ConfigProto.\nexport enum StorageType {\n RAM = 'ram',\n IDB = 'idb',\n CHROME = 'chrome',\n FIREFOX = 'firefox',\n NODE = 'node',\n WEBFS = 'webfs',\n}\n\nexport type DiskInfo = {\n /**\n * Bytes.\n */\n used: number;\n};\n\nexport interface Storage {\n readonly path: string;\n readonly type: StorageType;\n readonly size: number;\n\n getDiskInfo?(): Promise<DiskInfo>;\n\n // TODO(burdon): Make required.\n createDirectory: (path?: string) => Directory;\n reset: () => Promise<void>;\n}\n\nexport type StorageConstructor = (params?: { type?: StorageType; root?: string }) => Storage;\n", "//\n// Copyright 2021 DXOS.org\n//\n\n// NOTE: Removing the .js extension here breaks usage in create-react-app.\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport raw from 'random-access-web/mutable-file-wrapper.js';\n\nimport { BrowserStorage } from './browser-storage';\nimport { StorageType } from '../common';\n\n/**\n * Storage interface implementation for Firefox browser.\n * https://github.com/random-access-storage/random-access-web\n */\nexport class FirefoxStorage extends BrowserStorage {\n public override type: StorageType = StorageType.FIREFOX;\n\n protected override _createFileStorage(path: string) {\n return raw({ name: path });\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport type { RandomAccessStorage } from 'random-access-storage';\n\nimport { AbstractStorage, getFullPath } from '../common';\n\n/**\n * Base class for random access files based on IDB.\n */\nexport abstract class BrowserStorage extends AbstractStorage {\n private readonly _fileStorage: (filename: string, opts?: {}) => RandomAccessStorage;\n\n constructor(path: string) {\n super(path);\n this._fileStorage = this._createFileStorage(path);\n }\n\n protected _createFile(path: string, filename: string): RandomAccessStorage {\n const fullPath = getFullPath(path, filename);\n return this._fileStorage(fullPath);\n }\n\n protected abstract _createFileStorage(path: string): (filename: string, opts?: {}) => RandomAccessStorage;\n\n protected override async _destroy() {\n // eslint-disable-next-line no-undef\n return new Promise<void>((resolve, reject) => {\n const request = indexedDB.deleteDatabase(this.path);\n request.onsuccess = () => {\n resolve();\n };\n request.onupgradeneeded = () => {\n reject(new Error('Upgrade needed.'));\n };\n request.onblocked = () => {\n reject(new Error('Blocked.'));\n };\n request.onerror = (err: any) => {\n reject(err);\n };\n });\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport idb from 'random-access-idb';\n\nimport { BrowserStorage } from './browser-storage';\nimport { StorageType } from '../common';\n\n/**\n * Storage interface implementation for index DB.\n * https://github.com/random-access-storage/random-access-idb\n */\nexport class IDbStorage extends BrowserStorage {\n public override type: StorageType = StorageType.IDB;\n\n protected override _createFileStorage(path: string) {\n return idb(path);\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { EventEmitter } from 'node:events';\nimport { callbackify } from 'node:util';\nimport { type RandomAccessStorage } from 'random-access-storage';\n\nimport { synchronized } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { TimeSeriesCounter, trace } from '@dxos/tracing';\n\nimport { Directory, type DiskInfo, type File, type Storage, StorageType, getFullPath } from '../common';\n\n/**\n * Web file systems.\n */\nexport class WebFS implements Storage {\n readonly type = StorageType.WEBFS;\n\n protected readonly _files = new Map<string, WebFile>();\n protected _root?: FileSystemDirectoryHandle;\n\n constructor(public readonly path: string) {}\n\n public get size() {\n return this._files.size;\n }\n\n private _getFiles(path: string): Map<string, WebFile> {\n const fullName = this._getFullFilename(this.path, path);\n return new Map(\n [...this._files.entries()].filter(([path, file]) => path.includes(fullName) && file.destroyed !== true),\n );\n }\n\n private async _list(path: string): Promise<string[]> {\n const fullName = this._getFullFilename(path);\n\n const root = await this._initialize();\n\n // TODO(dmaretskyi): While we're storing all files in flat namespace we just iterate the root.\n // console.log({ path, fullName })\n // let dir: FileSystemDirectoryHandle;\n // if (path === '') {\n // dir = root;\n // } else {\n // dir = await root.getDirectoryHandle(fullName, { create: true });\n // }\n const entries: string[] = [];\n\n for await (const entry of (root as any).keys()) {\n if (entry.startsWith(fullName + '_')) {\n entries.push(entry.slice(fullName.length + 1));\n }\n }\n return entries;\n }\n\n @synchronized\n private async _initialize() {\n if (this._root) {\n return this._root;\n }\n this._root = await navigator.storage.getDirectory();\n invariant(this._root, 'Root is undefined');\n return this._root;\n }\n\n createDirectory(sub = '') {\n return new Directory({\n type: this.type,\n path: getFullPath(this.path, sub),\n list: (path) => this._list(path),\n getOrCreateFile: (...args) => this.getOrCreateFile(...args),\n remove: () => this._delete(sub),\n onFlush: async () => {\n await Promise.all(Array.from(this._getFiles(sub)).map(([path, file]) => file.flush()));\n },\n });\n }\n\n getOrCreateFile(path: string, filename: string, opts?: any): File {\n const fullName = this._getFullFilename(path, filename);\n const existingFile = this._files.get(fullName);\n if (existingFile) {\n return existingFile;\n }\n const file = this._createFile(fullName);\n this._files.set(fullName, file);\n return file;\n }\n\n private _createFile(fullName: string) {\n return new WebFile({\n fileName: fullName,\n file: this._initialize().then((root) => root.getFileHandle(fullName, { create: true })),\n destroy: async () => {\n this._files.delete(fullName);\n const root = await this._initialize();\n return root.removeEntry(fullName);\n },\n });\n }\n\n private async _delete(path: string): Promise<void> {\n await Promise.all(\n Array.from(this._getFiles(path)).map(async ([path, file]) => {\n await file.destroy().catch((err: any) => log.warn(err));\n this._files.delete(path);\n }),\n );\n }\n\n async reset() {\n await this._initialize();\n for await (const filename of await (this._root as any).keys()) {\n this._files.delete(filename);\n await this._root!.removeEntry(filename, { recursive: true }).catch((err: any) => log.warn(err));\n }\n this._root = undefined;\n }\n\n private _getFullFilename(path: string, filename?: string) {\n // Replace slashes with underscores. Because we can't have slashes in filenames in Browser File Handle API.\n if (filename) {\n return getFullPath(path, filename).split('/').join('_');\n } else {\n return path.split('/').join('_');\n }\n }\n\n async getDiskInfo(): Promise<DiskInfo> {\n let used = 0;\n\n const recurse = async (handle: FileSystemDirectoryHandle) => {\n const promises = [];\n\n for await (const entry of (handle as any).values()) {\n promises.push(\n (async () => {\n switch (entry.kind) {\n case 'file':\n used += await (entry as FileSystemFileHandle).getFile().then((f) => (used += f.size));\n break;\n case 'directory':\n await recurse(entry as FileSystemDirectoryHandle);\n break;\n }\n })(),\n );\n }\n await Promise.all(promises);\n };\n\n await recurse(this._root!);\n\n return {\n used,\n };\n }\n}\n\n// TODO(mykola): Remove EventEmitter.\n@trace.resource()\nexport class WebFile extends EventEmitter implements File {\n @trace.info()\n private readonly _fileName: string;\n\n private readonly _fileHandle: Promise<FileSystemFileHandle>;\n private readonly _destroy: () => Promise<void>;\n\n /**\n * Current view of the file contents.\n */\n private _buffer: Uint8Array | null = null;\n\n private _loadBufferPromise: Promise<void> | null = null;\n\n private _flushScheduled = false;\n\n private _flushPromise: Promise<void> | null = null;\n\n //\n // Metrics\n //\n\n @trace.metricsCounter()\n private _flushes = new TimeSeriesCounter();\n\n @trace.metricsCounter()\n private _operations = new TimeSeriesCounter();\n\n @trace.metricsCounter()\n private _reads = new TimeSeriesCounter();\n\n @trace.metricsCounter()\n private _readBytes = new TimeSeriesCounter();\n\n @trace.metricsCounter()\n private _writes = new TimeSeriesCounter();\n\n @trace.metricsCounter()\n private _writeBytes = new TimeSeriesCounter();\n\n @trace.info()\n get _bufferSize() {\n return this._buffer?.length;\n }\n\n constructor({\n fileName,\n file,\n destroy,\n }: {\n file: Promise<FileSystemFileHandle>;\n fileName: string;\n destroy: () => Promise<void>;\n }) {\n super();\n this._fileName = fileName;\n this._fileHandle = file;\n this._destroy = destroy;\n\n void this._loadBufferGuarded();\n }\n\n type: StorageType = StorageType.WEBFS;\n\n //\n // random-access-storage library compatibility\n //\n\n // TODO(dmaretskyi): Are those all needed?\n readonly opened: boolean = true;\n readonly suspended: boolean = false;\n readonly closed: boolean = false;\n readonly unlinked: boolean = false;\n readonly writing: boolean = false;\n readonly readable: boolean = true;\n readonly writable: boolean = true;\n readonly deletable: boolean = true;\n readonly truncatable: boolean = true;\n readonly statable: boolean = true;\n\n destroyed = false;\n directory = '';\n // TODO(dmaretskyi): is this used?\n filename = '';\n native: RandomAccessStorage = {\n write: callbackify(this.write.bind(this)),\n read: callbackify(this.read.bind(this)),\n del: callbackify(this.del.bind(this)),\n stat: callbackify(this.stat.bind(this)),\n destroy: callbackify(this.destroy.bind(this)),\n truncate: callbackify(this.truncate?.bind(this)),\n } as RandomAccessStorage;\n\n private async _loadBuffer() {\n const fileHandle = await this._fileHandle;\n const file = await fileHandle.getFile();\n this._buffer = new Uint8Array(await file.arrayBuffer());\n }\n\n private async _loadBufferGuarded() {\n await (this._loadBufferPromise ??= this._loadBuffer());\n }\n\n // Do not call directly, use _flushLater or _flushNow.\n private async _flushCache() {\n if (this.destroyed) {\n return;\n }\n\n this._flushes.inc();\n\n await this._loadBufferGuarded();\n invariant(this._buffer);\n\n const fileHandle = await this._fileHandle;\n const writable = await fileHandle.createWritable({ keepExistingData: true });\n await writable.write({ type: 'write', data: this._buffer, position: 0 });\n await writable.close();\n }\n\n private _flushLater() {\n if (this._flushScheduled) {\n return;\n }\n\n setTimeout(async () => {\n // Making sure only one flush can run at a time.\n const promiseBefore = this._flushPromise;\n await this._flushPromise;\n this._flushScheduled = false;\n\n // _flushNow might have been called. In that case we don't want to run the flush again.\n if (promiseBefore !== this._flushPromise) {\n return;\n }\n\n this._flushPromise = this._flushCache().catch((err) => log.warn(err));\n });\n\n this._flushScheduled = true;\n }\n\n private async _flushNow() {\n this._flushPromise = (this._flushPromise ?? Promise.resolve())\n .then(() => this._flushCache())\n .catch((err) => log.warn(err));\n\n await this._flushPromise;\n }\n\n async read(offset: number, size: number) {\n this._operations.inc();\n this._reads.inc();\n this._readBytes.inc(size);\n\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n\n if (offset + size > this._buffer.length) {\n throw new Error('Read out of bounds');\n }\n\n // Copy data into a new buffer.\n return Buffer.from(this._buffer.slice(offset, offset + size));\n }\n\n async write(offset: number, data: Buffer) {\n this._operations.inc();\n this._writes.inc();\n this._writeBytes.inc(data.length);\n\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n\n if (offset + data.length <= this._buffer.length) {\n this._buffer.set(data, offset);\n } else {\n // TODO(dmaretskyi): Optimize re-allocations.\n const newCache = new Uint8Array(offset + data.length);\n newCache.set(this._buffer);\n newCache.set(data, offset);\n this._buffer = newCache;\n }\n\n this._flushLater();\n }\n\n async del(offset: number, size: number) {\n this._operations.inc();\n\n if (offset < 0 || size < 0) {\n return;\n }\n\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n\n let leftoverSize = 0;\n if (offset + size < this._buffer.length) {\n leftoverSize = this._buffer.length - (offset + size);\n this._buffer.set(this._buffer.slice(offset + size, offset + size + leftoverSize), offset);\n }\n\n this._buffer = this._buffer.slice(0, offset + leftoverSize);\n\n this._flushLater();\n }\n\n async stat() {\n this._operations.inc();\n\n // NOTE: This will load all data from the file just to get it's size. While this is a lot of overhead, this works ok for out use cases.\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n\n return {\n size: this._buffer.length,\n };\n }\n\n async truncate(offset: number) {\n this._operations.inc();\n\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n\n this._buffer = this._buffer.slice(0, offset);\n\n this._flushLater();\n }\n\n async flush() {\n await this._flushNow();\n }\n\n async close(): Promise<void> {\n await this._flushNow();\n }\n\n @synchronized\n async destroy() {\n this.destroyed = true;\n return await this._destroy();\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { FirefoxStorage } from './firefox-storage';\nimport { IDbStorage } from './idb-storage';\nimport { WebFS } from './web-fs';\nimport { MemoryStorage, type Storage, type StorageConstructor, StorageType } from '../common';\n\nexport const createStorage: StorageConstructor = ({ type, root = '' } = {}): Storage => {\n if (type === undefined) {\n if (\n navigator &&\n navigator.storage &&\n typeof navigator.storage.getDirectory === 'function' &&\n FileSystemFileHandle &&\n typeof (FileSystemFileHandle.prototype as any).createWritable === 'function'\n ) {\n return new WebFS(root);\n } else {\n return new IDbStorage(root);\n }\n }\n\n switch (type) {\n case StorageType.RAM: {\n return new MemoryStorage(root);\n }\n\n case StorageType.IDB:\n case StorageType.CHROME: {\n return new IDbStorage(root);\n }\n\n case StorageType.FIREFOX: {\n return new FirefoxStorage(root);\n }\n\n case StorageType.WEBFS: {\n return new WebFS(root);\n }\n\n default: {\n throw new Error(`Invalid type: ${type}`);\n }\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;AAIA,SAASA,QAAAA,aAAY;AACrB,SAASC,eAAe;AAGxB,SAASC,qBAAqB;AAC9B,SAASC,OAAAA,YAAW;;;ACLpB,SAASC,YAAY;AAGd,IAAMC,aAAa,CAACC,OAAeC,WAAmBD,MAAME,MAAMD,MAAAA,EAAQE,KAAK,EAAA;AAE/E,IAAMC,cAAc,CAACC,MAAcC,SAAiBH,KAAKE,MAAMN,WAAWO,MAAMD,IAAAA,CAAAA;;;ACYhF,IAAME,YAAN,MAAMA,WAAAA;EASXC,YAAY,EAAEC,MAAMC,MAAMC,MAAMC,iBAAiBC,QAAQC,QAAO,GAAqB;AACnF,SAAKL,OAAOA;AACZ,SAAKC,OAAOA;AACZ,SAAKK,QAAQJ;AACb,SAAKK,mBAAmBJ;AACxB,SAAKK,UAAUJ;AACf,SAAKK,WAAWJ;EAClB;EAEAK,WAAW;AACT,WAAO,aAAaC,KAAKC,UAAU;MAAEZ,MAAM,KAAKA;MAAMC,MAAM,KAAKA;IAAK,CAAA,CAAA;EACxE;;;;EAKAY,gBAAgBZ,MAAyB;AACvC,WAAO,IAAIH,WAAU;MACnBE,MAAM,KAAKA;MACXC,MAAMa,YAAY,KAAKb,MAAMA,IAAAA;MAC7BC,MAAM,KAAKI;MACXH,iBAAiB,KAAKI;MACtBH,QAAQ,KAAKI;IACf,CAAA;EACF;;;;EAKAN,OAA0B;AACxB,WAAO,KAAKI,MAAM,KAAKL,IAAI;EAC7B;;;;EAKAE,gBAAgBY,UAAkBC,MAAkB;AAClD,WAAO,KAAKT,iBAAiB,KAAKN,MAAMc,UAAUC,IAAAA;EACpD;EAEA,MAAMC,QAAQ;AACZ,UAAM,KAAKR,WAAQ;EACrB;;;;EAKA,MAAMS,SAAS;AACb,UAAM,KAAKV,QAAO;EACpB;AACF;;;AC5EA,OAAOW,UAAU;AAGjB,SAASC,WAAW;;AAIpB,IAAMC,6BAA6B;AAoCnC,IAAMC,aAAa,CAACC,QAAaC,MAAmBC,WAAAA;AAClD,aAAWC,SAASD,QAAQ;AAC1B,QAAI,CAACF,OAAOG,KAAAA,GAAQ;IAGpB,OAAO;AACL,YAAMC,KAAKR,KAAKI,OAAOG,KAAAA,EAAOE,KAAKL,MAAAA,CAAAA;AACnCA,aAAOG,KAAAA,IAAS,UAAUG,SAAAA;AACxB,cAAMC,SAASC,YAAYC,IAAG;AAE9B,cAAMC,MAAM,MAAMN,GAAAA,GAAME,IAAAA;AAExB,cAAMK,UAAUH,YAAYC,IAAG,IAAKF;AACpC,YAAII,UAAUb,4BAA4B;AACxCD,cAAIe,KAAK,0BAA0B;YAAEX;YAAMY,WAAWV;YAAOQ;UAAQ,GAAA;;;;;;QACvE;AAEA,eAAOD;MACT;IACF;EACF;AAEA,SAAOV;AACT;AAMO,IAAMc,WAAW,CAACC,QAA6Bd,SAAAA;AACpD,QAAMe,OAAOjB,WAAWgB,QAAQd,MAAM;IAAC;IAAS;IAAQ;IAAO;IAAQ;IAAS;IAAW;GAAW;AACtG,SAAOgB,OAAOC,OAAOF,MAAM;IAAEf;IAAMc;EAAO,CAAA;AAC5C;;;;AH1DO,IAAeI,kBAAf,MAAeA;;EAMpBC,YAA4BC,MAAc;gBAAdA;SALTC,SAAS,oBAAIC,IAAAA;EAKW;EAE3C,CAACC,QAAQC,MAAM,IAAI;AACjB,WAAOC,cAAc,IAAI;EAC3B;EAEAC,SAAS;AACP,WAAO;MAAEC,MAAM,KAAKA;MAAMP,MAAM,KAAKA;IAAK;EAC5C;EAEA,IAAWQ,OAAO;AAChB,WAAO,KAAKP,OAAOO;EACrB;;EAGOC,gBAAgBC,MAAM,IAAe;AAE1C,WAAO,IAAIC,UAAU;MACnBJ,MAAM,KAAKA;MACXP,MAAMY,YAAY,KAAKZ,MAAMU,GAAAA;MAC7BG,MAAM,KAAKC,MAAMC,KAAK,IAAI;MAC1BC,iBAAiB,IAAIC,SAAS,KAAKD,gBAAe,GAAIC,IAAAA;MACtDC,QAAQ,MAAM,KAAKC,QAAQT,GAAAA;IAC7B,CAAA;EACF;;;;EAKA,MAAMU,QAAQ;AACZ,QAAI;AACFC,MAAAA,KAAIC,KAAK,uBAAA,QAAA;;;;;;AACT,YAAM,KAAKC,kBAAkB,EAAA;AAC7B,YAAM,KAAKJ,QAAQ,EAAA;AACnB,YAAM,KAAKK,SAAQ;AACnBH,MAAAA,KAAI,aAAA,QAAA;;;;;;IACN,SAASI,KAAU;AACjBJ,MAAAA,KAAIK,MAAMD,KAAAA,QAAAA;;;;;;IACZ;EACF;EAEA,MAAgBX,MAAMd,MAAiC;AAErD,WAAO2B,MAAMC,MAAM,MAAM,KAAKC,UAAU7B,IAAAA,GAAO8B,KAAI,CAAA,EAAIC,IAAI,CAACC,aAAAA;AAC1D,UAAIC,OAAOD,SAASE,QAAQlC,MAAM,EAAA;AAClC,UAAIiC,KAAKE,WAAW,GAAA,GAAM;AACxBF,eAAOA,KAAKG,UAAU,CAAA;MACxB;AACA,aAAOH;IACT,CAAA;EACF;EAEUjB,gBAAgBhB,MAAcgC,UAAkBK,MAAkB;AAC1E,UAAMC,WAAWC,MAAKvC,MAAMgC,QAAAA;AAE5B,QAAIQ;AACJ,QAAIC,OAAO,KAAKC,iBAAiBJ,QAAAA;AACjC,QAAIG,MAAM;AACR,UAAI,CAACA,KAAKE,QAAQ;AAChB,eAAOF;MACT;AAEAD,eAAS,KAAKI,UAAUH,KAAKD,MAAM;IACrC;AAEA,QAAI,CAACA,QAAQ;AACXA,eAAS,KAAKK,YAAY7C,MAAMgC,UAAUK,IAAAA;IAC5C;AAEAI,WAAOK,SAASN,QAAQ,KAAKjC,IAAI;AACjC,SAAKN,OAAO8C,IAAIT,UAAUG,IAAAA;AAC1B,WAAOA;EACT;EAEUjB,WAAsC;AAC9C,WAAOwB;EACT;;;;EAKUJ,UAAUH,MAA4D;AAC9E,WAAOO;EACT;EAIQN,iBAAiBV,UAAoC;AAC3D,QAAI,KAAK/B,OAAOgD,IAAIjB,QAAAA,GAAW;AAC7B,YAAMS,OAAO,KAAKxC,OAAOiD,IAAIlB,QAAAA;AAC7B,UAAIS,QAAQ,CAACA,KAAKU,WAAW;AAC3B,eAAOV;MACT;IACF;EACF;EAEA,MAAgBZ,UAAU7B,MAA0C;AAClE,UAAMsC,WAAW1B,YAAY,KAAKZ,MAAMA,IAAAA;AACxC,WAAO,IAAIE,IACT;SAAI,KAAKD,OAAOmD,QAAO;MAAIC,OAAO,CAAC,CAACrD,OAAMyC,IAAAA,MAAUzC,MAAKsD,SAAShB,QAAAA,KAAaG,KAAKU,cAAc,IAAA,CAAA;EAEtG;EAEA,MAAc5B,kBAAkBvB,MAA6B;AAC3D,UAAMuD,QAAQC,IACZ7B,MAAMC,MAAM,MAAM,KAAKC,UAAU7B,IAAAA,GAAOyD,OAAM,CAAA,EAAI1B,IAAI,CAACU,SAASA,KAAKiB,MAAK,EAAGhC,MAAM,CAACD,QAAaJ,KAAIK,MAAMD,KAAAA,QAAAA;;;;;;EAE/G;;EAGA,MAAgBN,QAAQnB,MAA6B;AACnD,UAAMuD,QAAQC,IACZ7B,MAAMC,KAAK,MAAM,KAAKC,UAAU7B,IAAAA,CAAAA,EAAO+B,IAAI,CAAC,CAAC/B,OAAMyC,IAAAA,MAAK;AACtD,aAAOA,KACJkB,QAAO,EACPC,KAAK,MAAM,KAAK3D,OAAO4D,OAAO7D,KAAAA,CAAAA,EAC9B0B,MAAM,CAACD,QAAaJ,KAAIyC,MAAMrC,IAAIsC,SAAO,QAAA;;;;;;IAC9C,CAAA,CAAA;EAEJ;AACF;;;AI/IA,OAAOC,SAAS;AAGhB,SAASC,qBAAqB;;;ICAvB;UAAKC,cAAW;AAAXA,EAAAA,aACVC,KAAAA,IAAM;AADID,EAAAA,aAEVE,KAAAA,IAAM;AAFIF,EAAAA,aAGVG,QAAAA,IAAS;AAHCH,EAAAA,aAIVI,SAAAA,IAAU;AAJAJ,EAAAA,aAKVK,MAAAA,IAAO;AALGL,EAAAA,aAMVM,OAAAA,IAAQ;GANEN,gBAAAA,cAAAA,CAAAA,EAAAA;;;ADSL,IAAMO,gBAAN,cAA4BC,gBAAAA;EAA5B;;AACWC,gBAAoBC,YAAYC;;EAE7BC,YAAYC,MAAcC,UAAuC;AAClF,WAAO,KAAKC,WAAWC,IAAAA,CAAAA;EACzB;EAEmBC,UAAUC,MAAgD;AAC3E,UAAMC,UAAUD,KAAKE,MAAK;AACzBD,YAAgBE,SAAS;AAC1B,WAAO,KAAKN,WAAWI,OAAAA;EACzB;EAEQJ,WAAWG,MAAgD;AAEjE,UAAMI,WAAWJ,KAAKK,KAAKC,KAAKN,IAAAA;AAEhCA,SAAKK,OAAO,CAACE,QAAgBC,MAAcC,OACzCL,SAASG,QAAQC,MAAM,CAACE,KAAmBC,SAAAA;AACzC,UAAID,KAAK;AACP,eAAOD,GAAGC,GAAAA;MACZ,OAAO;AACL,eAAOD,GAAGC,KAAKE,cAAcD,IAAAA,CAAAA;MAC/B;IACF,CAAA;AAEF,WAAOX;EACT;AACF;;;AErCA,OAAOa,SAAS;;;ACIT,IAAeC,iBAAf,cAAsCC,gBAAAA;EAG3CC,YAAYC,MAAc;AACxB,UAAMA,IAAAA;AACN,SAAKC,eAAe,KAAKC,mBAAmBF,IAAAA;EAC9C;EAEUG,YAAYH,MAAcI,UAAuC;AACzE,UAAMC,WAAWC,YAAYN,MAAMI,QAAAA;AACnC,WAAO,KAAKH,aAAaI,QAAAA;EAC3B;EAIA,MAAyBE,WAAW;AAElC,WAAO,IAAIC,QAAc,CAACC,SAASC,WAAAA;AACjC,YAAMC,UAAUC,UAAUC,eAAe,KAAKb,IAAI;AAClDW,cAAQG,YAAY,MAAA;AAClBL,gBAAAA;MACF;AACAE,cAAQI,kBAAkB,MAAA;AACxBL,eAAO,IAAIM,MAAM,iBAAA,CAAA;MACnB;AACAL,cAAQM,YAAY,MAAA;AAClBP,eAAO,IAAIM,MAAM,UAAA,CAAA;MACnB;AACAL,cAAQO,UAAU,CAACC,QAAAA;AACjBT,eAAOS,GAAAA;MACT;IACF,CAAA;EACF;AACF;;;AD5BO,IAAMC,iBAAN,cAA6BC,eAAAA;EAA7B;;AACWC,gBAAoBC,YAAYC;;EAE7BC,mBAAmBC,MAAc;AAClD,WAAOC,IAAI;MAAEC,MAAMF;IAAK,CAAA;EAC1B;AACF;;;AElBA,OAAOG,SAAS;AAST,IAAMC,aAAN,cAAyBC,eAAAA;EAAzB;;AACWC,gBAAoBC,YAAYC;;EAE7BC,mBAAmBC,MAAc;AAClD,WAAOC,IAAID,IAAAA;EACb;AACF;;;ACfA,SAASE,oBAAoB;AAC7B,SAASC,mBAAmB;AAG5B,SAASC,oBAAoB;AAC7B,SAASC,iBAAiB;AAC1B,SAASC,OAAAA,YAAW;AACpB,SAASC,mBAAmBC,aAAa;;;;;;;;;;;;AAOlC,IAAMC,QAAN,MAAMA;EAMXC,YAA4BC,MAAc;gBAAdA;SALnBC,OAAOC,YAAYC;SAETC,SAAS,oBAAIC,IAAAA;EAGW;EAE3C,IAAWC,OAAO;AAChB,WAAO,KAAKF,OAAOE;EACrB;EAEQC,UAAUP,MAAoC;AACpD,UAAMQ,WAAW,KAAKC,iBAAiB,KAAKT,MAAMA,IAAAA;AAClD,WAAO,IAAIK,IACT;SAAI,KAAKD,OAAOM,QAAO;MAAIC,OAAO,CAAC,CAACX,OAAMY,IAAAA,MAAUZ,MAAKa,SAASL,QAAAA,KAAaI,KAAKE,cAAc,IAAA,CAAA;EAEtG;EAEA,MAAcC,MAAMf,MAAiC;AACnD,UAAMQ,WAAW,KAAKC,iBAAiBT,IAAAA;AAEvC,UAAMgB,OAAO,MAAM,KAAKC,YAAW;AAUnC,UAAMP,UAAoB,CAAA;AAE1B,qBAAiBQ,SAAUF,KAAaG,KAAI,GAAI;AAC9C,UAAID,MAAME,WAAWZ,WAAW,GAAA,GAAM;AACpCE,gBAAQW,KAAKH,MAAMI,MAAMd,SAASe,SAAS,CAAA,CAAA;MAC7C;IACF;AACA,WAAOb;EACT;EAEA,MACcO,cAAc;AAC1B,QAAI,KAAKO,OAAO;AACd,aAAO,KAAKA;IACd;AACA,SAAKA,QAAQ,MAAMC,UAAUC,QAAQC,aAAY;AACjDC,cAAU,KAAKJ,OAAO,qBAAA;;;;;;;;;AACtB,WAAO,KAAKA;EACd;EAEAK,gBAAgBC,MAAM,IAAI;AACxB,WAAO,IAAIC,UAAU;MACnB9B,MAAM,KAAKA;MACXD,MAAMgC,YAAY,KAAKhC,MAAM8B,GAAAA;MAC7BG,MAAM,CAACjC,SAAS,KAAKe,MAAMf,IAAAA;MAC3BkC,iBAAiB,IAAIC,SAAS,KAAKD,gBAAe,GAAIC,IAAAA;MACtDC,QAAQ,MAAM,KAAKC,QAAQP,GAAAA;MAC3BQ,SAAS,YAAA;AACP,cAAMC,QAAQC,IAAIC,MAAMC,KAAK,KAAKnC,UAAUuB,GAAAA,CAAAA,EAAMa,IAAI,CAAC,CAAC3C,MAAMY,IAAAA,MAAUA,KAAKgC,MAAK,CAAA,CAAA;MACpF;IACF,CAAA;EACF;EAEAV,gBAAgBlC,MAAc6C,UAAkBC,MAAkB;AAChE,UAAMtC,WAAW,KAAKC,iBAAiBT,MAAM6C,QAAAA;AAC7C,UAAME,eAAe,KAAK3C,OAAO4C,IAAIxC,QAAAA;AACrC,QAAIuC,cAAc;AAChB,aAAOA;IACT;AACA,UAAMnC,OAAO,KAAKqC,YAAYzC,QAAAA;AAC9B,SAAKJ,OAAO8C,IAAI1C,UAAUI,IAAAA;AAC1B,WAAOA;EACT;EAEQqC,YAAYzC,UAAkB;AACpC,WAAO,IAAI2C,QAAQ;MACjBC,UAAU5C;MACVI,MAAM,KAAKK,YAAW,EAAGoC,KAAK,CAACrC,SAASA,KAAKsC,cAAc9C,UAAU;QAAE+C,QAAQ;MAAK,CAAA,CAAA;MACpFC,SAAS,YAAA;AACP,aAAKpD,OAAOqD,OAAOjD,QAAAA;AACnB,cAAMQ,OAAO,MAAM,KAAKC,YAAW;AACnC,eAAOD,KAAK0C,YAAYlD,QAAAA;MAC1B;IACF,CAAA;EACF;EAEA,MAAc6B,QAAQrC,MAA6B;AACjD,UAAMuC,QAAQC,IACZC,MAAMC,KAAK,KAAKnC,UAAUP,IAAAA,CAAAA,EAAO2C,IAAI,OAAO,CAAC3C,OAAMY,IAAAA,MAAK;AACtD,YAAMA,KAAK4C,QAAO,EAAGG,MAAM,CAACC,QAAaC,KAAIC,KAAKF,KAAAA,QAAAA;;;;;;AAClD,WAAKxD,OAAOqD,OAAOzD,KAAAA;IACrB,CAAA,CAAA;EAEJ;EAEA,MAAM+D,QAAQ;AACZ,UAAM,KAAK9C,YAAW;AACtB,qBAAiB4B,YAAY,MAAO,KAAKrB,MAAcL,KAAI,GAAI;AAC7D,WAAKf,OAAOqD,OAAOZ,QAAAA;AACnB,YAAM,KAAKrB,MAAOkC,YAAYb,UAAU;QAAEmB,WAAW;MAAK,CAAA,EAAGL,MAAM,CAACC,QAAaC,KAAIC,KAAKF,KAAAA,QAAAA;;;;;;IAC5F;AACA,SAAKpC,QAAQyC;EACf;EAEQxD,iBAAiBT,MAAc6C,UAAmB;AAExD,QAAIA,UAAU;AACZ,aAAOb,YAAYhC,MAAM6C,QAAAA,EAAUqB,MAAM,GAAA,EAAKC,KAAK,GAAA;IACrD,OAAO;AACL,aAAOnE,KAAKkE,MAAM,GAAA,EAAKC,KAAK,GAAA;IAC9B;EACF;EAEA,MAAMC,cAAiC;AACrC,QAAIC,OAAO;AAEX,UAAMC,UAAU,OAAOC,WAAAA;AACrB,YAAMC,WAAW,CAAA;AAEjB,uBAAiBtD,SAAUqD,OAAeE,OAAM,GAAI;AAClDD,iBAASnD,MACN,YAAA;AACC,kBAAQH,MAAMwD,MAAI;YAChB,KAAK;AACHL,sBAAQ,MAAOnD,MAA+ByD,QAAO,EAAGtB,KAAK,CAACuB,MAAOP,QAAQO,EAAEtE,IAAI;AACnF;YACF,KAAK;AACH,oBAAMgE,QAAQpD,KAAAA;AACd;UACJ;QACF,GAAA,CAAA;MAEJ;AACA,YAAMqB,QAAQC,IAAIgC,QAAAA;IACpB;AAEA,UAAMF,QAAQ,KAAK9C,KAAK;AAExB,WAAO;MACL6C;IACF;EACF;AACF;;EAtGGQ;GA1CU/E,MAAAA,WAAAA,eAAAA,IAAAA;AAoJb,IAAaqD,UAAN,MAAAA,iBAAsB2B,aAAAA;EA6C3B/E,YAAY,EACVqD,UACAxC,MACA4C,QAAO,GAKN;AACD,UAAK;AA5CCuB;;;mBAA6B;AAE7BC,8BAA2C;AAE3CC,2BAAkB;AAElBC,yBAAsC;AAOtCC;;;oBAAW,IAAIC,kBAAAA;AAGfC,uBAAc,IAAID,kBAAAA;AAGlBE,kBAAS,IAAIF,kBAAAA;AAGbG,sBAAa,IAAIH,kBAAAA;AAGjBI,mBAAU,IAAIJ,kBAAAA;AAGdK,uBAAc,IAAIL,kBAAAA;AAwB1BnF,gBAAoBC,YAAYC;AAOvBuF;;;;kBAAkB;AAClBC,qBAAqB;AACrBC,kBAAkB;AAClBC,oBAAoB;AACpBC,mBAAmB;AACnBC,oBAAoB;AACpBC,oBAAoB;AACpBC,qBAAqB;AACrBC,uBAAuB;AACvBC,oBAAoB;AAE7BrF,qBAAY;AACZsF,qBAAY;AAEZvD;oBAAW;AACXwD,kBAA8B;MAC5BC,OAAOC,YAAY,KAAKD,MAAME,KAAK,IAAI,CAAA;MACvCC,MAAMF,YAAY,KAAKE,KAAKD,KAAK,IAAI,CAAA;MACrCE,KAAKH,YAAY,KAAKG,IAAIF,KAAK,IAAI,CAAA;MACnCG,MAAMJ,YAAY,KAAKI,KAAKH,KAAK,IAAI,CAAA;MACrChD,SAAS+C,YAAY,KAAK/C,QAAQgD,KAAK,IAAI,CAAA;MAC3CI,UAAUL,YAAY,KAAKK,UAAUJ,KAAK,IAAI,CAAA;IAChD;AApCE,SAAKK,YAAYzD;AACjB,SAAK0D,cAAclG;AACnB,SAAKmG,WAAWvD;AAEhB,SAAK,KAAKwD,mBAAkB;EAC9B;EApBA,IACIC,cAAc;AAChB,WAAO,KAAKlC,SAASxD;EACvB;EAkDA,MAAc2F,cAAc;AAC1B,UAAMC,aAAa,MAAM,KAAKL;AAC9B,UAAMlG,OAAO,MAAMuG,WAAWxC,QAAO;AACrC,SAAKI,UAAU,IAAIqC,WAAW,MAAMxG,KAAKyG,YAAW,CAAA;EACtD;EAEA,MAAcL,qBAAqB;AACjC,WAAO,KAAKhC,uBAAuB,KAAKkC,YAAW;EACrD;;EAGA,MAAcI,cAAc;AAC1B,QAAI,KAAKxG,WAAW;AAClB;IACF;AAEA,SAAKqE,SAASoC,IAAG;AAEjB,UAAM,KAAKP,mBAAkB;AAC7BpF,cAAU,KAAKmD,SAAO,QAAA;;;;;;;;;AAEtB,UAAMoC,aAAa,MAAM,KAAKL;AAC9B,UAAMd,WAAW,MAAMmB,WAAWK,eAAe;MAAEC,kBAAkB;IAAK,CAAA;AAC1E,UAAMzB,SAASM,MAAM;MAAErG,MAAM;MAASyH,MAAM,KAAK3C;MAAS4C,UAAU;IAAE,CAAA;AACtE,UAAM3B,SAAS4B,MAAK;EACtB;EAEQC,cAAc;AACpB,QAAI,KAAK5C,iBAAiB;AACxB;IACF;AAEA6C,eAAW,YAAA;AAET,YAAMC,gBAAgB,KAAK7C;AAC3B,YAAM,KAAKA;AACX,WAAKD,kBAAkB;AAGvB,UAAI8C,kBAAkB,KAAK7C,eAAe;AACxC;MACF;AAEA,WAAKA,gBAAgB,KAAKoC,YAAW,EAAG3D,MAAM,CAACC,QAAQC,KAAIC,KAAKF,KAAAA,QAAAA;;;;;;IAClE,CAAA;AAEA,SAAKqB,kBAAkB;EACzB;EAEA,MAAc+C,YAAY;AACxB,SAAK9C,iBAAiB,KAAKA,iBAAiB3C,QAAQ0F,QAAO,GACxD5E,KAAK,MAAM,KAAKiE,YAAW,CAAA,EAC3B3D,MAAM,CAACC,QAAQC,KAAIC,KAAKF,KAAAA,QAAAA;;;;;;AAE3B,UAAM,KAAKsB;EACb;EAEA,MAAMuB,KAAKyB,QAAgB5H,MAAc;AACvC,SAAK+E,YAAYkC,IAAG;AACpB,SAAKjC,OAAOiC,IAAG;AACf,SAAKhC,WAAWgC,IAAIjH,IAAAA;AAEpB,QAAI,CAAC,KAAKyE,SAAS;AACjB,YAAM,KAAKiC,mBAAkB;AAC7BpF,gBAAU,KAAKmD,SAAO,QAAA;;;;;;;;;IACxB;AAEA,QAAImD,SAAS5H,OAAO,KAAKyE,QAAQxD,QAAQ;AACvC,YAAM,IAAI4G,MAAM,oBAAA;IAClB;AAGA,WAAOC,OAAO1F,KAAK,KAAKqC,QAAQzD,MAAM4G,QAAQA,SAAS5H,IAAAA,CAAAA;EACzD;EAEA,MAAMgG,MAAM4B,QAAgBR,MAAc;AACxC,SAAKrC,YAAYkC,IAAG;AACpB,SAAK/B,QAAQ+B,IAAG;AAChB,SAAK9B,YAAY8B,IAAIG,KAAKnG,MAAM;AAEhC,QAAI,CAAC,KAAKwD,SAAS;AACjB,YAAM,KAAKiC,mBAAkB;AAC7BpF,gBAAU,KAAKmD,SAAO,QAAA;;;;;;;;;IACxB;AAEA,QAAImD,SAASR,KAAKnG,UAAU,KAAKwD,QAAQxD,QAAQ;AAC/C,WAAKwD,QAAQ7B,IAAIwE,MAAMQ,MAAAA;IACzB,OAAO;AAEL,YAAMG,WAAW,IAAIjB,WAAWc,SAASR,KAAKnG,MAAM;AACpD8G,eAASnF,IAAI,KAAK6B,OAAO;AACzBsD,eAASnF,IAAIwE,MAAMQ,MAAAA;AACnB,WAAKnD,UAAUsD;IACjB;AAEA,SAAKR,YAAW;EAClB;EAEA,MAAMnB,IAAIwB,QAAgB5H,MAAc;AACtC,SAAK+E,YAAYkC,IAAG;AAEpB,QAAIW,SAAS,KAAK5H,OAAO,GAAG;AAC1B;IACF;AAEA,QAAI,CAAC,KAAKyE,SAAS;AACjB,YAAM,KAAKiC,mBAAkB;AAC7BpF,gBAAU,KAAKmD,SAAO,QAAA;;;;;;;;;IACxB;AAEA,QAAIuD,eAAe;AACnB,QAAIJ,SAAS5H,OAAO,KAAKyE,QAAQxD,QAAQ;AACvC+G,qBAAe,KAAKvD,QAAQxD,UAAU2G,SAAS5H;AAC/C,WAAKyE,QAAQ7B,IAAI,KAAK6B,QAAQzD,MAAM4G,SAAS5H,MAAM4H,SAAS5H,OAAOgI,YAAAA,GAAeJ,MAAAA;IACpF;AAEA,SAAKnD,UAAU,KAAKA,QAAQzD,MAAM,GAAG4G,SAASI,YAAAA;AAE9C,SAAKT,YAAW;EAClB;EAEA,MAAMlB,OAAO;AACX,SAAKtB,YAAYkC,IAAG;AAGpB,QAAI,CAAC,KAAKxC,SAAS;AACjB,YAAM,KAAKiC,mBAAkB;AAC7BpF,gBAAU,KAAKmD,SAAO,QAAA;;;;;;;;;IACxB;AAEA,WAAO;MACLzE,MAAM,KAAKyE,QAAQxD;IACrB;EACF;EAEA,MAAMqF,SAASsB,QAAgB;AAC7B,SAAK7C,YAAYkC,IAAG;AAEpB,QAAI,CAAC,KAAKxC,SAAS;AACjB,YAAM,KAAKiC,mBAAkB;AAC7BpF,gBAAU,KAAKmD,SAAO,QAAA;;;;;;;;;IACxB;AAEA,SAAKA,UAAU,KAAKA,QAAQzD,MAAM,GAAG4G,MAAAA;AAErC,SAAKL,YAAW;EAClB;EAEA,MAAMjF,QAAQ;AACZ,UAAM,KAAKoF,UAAS;EACtB;EAEA,MAAMJ,QAAuB;AAC3B,UAAM,KAAKI,UAAS;EACtB;EAEA,MACMxE,UAAU;AACd,SAAK1C,YAAY;AACjB,WAAO,MAAM,KAAKiG,SAAQ;EAC5B;AACF;;EA7PGwB,MAAMC,KAAI;GADArF,QAAAA,WAAAA,aAAAA,MAAAA;;EAsBVoF,MAAME,eAAc;GAtBVtF,QAAAA,WAAAA,YAAAA,MAAAA;;EAyBVoF,MAAME,eAAc;GAzBVtF,QAAAA,WAAAA,eAAAA,MAAAA;;EA4BVoF,MAAME,eAAc;GA5BVtF,QAAAA,WAAAA,UAAAA,MAAAA;;EA+BVoF,MAAME,eAAc;GA/BVtF,QAAAA,WAAAA,cAAAA,MAAAA;;EAkCVoF,MAAME,eAAc;GAlCVtF,QAAAA,WAAAA,WAAAA,MAAAA;;EAqCVoF,MAAME,eAAc;GArCVtF,QAAAA,WAAAA,eAAAA,MAAAA;;EAwCVoF,MAAMC,KAAI;GAxCArF,QAAAA,WAAAA,eAAAA,IAAAA;;EAyPV0B;GAzPU1B,QAAAA,WAAAA,WAAAA,IAAAA;AAAAA,UAAAA,aAAAA;EADZoF,MAAMG,SAAQ;GACFvF,OAAAA;;;AC7JN,IAAMwF,gBAAoC,CAAC,EAAEC,MAAMC,OAAO,GAAE,IAAK,CAAC,MAAC;AACxE,MAAID,SAASE,QAAW;AACtB,QACEC,aACAA,UAAUC,WACV,OAAOD,UAAUC,QAAQC,iBAAiB,cAC1CC,wBACA,OAAQA,qBAAqBC,UAAkBC,mBAAmB,YAClE;AACA,aAAO,IAAIC,MAAMR,IAAAA;IACnB,OAAO;AACL,aAAO,IAAIS,WAAWT,IAAAA;IACxB;EACF;AAEA,UAAQD,MAAAA;IACN,KAAKW,YAAYC,KAAK;AACpB,aAAO,IAAIC,cAAcZ,IAAAA;IAC3B;IAEA,KAAKU,YAAYG;IACjB,KAAKH,YAAYI,QAAQ;AACvB,aAAO,IAAIL,WAAWT,IAAAA;IACxB;IAEA,KAAKU,YAAYK,SAAS;AACxB,aAAO,IAAIC,eAAehB,IAAAA;IAC5B;IAEA,KAAKU,YAAYO,OAAO;AACtB,aAAO,IAAIT,MAAMR,IAAAA;IACnB;IAEA,SAAS;AACP,YAAM,IAAIkB,MAAM,iBAAiBnB,IAAAA,EAAM;IACzC;EACF;AACF;",
6
+ "names": ["join", "inspect", "inspectObject", "log", "join", "stringDiff", "first", "second", "split", "join", "getFullPath", "root", "path", "Directory", "constructor", "type", "path", "list", "getOrCreateFile", "remove", "onFlush", "_list", "_getOrCreateFile", "_remove", "_onFlush", "toString", "JSON", "stringify", "createDirectory", "getFullPath", "filename", "opts", "flush", "delete", "pify", "log", "MAX_STORAGE_OPERATION_TIME", "pifyFields", "object", "type", "fields", "field", "fn", "bind", "args", "before", "performance", "now", "res", "elapsed", "warn", "operation", "wrapFile", "native", "file", "Object", "assign", "AbstractStorage", "constructor", "path", "_files", "Map", "inspect", "custom", "inspectObject", "toJSON", "type", "size", "createDirectory", "sub", "Directory", "getFullPath", "list", "_list", "bind", "getOrCreateFile", "args", "remove", "_remove", "reset", "log", "info", "_closeFilesInPath", "_destroy", "err", "catch", "Array", "from", "_getFiles", "keys", "map", "filename", "name", "replace", "startsWith", "substring", "opts", "fullPath", "join", "native", "file", "_getFileIfExists", "closed", "_openFile", "_createFile", "wrapFile", "set", "undefined", "has", "get", "destroyed", "entries", "filter", "includes", "Promise", "all", "values", "close", "destroy", "then", "delete", "error", "message", "ram", "arrayToBuffer", "StorageType", "RAM", "IDB", "CHROME", "FIREFOX", "NODE", "WEBFS", "MemoryStorage", "AbstractStorage", "type", "StorageType", "RAM", "_createFile", "path", "filename", "_patchFile", "ram", "_openFile", "file", "newFile", "clone", "closed", "trueRead", "read", "bind", "offset", "size", "cb", "err", "data", "arrayToBuffer", "raw", "BrowserStorage", "AbstractStorage", "constructor", "path", "_fileStorage", "_createFileStorage", "_createFile", "filename", "fullPath", "getFullPath", "_destroy", "Promise", "resolve", "reject", "request", "indexedDB", "deleteDatabase", "onsuccess", "onupgradeneeded", "Error", "onblocked", "onerror", "err", "FirefoxStorage", "BrowserStorage", "type", "StorageType", "FIREFOX", "_createFileStorage", "path", "raw", "name", "idb", "IDbStorage", "BrowserStorage", "type", "StorageType", "IDB", "_createFileStorage", "path", "idb", "EventEmitter", "callbackify", "synchronized", "invariant", "log", "TimeSeriesCounter", "trace", "WebFS", "constructor", "path", "type", "StorageType", "WEBFS", "_files", "Map", "size", "_getFiles", "fullName", "_getFullFilename", "entries", "filter", "file", "includes", "destroyed", "_list", "root", "_initialize", "entry", "keys", "startsWith", "push", "slice", "length", "_root", "navigator", "storage", "getDirectory", "invariant", "createDirectory", "sub", "Directory", "getFullPath", "list", "getOrCreateFile", "args", "remove", "_delete", "onFlush", "Promise", "all", "Array", "from", "map", "flush", "filename", "opts", "existingFile", "get", "_createFile", "set", "WebFile", "fileName", "then", "getFileHandle", "create", "destroy", "delete", "removeEntry", "catch", "err", "log", "warn", "reset", "recursive", "undefined", "split", "join", "getDiskInfo", "used", "recurse", "handle", "promises", "values", "kind", "getFile", "f", "synchronized", "EventEmitter", "_buffer", "_loadBufferPromise", "_flushScheduled", "_flushPromise", "_flushes", "TimeSeriesCounter", "_operations", "_reads", "_readBytes", "_writes", "_writeBytes", "opened", "suspended", "closed", "unlinked", "writing", "readable", "writable", "deletable", "truncatable", "statable", "directory", "native", "write", "callbackify", "bind", "read", "del", "stat", "truncate", "_fileName", "_fileHandle", "_destroy", "_loadBufferGuarded", "_bufferSize", "_loadBuffer", "fileHandle", "Uint8Array", "arrayBuffer", "_flushCache", "inc", "createWritable", "keepExistingData", "data", "position", "close", "_flushLater", "setTimeout", "promiseBefore", "_flushNow", "resolve", "offset", "Error", "Buffer", "newCache", "leftoverSize", "trace", "info", "metricsCounter", "resource", "createStorage", "type", "root", "undefined", "navigator", "storage", "getDirectory", "FileSystemFileHandle", "prototype", "createWritable", "WebFS", "IDbStorage", "StorageType", "RAM", "MemoryStorage", "IDB", "CHROME", "FIREFOX", "FirefoxStorage", "WEBFS", "Error"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"inject-globals:@inject-globals":{"bytes":384,"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/utils.ts":{"bytes":1295,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/directory.ts":{"bytes":5037,"imports":[{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/file.ts":{"bytes":6374,"imports":[{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytes":14221,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/storage.ts":{"bytes":1874,"imports":[{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytes":4360,"imports":[{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/index.ts":{"bytes":947,"imports":[{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/memory-storage.ts","kind":"import-statement","original":"./memory-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/browser-storage.ts":{"bytes":4379,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/firefox-storage.ts":{"bytes":2391,"imports":[{"path":"random-access-web/mutable-file-wrapper.js","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/browser/browser-storage.ts","kind":"import-statement","original":"./browser-storage"},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/idb-storage.ts":{"bytes":1799,"imports":[{"path":"random-access-idb","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/browser/browser-storage.ts","kind":"import-statement","original":"./browser-storage"},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/web-fs.ts":{"bytes":42927,"imports":[{"path":"@dxos/node-std/events","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/tracing","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/storage.ts":{"bytes":4408,"imports":[{"path":"packages/common/random-access-storage/src/browser/firefox-storage.ts","kind":"import-statement","original":"./firefox-storage"},{"path":"packages/common/random-access-storage/src/browser/idb-storage.ts","kind":"import-statement","original":"./idb-storage"},{"path":"packages/common/random-access-storage/src/browser/web-fs.ts","kind":"import-statement","original":"./web-fs"},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/index.ts":{"bytes":571,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/browser/storage.ts","kind":"import-statement","original":"./storage"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"packages/common/random-access-storage/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":43314},"packages/common/random-access-storage/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"random-access-web/mutable-file-wrapper.js","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"random-access-idb","kind":"import-statement","external":true},{"path":"@dxos/node-std/events","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/tracing","kind":"import-statement","external":true}],"exports":["AbstractStorage","Directory","MemoryStorage","StorageType","createStorage","getFullPath","stringDiff","wrapFile"],"entryPoint":"packages/common/random-access-storage/src/browser/index.ts","inputs":{"inject-globals:@inject-globals":{"bytesInOutput":79},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytesInOutput":3348},"packages/common/random-access-storage/src/common/utils.ts":{"bytesInOutput":180},"packages/common/random-access-storage/src/common/directory.ts":{"bytesInOutput":1026},"packages/common/random-access-storage/src/common/file.ts":{"bytesInOutput":1149},"packages/common/random-access-storage/src/common/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytesInOutput":693},"packages/common/random-access-storage/src/common/storage.ts":{"bytesInOutput":288},"packages/common/random-access-storage/src/browser/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/browser/firefox-storage.ts":{"bytesInOutput":275},"packages/common/random-access-storage/src/browser/browser-storage.ts":{"bytesInOutput":769},"packages/common/random-access-storage/src/browser/idb-storage.ts":{"bytesInOutput":223},"packages/common/random-access-storage/src/browser/web-fs.ts":{"bytesInOutput":11455},"packages/common/random-access-storage/src/browser/storage.ts":{"bytesInOutput":765}},"bytes":21444}}}
1
+ {"inputs":{"inject-globals:@inject-globals":{"bytes":384,"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/utils.ts":{"bytes":1295,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/directory.ts":{"bytes":6503,"imports":[{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/file.ts":{"bytes":6374,"imports":[{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytes":14628,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/storage.ts":{"bytes":1874,"imports":[{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytes":4360,"imports":[{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/index.ts":{"bytes":947,"imports":[{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/memory-storage.ts","kind":"import-statement","original":"./memory-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/browser-storage.ts":{"bytes":4333,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/firefox-storage.ts":{"bytes":2391,"imports":[{"path":"random-access-web/mutable-file-wrapper.js","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/browser/browser-storage.ts","kind":"import-statement","original":"./browser-storage"},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/idb-storage.ts":{"bytes":1799,"imports":[{"path":"random-access-idb","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/browser/browser-storage.ts","kind":"import-statement","original":"./browser-storage"},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/web-fs.ts":{"bytes":43247,"imports":[{"path":"@dxos/node-std/events","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/tracing","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/storage.ts":{"bytes":4408,"imports":[{"path":"packages/common/random-access-storage/src/browser/firefox-storage.ts","kind":"import-statement","original":"./firefox-storage"},{"path":"packages/common/random-access-storage/src/browser/idb-storage.ts","kind":"import-statement","original":"./idb-storage"},{"path":"packages/common/random-access-storage/src/browser/web-fs.ts","kind":"import-statement","original":"./web-fs"},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/index.ts":{"bytes":571,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/browser/storage.ts","kind":"import-statement","original":"./storage"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"packages/common/random-access-storage/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":44380},"packages/common/random-access-storage/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"random-access-web/mutable-file-wrapper.js","kind":"import-statement","external":true},{"path":"random-access-idb","kind":"import-statement","external":true},{"path":"@dxos/node-std/events","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/tracing","kind":"import-statement","external":true}],"exports":["AbstractStorage","Directory","MemoryStorage","StorageType","createStorage","getFullPath","stringDiff","wrapFile"],"entryPoint":"packages/common/random-access-storage/src/browser/index.ts","inputs":{"inject-globals:@inject-globals":{"bytesInOutput":79},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytesInOutput":3457},"packages/common/random-access-storage/src/common/utils.ts":{"bytesInOutput":180},"packages/common/random-access-storage/src/common/directory.ts":{"bytesInOutput":1103},"packages/common/random-access-storage/src/common/file.ts":{"bytesInOutput":1149},"packages/common/random-access-storage/src/common/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytesInOutput":693},"packages/common/random-access-storage/src/common/storage.ts":{"bytesInOutput":288},"packages/common/random-access-storage/src/browser/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/browser/firefox-storage.ts":{"bytesInOutput":275},"packages/common/random-access-storage/src/browser/browser-storage.ts":{"bytesInOutput":722},"packages/common/random-access-storage/src/browser/idb-storage.ts":{"bytesInOutput":223},"packages/common/random-access-storage/src/browser/web-fs.ts":{"bytesInOutput":11555},"packages/common/random-access-storage/src/browser/storage.ts":{"bytesInOutput":765}},"bytes":21683}}}
@@ -48,19 +48,20 @@ var import_log2 = require("@dxos/log");
48
48
  var import_random_access_memory = __toESM(require("random-access-memory"));
49
49
  var import_util = require("@dxos/util");
50
50
  var import_del = __toESM(require("del"));
51
+ var import_node_fs = require("node:fs");
51
52
  var import_promises = require("node:fs/promises");
52
53
  var import_node_path3 = require("node:path");
53
54
  var import_random_access_file = __toESM(require("random-access-file"));
54
55
  var stringDiff = (first, second) => first.split(second).join("");
55
56
  var getFullPath = (root, path) => (0, import_node_path2.join)(root, stringDiff(path, root));
56
57
  var Directory = class _Directory {
57
- constructor(type, path, _list, _getOrCreateFile, _delete, _onFlush) {
58
+ constructor({ type, path, list, getOrCreateFile, remove, onFlush }) {
58
59
  this.type = type;
59
60
  this.path = path;
60
- this._list = _list;
61
- this._getOrCreateFile = _getOrCreateFile;
62
- this._delete = _delete;
63
- this._onFlush = _onFlush;
61
+ this._list = list;
62
+ this._getOrCreateFile = getOrCreateFile;
63
+ this._remove = remove;
64
+ this._onFlush = onFlush;
64
65
  }
65
66
  toString() {
66
67
  return `Directory(${JSON.stringify({
@@ -72,7 +73,13 @@ var Directory = class _Directory {
72
73
  * Create a new sub-directory.
73
74
  */
74
75
  createDirectory(path) {
75
- return new _Directory(this.type, getFullPath(this.path, path), this._list, this._getOrCreateFile, this._delete);
76
+ return new _Directory({
77
+ type: this.type,
78
+ path: getFullPath(this.path, path),
79
+ list: this._list,
80
+ getOrCreateFile: this._getOrCreateFile,
81
+ remove: this._remove
82
+ });
76
83
  }
77
84
  /**
78
85
  * Get all files in the current directory.
@@ -93,7 +100,7 @@ var Directory = class _Directory {
93
100
  * Close and delete all files in the directory and all its sub-directories.
94
101
  */
95
102
  async delete() {
96
- await this._delete();
103
+ await this._remove();
97
104
  }
98
105
  };
99
106
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/common/random-access-storage/src/common/file.ts";
@@ -161,7 +168,13 @@ var AbstractStorage = class {
161
168
  }
162
169
  // TODO(burdon): Make required.
163
170
  createDirectory(sub = "") {
164
- return new Directory(this.type, getFullPath(this.path, sub), this._list.bind(this), (...args) => this.getOrCreateFile(...args), () => this._delete(sub));
171
+ return new Directory({
172
+ type: this.type,
173
+ path: getFullPath(this.path, sub),
174
+ list: this._list.bind(this),
175
+ getOrCreateFile: (...args) => this.getOrCreateFile(...args),
176
+ remove: () => this._remove(sub)
177
+ });
165
178
  }
166
179
  /**
167
180
  * Delete all files.
@@ -175,7 +188,7 @@ var AbstractStorage = class {
175
188
  C: (f, a) => f(...a)
176
189
  });
177
190
  await this._closeFilesInPath("");
178
- await this._delete("");
191
+ await this._remove("");
179
192
  await this._destroy();
180
193
  (0, import_log.log)("Erased...", void 0, {
181
194
  F: __dxlog_file2,
@@ -193,7 +206,7 @@ var AbstractStorage = class {
193
206
  }
194
207
  }
195
208
  async _list(path) {
196
- return Array.from(this._getFiles(path).keys()).map((filename) => {
209
+ return Array.from((await this._getFiles(path)).keys()).map((filename) => {
197
210
  let name = filename.replace(path, "");
198
211
  if (name.startsWith("/")) {
199
212
  name = name.substring(1);
@@ -235,14 +248,14 @@ var AbstractStorage = class {
235
248
  }
236
249
  }
237
250
  }
238
- _getFiles(path) {
251
+ async _getFiles(path) {
239
252
  const fullPath = getFullPath(this.path, path);
240
253
  return new Map([
241
254
  ...this._files.entries()
242
255
  ].filter(([path2, file]) => path2.includes(fullPath) && file.destroyed !== true));
243
256
  }
244
257
  async _closeFilesInPath(path) {
245
- await Promise.all(Array.from(this._getFiles(path).values()).map((file) => file.close().catch((err) => import_log.log.catch(err, void 0, {
258
+ await Promise.all(Array.from((await this._getFiles(path)).values()).map((file) => file.close().catch((err) => import_log.log.catch(err, void 0, {
246
259
  F: __dxlog_file2,
247
260
  L: 133,
248
261
  S: this,
@@ -250,8 +263,8 @@ var AbstractStorage = class {
250
263
  }))));
251
264
  }
252
265
  // TODO(burdon): Delete directory (not just listed files).
253
- async _delete(path) {
254
- await Promise.all(Array.from(this._getFiles(path)).map(([path2, file]) => {
266
+ async _remove(path) {
267
+ await Promise.all(Array.from(await this._getFiles(path)).map(([path2, file]) => {
255
268
  return file.destroy().then(() => this._files.delete(path2)).catch((err) => import_log.log.error(err.message, void 0, {
256
269
  F: __dxlog_file2,
257
270
  L: 144,
@@ -299,6 +312,26 @@ var NodeStorage = class extends AbstractStorage {
299
312
  constructor() {
300
313
  super(...arguments);
301
314
  this.type = StorageType.NODE;
315
+ this._initialized = false;
316
+ }
317
+ async _loadFiles(path) {
318
+ if (!(0, import_node_fs.existsSync)(path)) {
319
+ return;
320
+ }
321
+ const dir = await (0, import_promises.readdir)(path);
322
+ for (const entry of dir) {
323
+ const fullPath = (0, import_node_path3.join)(path, entry);
324
+ if (this._files.has(fullPath)) {
325
+ continue;
326
+ }
327
+ const entryInfo = await (0, import_promises.stat)(fullPath);
328
+ if (entryInfo.isDirectory()) {
329
+ await this._loadFiles(fullPath);
330
+ } else if (entryInfo.isFile()) {
331
+ const file = this._createFile(path, entry);
332
+ this._files.set(fullPath, wrapFile(file, this.type));
333
+ }
334
+ }
302
335
  }
303
336
  _createFile(path, filename, opts = {}) {
304
337
  const file = (0, import_random_access_file.default)(filename, {
@@ -313,6 +346,13 @@ var NodeStorage = class extends AbstractStorage {
313
346
  force: true
314
347
  });
315
348
  }
349
+ async _getFiles(path) {
350
+ if (!this._initialized) {
351
+ await this._loadFiles(this.path);
352
+ this._initialized = true;
353
+ }
354
+ return super._getFiles(path);
355
+ }
316
356
  async getDiskInfo() {
317
357
  let used = 0;
318
358
  const recurse = async (path) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/common/abstract-storage.ts", "../../../src/common/utils.ts", "../../../src/common/directory.ts", "../../../src/common/file.ts", "../../../src/common/memory-storage.ts", "../../../src/common/storage.ts", "../../../src/node/node-storage.ts", "../../../src/node/storage.ts"],
4
- "sourcesContent": ["//\n// Copyright 2021 DXOS.org\n//\n\nimport { join } from 'node:path';\nimport { inspect } from 'node:util';\nimport type { RandomAccessStorage } from 'random-access-storage';\n\nimport { inspectObject } from '@dxos/debug';\nimport { log } from '@dxos/log';\n\nimport { Directory } from './directory';\nimport { type File, wrapFile } from './file';\nimport { type Storage, type StorageType } from './storage';\nimport { getFullPath } from './utils';\n\n/**\n * Base class for all storage implementations.\n * https://github.com/random-access-storage\n * https://github.com/random-access-storage/random-access-storage\n */\nexport abstract class AbstractStorage implements Storage {\n protected readonly _files = new Map<string, File>();\n\n public abstract readonly type: StorageType;\n\n // TODO(burdon): Make required.\n constructor(public readonly path: string) {}\n\n [inspect.custom]() {\n return inspectObject(this);\n }\n\n toJSON() {\n return { type: this.type, path: this.path };\n }\n\n public get size() {\n return this._files.size;\n }\n\n // TODO(burdon): Make required.\n public createDirectory(sub = ''): Directory {\n // invariant(sub.length);\n return new Directory(\n this.type,\n getFullPath(this.path, sub),\n this._list.bind(this),\n (...args) => this.getOrCreateFile(...args),\n () => this._delete(sub),\n );\n }\n\n /**\n * Delete all files.\n */\n async reset() {\n try {\n log.info('Erasing all data...');\n await this._closeFilesInPath('');\n await this._delete('');\n await this._destroy();\n log('Erased...');\n } catch (err: any) {\n log.catch(err);\n }\n }\n\n protected async _list(path: string): Promise<string[]> {\n // TODO(dmaretskyi): Fix me.\n return Array.from(this._getFiles(path).keys()).map((filename) => {\n let name = filename.replace(path, '');\n if (name.startsWith('/')) {\n name = name.substring(1);\n }\n return name;\n });\n }\n\n protected getOrCreateFile(path: string, filename: string, opts?: any): File {\n const fullPath = join(path, filename);\n\n let native;\n let file = this._getFileIfExists(fullPath);\n if (file) {\n if (!file.closed) {\n return file;\n }\n\n native = this._openFile(file.native);\n }\n\n if (!native) {\n native = this._createFile(path, filename, opts);\n }\n\n file = wrapFile(native, this.type);\n this._files.set(fullPath, file);\n return file;\n }\n\n protected _destroy(): Promise<void> | undefined {\n return undefined;\n }\n\n /**\n * Attempt to reopen file.\n */\n protected _openFile(file: RandomAccessStorage): RandomAccessStorage | undefined {\n return undefined;\n }\n\n protected abstract _createFile(path: string, filename: string, opts?: any): RandomAccessStorage;\n\n private _getFileIfExists(filename: string): File | undefined {\n if (this._files.has(filename)) {\n const file = this._files.get(filename);\n if (file && !file.destroyed) {\n return file;\n }\n }\n }\n\n private _getFiles(path: string): Map<string, File> {\n const fullPath = getFullPath(this.path, path);\n return new Map(\n [...this._files.entries()].filter(([path, file]) => path.includes(fullPath) && file.destroyed !== true),\n );\n }\n\n private async _closeFilesInPath(path: string): Promise<void> {\n await Promise.all(\n Array.from(this._getFiles(path).values()).map((file) => file.close().catch((err: any) => log.catch(err))),\n );\n }\n\n // TODO(burdon): Delete directory (not just listed files).\n protected async _delete(path: string): Promise<void> {\n await Promise.all(\n Array.from(this._getFiles(path)).map(([path, file]) => {\n return file\n .destroy()\n .then(() => this._files.delete(path))\n .catch((err: any) => log.error(err.message));\n }),\n );\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { join } from 'node:path';\n\n// TODO(burdon): Document.\nexport const stringDiff = (first: string, second: string) => first.split(second).join('');\n\nexport const getFullPath = (root: string, path: string) => join(root, stringDiff(path, root));\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type File } from './file';\nimport { type StorageType } from './storage';\nimport { getFullPath } from './utils';\n\n/**\n * Wraps a directory in the storage file system.\n */\nexport class Directory {\n constructor(\n public readonly type: StorageType,\n public readonly path: string,\n // TODO(burdon): Create interface for these methods (shared with AbstractStorage).\n private readonly _list: (path: string) => Promise<string[]>,\n private readonly _getOrCreateFile: (path: string, filename: string, opts?: any) => File,\n private readonly _delete: () => Promise<void>,\n private readonly _onFlush?: () => Promise<void>,\n ) {}\n\n toString() {\n return `Directory(${JSON.stringify({ type: this.type, path: this.path })})`;\n }\n\n /**\n * Create a new sub-directory.\n */\n createDirectory(path: string): Directory {\n return new Directory(this.type, getFullPath(this.path, path), this._list, this._getOrCreateFile, this._delete);\n }\n\n /**\n * Get all files in the current directory.\n */\n list(): Promise<string[]> {\n return this._list(this.path);\n }\n\n /**\n * Get or create a new file.\n */\n getOrCreateFile(filename: string, opts?: any): File {\n return this._getOrCreateFile(this.path, filename, opts);\n }\n\n async flush() {\n await this._onFlush?.();\n }\n\n /**\n * Close and delete all files in the directory and all its sub-directories.\n */\n async delete() {\n await this._delete();\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport pify from 'pify';\nimport type { FileStat, RandomAccessStorage, RandomAccessStorageProperties } from 'random-access-storage';\n\nimport { log } from '@dxos/log';\n\nimport { type StorageType } from './storage';\n\nconst MAX_STORAGE_OPERATION_TIME = 50;\n\n/**\n * Random access file wrapper.\n * https://github.com/random-access-storage/random-access-storage\n */\nexport interface File extends RandomAccessStorageProperties {\n readonly destroyed: boolean;\n\n // TODO(burdon): Can we remove these since they are not standard across implementations?\n readonly directory: string;\n readonly filename: string;\n\n // Added by factory.\n readonly type: StorageType;\n readonly native: RandomAccessStorage;\n\n write(offset: number, data: Buffer): Promise<void>;\n read(offset: number, size: number): Promise<Buffer>;\n del(offset: number, size: number): Promise<void>;\n stat(): Promise<FileStat>;\n close(): Promise<Error | void>;\n destroy(): Promise<Error | void>;\n\n /**\n * Save changes to disk.\n */\n flush?(): Promise<void>;\n\n // Not supported in node, memory.\n truncate?(offset: number): Promise<void>;\n\n // random-access-memory only.\n clone?(): RandomAccessStorage;\n}\n\nconst pifyFields = (object: any, type: StorageType, fields: string[]) => {\n for (const field of fields) {\n if (!object[field]) {\n // TODO(burdon): Suppress warning and throw error if used.\n // console.warn(`Field not supported for type: ${JSON.stringify({ type, field })}`);\n } else {\n const fn = pify(object[field].bind(object));\n object[field] = async (...args: any) => {\n const before = performance.now();\n\n const res = await fn(...args);\n\n const elapsed = performance.now() - before;\n if (elapsed > MAX_STORAGE_OPERATION_TIME) {\n log.warn('Slow storage operation', { type, operation: field, elapsed });\n }\n\n return res;\n };\n }\n }\n\n return object;\n};\n\n/**\n * Construct async File wrapper.\n * NOTE: This is safe since these are interface methods only (not used internally).\n */\nexport const wrapFile = (native: RandomAccessStorage, type: StorageType): File => {\n const file = pifyFields(native, type, ['write', 'read', 'del', 'stat', 'close', 'destroy', 'truncate']);\n return Object.assign(file, { type, native });\n};\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport ram from 'random-access-memory';\nimport { type Callback, type RandomAccessStorage } from 'random-access-storage';\n\nimport { arrayToBuffer } from '@dxos/util';\n\nimport { AbstractStorage } from './abstract-storage';\nimport { StorageType } from './storage';\n\n/**\n * Storage interface implementation for RAM.\n * https://github.com/random-access-storage/random-access-memory\n */\nexport class MemoryStorage extends AbstractStorage {\n public override type: StorageType = StorageType.RAM;\n\n protected override _createFile(path: string, filename: string): RandomAccessStorage {\n return this._patchFile(ram());\n }\n\n protected override _openFile(file: RandomAccessStorage): RandomAccessStorage {\n const newFile = file.clone!();\n (newFile as any).closed = false;\n return this._patchFile(newFile);\n }\n\n private _patchFile(file: RandomAccessStorage): RandomAccessStorage {\n // Patch required to make consistent across platforms.\n const trueRead = file.read.bind(file);\n\n file.read = (offset: number, size: number, cb: Callback<Buffer>) =>\n trueRead(offset, size, (err: Error | null, data?: Buffer) => {\n if (err) {\n return cb(err);\n } else {\n return cb(err, arrayToBuffer(data!));\n }\n });\n\n return file;\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { type Directory } from './directory';\n\n// TODO(burdon): Reconcile with ConfigProto.\nexport enum StorageType {\n RAM = 'ram',\n IDB = 'idb',\n CHROME = 'chrome',\n FIREFOX = 'firefox',\n NODE = 'node',\n WEBFS = 'webfs',\n}\n\nexport type DiskInfo = {\n /**\n * Bytes.\n */\n used: number;\n};\n\nexport interface Storage {\n readonly path: string;\n readonly type: StorageType;\n readonly size: number;\n\n getDiskInfo?(): Promise<DiskInfo>;\n\n // TODO(burdon): Make required.\n createDirectory: (path?: string) => Directory;\n reset: () => Promise<void>;\n}\n\nexport type StorageConstructor = (params?: { type?: StorageType; root?: string }) => Storage;\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport del from 'del';\nimport { readdir, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport raf from 'random-access-file';\nimport { type RandomAccessStorage } from 'random-access-storage';\n\nimport { AbstractStorage, type DiskInfo, type Storage, StorageType } from '../common';\n\n/**\n * Storage interface implementation for Node.\n */\nexport class NodeStorage extends AbstractStorage implements Storage {\n public override type: StorageType = StorageType.NODE;\n\n protected override _createFile(path: string, filename: string, opts: any = {}): RandomAccessStorage {\n const file = raf(filename, { directory: path, ...opts });\n\n // Empty write to create file on a drive.\n file.write(0, Buffer.from(''));\n\n return file;\n }\n\n protected override async _destroy() {\n await del(this.path, { force: true });\n }\n\n async getDiskInfo(): Promise<DiskInfo> {\n let used = 0;\n\n const recurse = async (path: string) => {\n const pathStats = await stat(path);\n\n used += pathStats.size;\n\n if (pathStats.isDirectory()) {\n const entries = await readdir(path);\n await Promise.all(entries.map((entry) => recurse(join(path, entry))));\n }\n };\n\n await recurse(this.path);\n\n return {\n used,\n };\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { NodeStorage } from './node-storage';\nimport { MemoryStorage, type Storage, type StorageConstructor, StorageType } from '../common';\n\nexport const createStorage: StorageConstructor = ({ type, root = '/tmp/dxos/testing' } = {}): Storage => {\n if (type === undefined) {\n return new NodeStorage(root);\n }\n\n switch (type) {\n case StorageType.RAM: {\n return new MemoryStorage(root);\n }\n\n case StorageType.NODE: {\n return new NodeStorage(root);\n }\n\n default: {\n throw new Error(`Invalid type: ${type}`);\n }\n }\n};\n"],
5
- "mappings": "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",
6
- "names": ["import_node_path", "import_log", "stringDiff", "first", "second", "split", "join", "getFullPath", "root", "path", "Directory", "constructor", "type", "_list", "_getOrCreateFile", "_delete", "_onFlush", "toString", "JSON", "stringify", "createDirectory", "list", "getOrCreateFile", "filename", "opts", "flush", "delete", "MAX_STORAGE_OPERATION_TIME", "pifyFields", "object", "fields", "field", "fn", "pify", "bind", "args", "before", "performance", "now", "res", "elapsed", "log", "warn", "operation", "wrapFile", "native", "file", "Object", "assign", "AbstractStorage", "_files", "Map", "inspect", "custom", "inspectObject", "toJSON", "size", "sub", "reset", "info", "_closeFilesInPath", "_destroy", "err", "catch", "Array", "from", "_getFiles", "keys", "map", "name", "replace", "startsWith", "substring", "fullPath", "_getFileIfExists", "closed", "_openFile", "_createFile", "set", "undefined", "has", "get", "destroyed", "entries", "filter", "includes", "Promise", "all", "values", "close", "destroy", "then", "error", "message", "StorageType", "RAM", "IDB", "CHROME", "FIREFOX", "NODE", "WEBFS", "MemoryStorage", "_patchFile", "ram", "newFile", "clone", "trueRead", "read", "offset", "cb", "data", "arrayToBuffer", "NodeStorage", "raf", "directory", "write", "Buffer", "del", "force", "getDiskInfo", "used", "recurse", "pathStats", "stat", "isDirectory", "readdir", "entry", "createStorage", "Error"]
4
+ "sourcesContent": ["//\n// Copyright 2021 DXOS.org\n//\n\nimport { join } from 'node:path';\nimport { inspect } from 'node:util';\nimport type { RandomAccessStorage } from 'random-access-storage';\n\nimport { inspectObject } from '@dxos/debug';\nimport { log } from '@dxos/log';\n\nimport { Directory } from './directory';\nimport { type File, wrapFile } from './file';\nimport { type Storage, type StorageType } from './storage';\nimport { getFullPath } from './utils';\n\n/**\n * Base class for all storage implementations.\n * https://github.com/random-access-storage\n * https://github.com/random-access-storage/random-access-storage\n */\nexport abstract class AbstractStorage implements Storage {\n protected readonly _files = new Map<string, File>();\n\n public abstract readonly type: StorageType;\n\n // TODO(burdon): Make required.\n constructor(public readonly path: string) {}\n\n [inspect.custom]() {\n return inspectObject(this);\n }\n\n toJSON() {\n return { type: this.type, path: this.path };\n }\n\n public get size() {\n return this._files.size;\n }\n\n // TODO(burdon): Make required.\n public createDirectory(sub = ''): Directory {\n // invariant(sub.length);\n return new Directory({\n type: this.type,\n path: getFullPath(this.path, sub),\n list: this._list.bind(this),\n getOrCreateFile: (...args) => this.getOrCreateFile(...args),\n remove: () => this._remove(sub),\n });\n }\n\n /**\n * Delete all files.\n */\n async reset() {\n try {\n log.info('Erasing all data...');\n await this._closeFilesInPath('');\n await this._remove('');\n await this._destroy();\n log('Erased...');\n } catch (err: any) {\n log.catch(err);\n }\n }\n\n protected async _list(path: string): Promise<string[]> {\n // TODO(dmaretskyi): Fix me.\n return Array.from((await this._getFiles(path)).keys()).map((filename) => {\n let name = filename.replace(path, '');\n if (name.startsWith('/')) {\n name = name.substring(1);\n }\n return name;\n });\n }\n\n protected getOrCreateFile(path: string, filename: string, opts?: any): File {\n const fullPath = join(path, filename);\n\n let native;\n let file = this._getFileIfExists(fullPath);\n if (file) {\n if (!file.closed) {\n return file;\n }\n\n native = this._openFile(file.native);\n }\n\n if (!native) {\n native = this._createFile(path, filename, opts);\n }\n\n file = wrapFile(native, this.type);\n this._files.set(fullPath, file);\n return file;\n }\n\n protected _destroy(): Promise<void> | undefined {\n return undefined;\n }\n\n /**\n * Attempt to reopen file.\n */\n protected _openFile(file: RandomAccessStorage): RandomAccessStorage | undefined {\n return undefined;\n }\n\n protected abstract _createFile(path: string, filename: string, opts?: any): RandomAccessStorage;\n\n private _getFileIfExists(filename: string): File | undefined {\n if (this._files.has(filename)) {\n const file = this._files.get(filename);\n if (file && !file.destroyed) {\n return file;\n }\n }\n }\n\n protected async _getFiles(path: string): Promise<Map<string, File>> {\n const fullPath = getFullPath(this.path, path);\n return new Map(\n [...this._files.entries()].filter(([path, file]) => path.includes(fullPath) && file.destroyed !== true),\n );\n }\n\n private async _closeFilesInPath(path: string): Promise<void> {\n await Promise.all(\n Array.from((await this._getFiles(path)).values()).map((file) => file.close().catch((err: any) => log.catch(err))),\n );\n }\n\n // TODO(burdon): Delete directory (not just listed files).\n protected async _remove(path: string): Promise<void> {\n await Promise.all(\n Array.from(await this._getFiles(path)).map(([path, file]) => {\n return file\n .destroy()\n .then(() => this._files.delete(path))\n .catch((err: any) => log.error(err.message));\n }),\n );\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { join } from 'node:path';\n\n// TODO(burdon): Document.\nexport const stringDiff = (first: string, second: string) => first.split(second).join('');\n\nexport const getFullPath = (root: string, path: string) => join(root, stringDiff(path, root));\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type File } from './file';\nimport { type StorageType } from './storage';\nimport { getFullPath } from './utils';\n\nexport type DirectoryParams = {\n type: StorageType;\n path: string;\n // TODO(burdon): Create interface for these methods (shared with AbstractStorage).\n list: (path: string) => Promise<string[]>;\n getOrCreateFile: (path: string, filename: string, opts?: any) => File;\n remove: () => Promise<void>;\n onFlush?: () => Promise<void>;\n};\n\n/**\n * Wraps a directory in the storage file system.\n */\nexport class Directory {\n public readonly type: StorageType;\n public readonly path: string;\n // TODO(burdon): Create interface for these methods (shared with AbstractStorage).\n private readonly _list: (path: string) => Promise<string[]>;\n private readonly _getOrCreateFile: (path: string, filename: string, opts?: any) => File;\n private readonly _remove: () => Promise<void>;\n private readonly _onFlush?: () => Promise<void>;\n\n constructor({ type, path, list, getOrCreateFile, remove, onFlush }: DirectoryParams) {\n this.type = type;\n this.path = path;\n this._list = list;\n this._getOrCreateFile = getOrCreateFile;\n this._remove = remove;\n this._onFlush = onFlush;\n }\n\n toString() {\n return `Directory(${JSON.stringify({ type: this.type, path: this.path })})`;\n }\n\n /**\n * Create a new sub-directory.\n */\n createDirectory(path: string): Directory {\n return new Directory({\n type: this.type,\n path: getFullPath(this.path, path),\n list: this._list,\n getOrCreateFile: this._getOrCreateFile,\n remove: this._remove,\n });\n }\n\n /**\n * Get all files in the current directory.\n */\n list(): Promise<string[]> {\n return this._list(this.path);\n }\n\n /**\n * Get or create a new file.\n */\n getOrCreateFile(filename: string, opts?: any): File {\n return this._getOrCreateFile(this.path, filename, opts);\n }\n\n async flush() {\n await this._onFlush?.();\n }\n\n /**\n * Close and delete all files in the directory and all its sub-directories.\n */\n async delete() {\n await this._remove();\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport pify from 'pify';\nimport type { FileStat, RandomAccessStorage, RandomAccessStorageProperties } from 'random-access-storage';\n\nimport { log } from '@dxos/log';\n\nimport { type StorageType } from './storage';\n\nconst MAX_STORAGE_OPERATION_TIME = 50;\n\n/**\n * Random access file wrapper.\n * https://github.com/random-access-storage/random-access-storage\n */\nexport interface File extends RandomAccessStorageProperties {\n readonly destroyed: boolean;\n\n // TODO(burdon): Can we remove these since they are not standard across implementations?\n readonly directory: string;\n readonly filename: string;\n\n // Added by factory.\n readonly type: StorageType;\n readonly native: RandomAccessStorage;\n\n write(offset: number, data: Buffer): Promise<void>;\n read(offset: number, size: number): Promise<Buffer>;\n del(offset: number, size: number): Promise<void>;\n stat(): Promise<FileStat>;\n close(): Promise<Error | void>;\n destroy(): Promise<Error | void>;\n\n /**\n * Save changes to disk.\n */\n flush?(): Promise<void>;\n\n // Not supported in node, memory.\n truncate?(offset: number): Promise<void>;\n\n // random-access-memory only.\n clone?(): RandomAccessStorage;\n}\n\nconst pifyFields = (object: any, type: StorageType, fields: string[]) => {\n for (const field of fields) {\n if (!object[field]) {\n // TODO(burdon): Suppress warning and throw error if used.\n // console.warn(`Field not supported for type: ${JSON.stringify({ type, field })}`);\n } else {\n const fn = pify(object[field].bind(object));\n object[field] = async (...args: any) => {\n const before = performance.now();\n\n const res = await fn(...args);\n\n const elapsed = performance.now() - before;\n if (elapsed > MAX_STORAGE_OPERATION_TIME) {\n log.warn('Slow storage operation', { type, operation: field, elapsed });\n }\n\n return res;\n };\n }\n }\n\n return object;\n};\n\n/**\n * Construct async File wrapper.\n * NOTE: This is safe since these are interface methods only (not used internally).\n */\nexport const wrapFile = (native: RandomAccessStorage, type: StorageType): File => {\n const file = pifyFields(native, type, ['write', 'read', 'del', 'stat', 'close', 'destroy', 'truncate']);\n return Object.assign(file, { type, native });\n};\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport ram from 'random-access-memory';\nimport { type Callback, type RandomAccessStorage } from 'random-access-storage';\n\nimport { arrayToBuffer } from '@dxos/util';\n\nimport { AbstractStorage } from './abstract-storage';\nimport { StorageType } from './storage';\n\n/**\n * Storage interface implementation for RAM.\n * https://github.com/random-access-storage/random-access-memory\n */\nexport class MemoryStorage extends AbstractStorage {\n public override type: StorageType = StorageType.RAM;\n\n protected override _createFile(path: string, filename: string): RandomAccessStorage {\n return this._patchFile(ram());\n }\n\n protected override _openFile(file: RandomAccessStorage): RandomAccessStorage {\n const newFile = file.clone!();\n (newFile as any).closed = false;\n return this._patchFile(newFile);\n }\n\n private _patchFile(file: RandomAccessStorage): RandomAccessStorage {\n // Patch required to make consistent across platforms.\n const trueRead = file.read.bind(file);\n\n file.read = (offset: number, size: number, cb: Callback<Buffer>) =>\n trueRead(offset, size, (err: Error | null, data?: Buffer) => {\n if (err) {\n return cb(err);\n } else {\n return cb(err, arrayToBuffer(data!));\n }\n });\n\n return file;\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { type Directory } from './directory';\n\n// TODO(burdon): Reconcile with ConfigProto.\nexport enum StorageType {\n RAM = 'ram',\n IDB = 'idb',\n CHROME = 'chrome',\n FIREFOX = 'firefox',\n NODE = 'node',\n WEBFS = 'webfs',\n}\n\nexport type DiskInfo = {\n /**\n * Bytes.\n */\n used: number;\n};\n\nexport interface Storage {\n readonly path: string;\n readonly type: StorageType;\n readonly size: number;\n\n getDiskInfo?(): Promise<DiskInfo>;\n\n // TODO(burdon): Make required.\n createDirectory: (path?: string) => Directory;\n reset: () => Promise<void>;\n}\n\nexport type StorageConstructor = (params?: { type?: StorageType; root?: string }) => Storage;\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport del from 'del';\nimport { existsSync } from 'node:fs';\nimport { readdir, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport raf from 'random-access-file';\nimport { type RandomAccessStorage } from 'random-access-storage';\n\nimport { AbstractStorage, type DiskInfo, type Storage, StorageType, wrapFile } from '../common';\n\n/**\n * Storage interface implementation for Node.\n */\nexport class NodeStorage extends AbstractStorage implements Storage {\n public override type: StorageType = StorageType.NODE;\n private _initialized = false;\n\n private async _loadFiles(path: string) {\n // TODO(mykola): Do not load all files at once. It is a quick fix.\n if (!existsSync(path)) {\n return;\n }\n\n // Preload all files in a directory.\n const dir = await readdir(path);\n for (const entry of dir) {\n const fullPath = join(path, entry);\n if (this._files.has(fullPath)) {\n continue;\n }\n const entryInfo = await stat(fullPath);\n if (entryInfo.isDirectory()) {\n await this._loadFiles(fullPath);\n } else if (entryInfo.isFile()) {\n const file = this._createFile(path, entry);\n this._files.set(fullPath, wrapFile(file, this.type));\n }\n }\n }\n\n protected override _createFile(path: string, filename: string, opts: any = {}): RandomAccessStorage {\n const file = raf(filename, { directory: path, ...opts });\n\n // Empty write to create file on a drive.\n file.write(0, Buffer.from(''));\n\n return file;\n }\n\n protected override async _destroy() {\n await del(this.path, { force: true });\n }\n\n protected override async _getFiles(path: string) {\n if (!this._initialized) {\n await this._loadFiles(this.path);\n this._initialized = true;\n }\n\n return super._getFiles(path);\n }\n\n async getDiskInfo(): Promise<DiskInfo> {\n let used = 0;\n\n const recurse = async (path: string) => {\n const pathStats = await stat(path);\n\n used += pathStats.size;\n\n if (pathStats.isDirectory()) {\n const entries = await readdir(path);\n await Promise.all(entries.map((entry) => recurse(join(path, entry))));\n }\n };\n\n await recurse(this.path);\n\n return {\n used,\n };\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { NodeStorage } from './node-storage';\nimport { MemoryStorage, type Storage, type StorageConstructor, StorageType } from '../common';\n\nexport const createStorage: StorageConstructor = ({ type, root = '/tmp/dxos/testing' } = {}): Storage => {\n if (type === undefined) {\n return new NodeStorage(root);\n }\n\n switch (type) {\n case StorageType.RAM: {\n return new MemoryStorage(root);\n }\n\n case StorageType.NODE: {\n return new NodeStorage(root);\n }\n\n default: {\n throw new Error(`Invalid type: ${type}`);\n }\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,uBAAqB;AACrB,uBAAwB;AAGxB,mBAA8B;AAC9B,iBAAoB;ACLpB,IAAAA,oBAAqB;AEArB,kBAAiB;AAGjB,IAAAC,cAAoB;ACHpB,kCAAgB;AAGhB,kBAA8B;AEH9B,iBAAgB;AAChB,qBAA2B;AAC3B,sBAA8B;AAC9B,IAAAD,oBAAqB;AACrB,gCAAgB;ALDT,IAAME,aAAa,CAACC,OAAeC,WAAmBD,MAAME,MAAMD,MAAAA,EAAQE,KAAK,EAAA;AAE/E,IAAMC,cAAc,CAACC,MAAcC,aAAiBH,wBAAKE,MAAMN,WAAWO,MAAMD,IAAAA,CAAAA;ACYhF,IAAME,YAAN,MAAMA,WAAAA;EASXC,YAAY,EAAEC,MAAMH,MAAMI,MAAMC,iBAAiBC,QAAQC,QAAO,GAAqB;AACnF,SAAKJ,OAAOA;AACZ,SAAKH,OAAOA;AACZ,SAAKQ,QAAQJ;AACb,SAAKK,mBAAmBJ;AACxB,SAAKK,UAAUJ;AACf,SAAKK,WAAWJ;EAClB;EAEAK,WAAW;AACT,WAAO,aAAaC,KAAKC,UAAU;MAAEX,MAAM,KAAKA;MAAMH,MAAM,KAAKA;IAAK,CAAA,CAAA;EACxE;;;;EAKAe,gBAAgBf,MAAyB;AACvC,WAAO,IAAIC,WAAU;MACnBE,MAAM,KAAKA;MACXH,MAAMF,YAAY,KAAKE,MAAMA,IAAAA;MAC7BI,MAAM,KAAKI;MACXH,iBAAiB,KAAKI;MACtBH,QAAQ,KAAKI;IACf,CAAA;EACF;;;;EAKAN,OAA0B;AACxB,WAAO,KAAKI,MAAM,KAAKR,IAAI;EAC7B;;;;EAKAK,gBAAgBW,UAAkBC,MAAkB;AAClD,WAAO,KAAKR,iBAAiB,KAAKT,MAAMgB,UAAUC,IAAAA;EACpD;EAEA,MAAMC,QAAQ;AACZ,UAAM,KAAKP,WAAQ;EACrB;;;;EAKA,MAAMQ,SAAS;AACb,UAAM,KAAKT,QAAO;EACpB;AACF;;ACrEA,IAAMU,6BAA6B;AAoCnC,IAAMC,aAAa,CAACC,QAAanB,MAAmBoB,WAAAA;AAClD,aAAWC,SAASD,QAAQ;AAC1B,QAAI,CAACD,OAAOE,KAAAA,GAAQ;IAGpB,OAAO;AACL,YAAMC,SAAKC,YAAAA,SAAKJ,OAAOE,KAAAA,EAAOG,KAAKL,MAAAA,CAAAA;AACnCA,aAAOE,KAAAA,IAAS,UAAUI,SAAAA;AACxB,cAAMC,SAASC,YAAYC,IAAG;AAE9B,cAAMC,MAAM,MAAMP,GAAAA,GAAMG,IAAAA;AAExB,cAAMK,UAAUH,YAAYC,IAAG,IAAKF;AACpC,YAAII,UAAUb,4BAA4B;AACxCc,0BAAIC,KAAK,0BAA0B;YAAEhC;YAAMiC,WAAWZ;YAAOS;UAAQ,GAAA;;;;;;QACvE;AAEA,eAAOD;MACT;IACF;EACF;AAEA,SAAOV;AACT;AAMO,IAAMe,WAAW,CAACC,QAA6BnC,SAAAA;AACpD,QAAMoC,OAAOlB,WAAWiB,QAAQnC,MAAM;IAAC;IAAS;IAAQ;IAAO;IAAQ;IAAS;IAAW;GAAW;AACtG,SAAOqC,OAAOC,OAAOF,MAAM;IAAEpC;IAAMmC;EAAO,CAAA;AAC5C;;AH1DO,IAAeI,kBAAf,MAAeA;;EAMpBxC,YAA4BF,MAAc;gBAAdA;SALT2C,SAAS,oBAAIC,IAAAA;EAKW;EAE3C,CAACC,yBAAQC,MAAM,IAAI;AACjB,eAAOC,4BAAc,IAAI;EAC3B;EAEAC,SAAS;AACP,WAAO;MAAE7C,MAAM,KAAKA;MAAMH,MAAM,KAAKA;IAAK;EAC5C;EAEA,IAAWiD,OAAO;AAChB,WAAO,KAAKN,OAAOM;EACrB;;EAGOlC,gBAAgBmC,MAAM,IAAe;AAE1C,WAAO,IAAIjD,UAAU;MACnBE,MAAM,KAAKA;MACXH,MAAMF,YAAY,KAAKE,MAAMkD,GAAAA;MAC7B9C,MAAM,KAAKI,MAAMmB,KAAK,IAAI;MAC1BtB,iBAAiB,IAAIuB,SAAS,KAAKvB,gBAAe,GAAIuB,IAAAA;MACtDtB,QAAQ,MAAM,KAAKI,QAAQwC,GAAAA;IAC7B,CAAA;EACF;;;;EAKA,MAAMC,QAAQ;AACZ,QAAI;AACFjB,iBAAAA,IAAIkB,KAAK,uBAAA,QAAA;;;;;;AACT,YAAM,KAAKC,kBAAkB,EAAA;AAC7B,YAAM,KAAK3C,QAAQ,EAAA;AACnB,YAAM,KAAK4C,SAAQ;AACnBpB,qBAAAA,KAAI,aAAA,QAAA;;;;;;IACN,SAASqB,KAAU;AACjBrB,iBAAAA,IAAIsB,MAAMD,KAAAA,QAAAA;;;;;;IACZ;EACF;EAEA,MAAgB/C,MAAMR,MAAiC;AAErD,WAAOyD,MAAMC,MAAM,MAAM,KAAKC,UAAU3D,IAAAA,GAAO4D,KAAI,CAAA,EAAIC,IAAI,CAAC7C,aAAAA;AAC1D,UAAI8C,OAAO9C,SAAS+C,QAAQ/D,MAAM,EAAA;AAClC,UAAI8D,KAAKE,WAAW,GAAA,GAAM;AACxBF,eAAOA,KAAKG,UAAU,CAAA;MACxB;AACA,aAAOH;IACT,CAAA;EACF;EAEUzD,gBAAgBL,MAAcgB,UAAkBC,MAAkB;AAC1E,UAAMiD,eAAWrE,iBAAAA,MAAKG,MAAMgB,QAAAA;AAE5B,QAAIsB;AACJ,QAAIC,OAAO,KAAK4B,iBAAiBD,QAAAA;AACjC,QAAI3B,MAAM;AACR,UAAI,CAACA,KAAK6B,QAAQ;AAChB,eAAO7B;MACT;AAEAD,eAAS,KAAK+B,UAAU9B,KAAKD,MAAM;IACrC;AAEA,QAAI,CAACA,QAAQ;AACXA,eAAS,KAAKgC,YAAYtE,MAAMgB,UAAUC,IAAAA;IAC5C;AAEAsB,WAAOF,SAASC,QAAQ,KAAKnC,IAAI;AACjC,SAAKwC,OAAO4B,IAAIL,UAAU3B,IAAAA;AAC1B,WAAOA;EACT;EAEUe,WAAsC;AAC9C,WAAOkB;EACT;;;;EAKUH,UAAU9B,MAA4D;AAC9E,WAAOiC;EACT;EAIQL,iBAAiBnD,UAAoC;AAC3D,QAAI,KAAK2B,OAAO8B,IAAIzD,QAAAA,GAAW;AAC7B,YAAMuB,OAAO,KAAKI,OAAO+B,IAAI1D,QAAAA;AAC7B,UAAIuB,QAAQ,CAACA,KAAKoC,WAAW;AAC3B,eAAOpC;MACT;IACF;EACF;EAEA,MAAgBoB,UAAU3D,MAA0C;AAClE,UAAMkE,WAAWpE,YAAY,KAAKE,MAAMA,IAAAA;AACxC,WAAO,IAAI4C,IACT;SAAI,KAAKD,OAAOiC,QAAO;MAAIC,OAAO,CAAC,CAAC7E,OAAMuC,IAAAA,MAAUvC,MAAK8E,SAASZ,QAAAA,KAAa3B,KAAKoC,cAAc,IAAA,CAAA;EAEtG;EAEA,MAActB,kBAAkBrD,MAA6B;AAC3D,UAAM+E,QAAQC,IACZvB,MAAMC,MAAM,MAAM,KAAKC,UAAU3D,IAAAA,GAAOiF,OAAM,CAAA,EAAIpB,IAAI,CAACtB,SAASA,KAAK2C,MAAK,EAAG1B,MAAM,CAACD,QAAarB,WAAAA,IAAIsB,MAAMD,KAAAA,QAAAA;;;;;;EAE/G;;EAGA,MAAgB7C,QAAQV,MAA6B;AACnD,UAAM+E,QAAQC,IACZvB,MAAMC,KAAK,MAAM,KAAKC,UAAU3D,IAAAA,CAAAA,EAAO6D,IAAI,CAAC,CAAC7D,OAAMuC,IAAAA,MAAK;AACtD,aAAOA,KACJ4C,QAAO,EACPC,KAAK,MAAM,KAAKzC,OAAOxB,OAAOnB,KAAAA,CAAAA,EAC9BwD,MAAM,CAACD,QAAarB,WAAAA,IAAImD,MAAM9B,IAAI+B,SAAO,QAAA;;;;;;IAC9C,CAAA,CAAA;EAEJ;AACF;IK5IO;UAAKC,cAAW;AAAXA,eACVC,KAAAA,IAAM;AADID,eAEVE,KAAAA,IAAM;AAFIF,eAGVG,QAAAA,IAAS;AAHCH,eAIVI,SAAAA,IAAU;AAJAJ,eAKVK,MAAAA,IAAO;AALGL,eAMVM,OAAAA,IAAQ;GANEN,gBAAAA,cAAAA,CAAAA,EAAAA;ADSL,IAAMO,gBAAN,cAA4BpD,gBAAAA;EAA5B,cAAA;;AACWvC,SAAAA,OAAoBoF,YAAYC;;EAE7BlB,YAAYtE,MAAcgB,UAAuC;AAClF,WAAO,KAAK+E,eAAWC,4BAAAA,SAAAA,CAAAA;EACzB;EAEmB3B,UAAU9B,MAAgD;AAC3E,UAAM0D,UAAU1D,KAAK2D,MAAK;AACzBD,YAAgB7B,SAAS;AAC1B,WAAO,KAAK2B,WAAWE,OAAAA;EACzB;EAEQF,WAAWxD,MAAgD;AAEjE,UAAM4D,WAAW5D,KAAK6D,KAAKzE,KAAKY,IAAAA;AAEhCA,SAAK6D,OAAO,CAACC,QAAgBpD,MAAcqD,OACzCH,SAASE,QAAQpD,MAAM,CAACM,KAAmBgD,SAAAA;AACzC,UAAIhD,KAAK;AACP,eAAO+C,GAAG/C,GAAAA;MACZ,OAAO;AACL,eAAO+C,GAAG/C,SAAKiD,2BAAcD,IAAAA,CAAAA;MAC/B;IACF,CAAA;AAEF,WAAOhE;EACT;AACF;AE5BO,IAAMkE,cAAN,cAA0B/D,gBAAAA;EAA1B,cAAA;;AACWvC,SAAAA,OAAoBoF,YAAYK;AACxCc,SAAAA,eAAe;;EAEvB,MAAcC,WAAW3G,MAAc;AAErC,QAAI,KAAC4G,2BAAW5G,IAAAA,GAAO;AACrB;IACF;AAGA,UAAM6G,MAAM,UAAMC,yBAAQ9G,IAAAA;AAC1B,eAAW+G,SAASF,KAAK;AACvB,YAAM3C,eAAWrE,kBAAAA,MAAKG,MAAM+G,KAAAA;AAC5B,UAAI,KAAKpE,OAAO8B,IAAIP,QAAAA,GAAW;AAC7B;MACF;AACA,YAAM8C,YAAY,UAAMC,sBAAK/C,QAAAA;AAC7B,UAAI8C,UAAUE,YAAW,GAAI;AAC3B,cAAM,KAAKP,WAAWzC,QAAAA;MACxB,WAAW8C,UAAUG,OAAM,GAAI;AAC7B,cAAM5E,OAAO,KAAK+B,YAAYtE,MAAM+G,KAAAA;AACpC,aAAKpE,OAAO4B,IAAIL,UAAU7B,SAASE,MAAM,KAAKpC,IAAI,CAAA;MACpD;IACF;EACF;EAEmBmE,YAAYtE,MAAcgB,UAAkBC,OAAY,CAAC,GAAwB;AAClG,UAAMsB,WAAO6E,0BAAAA,SAAIpG,UAAU;MAAEqG,WAAWrH;MAAM,GAAGiB;IAAK,CAAA;AAGtDsB,SAAK+E,MAAM,GAAGC,OAAO7D,KAAK,EAAA,CAAA;AAE1B,WAAOnB;EACT;EAEA,MAAyBe,WAAW;AAClC,cAAMkE,WAAAA,SAAI,KAAKxH,MAAM;MAAEyH,OAAO;IAAK,CAAA;EACrC;EAEA,MAAyB9D,UAAU3D,MAAc;AAC/C,QAAI,CAAC,KAAK0G,cAAc;AACtB,YAAM,KAAKC,WAAW,KAAK3G,IAAI;AAC/B,WAAK0G,eAAe;IACtB;AAEA,WAAO,MAAM/C,UAAU3D,IAAAA;EACzB;EAEA,MAAM0H,cAAiC;AACrC,QAAIC,OAAO;AAEX,UAAMC,UAAU,OAAO5H,SAAAA;AACrB,YAAM6H,YAAY,UAAMZ,sBAAKjH,IAAAA;AAE7B2H,cAAQE,UAAU5E;AAElB,UAAI4E,UAAUX,YAAW,GAAI;AAC3B,cAAMtC,UAAU,UAAMkC,yBAAQ9G,IAAAA;AAC9B,cAAM+E,QAAQC,IAAIJ,QAAQf,IAAI,CAACkD,UAAUa,YAAQ/H,kBAAAA,MAAKG,MAAM+G,KAAAA,CAAAA,CAAAA,CAAAA;MAC9D;IACF;AAEA,UAAMa,QAAQ,KAAK5H,IAAI;AAEvB,WAAO;MACL2H;IACF;EACF;AACF;AC9EO,IAAMG,gBAAoC,CAAC,EAAE3H,MAAMJ,OAAO,oBAAmB,IAAK,CAAC,MAAC;AACzF,MAAII,SAASqE,QAAW;AACtB,WAAO,IAAIiC,YAAY1G,IAAAA;EACzB;AAEA,UAAQI,MAAAA;IACN,KAAKoF,YAAYC,KAAK;AACpB,aAAO,IAAIM,cAAc/F,IAAAA;IAC3B;IAEA,KAAKwF,YAAYK,MAAM;AACrB,aAAO,IAAIa,YAAY1G,IAAAA;IACzB;IAEA,SAAS;AACP,YAAM,IAAIgI,MAAM,iBAAiB5H,IAAAA,EAAM;IACzC;EACF;AACF;",
6
+ "names": ["import_node_path", "import_log", "stringDiff", "first", "second", "split", "join", "getFullPath", "root", "path", "Directory", "constructor", "type", "list", "getOrCreateFile", "remove", "onFlush", "_list", "_getOrCreateFile", "_remove", "_onFlush", "toString", "JSON", "stringify", "createDirectory", "filename", "opts", "flush", "delete", "MAX_STORAGE_OPERATION_TIME", "pifyFields", "object", "fields", "field", "fn", "pify", "bind", "args", "before", "performance", "now", "res", "elapsed", "log", "warn", "operation", "wrapFile", "native", "file", "Object", "assign", "AbstractStorage", "_files", "Map", "inspect", "custom", "inspectObject", "toJSON", "size", "sub", "reset", "info", "_closeFilesInPath", "_destroy", "err", "catch", "Array", "from", "_getFiles", "keys", "map", "name", "replace", "startsWith", "substring", "fullPath", "_getFileIfExists", "closed", "_openFile", "_createFile", "set", "undefined", "has", "get", "destroyed", "entries", "filter", "includes", "Promise", "all", "values", "close", "destroy", "then", "error", "message", "StorageType", "RAM", "IDB", "CHROME", "FIREFOX", "NODE", "WEBFS", "MemoryStorage", "_patchFile", "ram", "newFile", "clone", "trueRead", "read", "offset", "cb", "data", "arrayToBuffer", "NodeStorage", "_initialized", "_loadFiles", "existsSync", "dir", "readdir", "entry", "entryInfo", "stat", "isDirectory", "isFile", "raf", "directory", "write", "Buffer", "del", "force", "getDiskInfo", "used", "recurse", "pathStats", "createStorage", "Error"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/common/random-access-storage/src/common/utils.ts":{"bytes":1295,"imports":[{"path":"node:path","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/directory.ts":{"bytes":5037,"imports":[{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/common/file.ts":{"bytes":6374,"imports":[{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytes":14221,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/common/storage.ts":{"bytes":1874,"imports":[],"format":"esm"},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytes":4360,"imports":[{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"}],"format":"esm"},"packages/common/random-access-storage/src/common/index.ts":{"bytes":947,"imports":[{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/memory-storage.ts","kind":"import-statement","original":"./memory-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/node/node-storage.ts":{"bytes":4807,"imports":[{"path":"del","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"random-access-file","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"}],"format":"esm"},"packages/common/random-access-storage/src/node/storage.ts":{"bytes":2441,"imports":[{"path":"packages/common/random-access-storage/src/node/node-storage.ts","kind":"import-statement","original":"./node-storage"},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"}],"format":"esm"},"packages/common/random-access-storage/src/node/index.ts":{"bytes":568,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/node/storage.ts","kind":"import-statement","original":"./storage"}],"format":"esm"},"packages/common/random-access-storage/src/index.ts":{"bytes":469,"imports":[{"path":"packages/common/random-access-storage/src/node/index.ts","kind":"import-statement","original":"./node"}],"format":"esm"}},"outputs":{"packages/common/random-access-storage/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":20324},"packages/common/random-access-storage/dist/lib/node/index.cjs":{"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"del","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"random-access-file","kind":"import-statement","external":true}],"exports":["AbstractStorage","Directory","MemoryStorage","StorageType","createStorage","getFullPath","stringDiff","wrapFile"],"entryPoint":"packages/common/random-access-storage/src/index.ts","inputs":{"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytesInOutput":3328},"packages/common/random-access-storage/src/common/utils.ts":{"bytesInOutput":170},"packages/common/random-access-storage/src/common/directory.ts":{"bytesInOutput":1026},"packages/common/random-access-storage/src/common/file.ts":{"bytesInOutput":1149},"packages/common/random-access-storage/src/common/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytesInOutput":693},"packages/common/random-access-storage/src/common/storage.ts":{"bytesInOutput":288},"packages/common/random-access-storage/src/node/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/node/node-storage.ts":{"bytesInOutput":938},"packages/common/random-access-storage/src/node/storage.ts":{"bytesInOutput":369},"packages/common/random-access-storage/src/index.ts":{"bytesInOutput":0}},"bytes":8798}}}
1
+ {"inputs":{"packages/common/random-access-storage/src/common/utils.ts":{"bytes":1295,"imports":[{"path":"node:path","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/directory.ts":{"bytes":6503,"imports":[{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/common/file.ts":{"bytes":6374,"imports":[{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytes":14628,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/common/storage.ts":{"bytes":1874,"imports":[],"format":"esm"},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytes":4360,"imports":[{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"}],"format":"esm"},"packages/common/random-access-storage/src/common/index.ts":{"bytes":947,"imports":[{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/memory-storage.ts","kind":"import-statement","original":"./memory-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/node/node-storage.ts":{"bytes":8334,"imports":[{"path":"del","kind":"import-statement","external":true},{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"random-access-file","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"}],"format":"esm"},"packages/common/random-access-storage/src/node/storage.ts":{"bytes":2441,"imports":[{"path":"packages/common/random-access-storage/src/node/node-storage.ts","kind":"import-statement","original":"./node-storage"},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"}],"format":"esm"},"packages/common/random-access-storage/src/node/index.ts":{"bytes":568,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/node/storage.ts","kind":"import-statement","original":"./storage"}],"format":"esm"},"packages/common/random-access-storage/src/index.ts":{"bytes":469,"imports":[{"path":"packages/common/random-access-storage/src/node/index.ts","kind":"import-statement","original":"./node"}],"format":"esm"}},"outputs":{"packages/common/random-access-storage/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":23074},"packages/common/random-access-storage/dist/lib/node/index.cjs":{"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"del","kind":"import-statement","external":true},{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"random-access-file","kind":"import-statement","external":true}],"exports":["AbstractStorage","Directory","MemoryStorage","StorageType","createStorage","getFullPath","stringDiff","wrapFile"],"entryPoint":"packages/common/random-access-storage/src/index.ts","inputs":{"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytesInOutput":3437},"packages/common/random-access-storage/src/common/utils.ts":{"bytesInOutput":170},"packages/common/random-access-storage/src/common/directory.ts":{"bytesInOutput":1103},"packages/common/random-access-storage/src/common/file.ts":{"bytesInOutput":1149},"packages/common/random-access-storage/src/common/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytesInOutput":693},"packages/common/random-access-storage/src/common/storage.ts":{"bytesInOutput":288},"packages/common/random-access-storage/src/node/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/node/node-storage.ts":{"bytesInOutput":1726},"packages/common/random-access-storage/src/node/storage.ts":{"bytesInOutput":369},"packages/common/random-access-storage/src/index.ts":{"bytesInOutput":0}},"bytes":9772}}}
@@ -1 +1 @@
1
- {"version":3,"file":"browser-storage.d.ts","sourceRoot":"","sources":["../../../../src/browser/browser-storage.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C;;GAEG;AACH,8BAAsB,cAAe,SAAQ,eAAe;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuD;gBAExE,IAAI,EAAE,MAAM;IAKxB,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,mBAAmB;IAK1E,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,mBAAmB;cAEhF,QAAQ;CAkBlC"}
1
+ {"version":3,"file":"browser-storage.d.ts","sourceRoot":"","sources":["../../../../src/browser/browser-storage.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAe,MAAM,WAAW,CAAC;AAEzD;;GAEG;AACH,8BAAsB,cAAe,SAAQ,eAAe;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuD;gBAExE,IAAI,EAAE,MAAM;IAKxB,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,mBAAmB;IAK1E,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,mBAAmB;cAEhF,QAAQ;CAkBlC"}
@@ -34,8 +34,8 @@ export declare abstract class AbstractStorage implements Storage {
34
34
  protected _openFile(file: RandomAccessStorage): RandomAccessStorage | undefined;
35
35
  protected abstract _createFile(path: string, filename: string, opts?: any): RandomAccessStorage;
36
36
  private _getFileIfExists;
37
- private _getFiles;
37
+ protected _getFiles(path: string): Promise<Map<string, File>>;
38
38
  private _closeFilesInPath;
39
- protected _delete(path: string): Promise<void>;
39
+ protected _remove(path: string): Promise<void>;
40
40
  }
41
41
  //# sourceMappingURL=abstract-storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"abstract-storage.d.ts","sourceRoot":"","sources":["../../../../src/common/abstract-storage.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAKjE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,IAAI,EAAY,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAG3D;;;;GAIG;AACH,8BAAsB,eAAgB,YAAW,OAAO;aAM1B,IAAI,EAAE,MAAM;IALxC,SAAS,CAAC,QAAQ,CAAC,MAAM,oBAA2B;IAEpD,kBAAyB,IAAI,EAAE,WAAW,CAAC;gBAGf,IAAI,EAAE,MAAM;IAExC,CAAC,OAAO,CAAC,MAAM,CAAC;IAIhB,MAAM;;;;IAIN,IAAW,IAAI,WAEd;IAGM,eAAe,CAAC,GAAG,SAAK,GAAG,SAAS;IAW3C;;OAEG;IACG,KAAK;cAYK,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAWtD,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAsB3E,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS;IAI/C;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,mBAAmB,GAAG,mBAAmB,GAAG,SAAS;IAI/E,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,mBAAmB;IAE/F,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,SAAS;YAOH,iBAAiB;cAOf,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAUrD"}
1
+ {"version":3,"file":"abstract-storage.d.ts","sourceRoot":"","sources":["../../../../src/common/abstract-storage.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAKjE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,IAAI,EAAY,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAG3D;;;;GAIG;AACH,8BAAsB,eAAgB,YAAW,OAAO;aAM1B,IAAI,EAAE,MAAM;IALxC,SAAS,CAAC,QAAQ,CAAC,MAAM,oBAA2B;IAEpD,kBAAyB,IAAI,EAAE,WAAW,CAAC;gBAGf,IAAI,EAAE,MAAM;IAExC,CAAC,OAAO,CAAC,MAAM,CAAC;IAIhB,MAAM;;;;IAIN,IAAW,IAAI,WAEd;IAGM,eAAe,CAAC,GAAG,SAAK,GAAG,SAAS;IAW3C;;OAEG;IACG,KAAK;cAYK,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAWtD,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAsB3E,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS;IAI/C;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,mBAAmB,GAAG,mBAAmB,GAAG,SAAS;IAI/E,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,mBAAmB;IAE/F,OAAO,CAAC,gBAAgB;cASR,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAOrD,iBAAiB;cAOf,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAUrD"}
@@ -1,5 +1,13 @@
1
1
  import { type File } from './file';
2
2
  import { type StorageType } from './storage';
3
+ export type DirectoryParams = {
4
+ type: StorageType;
5
+ path: string;
6
+ list: (path: string) => Promise<string[]>;
7
+ getOrCreateFile: (path: string, filename: string, opts?: any) => File;
8
+ remove: () => Promise<void>;
9
+ onFlush?: () => Promise<void>;
10
+ };
3
11
  /**
4
12
  * Wraps a directory in the storage file system.
5
13
  */
@@ -8,9 +16,9 @@ export declare class Directory {
8
16
  readonly path: string;
9
17
  private readonly _list;
10
18
  private readonly _getOrCreateFile;
11
- private readonly _delete;
19
+ private readonly _remove;
12
20
  private readonly _onFlush?;
13
- constructor(type: StorageType, path: string, _list: (path: string) => Promise<string[]>, _getOrCreateFile: (path: string, filename: string, opts?: any) => File, _delete: () => Promise<void>, _onFlush?: (() => Promise<void>) | undefined);
21
+ constructor({ type, path, list, getOrCreateFile, remove, onFlush }: DirectoryParams);
14
22
  toString(): string;
15
23
  /**
16
24
  * Create a new sub-directory.
@@ -1 +1 @@
1
- {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../../../src/common/directory.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C;;GAEG;AACH,qBAAa,SAAS;aAEF,IAAI,EAAE,WAAW;aACjB,IAAI,EAAE,MAAM;IAE5B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBANV,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE,MAAM,EAEX,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,EAC1C,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,EACtE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC5B,QAAQ,CAAC,SAAQ,QAAQ,IAAI,CAAC,aAAA;IAGjD,QAAQ;IAIR;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;IAIxC;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIzB;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAI7C,KAAK;IAIX;;OAEG;IACG,MAAM;CAGb"}
1
+ {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../../../src/common/directory.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IAEb,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACtE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,qBAAa,SAAS;IACpB,SAAgB,IAAI,EAAE,WAAW,CAAC;IAClC,SAAgB,IAAI,EAAE,MAAM,CAAC;IAE7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;IAC5D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuD;IACxF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAsB;gBAEpC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,eAAe;IASnF,QAAQ;IAIR;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;IAUxC;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIzB;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAI7C,KAAK;IAIX;;OAEG;IACG,MAAM;CAGb"}
@@ -5,8 +5,11 @@ import { AbstractStorage, type DiskInfo, type Storage, StorageType } from '../co
5
5
  */
6
6
  export declare class NodeStorage extends AbstractStorage implements Storage {
7
7
  type: StorageType;
8
+ private _initialized;
9
+ private _loadFiles;
8
10
  protected _createFile(path: string, filename: string, opts?: any): RandomAccessStorage;
9
11
  protected _destroy(): Promise<void>;
12
+ protected _getFiles(path: string): Promise<Map<string, import("../common").File>>;
10
13
  getDiskInfo(): Promise<DiskInfo>;
11
14
  }
12
15
  //# sourceMappingURL=node-storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-storage.d.ts","sourceRoot":"","sources":["../../../../src/node/node-storage.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEtF;;GAEG;AACH,qBAAa,WAAY,SAAQ,eAAgB,YAAW,OAAO;IACjD,IAAI,EAAE,WAAW,CAAoB;cAElC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,GAAQ,GAAG,mBAAmB;cAS1E,QAAQ;IAI3B,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC;CAoBvC"}
1
+ {"version":3,"file":"node-storage.d.ts","sourceRoot":"","sources":["../../../../src/node/node-storage.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,WAAW,EAAY,MAAM,WAAW,CAAC;AAEhG;;GAEG;AACH,qBAAa,WAAY,SAAQ,eAAgB,YAAW,OAAO;IACjD,IAAI,EAAE,WAAW,CAAoB;IACrD,OAAO,CAAC,YAAY,CAAS;YAEf,UAAU;cAuBL,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,GAAQ,GAAG,mBAAmB;cAS1E,QAAQ;cAIR,SAAS,CAAC,IAAI,EAAE,MAAM;IASzC,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC;CAoBvC"}
@@ -1 +1 @@
1
- {"version":3,"file":"storage.blueprint-test.d.ts","sourceRoot":"","sources":["../../../../src/testing/storage.blueprint-test.ts"],"names":[],"mappings":"AAUA,OAAO,EAAa,KAAK,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAIjE,eAAO,MAAM,UAAU,cAAgD,CAAC;AAExE,eAAO,MAAM,YAAY,kBAAmB,WAAW,iBAAiB,MAAM,OAAO,SAgTpF,CAAC"}
1
+ {"version":3,"file":"storage.blueprint-test.d.ts","sourceRoot":"","sources":["../../../../src/testing/storage.blueprint-test.ts"],"names":[],"mappings":"AAUA,OAAO,EAAa,KAAK,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAIjE,eAAO,MAAM,UAAU,cAAgD,CAAC;AAExE,eAAO,MAAM,YAAY,kBAAmB,WAAW,iBAAiB,MAAM,OAAO,SA+TpF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/random-access-storage",
3
- "version": "0.3.11-main.8be6c8a",
3
+ "version": "0.3.11-main.8feb6a5",
4
4
  "description": "Multiple random storage types.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -24,14 +24,14 @@
24
24
  "random-access-memory": "^4.1.0",
25
25
  "random-access-storage": "^3.0.0",
26
26
  "random-access-web": "^2.0.3",
27
- "@dxos/async": "0.3.11-main.8be6c8a",
28
- "@dxos/context": "0.3.11-main.8be6c8a",
29
- "@dxos/debug": "0.3.11-main.8be6c8a",
30
- "@dxos/log": "0.3.11-main.8be6c8a",
31
- "@dxos/node-std": "0.3.11-main.8be6c8a",
32
- "@dxos/util": "0.3.11-main.8be6c8a",
33
- "@dxos/invariant": "0.3.11-main.8be6c8a",
34
- "@dxos/tracing": "0.3.11-main.8be6c8a"
27
+ "@dxos/async": "0.3.11-main.8feb6a5",
28
+ "@dxos/context": "0.3.11-main.8feb6a5",
29
+ "@dxos/debug": "0.3.11-main.8feb6a5",
30
+ "@dxos/invariant": "0.3.11-main.8feb6a5",
31
+ "@dxos/log": "0.3.11-main.8feb6a5",
32
+ "@dxos/tracing": "0.3.11-main.8feb6a5",
33
+ "@dxos/node-std": "0.3.11-main.8feb6a5",
34
+ "@dxos/util": "0.3.11-main.8feb6a5"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/pify": "^3.0.2",
@@ -2,10 +2,9 @@
2
2
  // Copyright 2021 DXOS.org
3
3
  //
4
4
 
5
- import { join } from 'node:path';
6
5
  import type { RandomAccessStorage } from 'random-access-storage';
7
6
 
8
- import { AbstractStorage } from '../common';
7
+ import { AbstractStorage, getFullPath } from '../common';
9
8
 
10
9
  /**
11
10
  * Base class for random access files based on IDB.
@@ -19,7 +18,7 @@ export abstract class BrowserStorage extends AbstractStorage {
19
18
  }
20
19
 
21
20
  protected _createFile(path: string, filename: string): RandomAccessStorage {
22
- const fullPath = join(path, filename);
21
+ const fullPath = getFullPath(path, filename);
23
22
  return this._fileStorage(fullPath);
24
23
  }
25
24
 
@@ -69,16 +69,16 @@ export class WebFS implements Storage {
69
69
  }
70
70
 
71
71
  createDirectory(sub = '') {
72
- return new Directory(
73
- this.type,
74
- getFullPath(this.path, sub),
75
- (path) => this._list(path),
76
- (...args) => this.getOrCreateFile(...args),
77
- () => this._delete(sub),
78
- async () => {
72
+ return new Directory({
73
+ type: this.type,
74
+ path: getFullPath(this.path, sub),
75
+ list: (path) => this._list(path),
76
+ getOrCreateFile: (...args) => this.getOrCreateFile(...args),
77
+ remove: () => this._delete(sub),
78
+ onFlush: async () => {
79
79
  await Promise.all(Array.from(this._getFiles(sub)).map(([path, file]) => file.flush()));
80
80
  },
81
- );
81
+ });
82
82
  }
83
83
 
84
84
  getOrCreateFile(path: string, filename: string, opts?: any): File {
@@ -42,13 +42,13 @@ export abstract class AbstractStorage implements Storage {
42
42
  // TODO(burdon): Make required.
43
43
  public createDirectory(sub = ''): Directory {
44
44
  // invariant(sub.length);
45
- return new Directory(
46
- this.type,
47
- getFullPath(this.path, sub),
48
- this._list.bind(this),
49
- (...args) => this.getOrCreateFile(...args),
50
- () => this._delete(sub),
51
- );
45
+ return new Directory({
46
+ type: this.type,
47
+ path: getFullPath(this.path, sub),
48
+ list: this._list.bind(this),
49
+ getOrCreateFile: (...args) => this.getOrCreateFile(...args),
50
+ remove: () => this._remove(sub),
51
+ });
52
52
  }
53
53
 
54
54
  /**
@@ -58,7 +58,7 @@ export abstract class AbstractStorage implements Storage {
58
58
  try {
59
59
  log.info('Erasing all data...');
60
60
  await this._closeFilesInPath('');
61
- await this._delete('');
61
+ await this._remove('');
62
62
  await this._destroy();
63
63
  log('Erased...');
64
64
  } catch (err: any) {
@@ -68,7 +68,7 @@ export abstract class AbstractStorage implements Storage {
68
68
 
69
69
  protected async _list(path: string): Promise<string[]> {
70
70
  // TODO(dmaretskyi): Fix me.
71
- return Array.from(this._getFiles(path).keys()).map((filename) => {
71
+ return Array.from((await this._getFiles(path)).keys()).map((filename) => {
72
72
  let name = filename.replace(path, '');
73
73
  if (name.startsWith('/')) {
74
74
  name = name.substring(1);
@@ -121,7 +121,7 @@ export abstract class AbstractStorage implements Storage {
121
121
  }
122
122
  }
123
123
 
124
- private _getFiles(path: string): Map<string, File> {
124
+ protected async _getFiles(path: string): Promise<Map<string, File>> {
125
125
  const fullPath = getFullPath(this.path, path);
126
126
  return new Map(
127
127
  [...this._files.entries()].filter(([path, file]) => path.includes(fullPath) && file.destroyed !== true),
@@ -130,14 +130,14 @@ export abstract class AbstractStorage implements Storage {
130
130
 
131
131
  private async _closeFilesInPath(path: string): Promise<void> {
132
132
  await Promise.all(
133
- Array.from(this._getFiles(path).values()).map((file) => file.close().catch((err: any) => log.catch(err))),
133
+ Array.from((await this._getFiles(path)).values()).map((file) => file.close().catch((err: any) => log.catch(err))),
134
134
  );
135
135
  }
136
136
 
137
137
  // TODO(burdon): Delete directory (not just listed files).
138
- protected async _delete(path: string): Promise<void> {
138
+ protected async _remove(path: string): Promise<void> {
139
139
  await Promise.all(
140
- Array.from(this._getFiles(path)).map(([path, file]) => {
140
+ Array.from(await this._getFiles(path)).map(([path, file]) => {
141
141
  return file
142
142
  .destroy()
143
143
  .then(() => this._files.delete(path))
@@ -6,19 +6,36 @@ import { type File } from './file';
6
6
  import { type StorageType } from './storage';
7
7
  import { getFullPath } from './utils';
8
8
 
9
+ export type DirectoryParams = {
10
+ type: StorageType;
11
+ path: string;
12
+ // TODO(burdon): Create interface for these methods (shared with AbstractStorage).
13
+ list: (path: string) => Promise<string[]>;
14
+ getOrCreateFile: (path: string, filename: string, opts?: any) => File;
15
+ remove: () => Promise<void>;
16
+ onFlush?: () => Promise<void>;
17
+ };
18
+
9
19
  /**
10
20
  * Wraps a directory in the storage file system.
11
21
  */
12
22
  export class Directory {
13
- constructor(
14
- public readonly type: StorageType,
15
- public readonly path: string,
16
- // TODO(burdon): Create interface for these methods (shared with AbstractStorage).
17
- private readonly _list: (path: string) => Promise<string[]>,
18
- private readonly _getOrCreateFile: (path: string, filename: string, opts?: any) => File,
19
- private readonly _delete: () => Promise<void>,
20
- private readonly _onFlush?: () => Promise<void>,
21
- ) {}
23
+ public readonly type: StorageType;
24
+ public readonly path: string;
25
+ // TODO(burdon): Create interface for these methods (shared with AbstractStorage).
26
+ private readonly _list: (path: string) => Promise<string[]>;
27
+ private readonly _getOrCreateFile: (path: string, filename: string, opts?: any) => File;
28
+ private readonly _remove: () => Promise<void>;
29
+ private readonly _onFlush?: () => Promise<void>;
30
+
31
+ constructor({ type, path, list, getOrCreateFile, remove, onFlush }: DirectoryParams) {
32
+ this.type = type;
33
+ this.path = path;
34
+ this._list = list;
35
+ this._getOrCreateFile = getOrCreateFile;
36
+ this._remove = remove;
37
+ this._onFlush = onFlush;
38
+ }
22
39
 
23
40
  toString() {
24
41
  return `Directory(${JSON.stringify({ type: this.type, path: this.path })})`;
@@ -28,7 +45,13 @@ export class Directory {
28
45
  * Create a new sub-directory.
29
46
  */
30
47
  createDirectory(path: string): Directory {
31
- return new Directory(this.type, getFullPath(this.path, path), this._list, this._getOrCreateFile, this._delete);
48
+ return new Directory({
49
+ type: this.type,
50
+ path: getFullPath(this.path, path),
51
+ list: this._list,
52
+ getOrCreateFile: this._getOrCreateFile,
53
+ remove: this._remove,
54
+ });
32
55
  }
33
56
 
34
57
  /**
@@ -53,6 +76,6 @@ export class Directory {
53
76
  * Close and delete all files in the directory and all its sub-directories.
54
77
  */
55
78
  async delete() {
56
- await this._delete();
79
+ await this._remove();
57
80
  }
58
81
  }
@@ -3,18 +3,43 @@
3
3
  //
4
4
 
5
5
  import del from 'del';
6
+ import { existsSync } from 'node:fs';
6
7
  import { readdir, stat } from 'node:fs/promises';
7
8
  import { join } from 'node:path';
8
9
  import raf from 'random-access-file';
9
10
  import { type RandomAccessStorage } from 'random-access-storage';
10
11
 
11
- import { AbstractStorage, type DiskInfo, type Storage, StorageType } from '../common';
12
+ import { AbstractStorage, type DiskInfo, type Storage, StorageType, wrapFile } from '../common';
12
13
 
13
14
  /**
14
15
  * Storage interface implementation for Node.
15
16
  */
16
17
  export class NodeStorage extends AbstractStorage implements Storage {
17
18
  public override type: StorageType = StorageType.NODE;
19
+ private _initialized = false;
20
+
21
+ private async _loadFiles(path: string) {
22
+ // TODO(mykola): Do not load all files at once. It is a quick fix.
23
+ if (!existsSync(path)) {
24
+ return;
25
+ }
26
+
27
+ // Preload all files in a directory.
28
+ const dir = await readdir(path);
29
+ for (const entry of dir) {
30
+ const fullPath = join(path, entry);
31
+ if (this._files.has(fullPath)) {
32
+ continue;
33
+ }
34
+ const entryInfo = await stat(fullPath);
35
+ if (entryInfo.isDirectory()) {
36
+ await this._loadFiles(fullPath);
37
+ } else if (entryInfo.isFile()) {
38
+ const file = this._createFile(path, entry);
39
+ this._files.set(fullPath, wrapFile(file, this.type));
40
+ }
41
+ }
42
+ }
18
43
 
19
44
  protected override _createFile(path: string, filename: string, opts: any = {}): RandomAccessStorage {
20
45
  const file = raf(filename, { directory: path, ...opts });
@@ -29,6 +54,15 @@ export class NodeStorage extends AbstractStorage implements Storage {
29
54
  await del(this.path, { force: true });
30
55
  }
31
56
 
57
+ protected override async _getFiles(path: string) {
58
+ if (!this._initialized) {
59
+ await this._loadFiles(this.path);
60
+ this._initialized = true;
61
+ }
62
+
63
+ return super._getFiles(path);
64
+ }
65
+
32
66
  async getDiskInfo(): Promise<DiskInfo> {
33
67
  let used = 0;
34
68
 
@@ -285,7 +285,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
285
285
  });
286
286
 
287
287
  test('list all files after reopen', async function () {
288
- if (testGroupName !== StorageType.WEBFS) {
288
+ if (testGroupName !== StorageType.WEBFS && testGroupName !== StorageType.NODE) {
289
289
  this.skip();
290
290
  }
291
291
 
@@ -317,5 +317,20 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
317
317
  expect(entries.length).to.equal(files.length);
318
318
  }
319
319
  });
320
+
321
+ test('list returns correct filenames', async () => {
322
+ const FILES = ['one', 'two', 'three'];
323
+
324
+ // Create storage and check.
325
+ const storage = createStorage();
326
+ const directory = storage.createDirectory('dir');
327
+
328
+ for (const file of FILES) {
329
+ directory.getOrCreateFile(file);
330
+ }
331
+ await directory.flush();
332
+ const entries = await directory.list();
333
+ expect(entries).to.contain.members(FILES);
334
+ });
320
335
  });
321
336
  };