@dxos/random-access-storage 0.1.56-main.e47dfd1 → 0.1.56-main.e79d64a
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.
- package/dist/lib/browser/index.mjs +69 -14
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +2 -2
- package/dist/lib/node/index.cjs.map +1 -1
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/browser/web-fs.d.ts +6 -0
- package/dist/types/src/browser/web-fs.d.ts.map +1 -1
- package/dist/types/src/testing/storage.blueprint-test.d.ts.map +1 -1
- package/package.json +8 -7
- package/src/browser/web-fs.ts +46 -1
- package/src/testing/storage.blueprint-test.ts +27 -31
|
@@ -12,7 +12,7 @@ var stringDiff = (first, second) => first.split(second).join("");
|
|
|
12
12
|
var getFullPath = (root, path) => join(root, stringDiff(path, root));
|
|
13
13
|
|
|
14
14
|
// packages/common/random-access-storage/src/common/directory.ts
|
|
15
|
-
var Directory = class {
|
|
15
|
+
var Directory = class _Directory {
|
|
16
16
|
constructor(type, path, _list, _getOrCreateFile, _delete) {
|
|
17
17
|
this.type = type;
|
|
18
18
|
this.path = path;
|
|
@@ -30,7 +30,7 @@ var Directory = class {
|
|
|
30
30
|
* Create a new sub-directory.
|
|
31
31
|
*/
|
|
32
32
|
createDirectory(path) {
|
|
33
|
-
return new
|
|
33
|
+
return new _Directory(this.type, getFullPath(this.path, path), this._list, this._getOrCreateFile, this._delete);
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* Get all files in the current directory.
|
|
@@ -325,9 +325,10 @@ var IDbStorage = class extends BrowserStorage {
|
|
|
325
325
|
// packages/common/random-access-storage/src/browser/web-fs.ts
|
|
326
326
|
import { EventEmitter } from "@dxos/node-std/events";
|
|
327
327
|
import { callbackify } from "@dxos/node-std/util";
|
|
328
|
-
import invariant from "tiny-invariant";
|
|
329
328
|
import { synchronized } from "@dxos/async";
|
|
329
|
+
import { invariant } from "@dxos/invariant";
|
|
330
330
|
import { log as log3 } from "@dxos/log";
|
|
331
|
+
import { TimeSeriesCounter, TimeUsageCounter, trace } from "@dxos/tracing";
|
|
331
332
|
|
|
332
333
|
// packages/common/random-access-storage/src/monitor.ts
|
|
333
334
|
import { unrefTimeout } from "@dxos/async";
|
|
@@ -357,19 +358,18 @@ var StorageMonitor = class {
|
|
|
357
358
|
const beginTime = performance.now();
|
|
358
359
|
return {
|
|
359
360
|
end: () => {
|
|
360
|
-
var _a2, _b;
|
|
361
361
|
const endTime = performance.now();
|
|
362
362
|
const duration = endTime - beginTime;
|
|
363
363
|
const bucket = this._getOrInitBucket(op.resource);
|
|
364
364
|
switch (op.type) {
|
|
365
365
|
case "read":
|
|
366
366
|
bucket.readOps++;
|
|
367
|
-
bucket.readBytes +=
|
|
367
|
+
bucket.readBytes += op.size ?? 0;
|
|
368
368
|
bucket.readTime += duration;
|
|
369
369
|
break;
|
|
370
370
|
case "write":
|
|
371
371
|
bucket.writeOps++;
|
|
372
|
-
bucket.writeBytes +=
|
|
372
|
+
bucket.writeBytes += op.size ?? 0;
|
|
373
373
|
bucket.writeTime += duration;
|
|
374
374
|
break;
|
|
375
375
|
default:
|
|
@@ -402,7 +402,6 @@ var StorageMonitor = class {
|
|
|
402
402
|
return newBucket;
|
|
403
403
|
}
|
|
404
404
|
_finalizeBuckets() {
|
|
405
|
-
var _a2;
|
|
406
405
|
const now = performance.now();
|
|
407
406
|
const toEmit = [];
|
|
408
407
|
for (const bucket of this._buckets.values()) {
|
|
@@ -414,7 +413,7 @@ var StorageMonitor = class {
|
|
|
414
413
|
for (const bucket of toEmit) {
|
|
415
414
|
this._getOrInitBucket(bucket.resource);
|
|
416
415
|
}
|
|
417
|
-
(
|
|
416
|
+
(globalThis.__STORAGE_METRICS ??= []).push(...toEmit);
|
|
418
417
|
}
|
|
419
418
|
};
|
|
420
419
|
var STORAGE_MONITOR = new StorageMonitor();
|
|
@@ -462,7 +461,15 @@ var WebFS = class {
|
|
|
462
461
|
return this._root;
|
|
463
462
|
}
|
|
464
463
|
this._root = await navigator.storage.getDirectory();
|
|
465
|
-
invariant(this._root, "Root is undefined"
|
|
464
|
+
invariant(this._root, "Root is undefined", {
|
|
465
|
+
F: __dxlog_file3,
|
|
466
|
+
L: 68,
|
|
467
|
+
S: this,
|
|
468
|
+
A: [
|
|
469
|
+
"this._root",
|
|
470
|
+
"'Root is undefined'"
|
|
471
|
+
]
|
|
472
|
+
});
|
|
466
473
|
return this._root;
|
|
467
474
|
}
|
|
468
475
|
createDirectory(sub = "") {
|
|
@@ -495,7 +502,7 @@ var WebFS = class {
|
|
|
495
502
|
await Promise.all(Array.from(this._getFiles(path)).map(async ([path2, file]) => {
|
|
496
503
|
await file.destroy().catch((err) => log3.warn(err, void 0, {
|
|
497
504
|
F: __dxlog_file3,
|
|
498
|
-
L:
|
|
505
|
+
L: 108,
|
|
499
506
|
S: this,
|
|
500
507
|
C: (f, a) => f(...a)
|
|
501
508
|
}));
|
|
@@ -510,7 +517,7 @@ var WebFS = class {
|
|
|
510
517
|
recursive: true
|
|
511
518
|
}).catch((err) => log3.warn(err, void 0, {
|
|
512
519
|
F: __dxlog_file3,
|
|
513
|
-
L:
|
|
520
|
+
L: 118,
|
|
514
521
|
S: this,
|
|
515
522
|
C: (f, a) => f(...a)
|
|
516
523
|
}));
|
|
@@ -551,8 +558,7 @@ var WebFS = class {
|
|
|
551
558
|
_ts_decorate([
|
|
552
559
|
synchronized
|
|
553
560
|
], WebFS.prototype, "_initialize", null);
|
|
554
|
-
var
|
|
555
|
-
var WebFile = class extends EventEmitter {
|
|
561
|
+
var WebFile = class WebFile2 extends EventEmitter {
|
|
556
562
|
constructor({ fileName, file, destroy }) {
|
|
557
563
|
super();
|
|
558
564
|
this.opened = true;
|
|
@@ -565,6 +571,12 @@ var WebFile = class extends EventEmitter {
|
|
|
565
571
|
this.deletable = true;
|
|
566
572
|
this.truncatable = true;
|
|
567
573
|
this.statable = true;
|
|
574
|
+
this._usage = new TimeUsageCounter();
|
|
575
|
+
this._operations = new TimeSeriesCounter();
|
|
576
|
+
this._reads = new TimeSeriesCounter();
|
|
577
|
+
this._readBytes = new TimeSeriesCounter();
|
|
578
|
+
this._writes = new TimeSeriesCounter();
|
|
579
|
+
this._writeBytes = new TimeSeriesCounter();
|
|
568
580
|
this.destroyed = false;
|
|
569
581
|
this.directory = "";
|
|
570
582
|
// TODO(dmaretskyi): is this used?
|
|
@@ -576,13 +588,17 @@ var WebFile = class extends EventEmitter {
|
|
|
576
588
|
del: callbackify(this.del.bind(this)),
|
|
577
589
|
stat: callbackify(this.stat.bind(this)),
|
|
578
590
|
destroy: callbackify(this.destroy.bind(this)),
|
|
579
|
-
truncate: callbackify(
|
|
591
|
+
truncate: callbackify(this.truncate?.bind(this))
|
|
580
592
|
};
|
|
581
593
|
this._fileName = fileName;
|
|
582
594
|
this._fileHandle = file;
|
|
583
595
|
this._destroy = destroy;
|
|
584
596
|
}
|
|
585
597
|
async write(offset, data) {
|
|
598
|
+
const span = this._usage.beginRecording();
|
|
599
|
+
this._operations.inc();
|
|
600
|
+
this._writes.inc();
|
|
601
|
+
this._writeBytes.inc(data.length);
|
|
586
602
|
const metric = STORAGE_MONITOR.beginOp({
|
|
587
603
|
resource: this._fileName,
|
|
588
604
|
type: "write",
|
|
@@ -600,10 +616,15 @@ var WebFile = class extends EventEmitter {
|
|
|
600
616
|
});
|
|
601
617
|
await writable.close();
|
|
602
618
|
} finally {
|
|
619
|
+
span.end();
|
|
603
620
|
metric.end();
|
|
604
621
|
}
|
|
605
622
|
}
|
|
606
623
|
async read(offset, size) {
|
|
624
|
+
const span = this._usage.beginRecording();
|
|
625
|
+
this._operations.inc();
|
|
626
|
+
this._reads.inc();
|
|
627
|
+
this._readBytes.inc(size);
|
|
607
628
|
const metric = STORAGE_MONITOR.beginOp({
|
|
608
629
|
resource: this._fileName,
|
|
609
630
|
type: "read",
|
|
@@ -617,10 +638,13 @@ var WebFile = class extends EventEmitter {
|
|
|
617
638
|
}
|
|
618
639
|
return Buffer.from(await file.slice(offset, offset + size).arrayBuffer());
|
|
619
640
|
} finally {
|
|
641
|
+
span.end();
|
|
620
642
|
metric.end();
|
|
621
643
|
}
|
|
622
644
|
}
|
|
623
645
|
async del(offset, size) {
|
|
646
|
+
const span = this._usage.beginRecording();
|
|
647
|
+
this._operations.inc();
|
|
624
648
|
const metric = STORAGE_MONITOR.beginOp({
|
|
625
649
|
resource: this._fileName,
|
|
626
650
|
type: "delete",
|
|
@@ -651,10 +675,13 @@ var WebFile = class extends EventEmitter {
|
|
|
651
675
|
});
|
|
652
676
|
await writable.close();
|
|
653
677
|
} finally {
|
|
678
|
+
span.end();
|
|
654
679
|
metric.end();
|
|
655
680
|
}
|
|
656
681
|
}
|
|
657
682
|
async stat() {
|
|
683
|
+
const span = this._usage.beginRecording();
|
|
684
|
+
this._operations.inc();
|
|
658
685
|
const metric = STORAGE_MONITOR.beginOp({
|
|
659
686
|
resource: this._fileName,
|
|
660
687
|
type: "stat"
|
|
@@ -666,10 +693,13 @@ var WebFile = class extends EventEmitter {
|
|
|
666
693
|
size: file.size
|
|
667
694
|
};
|
|
668
695
|
} finally {
|
|
696
|
+
span.end();
|
|
669
697
|
metric.end();
|
|
670
698
|
}
|
|
671
699
|
}
|
|
672
700
|
async truncate(offset) {
|
|
701
|
+
const span = this._usage.beginRecording();
|
|
702
|
+
this._operations.inc();
|
|
673
703
|
const metric = STORAGE_MONITOR.beginOp({
|
|
674
704
|
resource: this._fileName,
|
|
675
705
|
type: "truncate"
|
|
@@ -685,6 +715,7 @@ var WebFile = class extends EventEmitter {
|
|
|
685
715
|
});
|
|
686
716
|
await writable.close();
|
|
687
717
|
} finally {
|
|
718
|
+
span.end();
|
|
688
719
|
metric.end();
|
|
689
720
|
}
|
|
690
721
|
}
|
|
@@ -695,6 +726,27 @@ var WebFile = class extends EventEmitter {
|
|
|
695
726
|
return await this._destroy();
|
|
696
727
|
}
|
|
697
728
|
};
|
|
729
|
+
_ts_decorate([
|
|
730
|
+
trace.info()
|
|
731
|
+
], WebFile.prototype, "_fileName", void 0);
|
|
732
|
+
_ts_decorate([
|
|
733
|
+
trace.metricsCounter()
|
|
734
|
+
], WebFile.prototype, "_usage", void 0);
|
|
735
|
+
_ts_decorate([
|
|
736
|
+
trace.metricsCounter()
|
|
737
|
+
], WebFile.prototype, "_operations", void 0);
|
|
738
|
+
_ts_decorate([
|
|
739
|
+
trace.metricsCounter()
|
|
740
|
+
], WebFile.prototype, "_reads", void 0);
|
|
741
|
+
_ts_decorate([
|
|
742
|
+
trace.metricsCounter()
|
|
743
|
+
], WebFile.prototype, "_readBytes", void 0);
|
|
744
|
+
_ts_decorate([
|
|
745
|
+
trace.metricsCounter()
|
|
746
|
+
], WebFile.prototype, "_writes", void 0);
|
|
747
|
+
_ts_decorate([
|
|
748
|
+
trace.metricsCounter()
|
|
749
|
+
], WebFile.prototype, "_writeBytes", void 0);
|
|
698
750
|
_ts_decorate([
|
|
699
751
|
synchronized
|
|
700
752
|
], WebFile.prototype, "write", null);
|
|
@@ -713,6 +765,9 @@ _ts_decorate([
|
|
|
713
765
|
_ts_decorate([
|
|
714
766
|
synchronized
|
|
715
767
|
], WebFile.prototype, "destroy", null);
|
|
768
|
+
WebFile = _ts_decorate([
|
|
769
|
+
trace.resource()
|
|
770
|
+
], WebFile);
|
|
716
771
|
|
|
717
772
|
// packages/common/random-access-storage/src/browser/storage.ts
|
|
718
773
|
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/monitor.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 { File, wrapFile } from './file';\nimport { Storage, 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 { File } from './file';\nimport { 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 ) {}\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 /**\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 { StorageType } from './storage';\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 // 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 > 10) {\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 { Callback, 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 { 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 { StorageType } from '../common';\nimport { BrowserStorage } from './browser-storage';\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 { StorageType } from '../common';\nimport { BrowserStorage } from './browser-storage';\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 { RandomAccessStorage } from 'random-access-storage';\nimport invariant from 'tiny-invariant';\n\nimport { synchronized } from '@dxos/async';\nimport { log } from '@dxos/log';\n\nimport { Directory, File, Storage, StorageType, getFullPath, DiskInfo } from '../common';\nimport { STORAGE_MONITOR } from '../monitor';\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, File>();\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, File> {\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 );\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.\nexport class WebFile extends EventEmitter implements File {\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 private readonly _fileName: string;\n\n private readonly _fileHandle: Promise<FileSystemFileHandle>;\n private readonly _destroy: () => Promise<void>;\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\n destroyed = false;\n directory = '';\n // TODO(dmaretskyi): is this used?\n filename = '';\n type: StorageType = StorageType.WEBFS;\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 @synchronized\n async write(offset: number, data: Buffer) {\n const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'write', size: data.length });\n try {\n // TODO(mykola): Fix types.\n const fileHandle: any = await this._fileHandle;\n const writable = await fileHandle.createWritable({ keepExistingData: true });\n await writable.write({ type: 'write', data, position: offset });\n await writable.close();\n } finally {\n metric.end();\n }\n }\n\n @synchronized\n async read(offset: number, size: number) {\n const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'read', size });\n try {\n const fileHandle: any = await this._fileHandle;\n const file = await fileHandle.getFile();\n if (offset + size > file.size) {\n throw new Error('Read out of bounds');\n }\n // does not copy the buffer\n return Buffer.from(await file.slice(offset, offset + size).arrayBuffer());\n } finally {\n metric.end();\n }\n }\n\n @synchronized\n async del(offset: number, size: number) {\n const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'delete', size });\n try {\n if (offset < 0 || size < 0) {\n return;\n }\n const fileHandle: any = await this._fileHandle;\n const writable = await fileHandle.createWritable({ keepExistingData: true });\n const file = await fileHandle.getFile();\n let leftoverSize = 0;\n if (offset + size < file.size) {\n // does not copy the buffer\n const leftover = Buffer.from(await file.slice(offset + size, file.size).arrayBuffer());\n leftoverSize = leftover.length;\n await writable.write({ type: 'write', data: leftover, position: offset });\n }\n\n await writable.write({ type: 'truncate', size: offset + leftoverSize });\n await writable.close();\n } finally {\n metric.end();\n }\n }\n\n @synchronized\n async stat() {\n const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'stat' });\n try {\n const fileHandle: any = await this._fileHandle;\n const file = await fileHandle.getFile();\n return {\n size: file.size,\n };\n } finally {\n metric.end();\n }\n }\n\n @synchronized\n async truncate(offset: number) {\n const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'truncate' });\n try {\n const fileHandle: any = await this._fileHandle;\n const writable = await fileHandle.createWritable({ keepExistingData: true });\n await writable.write({ type: 'truncate', size: offset });\n await writable.close();\n } finally {\n metric.end();\n }\n }\n\n async close(): Promise<void> {}\n\n @synchronized\n async destroy() {\n this.destroyed = true;\n return await this._destroy();\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { unrefTimeout } from '@dxos/async';\n\nexport type StorageOperation = {\n resource: string;\n type: 'read' | 'write' | 'stat' | 'delete' | 'truncate';\n size?: number;\n};\n\nexport type OpHandle = {\n end: () => void;\n};\n\nexport type StatsBucket = {\n resource: string;\n beginTime: number;\n endTime: number;\n\n /**\n * Fraction of time spent in storage operations.\n */\n usage: number;\n\n readOps: number;\n readBytes: number;\n readTime: number;\n\n writeOps: number;\n writeBytes: number;\n writeTime: number;\n\n otherOps: number;\n otherTime: number;\n};\n\nconst BUCKET_COLLECTION_INTERVAL = 1_000;\n\n/**\n * Storage performance metrics.\n */\nexport class StorageMonitor {\n private _enabled = false;\n\n /**\n * By resource.\n */\n private readonly _buckets = new Map<string, StatsBucket>();\n\n enable() {\n this._enabled = true;\n\n const timer = setInterval(() => {\n this._finalizeBuckets();\n }, BUCKET_COLLECTION_INTERVAL);\n unrefTimeout(timer);\n }\n\n beginOp(op: StorageOperation): OpHandle {\n if (!this._enabled) {\n return {\n end: () => {},\n };\n }\n\n const beginTime = performance.now();\n return {\n end: () => {\n const endTime = performance.now();\n const duration = endTime - beginTime;\n\n const bucket = this._getOrInitBucket(op.resource);\n switch (op.type) {\n case 'read':\n bucket.readOps++;\n bucket.readBytes += op.size ?? 0;\n bucket.readTime += duration;\n break;\n case 'write':\n bucket.writeOps++;\n bucket.writeBytes += op.size ?? 0;\n bucket.writeTime += duration;\n break;\n default:\n bucket.otherOps++;\n bucket.otherTime += duration;\n }\n },\n };\n }\n\n private _getOrInitBucket(resource: string): StatsBucket {\n const bucket = this._buckets.get(resource);\n if (bucket) {\n return bucket;\n }\n\n const newBucket = {\n resource,\n beginTime: performance.now(),\n endTime: 0,\n usage: 0,\n readOps: 0,\n readBytes: 0,\n readTime: 0,\n writeOps: 0,\n writeBytes: 0,\n writeTime: 0,\n otherOps: 0,\n otherTime: 0,\n };\n this._buckets.set(resource, newBucket);\n return newBucket;\n }\n\n private _finalizeBuckets() {\n const now = performance.now();\n const toEmit = [];\n for (const bucket of this._buckets.values()) {\n bucket.endTime = now;\n bucket.usage = (bucket.readTime + bucket.writeTime + bucket.otherTime) / (bucket.endTime - bucket.beginTime);\n toEmit.push(bucket);\n }\n\n // Clear the buckets.\n this._buckets.clear();\n for (const bucket of toEmit) {\n this._getOrInitBucket(bucket.resource);\n }\n\n ((globalThis as any).__STORAGE_METRICS ??= []).push(...toEmit);\n }\n}\n\nexport const STORAGE_MONITOR = new StorageMonitor();\n\n// TODO(dmaretskyi): Disabled due to performance concerns.\n// STORAGE_MONITOR.enable();\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { MemoryStorage, Storage, StorageConstructor, StorageType } from '../common';\nimport { FirefoxStorage } from './firefox-storage';\nimport { IDbStorage } from './idb-storage';\nimport { WebFS } from './web-fs';\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", "toString", "JSON", "stringify", "createDirectory", "getFullPath", "list", "getOrCreateFile", "filename", "opts", "delete", "pify", "log", "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", "
|
|
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 { File, wrapFile } from './file';\nimport { Storage, 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 { File } from './file';\nimport { 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 ) {}\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 /**\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 { StorageType } from './storage';\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 // 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 > 10) {\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 { Callback, 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 { 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 { StorageType } from '../common';\nimport { BrowserStorage } from './browser-storage';\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 { StorageType } from '../common';\nimport { BrowserStorage } from './browser-storage';\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 { RandomAccessStorage } from 'random-access-storage';\n\nimport { synchronized } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { TimeSeriesCounter, TimeUsageCounter, trace } from '@dxos/tracing';\n\nimport { Directory, File, Storage, StorageType, getFullPath, DiskInfo } from '../common';\nimport { STORAGE_MONITOR } from '../monitor';\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, File>();\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, File> {\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 );\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 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 @trace.info()\n private readonly _fileName: string;\n\n private readonly _fileHandle: Promise<FileSystemFileHandle>;\n private readonly _destroy: () => Promise<void>;\n\n @trace.metricsCounter()\n private _usage = new TimeUsageCounter();\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 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\n destroyed = false;\n directory = '';\n // TODO(dmaretskyi): is this used?\n filename = '';\n type: StorageType = StorageType.WEBFS;\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 @synchronized\n async write(offset: number, data: Buffer) {\n const span = this._usage.beginRecording();\n this._operations.inc();\n this._writes.inc();\n this._writeBytes.inc(data.length);\n\n const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'write', size: data.length });\n try {\n // TODO(mykola): Fix types.\n const fileHandle: any = await this._fileHandle;\n const writable = await fileHandle.createWritable({ keepExistingData: true });\n await writable.write({ type: 'write', data, position: offset });\n await writable.close();\n } finally {\n span.end();\n metric.end();\n }\n }\n\n @synchronized\n async read(offset: number, size: number) {\n const span = this._usage.beginRecording();\n this._operations.inc();\n this._reads.inc();\n this._readBytes.inc(size);\n\n const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'read', size });\n try {\n const fileHandle: any = await this._fileHandle;\n const file = await fileHandle.getFile();\n if (offset + size > file.size) {\n throw new Error('Read out of bounds');\n }\n // does not copy the buffer\n return Buffer.from(await file.slice(offset, offset + size).arrayBuffer());\n } finally {\n span.end();\n metric.end();\n }\n }\n\n @synchronized\n async del(offset: number, size: number) {\n const span = this._usage.beginRecording();\n this._operations.inc();\n\n const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'delete', size });\n try {\n if (offset < 0 || size < 0) {\n return;\n }\n const fileHandle: any = await this._fileHandle;\n const writable = await fileHandle.createWritable({ keepExistingData: true });\n const file = await fileHandle.getFile();\n let leftoverSize = 0;\n if (offset + size < file.size) {\n // does not copy the buffer\n const leftover = Buffer.from(await file.slice(offset + size, file.size).arrayBuffer());\n leftoverSize = leftover.length;\n await writable.write({ type: 'write', data: leftover, position: offset });\n }\n\n await writable.write({ type: 'truncate', size: offset + leftoverSize });\n await writable.close();\n } finally {\n span.end();\n metric.end();\n }\n }\n\n @synchronized\n async stat() {\n const span = this._usage.beginRecording();\n this._operations.inc();\n\n const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'stat' });\n try {\n const fileHandle: any = await this._fileHandle;\n const file = await fileHandle.getFile();\n return {\n size: file.size,\n };\n } finally {\n span.end();\n metric.end();\n }\n }\n\n @synchronized\n async truncate(offset: number) {\n const span = this._usage.beginRecording();\n this._operations.inc();\n\n const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'truncate' });\n try {\n const fileHandle: any = await this._fileHandle;\n const writable = await fileHandle.createWritable({ keepExistingData: true });\n await writable.write({ type: 'truncate', size: offset });\n await writable.close();\n } finally {\n span.end();\n metric.end();\n }\n }\n\n async close(): Promise<void> {}\n\n @synchronized\n async destroy() {\n this.destroyed = true;\n return await this._destroy();\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { unrefTimeout } from '@dxos/async';\n\nexport type StorageOperation = {\n resource: string;\n type: 'read' | 'write' | 'stat' | 'delete' | 'truncate';\n size?: number;\n};\n\nexport type OpHandle = {\n end: () => void;\n};\n\nexport type StatsBucket = {\n resource: string;\n beginTime: number;\n endTime: number;\n\n /**\n * Fraction of time spent in storage operations.\n */\n usage: number;\n\n readOps: number;\n readBytes: number;\n readTime: number;\n\n writeOps: number;\n writeBytes: number;\n writeTime: number;\n\n otherOps: number;\n otherTime: number;\n};\n\nconst BUCKET_COLLECTION_INTERVAL = 1_000;\n\n/**\n * Storage performance metrics.\n */\nexport class StorageMonitor {\n private _enabled = false;\n\n /**\n * By resource.\n */\n private readonly _buckets = new Map<string, StatsBucket>();\n\n enable() {\n this._enabled = true;\n\n const timer = setInterval(() => {\n this._finalizeBuckets();\n }, BUCKET_COLLECTION_INTERVAL);\n unrefTimeout(timer);\n }\n\n beginOp(op: StorageOperation): OpHandle {\n if (!this._enabled) {\n return {\n end: () => {},\n };\n }\n\n const beginTime = performance.now();\n return {\n end: () => {\n const endTime = performance.now();\n const duration = endTime - beginTime;\n\n const bucket = this._getOrInitBucket(op.resource);\n switch (op.type) {\n case 'read':\n bucket.readOps++;\n bucket.readBytes += op.size ?? 0;\n bucket.readTime += duration;\n break;\n case 'write':\n bucket.writeOps++;\n bucket.writeBytes += op.size ?? 0;\n bucket.writeTime += duration;\n break;\n default:\n bucket.otherOps++;\n bucket.otherTime += duration;\n }\n },\n };\n }\n\n private _getOrInitBucket(resource: string): StatsBucket {\n const bucket = this._buckets.get(resource);\n if (bucket) {\n return bucket;\n }\n\n const newBucket = {\n resource,\n beginTime: performance.now(),\n endTime: 0,\n usage: 0,\n readOps: 0,\n readBytes: 0,\n readTime: 0,\n writeOps: 0,\n writeBytes: 0,\n writeTime: 0,\n otherOps: 0,\n otherTime: 0,\n };\n this._buckets.set(resource, newBucket);\n return newBucket;\n }\n\n private _finalizeBuckets() {\n const now = performance.now();\n const toEmit = [];\n for (const bucket of this._buckets.values()) {\n bucket.endTime = now;\n bucket.usage = (bucket.readTime + bucket.writeTime + bucket.otherTime) / (bucket.endTime - bucket.beginTime);\n toEmit.push(bucket);\n }\n\n // Clear the buckets.\n this._buckets.clear();\n for (const bucket of toEmit) {\n this._getOrInitBucket(bucket.resource);\n }\n\n ((globalThis as any).__STORAGE_METRICS ??= []).push(...toEmit);\n }\n}\n\nexport const STORAGE_MONITOR = new StorageMonitor();\n\n// TODO(dmaretskyi): Disabled due to performance concerns.\n// STORAGE_MONITOR.enable();\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { MemoryStorage, Storage, StorageConstructor, StorageType } from '../common';\nimport { FirefoxStorage } from './firefox-storage';\nimport { IDbStorage } from './idb-storage';\nimport { WebFS } from './web-fs';\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", "toString", "JSON", "stringify", "createDirectory", "getFullPath", "list", "getOrCreateFile", "filename", "opts", "delete", "pify", "log", "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", "TimeUsageCounter", "trace", "unrefTimeout", "BUCKET_COLLECTION_INTERVAL", "StorageMonitor", "_enabled", "_buckets", "Map", "enable", "timer", "setInterval", "_finalizeBuckets", "unrefTimeout", "beginOp", "op", "end", "beginTime", "performance", "now", "endTime", "duration", "bucket", "_getOrInitBucket", "resource", "type", "readOps", "readBytes", "size", "readTime", "writeOps", "writeBytes", "writeTime", "otherOps", "otherTime", "get", "newBucket", "usage", "set", "toEmit", "values", "push", "clear", "globalThis", "__STORAGE_METRICS", "STORAGE_MONITOR", "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", "filename", "opts", "existingFile", "get", "_createFile", "set", "WebFile", "fileName", "then", "getFileHandle", "create", "destroy", "delete", "removeEntry", "Promise", "all", "Array", "from", "map", "catch", "err", "log", "warn", "reset", "recursive", "undefined", "split", "join", "getDiskInfo", "used", "recurse", "handle", "promises", "values", "kind", "getFile", "f", "synchronized", "EventEmitter", "opened", "suspended", "closed", "unlinked", "writing", "readable", "writable", "deletable", "truncatable", "statable", "_usage", "TimeUsageCounter", "_operations", "TimeSeriesCounter", "_reads", "_readBytes", "_writes", "_writeBytes", "directory", "native", "write", "callbackify", "bind", "read", "del", "stat", "truncate", "_fileName", "_fileHandle", "_destroy", "offset", "data", "span", "beginRecording", "inc", "metric", "STORAGE_MONITOR", "beginOp", "resource", "fileHandle", "createWritable", "keepExistingData", "position", "close", "end", "Error", "Buffer", "arrayBuffer", "leftoverSize", "leftover", "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
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/common/random-access-storage/src/common/utils.ts":{"bytes":1295,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true}]},"packages/common/random-access-storage/src/common/directory.ts":{"bytes":4648,"imports":[{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}]},"packages/common/random-access-storage/src/common/file.ts":{"bytes":6051,"imports":[{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}]},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytes":14201,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}]},"packages/common/random-access-storage/src/common/storage.ts":{"bytes":1866,"imports":[]},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytes":4348,"imports":[{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"}]},"packages/common/random-access-storage/src/common/index.ts":{"bytes":947,"imports":[{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/memory-storage.ts","kind":"import-statement","original":"./memory-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}]},"packages/common/random-access-storage/src/browser/browser-storage.ts":{"bytes":4379,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"}]},"packages/common/random-access-storage/src/browser/firefox-storage.ts":{"bytes":2391,"imports":[{"path":"random-access-web/mutable-file-wrapper.js","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/browser/browser-storage.ts","kind":"import-statement","original":"./browser-storage"}]},"packages/common/random-access-storage/src/browser/idb-storage.ts":{"bytes":1799,"imports":[{"path":"random-access-idb","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/browser/browser-storage.ts","kind":"import-statement","original":"./browser-storage"}]},"packages/common/random-access-storage/src/monitor.ts":{"bytes":10183,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}]},"packages/common/random-access-storage/src/browser/web-fs.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/common/random-access-storage/src/common/utils.ts":{"bytes":1295,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/directory.ts":{"bytes":4648,"imports":[{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/common/file.ts":{"bytes":6051,"imports":[{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytes":14201,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/common/storage.ts":{"bytes":1866,"imports":[],"format":"esm"},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytes":4348,"imports":[{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"}],"format":"esm"},"packages/common/random-access-storage/src/common/index.ts":{"bytes":947,"imports":[{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/memory-storage.ts","kind":"import-statement","original":"./memory-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/browser/browser-storage.ts":{"bytes":4379,"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"}],"format":"esm"},"packages/common/random-access-storage/src/browser/firefox-storage.ts":{"bytes":2391,"imports":[{"path":"random-access-web/mutable-file-wrapper.js","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/browser/browser-storage.ts","kind":"import-statement","original":"./browser-storage"}],"format":"esm"},"packages/common/random-access-storage/src/browser/idb-storage.ts":{"bytes":1799,"imports":[{"path":"random-access-idb","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/browser/browser-storage.ts","kind":"import-statement","original":"./browser-storage"}],"format":"esm"},"packages/common/random-access-storage/src/monitor.ts":{"bytes":10183,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/browser/web-fs.ts":{"bytes":38047,"imports":[{"path":"@dxos/node-std/events","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/tracing","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/monitor.ts","kind":"import-statement","original":"../monitor"}],"format":"esm"},"packages/common/random-access-storage/src/browser/storage.ts":{"bytes":4396,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/browser/firefox-storage.ts","kind":"import-statement","original":"./firefox-storage"},{"path":"packages/common/random-access-storage/src/browser/idb-storage.ts","kind":"import-statement","original":"./idb-storage"},{"path":"packages/common/random-access-storage/src/browser/web-fs.ts","kind":"import-statement","original":"./web-fs"}],"format":"esm"},"packages/common/random-access-storage/src/browser/index.ts":{"bytes":571,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/browser/storage.ts","kind":"import-statement","original":"./storage"}],"format":"esm"}},"outputs":{"packages/common/random-access-storage/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":46235},"packages/common/random-access-storage/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"random-access-web/mutable-file-wrapper.js","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"random-access-idb","kind":"import-statement","external":true},{"path":"@dxos/node-std/events","kind":"import-statement","external":true},{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/tracing","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true}],"exports":["AbstractStorage","Directory","MemoryStorage","StorageType","createStorage","getFullPath","stringDiff","wrapFile"],"entryPoint":"packages/common/random-access-storage/src/browser/index.ts","inputs":{"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytesInOutput":3348},"packages/common/random-access-storage/src/common/utils.ts":{"bytesInOutput":180},"packages/common/random-access-storage/src/common/directory.ts":{"bytesInOutput":935},"packages/common/random-access-storage/src/common/file.ts":{"bytesInOutput":1088},"packages/common/random-access-storage/src/common/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytesInOutput":693},"packages/common/random-access-storage/src/common/storage.ts":{"bytesInOutput":288},"packages/common/random-access-storage/src/browser/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/browser/firefox-storage.ts":{"bytesInOutput":275},"packages/common/random-access-storage/src/browser/browser-storage.ts":{"bytesInOutput":769},"packages/common/random-access-storage/src/browser/idb-storage.ts":{"bytesInOutput":223},"packages/common/random-access-storage/src/browser/web-fs.ts":{"bytesInOutput":10094},"packages/common/random-access-storage/src/monitor.ts":{"bytesInOutput":2207},"packages/common/random-access-storage/src/browser/storage.ts":{"bytesInOutput":765}},"bytes":22145}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -53,7 +53,7 @@ var stringDiff = (first, second) => first.split(second).join("");
|
|
|
53
53
|
var getFullPath = (root, path) => (0, import_node_path.join)(root, stringDiff(path, root));
|
|
54
54
|
|
|
55
55
|
// packages/common/random-access-storage/src/common/directory.ts
|
|
56
|
-
var Directory = class {
|
|
56
|
+
var Directory = class _Directory {
|
|
57
57
|
constructor(type, path, _list, _getOrCreateFile, _delete) {
|
|
58
58
|
this.type = type;
|
|
59
59
|
this.path = path;
|
|
@@ -71,7 +71,7 @@ var Directory = class {
|
|
|
71
71
|
* Create a new sub-directory.
|
|
72
72
|
*/
|
|
73
73
|
createDirectory(path) {
|
|
74
|
-
return new
|
|
74
|
+
return new _Directory(this.type, getFullPath(this.path, path), this._list, this._getOrCreateFile, this._delete);
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
77
|
* Get all files in the current directory.
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/index.ts", "../../../src/common/abstract-storage.ts", "../../../src/common/utils.ts", "../../../src/common/directory.ts", "../../../src/common/file.ts", "../../../src/common/memory-storage.ts", "../../../src/common/storage.ts", "../../../src/node/node-storage.ts", "../../../src/node/storage.ts"],
|
|
4
4
|
"sourcesContent": ["//\n// Copyright 2021 DXOS.org\n//\n\nexport * from './node';\n", "//\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 { File, wrapFile } from './file';\nimport { Storage, 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 { File } from './file';\nimport { 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 ) {}\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 /**\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 { StorageType } from './storage';\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 // 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 > 10) {\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 { Callback, 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 { Directory } from './directory';\n\n// TODO(burdon): Reconcile with ConfigProto.\nexport enum StorageType {\n RAM = 'ram',\n IDB = 'idb',\n CHROME = 'chrome',\n FIREFOX = 'firefox',\n NODE = 'node',\n WEBFS = 'webfs',\n}\n\nexport type DiskInfo = {\n /**\n * Bytes.\n */\n used: number;\n};\n\nexport interface Storage {\n readonly path: string;\n readonly type: StorageType;\n readonly size: number;\n\n getDiskInfo?(): Promise<DiskInfo>;\n\n // TODO(burdon): Make required.\n createDirectory: (path?: string) => Directory;\n reset: () => Promise<void>;\n}\n\nexport type StorageConstructor = (params?: { type?: StorageType; root?: string }) => Storage;\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport del from 'del';\nimport { readdir, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport raf from 'random-access-file';\nimport { RandomAccessStorage } from 'random-access-storage';\n\nimport { AbstractStorage, DiskInfo, Storage, StorageType } from '../common';\n\n/**\n * Storage interface implementation for Node.\n */\nexport class NodeStorage extends AbstractStorage implements Storage {\n public override type: StorageType = StorageType.NODE;\n\n protected override _createFile(path: string, filename: string, opts: any = {}): RandomAccessStorage {\n const file = raf(filename, { directory: path, ...opts });\n\n // Empty write to create file on a drive.\n file.write(0, Buffer.from(''));\n\n return file;\n }\n\n protected override async _destroy() {\n await del(this.path, { force: true });\n }\n\n async getDiskInfo(): Promise<DiskInfo> {\n let used = 0;\n\n const recurse = async (path: string) => {\n const pathStats = await stat(path);\n\n used += pathStats.size;\n\n if (pathStats.isDirectory()) {\n const entries = await readdir(path);\n await Promise.all(entries.map((entry) => recurse(join(path, entry))));\n }\n };\n\n await recurse(this.path);\n\n return {\n used,\n };\n }\n}\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { MemoryStorage, Storage, StorageConstructor, StorageType } from '../common';\nimport { NodeStorage } from './node-storage';\n\nexport const createStorage: StorageConstructor = ({ type, root = '/tmp/dxos/testing' } = {}): Storage => {\n if (type === undefined) {\n return new NodeStorage(root);\n }\n\n switch (type) {\n case StorageType.RAM: {\n return new MemoryStorage(root);\n }\n\n case StorageType.NODE: {\n return new NodeStorage(root);\n }\n\n default: {\n throw new Error(`Invalid type: ${type}`);\n }\n }\n};\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;ACIA,IAAAA,oBAAqB;AACrB,uBAAwB;AAGxB,mBAA8B;AAC9B,IAAAC,cAAoB;;;ACLpB,uBAAqB;AAGd,IAAMC,aAAa,CAACC,OAAeC,WAAmBD,MAAME,MAAMD,MAAAA,EAAQE,KAAK,EAAA;AAE/E,IAAMC,cAAc,CAACC,MAAcC,aAAiBH,uBAAKE,MAAMN,WAAWO,MAAMD,IAAAA,CAAAA;;;ACEhF,IAAME,YAAN,MAAMA;EACXC,YACkBC,MACAC,MAECC,OACAC,kBACAC,SACjB;gBANgBJ;gBACAC;iBAECC;4BACAC;mBACAC;EAChB;EAEHC,WAAW;AACT,WAAO,aAAaC,KAAKC,UAAU;MAAEP,MAAM,KAAKA;MAAMC,MAAM,KAAKA;IAAK,CAAA;EACxE;;;;EAKAO,gBAAgBP,MAAyB;AACvC,WAAO,IAAIH,
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_node_path", "import_log", "stringDiff", "first", "second", "split", "join", "getFullPath", "root", "path", "Directory", "constructor", "type", "path", "_list", "_getOrCreateFile", "_delete", "toString", "JSON", "stringify", "createDirectory", "getFullPath", "list", "getOrCreateFile", "filename", "opts", "delete", "pifyFields", "object", "type", "fields", "field", "fn", "pify", "bind", "args", "before", "performance", "now", "res", "elapsed", "log", "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", "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", "import_node_path", "NodeStorage", "AbstractStorage", "type", "StorageType", "NODE", "_createFile", "path", "filename", "opts", "file", "raf", "directory", "write", "Buffer", "from", "_destroy", "del", "force", "getDiskInfo", "used", "recurse", "pathStats", "stat", "size", "isDirectory", "entries", "readdir", "Promise", "all", "map", "entry", "join", "createStorage", "type", "root", "undefined", "NodeStorage", "StorageType", "RAM", "MemoryStorage", "NODE", "Error"]
|
|
7
7
|
}
|
package/dist/lib/node/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/common/random-access-storage/src/common/utils.ts":{"bytes":1295,"imports":[{"path":"node:path","kind":"import-statement","external":true}]},"packages/common/random-access-storage/src/common/directory.ts":{"bytes":4648,"imports":[{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}]},"packages/common/random-access-storage/src/common/file.ts":{"bytes":6051,"imports":[{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}]},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytes":14201,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}]},"packages/common/random-access-storage/src/common/storage.ts":{"bytes":1866,"imports":[]},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytes":4348,"imports":[{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"}]},"packages/common/random-access-storage/src/common/index.ts":{"bytes":947,"imports":[{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/memory-storage.ts","kind":"import-statement","original":"./memory-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}]},"packages/common/random-access-storage/src/node/node-storage.ts":{"bytes":4787,"imports":[{"path":"del","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"random-access-file","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"}]},"packages/common/random-access-storage/src/node/storage.ts":{"bytes":2425,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/node/node-storage.ts","kind":"import-statement","original":"./node-storage"}]},"packages/common/random-access-storage/src/node/index.ts":{"bytes":568,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/node/storage.ts","kind":"import-statement","original":"./storage"}]},"packages/common/random-access-storage/src/index.ts":{"bytes":469,"imports":[{"path":"packages/common/random-access-storage/src/node/index.ts","kind":"import-statement","original":"./node"}]}},"outputs":{"packages/common/random-access-storage/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":
|
|
1
|
+
{"inputs":{"packages/common/random-access-storage/src/common/utils.ts":{"bytes":1295,"imports":[{"path":"node:path","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/directory.ts":{"bytes":4648,"imports":[{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/common/file.ts":{"bytes":6051,"imports":[{"path":"pify","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytes":14201,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:util","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/common/storage.ts":{"bytes":1866,"imports":[],"format":"esm"},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytes":4348,"imports":[{"path":"random-access-memory","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"}],"format":"esm"},"packages/common/random-access-storage/src/common/index.ts":{"bytes":947,"imports":[{"path":"packages/common/random-access-storage/src/common/abstract-storage.ts","kind":"import-statement","original":"./abstract-storage"},{"path":"packages/common/random-access-storage/src/common/directory.ts","kind":"import-statement","original":"./directory"},{"path":"packages/common/random-access-storage/src/common/file.ts","kind":"import-statement","original":"./file"},{"path":"packages/common/random-access-storage/src/common/memory-storage.ts","kind":"import-statement","original":"./memory-storage"},{"path":"packages/common/random-access-storage/src/common/storage.ts","kind":"import-statement","original":"./storage"},{"path":"packages/common/random-access-storage/src/common/utils.ts","kind":"import-statement","original":"./utils"}],"format":"esm"},"packages/common/random-access-storage/src/node/node-storage.ts":{"bytes":4787,"imports":[{"path":"del","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"random-access-file","kind":"import-statement","external":true},{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"}],"format":"esm"},"packages/common/random-access-storage/src/node/storage.ts":{"bytes":2425,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/node/node-storage.ts","kind":"import-statement","original":"./node-storage"}],"format":"esm"},"packages/common/random-access-storage/src/node/index.ts":{"bytes":568,"imports":[{"path":"packages/common/random-access-storage/src/common/index.ts","kind":"import-statement","original":"../common"},{"path":"packages/common/random-access-storage/src/node/storage.ts","kind":"import-statement","original":"./storage"}],"format":"esm"},"packages/common/random-access-storage/src/index.ts":{"bytes":469,"imports":[{"path":"packages/common/random-access-storage/src/node/index.ts","kind":"import-statement","original":"./node"}],"format":"esm"}},"outputs":{"packages/common/random-access-storage/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":19919},"packages/common/random-access-storage/dist/lib/node/index.cjs":{"imports":[{"path":"node:path","kind":"require-call","external":true},{"path":"node:util","kind":"require-call","external":true},{"path":"@dxos/debug","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"node:path","kind":"require-call","external":true},{"path":"pify","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"random-access-memory","kind":"require-call","external":true},{"path":"@dxos/util","kind":"require-call","external":true},{"path":"del","kind":"require-call","external":true},{"path":"node:fs/promises","kind":"require-call","external":true},{"path":"node:path","kind":"require-call","external":true},{"path":"random-access-file","kind":"require-call","external":true}],"exports":[],"entryPoint":"packages/common/random-access-storage/src/index.ts","inputs":{"packages/common/random-access-storage/src/index.ts":{"bytesInOutput":369},"packages/common/random-access-storage/src/common/abstract-storage.ts":{"bytesInOutput":3453},"packages/common/random-access-storage/src/common/utils.ts":{"bytesInOutput":203},"packages/common/random-access-storage/src/common/directory.ts":{"bytesInOutput":935},"packages/common/random-access-storage/src/common/file.ts":{"bytesInOutput":1144},"packages/common/random-access-storage/src/common/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/common/memory-storage.ts":{"bytesInOutput":780},"packages/common/random-access-storage/src/common/storage.ts":{"bytesInOutput":288},"packages/common/random-access-storage/src/node/index.ts":{"bytesInOutput":0},"packages/common/random-access-storage/src/node/node-storage.ts":{"bytesInOutput":1114},"packages/common/random-access-storage/src/node/storage.ts":{"bytesInOutput":369}},"bytes":11023}}}
|
|
@@ -38,6 +38,12 @@ export declare class WebFile extends EventEmitter implements File {
|
|
|
38
38
|
private readonly _fileName;
|
|
39
39
|
private readonly _fileHandle;
|
|
40
40
|
private readonly _destroy;
|
|
41
|
+
private _usage;
|
|
42
|
+
private _operations;
|
|
43
|
+
private _reads;
|
|
44
|
+
private _readBytes;
|
|
45
|
+
private _writes;
|
|
46
|
+
private _writeBytes;
|
|
41
47
|
constructor({ fileName, file, destroy, }: {
|
|
42
48
|
file: Promise<FileSystemFileHandle>;
|
|
43
49
|
fileName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-fs.d.ts","sourceRoot":"","sources":["../../../../src/browser/web-fs.ts"],"names":[],"mappings":";;AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"web-fs.d.ts","sourceRoot":"","sources":["../../../../src/browser/web-fs.ts"],"names":[],"mappings":";;AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAO5D,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAe,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGzF;;GAEG;AACH,qBAAa,KAAM,YAAW,OAAO;aAMP,IAAI,EAAE,MAAM;IALxC,QAAQ,CAAC,IAAI,qBAAqB;IAElC,SAAS,CAAC,QAAQ,CAAC,MAAM,oBAA2B;IACpD,SAAS,CAAC,KAAK,CAAC,EAAE,yBAAyB,CAAC;gBAEhB,IAAI,EAAE,MAAM;IAExC,IAAW,IAAI,WAEd;IAED,OAAO,CAAC,SAAS;YAOH,KAAK;YAwBL,WAAW;IASzB,eAAe,CAAC,GAAG,SAAK;IAUxB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAWjE,OAAO,CAAC,WAAW;YAYL,OAAO;IASf,KAAK;IASX,OAAO,CAAC,gBAAgB;IASlB,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC;CA6BvC;AAGD,qBACa,OAAQ,SAAQ,YAAa,YAAW,IAAI;IACvD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAQ;IAChC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAS;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAS;IACjC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAS;IACnC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAS;IAClC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAQ;IAClC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAQ;IAClC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAQ;IACnC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAQ;IACrC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAQ;IAElC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAC5D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAG/C,OAAO,CAAC,MAAM,CAA0B;IAGxC,OAAO,CAAC,WAAW,CAA2B;IAG9C,OAAO,CAAC,MAAM,CAA2B;IAGzC,OAAO,CAAC,UAAU,CAA2B;IAG7C,OAAO,CAAC,OAAO,CAA2B;IAG1C,OAAO,CAAC,WAAW,CAA2B;gBAElC,EACV,QAAQ,EACR,IAAI,EACJ,OAAO,GACR,EAAE;QACD,IAAI,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACpC,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9B;IAOD,SAAS,UAAS;IAClB,SAAS,SAAM;IAEf,QAAQ,SAAM;IACd,IAAI,EAAE,WAAW,CAAqB;IACtC,MAAM,EAAE,mBAAmB,CAOF;IAGnB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAoBlC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAsBjC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IA6BhC,IAAI;;;IAkBJ,QAAQ,CAAC,MAAM,EAAE,MAAM;IAgBvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAGtB,OAAO;CAId"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.blueprint-test.d.ts","sourceRoot":"","sources":["../../../../src/testing/storage.blueprint-test.ts"],"names":[],"mappings":"AAUA,OAAO,EAAQ,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"storage.blueprint-test.d.ts","sourceRoot":"","sources":["../../../../src/testing/storage.blueprint-test.ts"],"names":[],"mappings":"AAUA,OAAO,EAAQ,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAIvD,eAAO,MAAM,UAAU,cAAgD,CAAC;AAExE,eAAO,MAAM,YAAY,kBAAmB,WAAW,iBAAiB,MAAM,OAAO,SAgTpF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/random-access-storage",
|
|
3
|
-
"version": "0.1.56-main.
|
|
3
|
+
"version": "0.1.56-main.e79d64a",
|
|
4
4
|
"description": "Multiple random storage types.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -24,12 +24,13 @@
|
|
|
24
24
|
"random-access-memory": "^4.1.0",
|
|
25
25
|
"random-access-storage": "^3.0.0",
|
|
26
26
|
"random-access-web": "^2.0.3",
|
|
27
|
-
"
|
|
28
|
-
"@dxos/
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/log": "0.1.56-main.
|
|
31
|
-
"@dxos/node-std": "0.1.56-main.
|
|
32
|
-
"@dxos/
|
|
27
|
+
"@dxos/async": "0.1.56-main.e79d64a",
|
|
28
|
+
"@dxos/debug": "0.1.56-main.e79d64a",
|
|
29
|
+
"@dxos/invariant": "0.1.56-main.e79d64a",
|
|
30
|
+
"@dxos/log": "0.1.56-main.e79d64a",
|
|
31
|
+
"@dxos/node-std": "0.1.56-main.e79d64a",
|
|
32
|
+
"@dxos/tracing": "0.1.56-main.e79d64a",
|
|
33
|
+
"@dxos/util": "0.1.56-main.e79d64a"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@types/pify": "^3.0.2",
|
package/src/browser/web-fs.ts
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
import { EventEmitter } from 'node:events';
|
|
6
6
|
import { callbackify } from 'node:util';
|
|
7
7
|
import { RandomAccessStorage } from 'random-access-storage';
|
|
8
|
-
import invariant from 'tiny-invariant';
|
|
9
8
|
|
|
10
9
|
import { synchronized } from '@dxos/async';
|
|
10
|
+
import { invariant } from '@dxos/invariant';
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
|
+
import { TimeSeriesCounter, TimeUsageCounter, trace } from '@dxos/tracing';
|
|
12
13
|
|
|
13
14
|
import { Directory, File, Storage, StorageType, getFullPath, DiskInfo } from '../common';
|
|
14
15
|
import { STORAGE_MONITOR } from '../monitor';
|
|
@@ -160,6 +161,7 @@ export class WebFS implements Storage {
|
|
|
160
161
|
}
|
|
161
162
|
|
|
162
163
|
// TODO(mykola): Remove EventEmitter.
|
|
164
|
+
@trace.resource()
|
|
163
165
|
export class WebFile extends EventEmitter implements File {
|
|
164
166
|
readonly opened: boolean = true;
|
|
165
167
|
readonly suspended: boolean = false;
|
|
@@ -171,11 +173,30 @@ export class WebFile extends EventEmitter implements File {
|
|
|
171
173
|
readonly deletable: boolean = true;
|
|
172
174
|
readonly truncatable: boolean = true;
|
|
173
175
|
readonly statable: boolean = true;
|
|
176
|
+
@trace.info()
|
|
174
177
|
private readonly _fileName: string;
|
|
175
178
|
|
|
176
179
|
private readonly _fileHandle: Promise<FileSystemFileHandle>;
|
|
177
180
|
private readonly _destroy: () => Promise<void>;
|
|
178
181
|
|
|
182
|
+
@trace.metricsCounter()
|
|
183
|
+
private _usage = new TimeUsageCounter();
|
|
184
|
+
|
|
185
|
+
@trace.metricsCounter()
|
|
186
|
+
private _operations = new TimeSeriesCounter();
|
|
187
|
+
|
|
188
|
+
@trace.metricsCounter()
|
|
189
|
+
private _reads = new TimeSeriesCounter();
|
|
190
|
+
|
|
191
|
+
@trace.metricsCounter()
|
|
192
|
+
private _readBytes = new TimeSeriesCounter();
|
|
193
|
+
|
|
194
|
+
@trace.metricsCounter()
|
|
195
|
+
private _writes = new TimeSeriesCounter();
|
|
196
|
+
|
|
197
|
+
@trace.metricsCounter()
|
|
198
|
+
private _writeBytes = new TimeSeriesCounter();
|
|
199
|
+
|
|
179
200
|
constructor({
|
|
180
201
|
fileName,
|
|
181
202
|
file,
|
|
@@ -207,6 +228,11 @@ export class WebFile extends EventEmitter implements File {
|
|
|
207
228
|
|
|
208
229
|
@synchronized
|
|
209
230
|
async write(offset: number, data: Buffer) {
|
|
231
|
+
const span = this._usage.beginRecording();
|
|
232
|
+
this._operations.inc();
|
|
233
|
+
this._writes.inc();
|
|
234
|
+
this._writeBytes.inc(data.length);
|
|
235
|
+
|
|
210
236
|
const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'write', size: data.length });
|
|
211
237
|
try {
|
|
212
238
|
// TODO(mykola): Fix types.
|
|
@@ -215,12 +241,18 @@ export class WebFile extends EventEmitter implements File {
|
|
|
215
241
|
await writable.write({ type: 'write', data, position: offset });
|
|
216
242
|
await writable.close();
|
|
217
243
|
} finally {
|
|
244
|
+
span.end();
|
|
218
245
|
metric.end();
|
|
219
246
|
}
|
|
220
247
|
}
|
|
221
248
|
|
|
222
249
|
@synchronized
|
|
223
250
|
async read(offset: number, size: number) {
|
|
251
|
+
const span = this._usage.beginRecording();
|
|
252
|
+
this._operations.inc();
|
|
253
|
+
this._reads.inc();
|
|
254
|
+
this._readBytes.inc(size);
|
|
255
|
+
|
|
224
256
|
const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'read', size });
|
|
225
257
|
try {
|
|
226
258
|
const fileHandle: any = await this._fileHandle;
|
|
@@ -231,12 +263,16 @@ export class WebFile extends EventEmitter implements File {
|
|
|
231
263
|
// does not copy the buffer
|
|
232
264
|
return Buffer.from(await file.slice(offset, offset + size).arrayBuffer());
|
|
233
265
|
} finally {
|
|
266
|
+
span.end();
|
|
234
267
|
metric.end();
|
|
235
268
|
}
|
|
236
269
|
}
|
|
237
270
|
|
|
238
271
|
@synchronized
|
|
239
272
|
async del(offset: number, size: number) {
|
|
273
|
+
const span = this._usage.beginRecording();
|
|
274
|
+
this._operations.inc();
|
|
275
|
+
|
|
240
276
|
const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'delete', size });
|
|
241
277
|
try {
|
|
242
278
|
if (offset < 0 || size < 0) {
|
|
@@ -256,12 +292,16 @@ export class WebFile extends EventEmitter implements File {
|
|
|
256
292
|
await writable.write({ type: 'truncate', size: offset + leftoverSize });
|
|
257
293
|
await writable.close();
|
|
258
294
|
} finally {
|
|
295
|
+
span.end();
|
|
259
296
|
metric.end();
|
|
260
297
|
}
|
|
261
298
|
}
|
|
262
299
|
|
|
263
300
|
@synchronized
|
|
264
301
|
async stat() {
|
|
302
|
+
const span = this._usage.beginRecording();
|
|
303
|
+
this._operations.inc();
|
|
304
|
+
|
|
265
305
|
const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'stat' });
|
|
266
306
|
try {
|
|
267
307
|
const fileHandle: any = await this._fileHandle;
|
|
@@ -270,12 +310,16 @@ export class WebFile extends EventEmitter implements File {
|
|
|
270
310
|
size: file.size,
|
|
271
311
|
};
|
|
272
312
|
} finally {
|
|
313
|
+
span.end();
|
|
273
314
|
metric.end();
|
|
274
315
|
}
|
|
275
316
|
}
|
|
276
317
|
|
|
277
318
|
@synchronized
|
|
278
319
|
async truncate(offset: number) {
|
|
320
|
+
const span = this._usage.beginRecording();
|
|
321
|
+
this._operations.inc();
|
|
322
|
+
|
|
279
323
|
const metric = STORAGE_MONITOR.beginOp({ resource: this._fileName, type: 'truncate' });
|
|
280
324
|
try {
|
|
281
325
|
const fileHandle: any = await this._fileHandle;
|
|
@@ -283,6 +327,7 @@ export class WebFile extends EventEmitter implements File {
|
|
|
283
327
|
await writable.write({ type: 'truncate', size: offset });
|
|
284
328
|
await writable.close();
|
|
285
329
|
} finally {
|
|
330
|
+
span.end();
|
|
286
331
|
metric.end();
|
|
287
332
|
}
|
|
288
333
|
}
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
// Copyright 2021 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import expect from '
|
|
6
|
-
import
|
|
5
|
+
import chai, { expect } from 'chai';
|
|
6
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
7
7
|
|
|
8
8
|
import { asyncTimeout } from '@dxos/async';
|
|
9
9
|
import { describe, test } from '@dxos/test';
|
|
10
10
|
|
|
11
11
|
import { File, Storage, StorageType } from '../common';
|
|
12
12
|
|
|
13
|
+
chai.use(chaiAsPromised);
|
|
14
|
+
|
|
13
15
|
export const randomText = () => Math.random().toString(36).substring(2);
|
|
14
16
|
|
|
15
17
|
export const storageTests = (testGroupName: StorageType, createStorage: () => Storage) => {
|
|
@@ -17,7 +19,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
17
19
|
await file.write(offset, data);
|
|
18
20
|
const bufferRead = await file.read(offset, data.length);
|
|
19
21
|
const result = data.equals(bufferRead);
|
|
20
|
-
expect(result).
|
|
22
|
+
expect(result).to.be.true;
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
describe(testGroupName, () => {
|
|
@@ -61,7 +63,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
const entries = await directory.list();
|
|
64
|
-
expect(entries).
|
|
66
|
+
expect(entries.length).to.equal(count);
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
{
|
|
@@ -73,7 +75,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
const entries = await directory.list();
|
|
76
|
-
expect(entries).
|
|
78
|
+
expect(entries.length).to.equal(count - amountToDelete);
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
// Cleanup.
|
|
@@ -90,7 +92,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
90
92
|
const file = directory.getOrCreateFile(fileName);
|
|
91
93
|
const { size } = await file.stat();
|
|
92
94
|
const data = await file.read(0, size);
|
|
93
|
-
expect(Buffer.from('').equals(data)).
|
|
95
|
+
expect(Buffer.from('').equals(data)).to.be.true;
|
|
94
96
|
});
|
|
95
97
|
|
|
96
98
|
test('reopen and check if data is the same', async () => {
|
|
@@ -108,7 +110,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
108
110
|
{
|
|
109
111
|
const file = directory.getOrCreateFile(fileName);
|
|
110
112
|
const data2 = await file.read(0, data1.length);
|
|
111
|
-
expect(data1.equals(data2)).
|
|
113
|
+
expect(data1.equals(data2)).to.be.true;
|
|
112
114
|
await file.close();
|
|
113
115
|
}
|
|
114
116
|
});
|
|
@@ -132,7 +134,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
132
134
|
{
|
|
133
135
|
const file = directory.getOrCreateFile(fileName);
|
|
134
136
|
const { size } = await file.stat();
|
|
135
|
-
expect(size).
|
|
137
|
+
expect(size).to.equal(0);
|
|
136
138
|
await file.close();
|
|
137
139
|
}
|
|
138
140
|
});
|
|
@@ -156,8 +158,8 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
156
158
|
await file2.write(0, buffer2);
|
|
157
159
|
|
|
158
160
|
// 4. Check that they have correct content.
|
|
159
|
-
expect(await file1.read(0, buffer1.length)).
|
|
160
|
-
expect(await file2.read(0, buffer2.length)).
|
|
161
|
+
expect(await file1.read(0, buffer1.length)).to.deep.equal(buffer1);
|
|
162
|
+
expect(await file2.read(0, buffer2.length)).to.deep.equal(buffer2);
|
|
161
163
|
});
|
|
162
164
|
|
|
163
165
|
test('write in directory/sub-directory/file', async () => {
|
|
@@ -170,7 +172,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
170
172
|
await file.write(0, buffer);
|
|
171
173
|
|
|
172
174
|
const readBuffer = await file.read(0, buffer.length);
|
|
173
|
-
expect(readBuffer).
|
|
175
|
+
expect(readBuffer).to.deep.equal(buffer);
|
|
174
176
|
await file.close();
|
|
175
177
|
});
|
|
176
178
|
|
|
@@ -183,7 +185,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
183
185
|
await writeAndCheck(file, buffer);
|
|
184
186
|
|
|
185
187
|
await directory.delete();
|
|
186
|
-
await
|
|
188
|
+
await expect(file.read(0, buffer.length)).to.be.rejected;
|
|
187
189
|
});
|
|
188
190
|
|
|
189
191
|
test('del method', async () => {
|
|
@@ -196,24 +198,20 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
196
198
|
await file.write(0, buffer1);
|
|
197
199
|
const buffer2 = Buffer.from(randomText());
|
|
198
200
|
await file.write(buffer1.length, buffer2);
|
|
199
|
-
expect((await file.stat()).size).
|
|
201
|
+
expect((await file.stat()).size).to.equal(buffer1.length + buffer2.length);
|
|
200
202
|
|
|
201
203
|
// Weird behavior. Works only if offset + size === file size. If greater - throws error, if less - does nothing.
|
|
202
204
|
await file.del(buffer1.length, buffer2.length);
|
|
203
|
-
expect((await file.stat()).size).
|
|
204
|
-
expect(await file.read(0, buffer1.length)).
|
|
205
|
-
await
|
|
206
|
-
async () => await file.read(buffer1.length, buffer2.length),
|
|
207
|
-
Error,
|
|
208
|
-
'Could not satisfy length',
|
|
209
|
-
);
|
|
205
|
+
expect((await file.stat()).size).to.equal(buffer1.length);
|
|
206
|
+
expect(await file.read(0, buffer1.length)).to.deep.equal(buffer1);
|
|
207
|
+
await expect(file.read(buffer1.length, buffer2.length)).to.be.rejectedWith('Could not satisfy length');
|
|
210
208
|
}).onlyEnvironments('nodejs'); // File.del() throws 'Not deletable' error for IDb.
|
|
211
209
|
|
|
212
210
|
test('stat of new file', async () => {
|
|
213
211
|
const storage = createStorage();
|
|
214
212
|
const directory = storage.createDirectory();
|
|
215
213
|
const file = directory.getOrCreateFile(randomText());
|
|
216
|
-
expect((await file.stat()).size).
|
|
214
|
+
expect((await file.stat()).size).to.equal(0);
|
|
217
215
|
});
|
|
218
216
|
|
|
219
217
|
test('call del with edge arguments', async () => {
|
|
@@ -229,21 +227,21 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
229
227
|
const file = directory.getOrCreateFile(randomText());
|
|
230
228
|
await file.write(0, buffer);
|
|
231
229
|
await file.del(0, buffer.length + 1);
|
|
232
|
-
expect((await file.stat()).size).
|
|
230
|
+
expect((await file.stat()).size).to.equal(0);
|
|
233
231
|
}
|
|
234
232
|
|
|
235
233
|
{
|
|
236
234
|
const file = directory.getOrCreateFile(randomText());
|
|
237
235
|
await file.write(0, buffer);
|
|
238
236
|
await file.del(1, buffer.length);
|
|
239
|
-
expect((await file.stat()).size).
|
|
237
|
+
expect((await file.stat()).size).to.equal(1);
|
|
240
238
|
}
|
|
241
239
|
|
|
242
240
|
{
|
|
243
241
|
const file = directory.getOrCreateFile(randomText());
|
|
244
242
|
await file.write(0, buffer);
|
|
245
243
|
await file.del(0, -1);
|
|
246
|
-
expect((await file.stat()).size).
|
|
244
|
+
expect((await file.stat()).size).to.equal(buffer.length);
|
|
247
245
|
}
|
|
248
246
|
});
|
|
249
247
|
|
|
@@ -269,7 +267,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
269
267
|
const storage = createStorage();
|
|
270
268
|
const directory = storage.createDirectory();
|
|
271
269
|
const file = directory.getOrCreateFile(filename);
|
|
272
|
-
expect(await file.read(0, buffer.length)).
|
|
270
|
+
expect(await file.read(0, buffer.length)).to.deep.equal(buffer);
|
|
273
271
|
await file.close();
|
|
274
272
|
}
|
|
275
273
|
|
|
@@ -282,9 +280,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
282
280
|
const storage = createStorage();
|
|
283
281
|
const directory = storage.createDirectory();
|
|
284
282
|
const file = directory.getOrCreateFile(filename);
|
|
285
|
-
await expect(
|
|
286
|
-
await file.read(0, buffer.length);
|
|
287
|
-
}).rejects.toThrow();
|
|
283
|
+
await expect(file.read(0, buffer.length)).to.be.rejected;
|
|
288
284
|
}
|
|
289
285
|
});
|
|
290
286
|
|
|
@@ -300,7 +296,7 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
300
296
|
|
|
301
297
|
{
|
|
302
298
|
const entries = await directory.list();
|
|
303
|
-
expect(entries).
|
|
299
|
+
expect(entries.length).to.equal(0);
|
|
304
300
|
}
|
|
305
301
|
|
|
306
302
|
const files = [...Array(10)].map(() => directory.getOrCreateFile(randomText()));
|
|
@@ -311,14 +307,14 @@ export const storageTests = (testGroupName: StorageType, createStorage: () => St
|
|
|
311
307
|
|
|
312
308
|
{
|
|
313
309
|
const entries = await directory.list();
|
|
314
|
-
expect(entries).
|
|
310
|
+
expect(entries.length).to.equal(files.length);
|
|
315
311
|
}
|
|
316
312
|
|
|
317
313
|
{
|
|
318
314
|
const storage = createStorage();
|
|
319
315
|
const directory = storage.createDirectory(dirname);
|
|
320
316
|
const entries = await directory.list();
|
|
321
|
-
expect(entries).
|
|
317
|
+
expect(entries.length).to.equal(files.length);
|
|
322
318
|
}
|
|
323
319
|
});
|
|
324
320
|
});
|