@dxos/random-access-storage 0.3.11-main.74d6c88 → 0.3.11-main.764a9c1

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.
Files changed (53) hide show
  1. package/dist/lib/browser/index.mjs +71 -44
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +58 -15
  5. package/dist/lib/node/index.cjs.map +3 -3
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/types/src/browser/bench.browser.test.d.ts +2 -0
  8. package/dist/types/src/browser/bench.browser.test.d.ts.map +1 -0
  9. package/dist/types/src/browser/browser-storage.d.ts.map +1 -1
  10. package/dist/types/src/browser/storage.browser.test.d.ts +2 -0
  11. package/dist/types/src/browser/storage.browser.test.d.ts.map +1 -0
  12. package/dist/types/src/browser/web-fs.d.ts +1 -1
  13. package/dist/types/src/browser/web-fs.d.ts.map +1 -1
  14. package/dist/types/src/common/abstract-storage.d.ts +3 -2
  15. package/dist/types/src/common/abstract-storage.d.ts.map +1 -1
  16. package/dist/types/src/common/directory.d.ts +10 -2
  17. package/dist/types/src/common/directory.d.ts.map +1 -1
  18. package/dist/types/src/common/storage.d.ts +1 -0
  19. package/dist/types/src/common/storage.d.ts.map +1 -1
  20. package/dist/types/src/node/bench.node.test.d.ts +2 -0
  21. package/dist/types/src/node/bench.node.test.d.ts.map +1 -0
  22. package/dist/types/src/node/node-storage.d.ts +3 -0
  23. package/dist/types/src/node/node-storage.d.ts.map +1 -1
  24. package/dist/types/src/node/storage.node.test.d.ts +2 -0
  25. package/dist/types/src/node/storage.node.test.d.ts.map +1 -0
  26. package/dist/types/src/testing/benchmark.blueprint-test.d.ts +1 -1
  27. package/dist/types/src/testing/benchmark.blueprint-test.d.ts.map +1 -1
  28. package/dist/types/src/testing/storage.blueprint-test.d.ts +1 -1
  29. package/dist/types/src/testing/storage.blueprint-test.d.ts.map +1 -1
  30. package/dist/types/src/testing/wait-for-debugger.d.ts +6 -0
  31. package/dist/types/src/testing/wait-for-debugger.d.ts.map +1 -0
  32. package/package.json +9 -9
  33. package/src/browser/{bench.test.ts → bench.browser.test.ts} +2 -4
  34. package/src/browser/browser-storage.ts +2 -3
  35. package/src/browser/{storage.test.ts → storage.browser.test.ts} +1 -8
  36. package/src/browser/web-fs.ts +39 -18
  37. package/src/common/abstract-storage.ts +17 -13
  38. package/src/common/directory.ts +34 -11
  39. package/src/common/storage.ts +1 -0
  40. package/src/node/{bench.test.ts → bench.node.test.ts} +8 -7
  41. package/src/node/node-storage.ts +35 -1
  42. package/src/node/{storage.test.ts → storage.node.test.ts} +8 -7
  43. package/src/testing/benchmark.blueprint-test.ts +3 -3
  44. package/src/testing/storage.blueprint-test.ts +78 -31
  45. package/src/testing/wait-for-debugger.ts +22 -0
  46. package/dist/types/src/browser/bench.test.d.ts +0 -2
  47. package/dist/types/src/browser/bench.test.d.ts.map +0 -1
  48. package/dist/types/src/browser/storage.test.d.ts +0 -2
  49. package/dist/types/src/browser/storage.test.d.ts.map +0 -1
  50. package/dist/types/src/node/bench.test.d.ts +0 -2
  51. package/dist/types/src/node/bench.test.d.ts.map +0 -1
  52. package/dist/types/src/node/storage.test.d.ts +0 -2
  53. package/dist/types/src/node/storage.test.d.ts.map +0 -1
@@ -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,26 +219,29 @@ 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,
221
233
  C: (f, a) => f(...a)
222
234
  }))));
223
235
  }
236
+ async close() {
237
+ await this._closeFilesInPath("");
238
+ }
224
239
  // TODO(burdon): Delete directory (not just listed files).
225
- async _delete(path) {
226
- await Promise.all(Array.from(this._getFiles(path)).map(([path2, file]) => {
240
+ async _remove(path) {
241
+ await Promise.all(Array.from(await this._getFiles(path)).map(([path2, file]) => {
227
242
  return file.destroy().then(() => this._files.delete(path2)).catch((err) => log2.error(err.message, void 0, {
228
243
  F: __dxlog_file2,
229
- L: 144,
244
+ L: 148,
230
245
  S: this,
231
246
  C: (f, a) => f(...a)
232
247
  }));
@@ -280,14 +295,13 @@ var MemoryStorage = class extends AbstractStorage {
280
295
  import raw from "random-access-web/mutable-file-wrapper.js";
281
296
 
282
297
  // packages/common/random-access-storage/src/browser/browser-storage.ts
283
- import { join as join3 } from "@dxos/node-std/path";
284
298
  var BrowserStorage = class extends AbstractStorage {
285
299
  constructor(path) {
286
300
  super(path);
287
301
  this._fileStorage = this._createFileStorage(path);
288
302
  }
289
303
  _createFile(path, filename) {
290
- const fullPath = join3(path, filename);
304
+ const fullPath = getFullPath(path, filename);
291
305
  return this._fileStorage(fullPath);
292
306
  }
293
307
  async _destroy() {
@@ -352,27 +366,29 @@ function _ts_decorate(decorators, target, key, desc) {
352
366
  return c > 3 && r && Object.defineProperty(target, key, r), r;
353
367
  }
354
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();
355
370
  var WebFS = class {
356
371
  constructor(path) {
357
372
  this.path = path;
358
373
  this.type = StorageType.WEBFS;
359
- this._files = /* @__PURE__ */ new Map();
360
374
  }
361
375
  get size() {
362
- return this._files.size;
376
+ return files.size;
363
377
  }
364
378
  _getFiles(path) {
365
379
  const fullName = this._getFullFilename(this.path, path);
366
380
  return new Map([
367
- ...this._files.entries()
368
- ].filter(([path2, file]) => path2.includes(fullName) && file.destroyed !== true));
381
+ ...files.entries()
382
+ ].filter(([path2, file]) => {
383
+ return path2.includes(fullName) && !file.destroyed;
384
+ }));
369
385
  }
370
386
  async _list(path) {
371
387
  const fullName = this._getFullFilename(path);
372
388
  const root = await this._initialize();
373
389
  const entries = [];
374
390
  for await (const entry of root.keys()) {
375
- if (entry.startsWith(fullName + "_")) {
391
+ if (entry.startsWith(fullName + "_") && !entry.endsWith(".crswap")) {
376
392
  entries.push(entry.slice(fullName.length + 1));
377
393
  }
378
394
  }
@@ -385,7 +401,7 @@ var WebFS = class {
385
401
  this._root = await navigator.storage.getDirectory();
386
402
  invariant(this._root, "Root is undefined", {
387
403
  F: __dxlog_file3,
388
- L: 67,
404
+ L: 79,
389
405
  S: this,
390
406
  A: [
391
407
  "this._root",
@@ -395,18 +411,25 @@ var WebFS = class {
395
411
  return this._root;
396
412
  }
397
413
  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()));
414
+ return new Directory({
415
+ type: this.type,
416
+ path: getFullPath(this.path, sub),
417
+ list: (path) => this._list(path),
418
+ getOrCreateFile: (...args) => this.getOrCreateFile(...args),
419
+ remove: () => this._delete(sub),
420
+ onFlush: async () => {
421
+ await Promise.all(Array.from(this._getFiles(sub)).map(([path, file]) => file.flush()));
422
+ }
400
423
  });
401
424
  }
402
425
  getOrCreateFile(path, filename, opts) {
403
426
  const fullName = this._getFullFilename(path, filename);
404
- const existingFile = this._files.get(fullName);
427
+ const existingFile = files.get(fullName);
405
428
  if (existingFile) {
406
429
  return existingFile;
407
430
  }
408
431
  const file = this._createFile(fullName);
409
- this._files.set(fullName, file);
432
+ files.set(fullName, file);
410
433
  return file;
411
434
  }
412
435
  _createFile(fullName) {
@@ -416,7 +439,7 @@ var WebFS = class {
416
439
  create: true
417
440
  })),
418
441
  destroy: async () => {
419
- this._files.delete(fullName);
442
+ files.delete(fullName);
420
443
  const root = await this._initialize();
421
444
  return root.removeEntry(fullName);
422
445
  }
@@ -426,28 +449,31 @@ var WebFS = class {
426
449
  await Promise.all(Array.from(this._getFiles(path)).map(async ([path2, file]) => {
427
450
  await file.destroy().catch((err) => log3.warn(err, void 0, {
428
451
  F: __dxlog_file3,
429
- L: 110,
452
+ L: 122,
430
453
  S: this,
431
454
  C: (f, a) => f(...a)
432
455
  }));
433
- this._files.delete(path2);
456
+ files.delete(path2);
434
457
  }));
435
458
  }
436
459
  async reset() {
437
460
  await this._initialize();
438
461
  for await (const filename of await this._root.keys()) {
439
- this._files.delete(filename);
462
+ files.delete(filename);
440
463
  await this._root.removeEntry(filename, {
441
464
  recursive: true
442
465
  }).catch((err) => log3.warn(err, void 0, {
443
466
  F: __dxlog_file3,
444
- L: 120,
467
+ L: 132,
445
468
  S: this,
446
469
  C: (f, a) => f(...a)
447
470
  }));
448
471
  }
449
472
  this._root = void 0;
450
473
  }
474
+ async close() {
475
+ await Promise.all(Array.from(files.values()).map((file) => file.close()));
476
+ }
451
477
  _getFullFilename(path, filename) {
452
478
  if (filename) {
453
479
  return getFullPath(path, filename).split("/").join("_");
@@ -482,7 +508,7 @@ var WebFS = class {
482
508
  _ts_decorate([
483
509
  synchronized
484
510
  ], WebFS.prototype, "_initialize", null);
485
- var WebFile = class WebFile2 extends EventEmitter {
511
+ var WebFile = class extends EventEmitter {
486
512
  constructor({ fileName, file, destroy }) {
487
513
  super();
488
514
  /**
@@ -553,7 +579,7 @@ var WebFile = class WebFile2 extends EventEmitter {
553
579
  await this._loadBufferGuarded();
554
580
  invariant(this._buffer, void 0, {
555
581
  F: __dxlog_file3,
556
- L: 279,
582
+ L: 295,
557
583
  S: this,
558
584
  A: [
559
585
  "this._buffer",
@@ -584,7 +610,7 @@ var WebFile = class WebFile2 extends EventEmitter {
584
610
  }
585
611
  this._flushPromise = this._flushCache().catch((err) => log3.warn(err, void 0, {
586
612
  F: __dxlog_file3,
587
- L: 303,
613
+ L: 319,
588
614
  S: this,
589
615
  C: (f, a) => f(...a)
590
616
  }));
@@ -594,13 +620,16 @@ var WebFile = class WebFile2 extends EventEmitter {
594
620
  async _flushNow() {
595
621
  this._flushPromise = (this._flushPromise ?? Promise.resolve()).then(() => this._flushCache()).catch((err) => log3.warn(err, void 0, {
596
622
  F: __dxlog_file3,
597
- L: 312,
623
+ L: 328,
598
624
  S: this,
599
625
  C: (f, a) => f(...a)
600
626
  }));
601
627
  await this._flushPromise;
602
628
  }
603
629
  async read(offset, size) {
630
+ if (this.destroyed) {
631
+ throw new Error("Read of a destroyed file");
632
+ }
604
633
  this._operations.inc();
605
634
  this._reads.inc();
606
635
  this._readBytes.inc(size);
@@ -608,7 +637,7 @@ var WebFile = class WebFile2 extends EventEmitter {
608
637
  await this._loadBufferGuarded();
609
638
  invariant(this._buffer, void 0, {
610
639
  F: __dxlog_file3,
611
- L: 324,
640
+ L: 344,
612
641
  S: this,
613
642
  A: [
614
643
  "this._buffer",
@@ -629,7 +658,7 @@ var WebFile = class WebFile2 extends EventEmitter {
629
658
  await this._loadBufferGuarded();
630
659
  invariant(this._buffer, void 0, {
631
660
  F: __dxlog_file3,
632
- L: 342,
661
+ L: 362,
633
662
  S: this,
634
663
  A: [
635
664
  "this._buffer",
@@ -656,7 +685,7 @@ var WebFile = class WebFile2 extends EventEmitter {
656
685
  await this._loadBufferGuarded();
657
686
  invariant(this._buffer, void 0, {
658
687
  F: __dxlog_file3,
659
- L: 367,
688
+ L: 387,
660
689
  S: this,
661
690
  A: [
662
691
  "this._buffer",
@@ -678,7 +707,7 @@ var WebFile = class WebFile2 extends EventEmitter {
678
707
  await this._loadBufferGuarded();
679
708
  invariant(this._buffer, void 0, {
680
709
  F: __dxlog_file3,
681
- L: 387,
710
+ L: 407,
682
711
  S: this,
683
712
  A: [
684
713
  "this._buffer",
@@ -696,7 +725,7 @@ var WebFile = class WebFile2 extends EventEmitter {
696
725
  await this._loadBufferGuarded();
697
726
  invariant(this._buffer, void 0, {
698
727
  F: __dxlog_file3,
699
- L: 400,
728
+ L: 420,
700
729
  S: this,
701
730
  A: [
702
731
  "this._buffer",
@@ -714,6 +743,7 @@ var WebFile = class WebFile2 extends EventEmitter {
714
743
  await this._flushNow();
715
744
  }
716
745
  async destroy() {
746
+ await this._flushNow();
717
747
  this.destroyed = true;
718
748
  return await this._destroy();
719
749
  }
@@ -745,9 +775,6 @@ _ts_decorate([
745
775
  _ts_decorate([
746
776
  synchronized
747
777
  ], WebFile.prototype, "destroy", null);
748
- WebFile = _ts_decorate([
749
- trace.resource()
750
- ], WebFile);
751
778
 
752
779
  // packages/common/random-access-storage/src/browser/storage.ts
753
780
  var createStorage = ({ type, root = "" } = {}) => {
@@ -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 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
  }