@dxos/random-access-storage 0.4.3-main.dda98d3 → 0.4.3-main.e5bbcda

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.
@@ -289,16 +289,6 @@ var MemoryStorage = class extends AbstractStorage {
289
289
  });
290
290
  return file;
291
291
  }
292
- async getDiskInfo() {
293
- let used = 0;
294
- for (const file of this._files.values()) {
295
- const size = file.length;
296
- used += Number.isNaN(size) ? 0 : size;
297
- }
298
- return {
299
- used
300
- };
301
- }
302
292
  };
303
293
 
304
294
  // packages/common/random-access-storage/src/browser/firefox-storage.ts
@@ -376,19 +366,19 @@ function _ts_decorate(decorators, target, key, desc) {
376
366
  return c > 3 && r && Object.defineProperty(target, key, r), r;
377
367
  }
378
368
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/common/random-access-storage/src/browser/web-fs.ts";
369
+ var files = /* @__PURE__ */ new Map();
379
370
  var WebFS = class {
380
371
  constructor(path) {
381
372
  this.path = path;
382
- this._files = /* @__PURE__ */ new Map();
383
373
  this.type = StorageType.WEBFS;
384
374
  }
385
375
  get size() {
386
- return this._files.size;
376
+ return files.size;
387
377
  }
388
378
  _getFiles(path) {
389
379
  const fullName = this._getFullFilename(this.path, path);
390
380
  return new Map([
391
- ...this._files.entries()
381
+ ...files.entries()
392
382
  ].filter(([path2, file]) => {
393
383
  return path2.includes(fullName) && !file.destroyed;
394
384
  }));
@@ -411,7 +401,7 @@ var WebFS = class {
411
401
  this._root = await navigator.storage.getDirectory();
412
402
  invariant(this._root, "Root is undefined", {
413
403
  F: __dxlog_file3,
414
- L: 73,
404
+ L: 79,
415
405
  S: this,
416
406
  A: [
417
407
  "this._root",
@@ -428,18 +418,18 @@ var WebFS = class {
428
418
  getOrCreateFile: (...args) => this.getOrCreateFile(...args),
429
419
  remove: () => this._delete(sub),
430
420
  onFlush: async () => {
431
- await Promise.all(Array.from(this._getFiles(sub)).map(([_, file]) => file.flush()));
421
+ await Promise.all(Array.from(this._getFiles(sub)).map(([path, file]) => file.flush()));
432
422
  }
433
423
  });
434
424
  }
435
425
  getOrCreateFile(path, filename, opts) {
436
426
  const fullName = this._getFullFilename(path, filename);
437
- const existingFile = this._files.get(fullName);
427
+ const existingFile = files.get(fullName);
438
428
  if (existingFile) {
439
429
  return existingFile;
440
430
  }
441
431
  const file = this._createFile(fullName);
442
- this._files.set(fullName, file);
432
+ files.set(fullName, file);
443
433
  return file;
444
434
  }
445
435
  _createFile(fullName) {
@@ -449,7 +439,7 @@ var WebFS = class {
449
439
  create: true
450
440
  })),
451
441
  destroy: async () => {
452
- this._files.delete(fullName);
442
+ files.delete(fullName);
453
443
  const root = await this._initialize();
454
444
  return root.removeEntry(fullName);
455
445
  }
@@ -459,49 +449,36 @@ var WebFS = class {
459
449
  await Promise.all(Array.from(this._getFiles(path)).map(async ([path2, file]) => {
460
450
  await file.destroy().catch((err) => log3.warn(err, void 0, {
461
451
  F: __dxlog_file3,
462
- L: 116,
452
+ L: 122,
463
453
  S: this,
464
454
  C: (f, a) => f(...a)
465
455
  }));
466
- this._files.delete(path2);
456
+ files.delete(path2);
467
457
  }));
468
458
  }
469
459
  async reset() {
470
460
  await this._initialize();
471
461
  for await (const filename of await this._root.keys()) {
462
+ files.delete(filename);
472
463
  await this._root.removeEntry(filename, {
473
464
  recursive: true
474
- }).catch((err) => log3.warn("failed to remove an entry", {
475
- filename,
476
- err
477
- }, {
465
+ }).catch((err) => log3.warn(err, void 0, {
478
466
  F: __dxlog_file3,
479
- L: 126,
467
+ L: 132,
480
468
  S: this,
481
469
  C: (f, a) => f(...a)
482
470
  }));
483
- this._files.delete(filename);
484
471
  }
485
472
  this._root = void 0;
486
473
  }
487
474
  async close() {
488
- await Promise.all(Array.from(this._files.values()).map((file) => {
489
- return file.close().catch((e) => log3.warn("failed to close a file", {
490
- file: file.fileName,
491
- e
492
- }, {
493
- F: __dxlog_file3,
494
- L: 136,
495
- S: this,
496
- C: (f, a) => f(...a)
497
- }));
498
- }));
475
+ await Promise.all(Array.from(files.values()).map((file) => file.close()));
499
476
  }
500
477
  _getFullFilename(path, filename) {
501
478
  if (filename) {
502
- return getFullPath(path, filename).replace(/\//g, "_");
479
+ return getFullPath(path, filename).split("/").join("_");
503
480
  } else {
504
- return path.replace(/\//g, "_");
481
+ return path.split("/").join("_");
505
482
  }
506
483
  }
507
484
  async getDiskInfo() {
@@ -512,7 +489,7 @@ var WebFS = class {
512
489
  promises.push((async () => {
513
490
  switch (entry.kind) {
514
491
  case "file":
515
- used += await entry.getFile().then((f) => f.size);
492
+ used += await entry.getFile().then((f) => used += f.size);
516
493
  break;
517
494
  case "directory":
518
495
  await recurse(entry);
@@ -540,12 +517,7 @@ var WebFile = class extends EventEmitter {
540
517
  this._buffer = null;
541
518
  this._loadBufferPromise = null;
542
519
  this._flushScheduled = false;
543
- this._flushPromise = Promise.resolve();
544
- /**
545
- * Used to discard unnecessary scheduled flushes.
546
- * If _flushNow() is called with a lower sequence number it should early exit.
547
- */
548
- this._flushSequence = 0;
520
+ this._flushPromise = null;
549
521
  //
550
522
  // Metrics
551
523
  //
@@ -582,7 +554,7 @@ var WebFile = class extends EventEmitter {
582
554
  destroy: callbackify(this.destroy.bind(this)),
583
555
  truncate: callbackify(this.truncate?.bind(this))
584
556
  };
585
- this.fileName = fileName;
557
+ this._fileName = fileName;
586
558
  this._fileHandle = file;
587
559
  this._destroy = destroy;
588
560
  void this._loadBufferGuarded();
@@ -599,16 +571,15 @@ var WebFile = class extends EventEmitter {
599
571
  await (this._loadBufferPromise ??= this._loadBuffer());
600
572
  }
601
573
  // Do not call directly, use _flushLater or _flushNow.
602
- async _flushCache(sequence) {
603
- if (this.destroyed || sequence < this._flushSequence) {
574
+ async _flushCache() {
575
+ if (this.destroyed) {
604
576
  return;
605
577
  }
606
- this._flushSequence = sequence + 1;
607
578
  this._flushes.inc();
608
579
  await this._loadBufferGuarded();
609
580
  invariant(this._buffer, void 0, {
610
581
  F: __dxlog_file3,
611
- L: 300,
582
+ L: 295,
612
583
  S: this,
613
584
  A: [
614
585
  "this._buffer",
@@ -630,13 +601,16 @@ var WebFile = class extends EventEmitter {
630
601
  if (this._flushScheduled) {
631
602
  return;
632
603
  }
633
- const sequence = this._flushSequence;
634
604
  setTimeout(async () => {
605
+ const promiseBefore = this._flushPromise;
635
606
  await this._flushPromise;
636
607
  this._flushScheduled = false;
637
- this._flushPromise = this._flushCache(sequence).catch((err) => log3.warn(err, void 0, {
608
+ if (promiseBefore !== this._flushPromise) {
609
+ return;
610
+ }
611
+ this._flushPromise = this._flushCache().catch((err) => log3.warn(err, void 0, {
638
612
  F: __dxlog_file3,
639
- L: 318,
613
+ L: 319,
640
614
  S: this,
641
615
  C: (f, a) => f(...a)
642
616
  }));
@@ -644,102 +618,114 @@ var WebFile = class extends EventEmitter {
644
618
  this._flushScheduled = true;
645
619
  }
646
620
  async _flushNow() {
647
- await this._flushPromise;
648
- this._flushPromise = this._flushCache(this._flushSequence).catch((err) => log3.warn(err, void 0, {
621
+ this._flushPromise = (this._flushPromise ?? Promise.resolve()).then(() => this._flushCache()).catch((err) => log3.warn(err, void 0, {
649
622
  F: __dxlog_file3,
650
- L: 326,
623
+ L: 328,
651
624
  S: this,
652
625
  C: (f, a) => f(...a)
653
626
  }));
654
627
  await this._flushPromise;
655
628
  }
656
629
  async read(offset, size) {
657
- this.assertNotDestroyed("Read");
630
+ if (this.destroyed) {
631
+ throw new Error("Read of a destroyed file");
632
+ }
658
633
  this._operations.inc();
659
634
  this._reads.inc();
660
635
  this._readBytes.inc(size);
661
- const buffer = await this.requireBuffer();
662
- if (offset + size > buffer.length) {
636
+ if (!this._buffer) {
637
+ await this._loadBufferGuarded();
638
+ invariant(this._buffer, void 0, {
639
+ F: __dxlog_file3,
640
+ L: 344,
641
+ S: this,
642
+ A: [
643
+ "this._buffer",
644
+ ""
645
+ ]
646
+ });
647
+ }
648
+ if (offset + size > this._buffer.length) {
663
649
  throw new Error("Read out of bounds");
664
650
  }
665
- return Buffer.from(buffer.slice(offset, offset + size));
651
+ return Buffer.from(this._buffer.slice(offset, offset + size));
666
652
  }
667
653
  async write(offset, data) {
668
- this.assertNotDestroyed("Write");
669
654
  this._operations.inc();
670
655
  this._writes.inc();
671
656
  this._writeBytes.inc(data.length);
672
- const buffer = await this.requireBuffer();
673
- if (offset + data.length <= buffer.length) {
674
- buffer.set(data, offset);
657
+ if (!this._buffer) {
658
+ await this._loadBufferGuarded();
659
+ invariant(this._buffer, void 0, {
660
+ F: __dxlog_file3,
661
+ L: 362,
662
+ S: this,
663
+ A: [
664
+ "this._buffer",
665
+ ""
666
+ ]
667
+ });
668
+ }
669
+ if (offset + data.length <= this._buffer.length) {
670
+ this._buffer.set(data, offset);
675
671
  } else {
676
672
  const newCache = new Uint8Array(offset + data.length);
677
- newCache.set(buffer);
673
+ newCache.set(this._buffer);
678
674
  newCache.set(data, offset);
679
675
  this._buffer = newCache;
680
676
  }
681
677
  this._flushLater();
682
678
  }
683
679
  async del(offset, size) {
684
- this.assertNotDestroyed("Del");
685
680
  this._operations.inc();
686
- if (offset < 0 || size <= 0) {
681
+ if (offset < 0 || size < 0) {
687
682
  return;
688
683
  }
689
- const buffer = await this.requireBuffer();
684
+ if (!this._buffer) {
685
+ await this._loadBufferGuarded();
686
+ invariant(this._buffer, void 0, {
687
+ F: __dxlog_file3,
688
+ L: 387,
689
+ S: this,
690
+ A: [
691
+ "this._buffer",
692
+ ""
693
+ ]
694
+ });
695
+ }
690
696
  let leftoverSize = 0;
691
- if (offset + size < buffer.length) {
692
- leftoverSize = buffer.length - (offset + size);
693
- buffer.set(buffer.slice(offset + size, offset + size + leftoverSize), offset);
697
+ if (offset + size < this._buffer.length) {
698
+ leftoverSize = this._buffer.length - (offset + size);
699
+ this._buffer.set(this._buffer.slice(offset + size, offset + size + leftoverSize), offset);
694
700
  }
695
- this._buffer = buffer.slice(0, offset + leftoverSize);
701
+ this._buffer = this._buffer.slice(0, offset + leftoverSize);
696
702
  this._flushLater();
697
703
  }
698
704
  async stat() {
699
- this.assertNotDestroyed("Truncate");
700
705
  this._operations.inc();
701
- const buffer = await this.requireBuffer();
706
+ if (!this._buffer) {
707
+ await this._loadBufferGuarded();
708
+ invariant(this._buffer, void 0, {
709
+ F: __dxlog_file3,
710
+ L: 407,
711
+ S: this,
712
+ A: [
713
+ "this._buffer",
714
+ ""
715
+ ]
716
+ });
717
+ }
702
718
  return {
703
- size: buffer.length
719
+ size: this._buffer.length
704
720
  };
705
721
  }
706
722
  async truncate(offset) {
707
- this.assertNotDestroyed("Truncate");
708
723
  this._operations.inc();
709
- this._buffer = (await this.requireBuffer()).slice(0, offset);
710
- this._flushLater();
711
- }
712
- async flush() {
713
- this.assertNotDestroyed("Flush");
714
- await this._flushNow();
715
- }
716
- /**
717
- * It's best to avoid using this method as it doesn't really close a file.
718
- * We could update the _opened flag and add a guard like for destroyed, but this would break
719
- * the FileSystemFileHandle sharing required for browser tests to run, where writes are
720
- * not immediately visible if using different file handles.
721
- */
722
- async close() {
723
- await this._flushNow();
724
- }
725
- async destroy() {
726
- if (!this.destroyed) {
727
- this.destroyed = true;
728
- await this._flushNow();
729
- return await this._destroy();
730
- }
731
- }
732
- assertNotDestroyed(operation) {
733
- if (this.destroyed) {
734
- throw new Error(`${operation} on a destroyed or closed file`);
735
- }
736
- }
737
- async requireBuffer() {
738
724
  if (!this._buffer) {
739
725
  await this._loadBufferGuarded();
740
726
  invariant(this._buffer, void 0, {
741
727
  F: __dxlog_file3,
742
- L: 448,
728
+ L: 420,
743
729
  S: this,
744
730
  A: [
745
731
  "this._buffer",
@@ -747,12 +733,24 @@ var WebFile = class extends EventEmitter {
747
733
  ]
748
734
  });
749
735
  }
750
- return this._buffer;
736
+ this._buffer = this._buffer.slice(0, offset);
737
+ this._flushLater();
738
+ }
739
+ async flush() {
740
+ await this._flushNow();
741
+ }
742
+ async close() {
743
+ await this._flushNow();
744
+ }
745
+ async destroy() {
746
+ await this._flushNow();
747
+ this.destroyed = true;
748
+ return await this._destroy();
751
749
  }
752
750
  };
753
751
  _ts_decorate([
754
752
  trace.info()
755
- ], WebFile.prototype, "fileName", void 0);
753
+ ], WebFile.prototype, "_fileName", void 0);
756
754
  _ts_decorate([
757
755
  trace.metricsCounter()
758
756
  ], WebFile.prototype, "_flushes", void 0);
@@ -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 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 async close() {\n await this._closeFilesInPath('');\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 { type DiskInfo, 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 async getDiskInfo(): Promise<DiskInfo> {\n let used = 0;\n\n for (const file of this._files.values()) {\n const size = (file as any).length;\n used += Number.isNaN(size) ? 0 : size;\n }\n\n return {\n used,\n };\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 close: () => 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 private readonly _files = new Map<string, WebFile>();\n\n readonly type = StorageType.WEBFS;\n\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]) => {\n return path.includes(fullName) && !file.destroyed;\n }),\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 // Filter out .crswap files.\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1228068\n // https://github.com/logseq/logseq/issues/4466#:~:text=Jun%2015%2C%202023-,.,is%20used%20to%20edit%20files.\n if (entry.startsWith(fullName + '_') && !entry.endsWith('.crswap')) {\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(([_, 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 await this._root!.removeEntry(filename, { recursive: true }).catch((err: any) =>\n log.warn('failed to remove an entry', { filename, err }),\n );\n this._files.delete(filename);\n }\n this._root = undefined;\n }\n\n async close() {\n await Promise.all(\n Array.from(this._files.values()).map((file) => {\n return file.close().catch((e) => log.warn('failed to close a file', { file: file.fileName, e }));\n }),\n );\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).replace(/\\//g, '_');\n } else {\n return path.replace(/\\//g, '_');\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) => 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 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 private _flushPromise: Promise<void> = Promise.resolve();\n /**\n * Used to discard unnecessary scheduled flushes.\n * If _flushNow() is called with a lower sequence number it should early exit.\n */\n private _flushSequence = 0;\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(sequence: number) {\n if (this.destroyed || sequence < this._flushSequence) {\n return;\n }\n this._flushSequence = sequence + 1;\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 const sequence = this._flushSequence;\n setTimeout(async () => {\n // Making sure only one flush can run at a time.\n await this._flushPromise;\n this._flushScheduled = false;\n this._flushPromise = this._flushCache(sequence).catch((err) => log.warn(err));\n });\n\n this._flushScheduled = true;\n }\n\n private async _flushNow() {\n await this._flushPromise;\n this._flushPromise = this._flushCache(this._flushSequence).catch((err) => log.warn(err));\n await this._flushPromise;\n }\n\n async read(offset: number, size: number) {\n this.assertNotDestroyed('Read');\n\n this._operations.inc();\n this._reads.inc();\n this._readBytes.inc(size);\n\n const buffer = await this.requireBuffer();\n\n if (offset + size > buffer.length) {\n throw new Error('Read out of bounds');\n }\n\n // Copy data into a new buffer.\n return Buffer.from(buffer.slice(offset, offset + size));\n }\n\n async write(offset: number, data: Buffer) {\n this.assertNotDestroyed('Write');\n\n this._operations.inc();\n this._writes.inc();\n this._writeBytes.inc(data.length);\n\n const buffer = await this.requireBuffer();\n\n if (offset + data.length <= buffer.length) {\n buffer.set(data, offset);\n } else {\n // TODO(dmaretskyi): Optimize re-allocations.\n const newCache = new Uint8Array(offset + data.length);\n newCache.set(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.assertNotDestroyed('Del');\n\n this._operations.inc();\n\n if (offset < 0 || size <= 0) {\n return;\n }\n\n const buffer = await this.requireBuffer();\n\n let leftoverSize = 0;\n if (offset + size < buffer.length) {\n leftoverSize = buffer.length - (offset + size);\n buffer.set(buffer.slice(offset + size, offset + size + leftoverSize), offset);\n }\n\n this._buffer = buffer.slice(0, offset + leftoverSize);\n\n this._flushLater();\n }\n\n async stat() {\n this.assertNotDestroyed('Truncate');\n\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 const buffer = await this.requireBuffer();\n\n return {\n size: buffer.length,\n };\n }\n\n async truncate(offset: number) {\n this.assertNotDestroyed('Truncate');\n\n this._operations.inc();\n\n this._buffer = (await this.requireBuffer()).slice(0, offset);\n\n this._flushLater();\n }\n\n async flush() {\n this.assertNotDestroyed('Flush');\n\n await this._flushNow();\n }\n\n /**\n * It's best to avoid using this method as it doesn't really close a file.\n * We could update the _opened flag and add a guard like for destroyed, but this would break\n * the FileSystemFileHandle sharing required for browser tests to run, where writes are\n * not immediately visible if using different file handles.\n */\n async close(): Promise<void> {\n await this._flushNow();\n }\n\n @synchronized\n async destroy() {\n if (!this.destroyed) {\n this.destroyed = true;\n await this._flushNow();\n return await this._destroy();\n }\n }\n\n private assertNotDestroyed(operation: string) {\n if (this.destroyed) {\n throw new Error(`${operation} on a destroyed or closed file`);\n }\n }\n\n private async requireBuffer(): Promise<Uint8Array> {\n if (!this._buffer) {\n await this._loadBufferGuarded();\n invariant(this._buffer);\n }\n return this._buffer;\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", "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", "MemoryStorage", "AbstractStorage", "type", "StorageType", "RAM", "_createFile", "path", "filename", "_patchFile", "ram", "_openFile", "file", "newFile", "clone", "closed", "trueRead", "read", "bind", "offset", "size", "cb", "err", "data", "arrayToBuffer", "getDiskInfo", "used", "_files", "values", "length", "Number", "isNaN", "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", "_files", "Map", "type", "StorageType", "WEBFS", "size", "_getFiles", "fullName", "_getFullFilename", "entries", "filter", "file", "includes", "destroyed", "_list", "root", "_initialize", "entry", "keys", "startsWith", "endsWith", "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", "close", "values", "e", "replace", "getDiskInfo", "used", "recurse", "handle", "promises", "kind", "getFile", "f", "synchronized", "EventEmitter", "_buffer", "_loadBufferPromise", "_flushScheduled", "_flushPromise", "resolve", "_flushSequence", "_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", "_fileHandle", "_destroy", "_loadBufferGuarded", "_bufferSize", "_loadBuffer", "fileHandle", "Uint8Array", "arrayBuffer", "_flushCache", "sequence", "inc", "createWritable", "keepExistingData", "data", "position", "_flushLater", "setTimeout", "_flushNow", "offset", "assertNotDestroyed", "buffer", "requireBuffer", "Error", "Buffer", "newCache", "leftoverSize", "operation", "trace", "info", "metricsCounter", "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 async close() {\n await this._closeFilesInPath('');\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 close: () => 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 * When handles weren't shared by different WebFS instances, browser tests\n * were sporadically failing with NonReadableError on test cases like:\n * webFs1.createFile->createWritable->write->close\n * webFs2.createFile->read\n * Presumably due to some handle-level write buffering.\n */\nconst files = new Map<string, WebFile>();\n/**\n * Web file systems.\n */\nexport class WebFS implements Storage {\n readonly type = StorageType.WEBFS;\n\n protected _root?: FileSystemDirectoryHandle;\n\n constructor(public readonly path: string) {}\n\n public get size() {\n return 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 [...files.entries()].filter(([path, file]) => {\n return path.includes(fullName) && !file.destroyed;\n }),\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 // Filter out .crswap files.\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1228068\n // https://github.com/logseq/logseq/issues/4466#:~:text=Jun%2015%2C%202023-,.,is%20used%20to%20edit%20files.\n if (entry.startsWith(fullName + '_') && !entry.endsWith('.crswap')) {\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 = files.get(fullName);\n if (existingFile) {\n return existingFile;\n }\n const file = this._createFile(fullName);\n 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 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 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 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 async close() {\n await Promise.all(Array.from(files.values()).map((file) => file.close()));\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 if (this.destroyed) {\n throw new Error('Read of a destroyed file');\n }\n\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 await this._flushNow();\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", "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", "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", "files", "Map", "WebFS", "constructor", "path", "type", "StorageType", "WEBFS", "size", "_getFiles", "fullName", "_getFullFilename", "entries", "filter", "file", "includes", "destroyed", "_list", "root", "_initialize", "entry", "keys", "startsWith", "endsWith", "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", "close", "values", "split", "join", "getDiskInfo", "used", "recurse", "handle", "promises", "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", "_flushLater", "setTimeout", "promiseBefore", "_flushNow", "resolve", "offset", "Error", "Buffer", "newCache", "leftoverSize", "trace", "info", "metricsCounter", "createStorage", "type", "root", "undefined", "navigator", "storage", "getDirectory", "FileSystemFileHandle", "prototype", "createWritable", "WebFS", "IDbStorage", "StorageType", "RAM", "MemoryStorage", "IDB", "CHROME", "FIREFOX", "FirefoxStorage", "WEBFS", "Error"]
7
7
  }