@zenfs/core 0.3.5 → 0.4.0
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/FileIndex.d.ts +4 -0
- package/dist/FileIndex.js +3 -3
- package/dist/backends/AsyncMirror.d.ts +3 -5
- package/dist/backends/AsyncMirror.js +7 -6
- package/dist/backends/AsyncStore.d.ts +9 -4
- package/dist/backends/AsyncStore.js +7 -2
- package/dist/backends/Locked.d.ts +8 -8
- package/dist/backends/Locked.js +2 -1
- package/dist/backends/Overlay.d.ts +13 -1
- package/dist/backends/Overlay.js +16 -16
- package/dist/backends/SyncStore.d.ts +8 -5
- package/dist/backends/SyncStore.js +9 -5
- package/dist/backends/backend.js +8 -8
- package/dist/browser.min.js +4 -5
- package/dist/browser.min.js.map +4 -4
- package/dist/cred.d.ts +1 -1
- package/dist/cred.js +1 -1
- package/dist/emulation/callbacks.d.ts +1 -1
- package/dist/emulation/callbacks.js +1 -1
- package/dist/emulation/constants.d.ts +48 -42
- package/dist/emulation/constants.js +68 -59
- package/dist/emulation/dir.d.ts +2 -2
- package/dist/emulation/promises.d.ts +1 -1
- package/dist/emulation/promises.js +6 -6
- package/dist/emulation/sync.d.ts +1 -1
- package/dist/emulation/sync.js +7 -7
- package/dist/file.d.ts +26 -12
- package/dist/file.js +68 -29
- package/dist/filesystem.d.ts +3 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js +4 -5
- package/dist/inode.d.ts +21 -15
- package/dist/inode.js +52 -40
- package/dist/mutex.d.ts +1 -2
- package/dist/mutex.js +1 -1
- package/dist/stats.d.ts +70 -18
- package/dist/stats.js +12 -18
- package/dist/utils.d.ts +3 -8
- package/dist/utils.js +60 -39
- package/package.json +5 -1
- package/readme.md +13 -9
- package/scripts/make-index.js +100 -0
- package/dist/backends/index.d.ts +0 -10
- package/dist/backends/index.js +0 -12
package/dist/FileIndex.d.ts
CHANGED
|
@@ -216,6 +216,10 @@ export declare abstract class SyncFileIndexFS<TIndex> extends SyncFileIndexFS_ba
|
|
|
216
216
|
protected openFileInode(inode: IndexFileInode<TIndex>, path: string, flag: FileFlag): Promise<NoSyncFile<this>>;
|
|
217
217
|
}
|
|
218
218
|
declare const AsyncFileIndexFS_base: (abstract new (...args: any[]) => {
|
|
219
|
+
/**
|
|
220
|
+
* Returns the inode for the indicated item, or null if it does not exist.
|
|
221
|
+
* @param path Name of item in this directory.
|
|
222
|
+
*/
|
|
219
223
|
metadata(): import("./filesystem.js").FileSystemMetadata;
|
|
220
224
|
renameSync(oldPath: string, newPath: string, cred: Cred): void;
|
|
221
225
|
statSync(path: string, cred: Cred): Stats;
|
package/dist/FileIndex.js
CHANGED
|
@@ -40,7 +40,7 @@ export class FileIndex {
|
|
|
40
40
|
}
|
|
41
41
|
else {
|
|
42
42
|
// This inode doesn't have correct size information, noted with -1.
|
|
43
|
-
inode = new IndexFileInode(new Stats(FileType.FILE
|
|
43
|
+
inode = new IndexFileInode(new Stats({ mode: FileType.FILE | 0o555 }));
|
|
44
44
|
}
|
|
45
45
|
if (!parent) {
|
|
46
46
|
continue;
|
|
@@ -219,7 +219,7 @@ export class IndexFileInode extends IndexInode {
|
|
|
219
219
|
return false;
|
|
220
220
|
}
|
|
221
221
|
toStats() {
|
|
222
|
-
return new Stats(FileType.FILE, 4096
|
|
222
|
+
return new Stats({ mode: FileType.FILE | 0o666, size: 4096 });
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
/**
|
|
@@ -244,7 +244,7 @@ export class IndexDirInode extends IndexInode {
|
|
|
244
244
|
* @todo Should probably remove this at some point. This isn't the responsibility of the FileIndex.
|
|
245
245
|
*/
|
|
246
246
|
get stats() {
|
|
247
|
-
return new Stats(FileType.DIRECTORY, 4096
|
|
247
|
+
return new Stats({ mode: FileType.DIRECTORY | 0o555, size: 4096 });
|
|
248
248
|
}
|
|
249
249
|
/**
|
|
250
250
|
* Alias of getStats()
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { FileSystem, FileSystemMetadata } from '../filesystem.js';
|
|
2
2
|
import { File, FileFlag, PreloadFile } from '../file.js';
|
|
3
|
-
import { Stats } from '../stats.js';
|
|
3
|
+
import type { Stats } from '../stats.js';
|
|
4
4
|
import { Cred } from '../cred.js';
|
|
5
5
|
import type { Backend } from './backend.js';
|
|
6
6
|
/**
|
|
7
7
|
* We define our own file to interpose on syncSync() for mirroring purposes.
|
|
8
|
+
* @internal
|
|
8
9
|
*/
|
|
9
|
-
declare class MirrorFile extends PreloadFile<AsyncMirrorFS> {
|
|
10
|
+
export declare class MirrorFile extends PreloadFile<AsyncMirrorFS> {
|
|
10
11
|
constructor(fs: AsyncMirrorFS, path: string, flag: FileFlag, stat: Stats, data: Uint8Array);
|
|
11
12
|
sync(): Promise<void>;
|
|
12
13
|
syncSync(): void;
|
|
@@ -41,9 +42,6 @@ declare const AsyncMirrorFS_base: (abstract new (...args: any[]) => {
|
|
|
41
42
|
link(srcpath: string, dstpath: string, cred: Cred): Promise<void>;
|
|
42
43
|
sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
|
|
43
44
|
renameSync(oldPath: string, newPath: string, cred: Cred): void;
|
|
44
|
-
/**
|
|
45
|
-
* Queue of pending asynchronous operations.
|
|
46
|
-
*/
|
|
47
45
|
statSync(path: string, cred: Cred): Stats;
|
|
48
46
|
openFileSync(path: string, flag: FileFlag, cred: Cred): File;
|
|
49
47
|
createFileSync(path: string, flag: FileFlag, mode: number, cred: Cred): File;
|
|
@@ -5,8 +5,9 @@ import { join } from '../emulation/path.js';
|
|
|
5
5
|
import { Cred } from '../cred.js';
|
|
6
6
|
/**
|
|
7
7
|
* We define our own file to interpose on syncSync() for mirroring purposes.
|
|
8
|
+
* @internal
|
|
8
9
|
*/
|
|
9
|
-
class MirrorFile extends PreloadFile {
|
|
10
|
+
export class MirrorFile extends PreloadFile {
|
|
10
11
|
constructor(fs, path, flag, stat, data) {
|
|
11
12
|
super(fs, path, flag, stat, data);
|
|
12
13
|
}
|
|
@@ -153,8 +154,8 @@ export class AsyncMirrorFS extends Sync(FileSystem) {
|
|
|
153
154
|
* @internal
|
|
154
155
|
*/
|
|
155
156
|
async crossCopyFile(p, mode) {
|
|
156
|
-
const asyncFile = await this._async.openFile(p, FileFlag.
|
|
157
|
-
const syncFile = this._sync.createFileSync(p, FileFlag.
|
|
157
|
+
const asyncFile = await this._async.openFile(p, FileFlag.Get('r'), Cred.Root);
|
|
158
|
+
const syncFile = this._sync.createFileSync(p, FileFlag.Get('w'), mode, Cred.Root);
|
|
158
159
|
try {
|
|
159
160
|
const { size } = await asyncFile.stat();
|
|
160
161
|
const buffer = new Uint8Array(size);
|
|
@@ -230,9 +231,9 @@ export const AsyncMirror = {
|
|
|
230
231
|
sync: {
|
|
231
232
|
type: 'object',
|
|
232
233
|
description: 'The synchronous file system to mirror the asynchronous file system to.',
|
|
233
|
-
validator: async (
|
|
234
|
-
if (!
|
|
235
|
-
throw new ApiError(ErrorCode.EINVAL,
|
|
234
|
+
validator: async (backend) => {
|
|
235
|
+
if ('metadata' in backend && !backend.metadata().synchronous) {
|
|
236
|
+
throw new ApiError(ErrorCode.EINVAL, '"sync" option must be a file system that supports synchronous operations');
|
|
236
237
|
}
|
|
237
238
|
},
|
|
238
239
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Cred } from '../cred.js';
|
|
1
|
+
import type { Cred } from '../cred.js';
|
|
2
2
|
import { PreloadFile, File, FileFlag } from '../file.js';
|
|
3
3
|
import { FileSystem, type FileSystemMetadata } from '../filesystem.js';
|
|
4
4
|
import { type Ino } from '../inode.js';
|
|
5
|
-
import { Stats } from '../stats.js';
|
|
5
|
+
import { type Stats } from '../stats.js';
|
|
6
6
|
/**
|
|
7
7
|
* Represents an *asynchronous* key-value store.
|
|
8
8
|
*/
|
|
@@ -62,6 +62,10 @@ export interface AsyncRWTransaction extends AsyncROTransaction {
|
|
|
62
62
|
*/
|
|
63
63
|
abort(): Promise<void>;
|
|
64
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Async preload file for usage with AsyncStore
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
65
69
|
export declare class AsyncFile extends PreloadFile<AsyncStoreFS> {
|
|
66
70
|
constructor(_fs: AsyncStoreFS, _path: string, _flag: FileFlag, _stat: Stats, contents?: Uint8Array);
|
|
67
71
|
sync(): Promise<void>;
|
|
@@ -93,8 +97,9 @@ declare const AsyncStoreFS_base: (abstract new (...args: any[]) => {
|
|
|
93
97
|
syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
|
|
94
98
|
}) & typeof FileSystem;
|
|
95
99
|
/**
|
|
96
|
-
* An
|
|
97
|
-
*
|
|
100
|
+
* An asynchronous file system which uses an async store to store its data.
|
|
101
|
+
* @see AsyncStore
|
|
102
|
+
* @internal
|
|
98
103
|
*/
|
|
99
104
|
export declare class AsyncStoreFS extends AsyncStoreFS_base {
|
|
100
105
|
protected store: AsyncStore;
|
|
@@ -44,6 +44,10 @@ class LRUCache {
|
|
|
44
44
|
this.cache = [];
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Async preload file for usage with AsyncStore
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
47
51
|
export class AsyncFile extends PreloadFile {
|
|
48
52
|
constructor(_fs, _path, _flag, _stat, contents) {
|
|
49
53
|
super(_fs, _path, _flag, _stat, contents);
|
|
@@ -66,8 +70,9 @@ export class AsyncFile extends PreloadFile {
|
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
/**
|
|
69
|
-
* An
|
|
70
|
-
*
|
|
73
|
+
* An asynchronous file system which uses an async store to store its data.
|
|
74
|
+
* @see AsyncStore
|
|
75
|
+
* @internal
|
|
71
76
|
*/
|
|
72
77
|
export class AsyncStoreFS extends Async(FileSystem) {
|
|
73
78
|
ready() {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { FileFlag } from '../file.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { Cred } from '../cred.js';
|
|
1
|
+
import type { Cred } from '../cred.js';
|
|
2
|
+
import type { File, FileFlag } from '../file.js';
|
|
3
|
+
import type { FileSystem, FileSystemMetadata } from '../filesystem.js';
|
|
4
|
+
import type { Stats } from '../stats.js';
|
|
6
5
|
/**
|
|
7
6
|
* This class serializes access to an underlying async filesystem.
|
|
8
7
|
* For example, on an OverlayFS instance with an async lower
|
|
@@ -11,11 +10,12 @@ import { Cred } from '../cred.js';
|
|
|
11
10
|
* are not executed in a single atomic step. OverlayFS uses this
|
|
12
11
|
* LockedFS to avoid having to reason about the correctness of
|
|
13
12
|
* multiple requests interleaving.
|
|
13
|
+
* @internal
|
|
14
14
|
*/
|
|
15
|
-
export declare class LockedFS<
|
|
16
|
-
readonly fs:
|
|
15
|
+
export declare class LockedFS<FS extends FileSystem> implements FileSystem {
|
|
16
|
+
readonly fs: FS;
|
|
17
17
|
private _mu;
|
|
18
|
-
constructor(fs:
|
|
18
|
+
constructor(fs: FS);
|
|
19
19
|
ready(): Promise<this>;
|
|
20
20
|
metadata(): FileSystemMetadata;
|
|
21
21
|
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
|
package/dist/backends/Locked.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Mutex from '../mutex.js';
|
|
1
|
+
import { Mutex } from '../mutex.js';
|
|
2
2
|
/**
|
|
3
3
|
* This class serializes access to an underlying async filesystem.
|
|
4
4
|
* For example, on an OverlayFS instance with an async lower
|
|
@@ -7,6 +7,7 @@ import Mutex from '../mutex.js';
|
|
|
7
7
|
* are not executed in a single atomic step. OverlayFS uses this
|
|
8
8
|
* LockedFS to avoid having to reason about the correctness of
|
|
9
9
|
* multiple requests interleaving.
|
|
10
|
+
* @internal
|
|
10
11
|
*/
|
|
11
12
|
export class LockedFS {
|
|
12
13
|
constructor(fs) {
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { FileSystem, FileSystemMetadata } from '../filesystem.js';
|
|
2
|
-
import { File, FileFlag } from '../file.js';
|
|
2
|
+
import { File, FileFlag, PreloadFile } from '../file.js';
|
|
3
3
|
import { Stats } from '../stats.js';
|
|
4
4
|
import { LockedFS } from './Locked.js';
|
|
5
5
|
import { Cred } from '../cred.js';
|
|
6
6
|
import type { Backend } from './backend.js';
|
|
7
|
+
/**
|
|
8
|
+
* Overlays a RO file to make it writable.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export declare class OverlayFile extends PreloadFile<UnlockedOverlayFS> implements File {
|
|
12
|
+
constructor(fs: UnlockedOverlayFS, path: string, flag: FileFlag, stats: Stats, data: Uint8Array);
|
|
13
|
+
sync(): Promise<void>;
|
|
14
|
+
syncSync(): void;
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
closeSync(): void;
|
|
17
|
+
}
|
|
7
18
|
/**
|
|
8
19
|
* Configuration options for OverlayFS instances.
|
|
9
20
|
*/
|
|
@@ -95,6 +106,7 @@ export declare class UnlockedOverlayFS extends FileSystem {
|
|
|
95
106
|
* OverlayFS makes a read-only filesystem writable by storing writes on a second,
|
|
96
107
|
* writable file system. Deletes are persisted via metadata stored on the writable
|
|
97
108
|
* file system.
|
|
109
|
+
* @internal
|
|
98
110
|
*/
|
|
99
111
|
export declare class OverlayFS extends LockedFS<UnlockedOverlayFS> {
|
|
100
112
|
ready(): Promise<this>;
|
package/dist/backends/Overlay.js
CHANGED
|
@@ -12,8 +12,9 @@ import { decode, encode } from '../utils.js';
|
|
|
12
12
|
const deletionLogPath = '/.deleted';
|
|
13
13
|
/**
|
|
14
14
|
* Overlays a RO file to make it writable.
|
|
15
|
+
* @internal
|
|
15
16
|
*/
|
|
16
|
-
class OverlayFile extends PreloadFile {
|
|
17
|
+
export class OverlayFile extends PreloadFile {
|
|
17
18
|
constructor(fs, path, flag, stats, data) {
|
|
18
19
|
super(fs, path, flag, stats, data);
|
|
19
20
|
}
|
|
@@ -103,7 +104,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
103
104
|
}
|
|
104
105
|
// Read deletion log, process into metadata.
|
|
105
106
|
try {
|
|
106
|
-
const file = await this._writable.openFile(deletionLogPath, FileFlag.
|
|
107
|
+
const file = await this._writable.openFile(deletionLogPath, FileFlag.Get('r'), Cred.Root);
|
|
107
108
|
const { size } = await file.stat();
|
|
108
109
|
const { buffer } = await file.read(new Uint8Array(size));
|
|
109
110
|
this._deleteLog = decode(buffer);
|
|
@@ -159,9 +160,8 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
159
160
|
if (this._deletedFiles.has(p)) {
|
|
160
161
|
throw ApiError.ENOENT(p);
|
|
161
162
|
}
|
|
162
|
-
const oldStat = Stats
|
|
163
|
-
// Make the oldStat's mode writable. Preserve the topmost part of the
|
|
164
|
-
// mode, which specifies if it is a file or a directory.
|
|
163
|
+
const oldStat = new Stats(await this._readable.stat(p, cred));
|
|
164
|
+
// Make the oldStat's mode writable. Preserve the topmost part of the mode, which specifies the type
|
|
165
165
|
oldStat.mode |= 0o222;
|
|
166
166
|
return oldStat;
|
|
167
167
|
}
|
|
@@ -175,9 +175,8 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
175
175
|
if (this._deletedFiles.has(p)) {
|
|
176
176
|
throw ApiError.ENOENT(p);
|
|
177
177
|
}
|
|
178
|
-
const oldStat = Stats
|
|
179
|
-
// Make the oldStat's mode writable. Preserve the topmost part of the
|
|
180
|
-
// mode, which specifies if it is a file or a directory.
|
|
178
|
+
const oldStat = new Stats(this._readable.statSync(p, cred));
|
|
179
|
+
// Make the oldStat's mode writable. Preserve the topmost part of the mode, which specifies the type.
|
|
181
180
|
oldStat.mode |= 0o222;
|
|
182
181
|
return oldStat;
|
|
183
182
|
}
|
|
@@ -187,8 +186,8 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
187
186
|
return this._writable.openFile(path, flag, cred);
|
|
188
187
|
}
|
|
189
188
|
// Create an OverlayFile.
|
|
190
|
-
const file = await this._readable.openFile(path, FileFlag.
|
|
191
|
-
const stats = Stats
|
|
189
|
+
const file = await this._readable.openFile(path, FileFlag.Get('r'), cred);
|
|
190
|
+
const stats = new Stats(await file.stat());
|
|
192
191
|
const { buffer } = await file.read(new Uint8Array(stats.size));
|
|
193
192
|
return new OverlayFile(this, path, flag, stats, buffer);
|
|
194
193
|
}
|
|
@@ -197,7 +196,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
197
196
|
return this._writable.openFileSync(path, flag, cred);
|
|
198
197
|
}
|
|
199
198
|
// Create an OverlayFile.
|
|
200
|
-
const file = this._readable.openFileSync(path, FileFlag.
|
|
199
|
+
const file = this._readable.openFileSync(path, FileFlag.Get('r'), cred);
|
|
201
200
|
const stats = Stats.clone(file.statSync());
|
|
202
201
|
const data = new Uint8Array(stats.size);
|
|
203
202
|
file.readSync(data);
|
|
@@ -368,7 +367,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
368
367
|
return;
|
|
369
368
|
}
|
|
370
369
|
this._deleteLogUpdatePending = true;
|
|
371
|
-
const log = await this._writable.openFile(deletionLogPath, FileFlag.
|
|
370
|
+
const log = await this._writable.openFile(deletionLogPath, FileFlag.Get('w'), cred);
|
|
372
371
|
try {
|
|
373
372
|
await log.write(encode(this._deleteLog));
|
|
374
373
|
if (this._deleteLogUpdateNeeded) {
|
|
@@ -470,10 +469,10 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
470
469
|
return;
|
|
471
470
|
}
|
|
472
471
|
const data = new Uint8Array(stats.size);
|
|
473
|
-
const readable = this._readable.openFileSync(p, FileFlag.
|
|
472
|
+
const readable = this._readable.openFileSync(p, FileFlag.Get('r'), cred);
|
|
474
473
|
readable.readSync(data);
|
|
475
474
|
readable.closeSync();
|
|
476
|
-
const writable = this._writable.openFileSync(p, FileFlag.
|
|
475
|
+
const writable = this._writable.openFileSync(p, FileFlag.Get('w'), cred);
|
|
477
476
|
writable.writeSync(data);
|
|
478
477
|
writable.closeSync();
|
|
479
478
|
}
|
|
@@ -484,10 +483,10 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
484
483
|
return;
|
|
485
484
|
}
|
|
486
485
|
const data = new Uint8Array(stats.size);
|
|
487
|
-
const readable = await this._readable.openFile(p, FileFlag.
|
|
486
|
+
const readable = await this._readable.openFile(p, FileFlag.Get('r'), cred);
|
|
488
487
|
await readable.read(data);
|
|
489
488
|
await readable.close();
|
|
490
|
-
const writable = await this._writable.openFile(p, FileFlag.
|
|
489
|
+
const writable = await this._writable.openFile(p, FileFlag.Get('w'), cred);
|
|
491
490
|
await writable.write(data);
|
|
492
491
|
await writable.close();
|
|
493
492
|
}
|
|
@@ -496,6 +495,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
496
495
|
* OverlayFS makes a read-only filesystem writable by storing writes on a second,
|
|
497
496
|
* writable file system. Deletes are persisted via metadata stored on the writable
|
|
498
497
|
* file system.
|
|
498
|
+
* @internal
|
|
499
499
|
*/
|
|
500
500
|
export class OverlayFS extends LockedFS {
|
|
501
501
|
async ready() {
|
|
@@ -2,7 +2,7 @@ import { Cred } from '../cred.js';
|
|
|
2
2
|
import { FileFlag, PreloadFile } from '../file.js';
|
|
3
3
|
import { type FileSystemMetadata, FileSystem } from '../filesystem.js';
|
|
4
4
|
import { type Ino, Inode } from '../inode.js';
|
|
5
|
-
import { Stats, FileType } from '../stats.js';
|
|
5
|
+
import { type Stats, FileType } from '../stats.js';
|
|
6
6
|
/**
|
|
7
7
|
* Represents a *synchronous* key-value store.
|
|
8
8
|
*/
|
|
@@ -112,6 +112,10 @@ export interface SyncStoreOptions {
|
|
|
112
112
|
*/
|
|
113
113
|
store: SyncStore;
|
|
114
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* File backend by a SyncStoreFS
|
|
117
|
+
* @internal
|
|
118
|
+
*/
|
|
115
119
|
export declare class SyncStoreFile extends PreloadFile<SyncStoreFS> {
|
|
116
120
|
constructor(_fs: SyncStoreFS, _path: string, _flag: FileFlag, _stat: Stats, contents?: Uint8Array);
|
|
117
121
|
sync(): Promise<void>;
|
|
@@ -146,13 +150,12 @@ declare const SyncStoreFS_base: (abstract new (...args: any[]) => {
|
|
|
146
150
|
syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
|
|
147
151
|
}) & typeof FileSystem;
|
|
148
152
|
/**
|
|
149
|
-
* A
|
|
150
|
-
* underlying key-value store.
|
|
153
|
+
* A synchronous key-value file system. Uses a SyncStore to store the data.
|
|
151
154
|
*
|
|
152
|
-
* We use a unique ID for each node in the file system. The root node has a
|
|
153
|
-
* fixed ID.
|
|
155
|
+
* We use a unique ID for each node in the file system. The root node has a fixed ID.
|
|
154
156
|
* @todo Introduce Node ID caching.
|
|
155
157
|
* @todo Check modes.
|
|
158
|
+
* @internal
|
|
156
159
|
*/
|
|
157
160
|
export declare class SyncStoreFS extends SyncStoreFS_base {
|
|
158
161
|
protected store: SyncStore;
|
|
@@ -76,6 +76,10 @@ export class SimpleSyncRWTransaction {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* File backend by a SyncStoreFS
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
79
83
|
export class SyncStoreFile extends PreloadFile {
|
|
80
84
|
constructor(_fs, _path, _flag, _stat, contents) {
|
|
81
85
|
super(_fs, _path, _flag, _stat, contents);
|
|
@@ -97,13 +101,12 @@ export class SyncStoreFile extends PreloadFile {
|
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
103
|
/**
|
|
100
|
-
* A
|
|
101
|
-
* underlying key-value store.
|
|
104
|
+
* A synchronous key-value file system. Uses a SyncStore to store the data.
|
|
102
105
|
*
|
|
103
|
-
* We use a unique ID for each node in the file system. The root node has a
|
|
104
|
-
* fixed ID.
|
|
106
|
+
* We use a unique ID for each node in the file system. The root node has a fixed ID.
|
|
105
107
|
* @todo Introduce Node ID caching.
|
|
106
108
|
* @todo Check modes.
|
|
109
|
+
* @internal
|
|
107
110
|
*/
|
|
108
111
|
export class SyncStoreFS extends Sync(FileSystem) {
|
|
109
112
|
constructor(options) {
|
|
@@ -347,7 +350,8 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
347
350
|
if (!data) {
|
|
348
351
|
throw ApiError.ENOENT(p);
|
|
349
352
|
}
|
|
350
|
-
|
|
353
|
+
const inode = new Inode(data.buffer);
|
|
354
|
+
return inode;
|
|
351
355
|
}
|
|
352
356
|
/**
|
|
353
357
|
* Given the Inode of a directory, retrieves the corresponding directory listing.
|
package/dist/backends/backend.js
CHANGED
|
@@ -16,7 +16,7 @@ export async function checkOptions(backend, opts) {
|
|
|
16
16
|
}
|
|
17
17
|
// Check for required options.
|
|
18
18
|
for (const [optName, opt] of Object.entries(backend.options)) {
|
|
19
|
-
const providedValue = opts
|
|
19
|
+
const providedValue = opts?.[optName];
|
|
20
20
|
if (providedValue === undefined || providedValue === null) {
|
|
21
21
|
if (!opt.required) {
|
|
22
22
|
continue;
|
|
@@ -36,7 +36,7 @@ export async function checkOptions(backend, opts) {
|
|
|
36
36
|
// Option provided, check type.
|
|
37
37
|
const typeMatches = Array.isArray(opt.type) ? opt.type.indexOf(typeof providedValue) != -1 : typeof providedValue == opt.type;
|
|
38
38
|
if (!typeMatches) {
|
|
39
|
-
throw new ApiError(ErrorCode.EINVAL, `${backend.name}: Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}
|
|
39
|
+
throw new ApiError(ErrorCode.EINVAL, `${backend.name}: Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}`);
|
|
40
40
|
}
|
|
41
41
|
if (opt.validator) {
|
|
42
42
|
await opt.validator(providedValue);
|
|
@@ -60,13 +60,13 @@ export function isBackendConfig(arg) {
|
|
|
60
60
|
* @param config A BackendConfig object.
|
|
61
61
|
*/
|
|
62
62
|
export async function resolveBackendConfig(options) {
|
|
63
|
-
const { backend } = options;
|
|
64
|
-
if (!backend) {
|
|
65
|
-
throw new ApiError(ErrorCode.EPERM, 'Missing backend');
|
|
66
|
-
}
|
|
67
63
|
if (typeof options !== 'object' || options == null) {
|
|
68
64
|
throw new ApiError(ErrorCode.EINVAL, 'Invalid options on configuration object.');
|
|
69
65
|
}
|
|
66
|
+
const { backend } = options;
|
|
67
|
+
if (!isBackend(backend)) {
|
|
68
|
+
throw new ApiError(ErrorCode.EINVAL, 'Missing or invalid backend');
|
|
69
|
+
}
|
|
70
70
|
const props = Object.keys(options).filter(k => k != 'backend');
|
|
71
71
|
for (const prop of props) {
|
|
72
72
|
let option = options[prop];
|
|
@@ -77,8 +77,8 @@ export async function resolveBackendConfig(options) {
|
|
|
77
77
|
options[prop] = await resolveBackendConfig(option);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
if (!backend) {
|
|
81
|
-
throw new ApiError(ErrorCode.EPERM,
|
|
80
|
+
if (!backend.isAvailable()) {
|
|
81
|
+
throw new ApiError(ErrorCode.EPERM, 'Backend not available: ' + backend);
|
|
82
82
|
}
|
|
83
83
|
checkOptions(backend, options);
|
|
84
84
|
const fs = backend.create(options);
|