@zenfs/core 1.11.4 → 2.0.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/backends/backend.d.ts +19 -15
- package/dist/backends/backend.js +31 -15
- package/dist/backends/cow.d.ts +20 -30
- package/dist/backends/cow.js +52 -142
- package/dist/backends/fetch.d.ts +1 -0
- package/dist/backends/fetch.js +3 -1
- package/dist/backends/index.d.ts +1 -1
- package/dist/backends/index.js +1 -1
- package/dist/backends/memory.d.ts +5 -7
- package/dist/backends/memory.js +2 -3
- package/dist/backends/passthrough.d.ts +19 -22
- package/dist/backends/passthrough.js +85 -160
- package/dist/backends/port.d.ts +207 -0
- package/dist/backends/port.js +297 -0
- package/dist/backends/single_buffer.d.ts +11 -5
- package/dist/backends/single_buffer.js +18 -12
- package/dist/backends/store/fs.d.ts +11 -27
- package/dist/backends/store/fs.js +67 -91
- package/dist/backends/store/store.d.ts +7 -12
- package/dist/config.d.ts +1 -10
- package/dist/config.js +7 -8
- package/dist/context.d.ts +8 -21
- package/dist/context.js +33 -10
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/contexts.d.ts +63 -0
- package/dist/internal/contexts.js +15 -0
- package/dist/internal/credentials.d.ts +2 -11
- package/dist/internal/credentials.js +0 -19
- package/dist/internal/devices.d.ts +18 -80
- package/dist/internal/devices.js +76 -279
- package/dist/internal/file_index.js +3 -3
- package/dist/internal/filesystem.d.ts +31 -89
- package/dist/internal/filesystem.js +21 -20
- package/dist/internal/index.d.ts +0 -1
- package/dist/internal/index.js +0 -1
- package/dist/internal/index_fs.d.ts +12 -30
- package/dist/internal/index_fs.js +23 -55
- package/dist/internal/inode.d.ts +147 -9
- package/dist/internal/inode.js +333 -25
- package/dist/internal/log.d.ts +19 -13
- package/dist/internal/log.js +81 -80
- package/dist/mixins/async.js +26 -90
- package/dist/mixins/mutexed.d.ts +17 -16
- package/dist/mixins/mutexed.js +29 -31
- package/dist/mixins/readonly.d.ts +7 -6
- package/dist/mixins/readonly.js +6 -0
- package/dist/mixins/sync.js +8 -8
- package/dist/{vfs/path.d.ts → path.d.ts} +3 -4
- package/dist/{vfs/path.js → path.js} +6 -9
- package/dist/readline.d.ts +134 -0
- package/dist/readline.js +623 -0
- package/dist/utils.d.ts +4 -35
- package/dist/utils.js +8 -73
- package/dist/vfs/acl.d.ts +42 -0
- package/dist/vfs/acl.js +249 -0
- package/dist/vfs/async.d.ts +7 -21
- package/dist/vfs/async.js +19 -19
- package/dist/vfs/config.d.ts +6 -18
- package/dist/vfs/config.js +8 -18
- package/dist/vfs/dir.d.ts +3 -3
- package/dist/vfs/dir.js +9 -8
- package/dist/vfs/file.d.ts +106 -0
- package/dist/vfs/file.js +235 -0
- package/dist/vfs/flags.d.ts +19 -0
- package/dist/vfs/flags.js +62 -0
- package/dist/vfs/index.d.ts +4 -10
- package/dist/vfs/index.js +4 -13
- package/dist/vfs/ioctl.d.ts +87 -0
- package/dist/vfs/ioctl.js +304 -0
- package/dist/vfs/promises.d.ts +78 -16
- package/dist/vfs/promises.js +273 -122
- package/dist/vfs/shared.d.ts +7 -26
- package/dist/vfs/shared.js +25 -53
- package/dist/{stats.d.ts → vfs/stats.d.ts} +14 -28
- package/dist/{stats.js → vfs/stats.js} +11 -66
- package/dist/vfs/streams.d.ts +1 -0
- package/dist/vfs/streams.js +24 -19
- package/dist/vfs/sync.d.ts +4 -3
- package/dist/vfs/sync.js +143 -128
- package/dist/vfs/watchers.d.ts +2 -2
- package/dist/vfs/watchers.js +6 -6
- package/dist/vfs/xattr.d.ts +116 -0
- package/dist/vfs/xattr.js +218 -0
- package/package.json +3 -3
- package/readme.md +1 -1
- package/tests/backend/config.worker.js +4 -1
- package/tests/backend/fetch.test.ts +3 -0
- package/tests/backend/port.test.ts +21 -35
- package/tests/backend/remote.worker.js +4 -1
- package/tests/backend/single-buffer.test.ts +24 -0
- package/tests/common/context.test.ts +1 -1
- package/tests/common/handle.test.ts +17 -12
- package/tests/common/path.test.ts +1 -1
- package/tests/common/readline.test.ts +104 -0
- package/tests/common.ts +4 -19
- package/tests/fetch/fetch.ts +1 -1
- package/tests/fs/links.test.ts +1 -1
- package/tests/fs/permissions.test.ts +7 -6
- package/tests/fs/readFile.test.ts +3 -3
- package/tests/fs/stat.test.ts +6 -6
- package/tests/fs/streams.test.ts +2 -11
- package/tests/fs/times.test.ts +1 -1
- package/tests/fs/xattr.test.ts +85 -0
- package/tests/logs.js +22 -0
- package/tests/setup/context.ts +1 -1
- package/tests/setup/index.ts +3 -3
- package/tests/setup/port.ts +1 -1
- package/dist/backends/port/fs.d.ts +0 -84
- package/dist/backends/port/fs.js +0 -151
- package/dist/backends/port/rpc.d.ts +0 -77
- package/dist/backends/port/rpc.js +0 -100
- package/dist/backends/store/simple.d.ts +0 -20
- package/dist/backends/store/simple.js +0 -13
- package/dist/internal/file.d.ts +0 -359
- package/dist/internal/file.js +0 -751
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { RequiredKeys } from 'utilium';
|
|
2
2
|
import type { FileSystem } from '../internal/filesystem.js';
|
|
3
|
-
type OptionType = 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' |
|
|
3
|
+
type OptionType = 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | string | ((arg: any) => boolean) | {
|
|
4
|
+
[Symbol.hasInstance](instance: any): boolean;
|
|
5
|
+
toString(): string;
|
|
6
|
+
};
|
|
4
7
|
/**
|
|
5
8
|
* Resolves the type of Backend.options from the options interface
|
|
6
9
|
* @category Backends and Configuration
|
|
@@ -8,24 +11,17 @@ type OptionType = 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undef
|
|
|
8
11
|
export type OptionsConfig<T> = {
|
|
9
12
|
[K in keyof T]: {
|
|
10
13
|
/**
|
|
11
|
-
* The
|
|
14
|
+
* The type of the option. Can be a:
|
|
15
|
+
* - string given by `typeof`
|
|
16
|
+
* - string that is the name of the class (e.g. `'Map'`)
|
|
17
|
+
* - object with a `Symbol.hasInstance` property
|
|
18
|
+
* - function that returns a boolean
|
|
12
19
|
*/
|
|
13
20
|
type: OptionType | readonly OptionType[];
|
|
14
|
-
/**
|
|
15
|
-
* Description of the option. Used in error messages and documentation.
|
|
16
|
-
* @deprecated
|
|
17
|
-
*/
|
|
18
|
-
description?: string;
|
|
19
21
|
/**
|
|
20
22
|
* Whether or not the option is required (optional can be set to null or undefined). Defaults to false.
|
|
21
23
|
*/
|
|
22
24
|
required: K extends RequiredKeys<T> ? true : false;
|
|
23
|
-
/**
|
|
24
|
-
* A custom validation function to check if the option is valid.
|
|
25
|
-
* When async, resolves if valid and rejects if not.
|
|
26
|
-
* When sync, it will throw an error if not valid.
|
|
27
|
-
*/
|
|
28
|
-
validator?(opt: T[K]): void | Promise<void>;
|
|
29
25
|
};
|
|
30
26
|
};
|
|
31
27
|
/**
|
|
@@ -64,7 +60,7 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
|
|
|
64
60
|
* 'false' if the API is unavailable
|
|
65
61
|
*
|
|
66
62
|
*/
|
|
67
|
-
isAvailable?(): boolean | Promise<boolean>;
|
|
63
|
+
isAvailable?(config: TOptions): boolean | Promise<boolean>;
|
|
68
64
|
}
|
|
69
65
|
/**
|
|
70
66
|
* Gets the options type of a backend
|
|
@@ -83,12 +79,20 @@ export type FilesystemOf<T extends Backend> = T extends Backend<infer FS> ? FS :
|
|
|
83
79
|
* @internal
|
|
84
80
|
*/
|
|
85
81
|
export declare function isBackend(arg: unknown): arg is Backend;
|
|
82
|
+
/**
|
|
83
|
+
* Use a function as the type of an option, but don't treat it as a class.
|
|
84
|
+
*
|
|
85
|
+
* Optionally sets the name of a function, useful for error messages.
|
|
86
|
+
* @category Backends and Configuration
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
export declare function _fnOpt<const T>(name: string | null | undefined, fn: (arg: T) => boolean): (arg: T) => boolean;
|
|
86
90
|
/**
|
|
87
91
|
* Checks that `options` object is valid for the file system options.
|
|
88
92
|
* @category Backends and Configuration
|
|
89
93
|
* @internal
|
|
90
94
|
*/
|
|
91
|
-
export declare function checkOptions<T extends Backend>(backend: T, options: Record<string, unknown>):
|
|
95
|
+
export declare function checkOptions<T extends Backend>(backend: T, options: Record<string, unknown>): void;
|
|
92
96
|
/**
|
|
93
97
|
* Specifies a file system backend type and its options.
|
|
94
98
|
*
|
package/dist/backends/backend.js
CHANGED
|
@@ -7,12 +7,25 @@ import { debug, err } from '../internal/log.js';
|
|
|
7
7
|
export function isBackend(arg) {
|
|
8
8
|
return arg != null && typeof arg == 'object' && 'create' in arg && typeof arg.create == 'function';
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Use a function as the type of an option, but don't treat it as a class.
|
|
12
|
+
*
|
|
13
|
+
* Optionally sets the name of a function, useful for error messages.
|
|
14
|
+
* @category Backends and Configuration
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export function _fnOpt(name, fn) {
|
|
18
|
+
Object.defineProperty(fn, 'prototype', { value: undefined });
|
|
19
|
+
if (name)
|
|
20
|
+
Object.defineProperty(fn, 'name', { value: name });
|
|
21
|
+
return fn;
|
|
22
|
+
}
|
|
10
23
|
/**
|
|
11
24
|
* Checks that `options` object is valid for the file system options.
|
|
12
25
|
* @category Backends and Configuration
|
|
13
26
|
* @internal
|
|
14
27
|
*/
|
|
15
|
-
export
|
|
28
|
+
export function checkOptions(backend, options) {
|
|
16
29
|
if (typeof options != 'object' || options === null) {
|
|
17
30
|
throw err(new ErrnoError(Errno.EINVAL, 'Invalid options'));
|
|
18
31
|
}
|
|
@@ -21,24 +34,27 @@ export async function checkOptions(backend, options) {
|
|
|
21
34
|
const value = options === null || options === void 0 ? void 0 : options[optName];
|
|
22
35
|
if (value === undefined || value === null) {
|
|
23
36
|
if (!opt.required) {
|
|
24
|
-
debug('
|
|
37
|
+
debug('Using default for option: ' + optName);
|
|
25
38
|
continue;
|
|
26
39
|
}
|
|
27
40
|
throw err(new ErrnoError(Errno.EINVAL, 'Missing required option: ' + optName));
|
|
28
41
|
}
|
|
29
|
-
const isType = (type, _ = value) =>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
//
|
|
42
|
+
const isType = (type, _ = value) => {
|
|
43
|
+
var _a;
|
|
44
|
+
return typeof type == 'function'
|
|
45
|
+
? Symbol.hasInstance in type && type.prototype
|
|
46
|
+
? value instanceof type
|
|
47
|
+
: type(value)
|
|
48
|
+
: typeof value === type || ((_a = value === null || value === void 0 ? void 0 : value.constructor) === null || _a === void 0 ? void 0 : _a.name) === type;
|
|
49
|
+
};
|
|
50
|
+
if (Array.isArray(opt.type) ? opt.type.some(v => isType(v)) : isType(opt.type))
|
|
51
|
+
continue;
|
|
52
|
+
// The type of the value as a string
|
|
53
|
+
const type = typeof value == 'object' && 'constructor' in value ? value.constructor.name : typeof value;
|
|
54
|
+
// The expected type (as a string)
|
|
55
|
+
const name = (type) => (typeof type == 'function' ? (type.name != 'type' ? type.name : type.toString()) : type);
|
|
56
|
+
const expected = Array.isArray(opt.type) ? `one of ${opt.type.map(name).join(', ')}` : name(opt.type);
|
|
57
|
+
throw err(new ErrnoError(Errno.EINVAL, `Incorrect type for "${optName}": ${type} (expected ${expected})`));
|
|
42
58
|
}
|
|
43
59
|
}
|
|
44
60
|
/**
|
package/dist/backends/cow.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import type { File } from '../internal/file.js';
|
|
2
1
|
import type { CreationOptions, StreamOptions, UsageInfo } from '../internal/filesystem.js';
|
|
3
2
|
import type { InodeLike } from '../internal/inode.js';
|
|
4
|
-
import type { Stats } from '../stats.js';
|
|
5
|
-
import { FileSystem } from '../internal/filesystem.js';
|
|
6
3
|
import { EventEmitter } from 'eventemitter3';
|
|
7
4
|
import { type MountConfiguration } from '../config.js';
|
|
5
|
+
import { FileSystem } from '../internal/filesystem.js';
|
|
8
6
|
/**
|
|
9
7
|
* Configuration options for CoW.
|
|
10
8
|
* @category Backends and Configuration
|
|
@@ -17,16 +15,14 @@ export interface CopyOnWriteOptions {
|
|
|
17
15
|
/** @see {@link Journal} */
|
|
18
16
|
journal?: Journal;
|
|
19
17
|
}
|
|
20
|
-
/**
|
|
21
|
-
* @hidden @deprecated use `CopyOnWriteOptions`
|
|
22
|
-
*/
|
|
23
|
-
export type OverlayOptions = CopyOnWriteOptions;
|
|
24
18
|
declare const journalOperations: readonly ["delete"];
|
|
25
19
|
/**
|
|
20
|
+
* @category Internals
|
|
26
21
|
* @internal
|
|
27
22
|
*/
|
|
28
23
|
export type JournalOperation = (typeof journalOperations)[number];
|
|
29
24
|
/**
|
|
25
|
+
* @category Internals
|
|
30
26
|
* @internal
|
|
31
27
|
*/
|
|
32
28
|
export interface JournalEntry {
|
|
@@ -35,6 +31,7 @@ export interface JournalEntry {
|
|
|
35
31
|
}
|
|
36
32
|
/**
|
|
37
33
|
* Tracks various operations for the CoW backend
|
|
34
|
+
* @category Internals
|
|
38
35
|
* @internal
|
|
39
36
|
*/
|
|
40
37
|
export declare class Journal extends EventEmitter<{
|
|
@@ -54,6 +51,7 @@ export declare class Journal extends EventEmitter<{
|
|
|
54
51
|
/**
|
|
55
52
|
* Using a readable file system as a base, writes are done to a writable file system.
|
|
56
53
|
* @internal
|
|
54
|
+
* @category Internals
|
|
57
55
|
*/
|
|
58
56
|
export declare class CopyOnWriteFS extends FileSystem {
|
|
59
57
|
/** The file system that initially populates this file system. */
|
|
@@ -75,28 +73,28 @@ export declare class CopyOnWriteFS extends FileSystem {
|
|
|
75
73
|
* @todo Consider trying to track information on the writable as well
|
|
76
74
|
*/
|
|
77
75
|
usage(): UsageInfo;
|
|
78
|
-
sync(path: string
|
|
79
|
-
syncSync(path: string
|
|
76
|
+
sync(path: string): Promise<void>;
|
|
77
|
+
syncSync(path: string): void;
|
|
80
78
|
read(path: string, buffer: Uint8Array, offset: number, end: number): Promise<void>;
|
|
81
79
|
readSync(path: string, buffer: Uint8Array, offset: number, end: number): void;
|
|
82
80
|
write(path: string, buffer: Uint8Array, offset: number): Promise<void>;
|
|
83
81
|
writeSync(path: string, buffer: Uint8Array, offset: number): void;
|
|
84
82
|
rename(oldPath: string, newPath: string): Promise<void>;
|
|
85
83
|
renameSync(oldPath: string, newPath: string): void;
|
|
86
|
-
stat(path: string): Promise<
|
|
87
|
-
statSync(path: string):
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
createFile(path: string,
|
|
91
|
-
createFileSync(path: string,
|
|
84
|
+
stat(path: string): Promise<InodeLike>;
|
|
85
|
+
statSync(path: string): InodeLike;
|
|
86
|
+
touch(path: string, metadata: InodeLike): Promise<void>;
|
|
87
|
+
touchSync(path: string, metadata: InodeLike): void;
|
|
88
|
+
createFile(path: string, options: CreationOptions): Promise<InodeLike>;
|
|
89
|
+
createFileSync(path: string, options: CreationOptions): InodeLike;
|
|
92
90
|
link(srcpath: string, dstpath: string): Promise<void>;
|
|
93
91
|
linkSync(srcpath: string, dstpath: string): void;
|
|
94
92
|
unlink(path: string): Promise<void>;
|
|
95
93
|
unlinkSync(path: string): void;
|
|
96
94
|
rmdir(path: string): Promise<void>;
|
|
97
95
|
rmdirSync(path: string): void;
|
|
98
|
-
mkdir(path: string,
|
|
99
|
-
mkdirSync(path: string,
|
|
96
|
+
mkdir(path: string, options: CreationOptions): Promise<InodeLike>;
|
|
97
|
+
mkdirSync(path: string, options: CreationOptions): InodeLike;
|
|
100
98
|
readdir(path: string): Promise<string[]>;
|
|
101
99
|
readdirSync(path: string): string[];
|
|
102
100
|
streamRead(path: string, options: StreamOptions): ReadableStream;
|
|
@@ -125,11 +123,6 @@ export declare class CopyOnWriteFS extends FileSystem {
|
|
|
125
123
|
private copyToWritableSync;
|
|
126
124
|
private copyToWritable;
|
|
127
125
|
}
|
|
128
|
-
/**
|
|
129
|
-
* @hidden @deprecated use `CopyOnWriteFS`
|
|
130
|
-
*/
|
|
131
|
-
export declare class OverlayFS extends CopyOnWriteFS {
|
|
132
|
-
}
|
|
133
126
|
declare const _CopyOnWrite: {
|
|
134
127
|
readonly name: "CopyOnWrite";
|
|
135
128
|
readonly options: {
|
|
@@ -149,21 +142,18 @@ declare const _CopyOnWrite: {
|
|
|
149
142
|
readonly create: (options: CopyOnWriteOptions) => Promise<CopyOnWriteFS>;
|
|
150
143
|
};
|
|
151
144
|
type _CopyOnWrite = typeof _CopyOnWrite;
|
|
152
|
-
export interface CopyOnWrite extends _CopyOnWrite {
|
|
153
|
-
}
|
|
154
145
|
/**
|
|
155
146
|
* Overlay makes a read-only filesystem writable by storing writes on a second, writable file system.
|
|
156
147
|
* Deletes are persisted via metadata stored on the writable file system.
|
|
157
148
|
* @category Backends and Configuration
|
|
158
|
-
* @internal
|
|
159
149
|
*/
|
|
160
|
-
export
|
|
161
|
-
export interface Overlay extends _CopyOnWrite {
|
|
150
|
+
export interface CopyOnWrite extends _CopyOnWrite {
|
|
162
151
|
}
|
|
163
152
|
/**
|
|
164
|
-
*
|
|
153
|
+
* Overlay makes a read-only filesystem writable by storing writes on a second, writable file system.
|
|
154
|
+
* Deletes are persisted via metadata stored on the writable file system.
|
|
165
155
|
* @category Backends and Configuration
|
|
166
|
-
* @internal
|
|
156
|
+
* @internal
|
|
167
157
|
*/
|
|
168
|
-
export declare const
|
|
158
|
+
export declare const CopyOnWrite: CopyOnWrite;
|
|
169
159
|
export {};
|
package/dist/backends/cow.js
CHANGED
|
@@ -1,63 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
if (value !== null && value !== void 0) {
|
|
3
|
-
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
-
var dispose, inner;
|
|
5
|
-
if (async) {
|
|
6
|
-
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
-
dispose = value[Symbol.asyncDispose];
|
|
8
|
-
}
|
|
9
|
-
if (dispose === void 0) {
|
|
10
|
-
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
-
dispose = value[Symbol.dispose];
|
|
12
|
-
if (async) inner = dispose;
|
|
13
|
-
}
|
|
14
|
-
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
-
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
-
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
-
}
|
|
18
|
-
else if (async) {
|
|
19
|
-
env.stack.push({ async: true });
|
|
20
|
-
}
|
|
21
|
-
return value;
|
|
22
|
-
};
|
|
23
|
-
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
-
return function (env) {
|
|
25
|
-
function fail(e) {
|
|
26
|
-
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
-
env.hasError = true;
|
|
28
|
-
}
|
|
29
|
-
var r, s = 0;
|
|
30
|
-
function next() {
|
|
31
|
-
while (r = env.stack.pop()) {
|
|
32
|
-
try {
|
|
33
|
-
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
-
if (r.dispose) {
|
|
35
|
-
var result = r.dispose.call(r.value);
|
|
36
|
-
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
-
}
|
|
38
|
-
else s |= 1;
|
|
39
|
-
}
|
|
40
|
-
catch (e) {
|
|
41
|
-
fail(e);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
-
if (env.hasError) throw env.error;
|
|
46
|
-
}
|
|
47
|
-
return next();
|
|
48
|
-
};
|
|
49
|
-
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
-
var e = new Error(message);
|
|
51
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
-
});
|
|
1
|
+
import { EventEmitter } from 'eventemitter3';
|
|
53
2
|
import { canary } from 'utilium';
|
|
3
|
+
import { resolveMountConfig } from '../config.js';
|
|
54
4
|
import { Errno, ErrnoError } from '../internal/error.js';
|
|
55
|
-
import { LazyFile } from '../internal/file.js';
|
|
56
5
|
import { FileSystem } from '../internal/filesystem.js';
|
|
6
|
+
import { isDirectory } from '../internal/inode.js';
|
|
57
7
|
import { debug, err, warn } from '../internal/log.js';
|
|
58
|
-
import { dirname, join } from '../
|
|
59
|
-
import { EventEmitter } from 'eventemitter3';
|
|
60
|
-
import { resolveMountConfig } from '../config.js';
|
|
8
|
+
import { dirname, join } from '../path.js';
|
|
61
9
|
const journalOperations = ['delete'];
|
|
62
10
|
/** Because TS doesn't work right w/o it */
|
|
63
11
|
function isJournalOp(op) {
|
|
@@ -67,6 +15,7 @@ const maxOpLength = Math.max(...journalOperations.map(op => op.length));
|
|
|
67
15
|
const journalMagicString = '#journal@v0\n';
|
|
68
16
|
/**
|
|
69
17
|
* Tracks various operations for the CoW backend
|
|
18
|
+
* @category Internals
|
|
70
19
|
* @internal
|
|
71
20
|
*/
|
|
72
21
|
export class Journal extends EventEmitter {
|
|
@@ -123,6 +72,7 @@ export class Journal extends EventEmitter {
|
|
|
123
72
|
/**
|
|
124
73
|
* Using a readable file system as a base, writes are done to a writable file system.
|
|
125
74
|
* @internal
|
|
75
|
+
* @category Internals
|
|
126
76
|
*/
|
|
127
77
|
export class CopyOnWriteFS extends FileSystem {
|
|
128
78
|
async ready() {
|
|
@@ -154,13 +104,13 @@ export class CopyOnWriteFS extends FileSystem {
|
|
|
154
104
|
usage() {
|
|
155
105
|
return this.readable.usage();
|
|
156
106
|
}
|
|
157
|
-
async sync(path
|
|
107
|
+
async sync(path) {
|
|
158
108
|
await this.copyForWrite(path);
|
|
159
|
-
await this.writable.sync(path
|
|
109
|
+
await this.writable.sync(path);
|
|
160
110
|
}
|
|
161
|
-
syncSync(path
|
|
111
|
+
syncSync(path) {
|
|
162
112
|
this.copyForWriteSync(path);
|
|
163
|
-
this.writable.syncSync(path
|
|
113
|
+
this.writable.syncSync(path);
|
|
164
114
|
}
|
|
165
115
|
async read(path, buffer, offset, end) {
|
|
166
116
|
return (await this.writable.exists(path))
|
|
@@ -226,27 +176,21 @@ export class CopyOnWriteFS extends FileSystem {
|
|
|
226
176
|
return oldStat;
|
|
227
177
|
}
|
|
228
178
|
}
|
|
229
|
-
async
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
const stats = await this.readable.stat(path);
|
|
234
|
-
return new LazyFile(this, path, flag, stats);
|
|
179
|
+
async touch(path, metadata) {
|
|
180
|
+
await this.copyForWrite(path);
|
|
181
|
+
await this.writable.touch(path, metadata);
|
|
235
182
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
const stats = this.readable.statSync(path);
|
|
241
|
-
return new LazyFile(this, path, flag, stats);
|
|
183
|
+
touchSync(path, metadata) {
|
|
184
|
+
this.copyForWriteSync(path);
|
|
185
|
+
this.writable.touchSync(path, metadata);
|
|
242
186
|
}
|
|
243
|
-
async createFile(path,
|
|
244
|
-
await this.
|
|
245
|
-
return this.
|
|
187
|
+
async createFile(path, options) {
|
|
188
|
+
await this.createParentDirectories(path);
|
|
189
|
+
return await this.writable.createFile(path, options);
|
|
246
190
|
}
|
|
247
|
-
createFileSync(path,
|
|
248
|
-
this.
|
|
249
|
-
return this.
|
|
191
|
+
createFileSync(path, options) {
|
|
192
|
+
this.createParentDirectoriesSync(path);
|
|
193
|
+
return this.writable.createFileSync(path, options);
|
|
250
194
|
}
|
|
251
195
|
async link(srcpath, dstpath) {
|
|
252
196
|
await this.copyForWrite(srcpath);
|
|
@@ -311,17 +255,17 @@ export class CopyOnWriteFS extends FileSystem {
|
|
|
311
255
|
}
|
|
312
256
|
this.journal.add('delete', path);
|
|
313
257
|
}
|
|
314
|
-
async mkdir(path,
|
|
258
|
+
async mkdir(path, options) {
|
|
315
259
|
if (await this.exists(path))
|
|
316
260
|
throw ErrnoError.With('EEXIST', path, 'mkdir');
|
|
317
261
|
await this.createParentDirectories(path);
|
|
318
|
-
await this.writable.mkdir(path,
|
|
262
|
+
return await this.writable.mkdir(path, options);
|
|
319
263
|
}
|
|
320
|
-
mkdirSync(path,
|
|
264
|
+
mkdirSync(path, options) {
|
|
321
265
|
if (this.existsSync(path))
|
|
322
266
|
throw ErrnoError.With('EEXIST', path, 'mkdir');
|
|
323
267
|
this.createParentDirectoriesSync(path);
|
|
324
|
-
this.writable.mkdirSync(path,
|
|
268
|
+
return this.writable.mkdirSync(path, options);
|
|
325
269
|
}
|
|
326
270
|
async readdir(path) {
|
|
327
271
|
if (this.isDeleted(path) || !(await this.exists(path)))
|
|
@@ -366,8 +310,7 @@ export class CopyOnWriteFS extends FileSystem {
|
|
|
366
310
|
if (toCreate.length)
|
|
367
311
|
debug('COW: Creating parent directories: ' + toCreate.join(', '));
|
|
368
312
|
for (const path of toCreate.reverse()) {
|
|
369
|
-
|
|
370
|
-
this.writable.mkdirSync(path, mode, { uid, gid });
|
|
313
|
+
this.writable.mkdirSync(path, this.statSync(path));
|
|
371
314
|
}
|
|
372
315
|
}
|
|
373
316
|
/**
|
|
@@ -384,8 +327,7 @@ export class CopyOnWriteFS extends FileSystem {
|
|
|
384
327
|
if (toCreate.length)
|
|
385
328
|
debug('COW: Creating parent directories: ' + toCreate.join(', '));
|
|
386
329
|
for (const path of toCreate.reverse()) {
|
|
387
|
-
|
|
388
|
-
await this.writable.mkdir(path, mode, { uid, gid });
|
|
330
|
+
await this.writable.mkdir(path, await this.stat(path));
|
|
389
331
|
}
|
|
390
332
|
}
|
|
391
333
|
/**
|
|
@@ -420,64 +362,38 @@ export class CopyOnWriteFS extends FileSystem {
|
|
|
420
362
|
* PRECONDITION: File does not exist on writable storage.
|
|
421
363
|
*/
|
|
422
364
|
copyToWritableSync(path) {
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
this.
|
|
429
|
-
for (const k of this.readable.readdirSync(path)) {
|
|
430
|
-
this.copyToWritableSync(join(path, k));
|
|
431
|
-
}
|
|
432
|
-
return;
|
|
365
|
+
const stats = this.statSync(path);
|
|
366
|
+
stats.mode |= 0o222;
|
|
367
|
+
if (isDirectory(stats)) {
|
|
368
|
+
this.writable.mkdirSync(path, stats);
|
|
369
|
+
for (const k of this.readable.readdirSync(path)) {
|
|
370
|
+
this.copyToWritableSync(join(path, k));
|
|
433
371
|
}
|
|
434
|
-
|
|
435
|
-
const readable = __addDisposableResource(env_1, this.readable.openFileSync(path, 'r'), false);
|
|
436
|
-
readable.readSync(data);
|
|
437
|
-
const writable = __addDisposableResource(env_1, this.writable.createFileSync(path, 'w', stats.mode, stats), false);
|
|
438
|
-
writable.writeSync(data);
|
|
439
|
-
}
|
|
440
|
-
catch (e_1) {
|
|
441
|
-
env_1.error = e_1;
|
|
442
|
-
env_1.hasError = true;
|
|
443
|
-
}
|
|
444
|
-
finally {
|
|
445
|
-
__disposeResources(env_1);
|
|
372
|
+
return;
|
|
446
373
|
}
|
|
374
|
+
const data = new Uint8Array(stats.size);
|
|
375
|
+
this.readable.readSync(path, data, 0, data.byteLength);
|
|
376
|
+
this.writable.createFileSync(path, stats);
|
|
377
|
+
this.writable.touchSync(path, stats);
|
|
378
|
+
this.writable.writeSync(path, data, 0);
|
|
447
379
|
}
|
|
448
380
|
async copyToWritable(path) {
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
await this.
|
|
455
|
-
for (const k of await this.readable.readdir(path)) {
|
|
456
|
-
await this.copyToWritable(join(path, k));
|
|
457
|
-
}
|
|
458
|
-
return;
|
|
381
|
+
const stats = await this.stat(path);
|
|
382
|
+
stats.mode |= 0o222;
|
|
383
|
+
if (isDirectory(stats)) {
|
|
384
|
+
await this.writable.mkdir(path, stats);
|
|
385
|
+
for (const k of await this.readable.readdir(path)) {
|
|
386
|
+
await this.copyToWritable(join(path, k));
|
|
459
387
|
}
|
|
460
|
-
|
|
461
|
-
await this.readable.read(path, data, 0, stats.size);
|
|
462
|
-
const writable = __addDisposableResource(env_2, await this.writable.createFile(path, 'w', stats.mode, stats), true);
|
|
463
|
-
await writable.write(data);
|
|
464
|
-
}
|
|
465
|
-
catch (e_2) {
|
|
466
|
-
env_2.error = e_2;
|
|
467
|
-
env_2.hasError = true;
|
|
468
|
-
}
|
|
469
|
-
finally {
|
|
470
|
-
const result_1 = __disposeResources(env_2);
|
|
471
|
-
if (result_1)
|
|
472
|
-
await result_1;
|
|
388
|
+
return;
|
|
473
389
|
}
|
|
390
|
+
const data = new Uint8Array(stats.size);
|
|
391
|
+
await this.readable.read(path, data, 0, stats.size);
|
|
392
|
+
await this.writable.createFile(path, stats);
|
|
393
|
+
await this.writable.touch(path, stats);
|
|
394
|
+
await this.writable.write(path, data, 0);
|
|
474
395
|
}
|
|
475
396
|
}
|
|
476
|
-
/**
|
|
477
|
-
* @hidden @deprecated use `CopyOnWriteFS`
|
|
478
|
-
*/
|
|
479
|
-
export class OverlayFS extends CopyOnWriteFS {
|
|
480
|
-
}
|
|
481
397
|
const _CopyOnWrite = {
|
|
482
398
|
name: 'CopyOnWrite',
|
|
483
399
|
options: {
|
|
@@ -498,9 +414,3 @@ const _CopyOnWrite = {
|
|
|
498
414
|
* @internal
|
|
499
415
|
*/
|
|
500
416
|
export const CopyOnWrite = _CopyOnWrite;
|
|
501
|
-
/**
|
|
502
|
-
* @deprecated Use `CopyOnWrite`
|
|
503
|
-
* @category Backends and Configuration
|
|
504
|
-
* @internal @hidden
|
|
505
|
-
*/
|
|
506
|
-
export const Overlay = _CopyOnWrite;
|
package/dist/backends/fetch.d.ts
CHANGED
package/dist/backends/fetch.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { decodeUTF8 } from 'utilium';
|
|
1
2
|
import * as requests from 'utilium/requests.js';
|
|
2
3
|
import { Errno, ErrnoError } from '../internal/error.js';
|
|
3
4
|
import { Index } from '../internal/file_index.js';
|
|
4
5
|
import { IndexFS } from '../internal/index_fs.js';
|
|
5
6
|
import { err, warn } from '../internal/log.js';
|
|
6
|
-
import {
|
|
7
|
+
import { normalizePath } from '../utils.js';
|
|
7
8
|
import { S_IFREG } from '../vfs/constants.js';
|
|
8
9
|
/** Parse and throw */
|
|
9
10
|
function parseError(path, fs) {
|
|
@@ -24,6 +25,7 @@ function parseError(path, fs) {
|
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
26
27
|
* A simple filesystem backed by HTTP using the `fetch` API.
|
|
28
|
+
* @category Internals
|
|
27
29
|
* @internal
|
|
28
30
|
*/
|
|
29
31
|
export class FetchFS extends IndexFS {
|
package/dist/backends/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export * from './cow.js';
|
|
|
3
3
|
export * from './fetch.js';
|
|
4
4
|
export * from './memory.js';
|
|
5
5
|
export * from './passthrough.js';
|
|
6
|
-
export * from './port
|
|
6
|
+
export * from './port.js';
|
|
7
7
|
export * from './single_buffer.js';
|
|
8
8
|
export * from './store/fs.js';
|
|
9
9
|
export * from './store/map.js';
|
package/dist/backends/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export * from './cow.js';
|
|
|
3
3
|
export * from './fetch.js';
|
|
4
4
|
export * from './memory.js';
|
|
5
5
|
export * from './passthrough.js';
|
|
6
|
-
export * from './port
|
|
6
|
+
export * from './port.js';
|
|
7
7
|
export * from './single_buffer.js';
|
|
8
8
|
export * from './store/fs.js';
|
|
9
9
|
export * from './store/map.js';
|
|
@@ -25,8 +25,6 @@ export interface InMemoryOptions {
|
|
|
25
25
|
maxSize?: number;
|
|
26
26
|
/** The label to use for the store and file system */
|
|
27
27
|
label?: string;
|
|
28
|
-
/** @deprecated use `label` */
|
|
29
|
-
name?: string;
|
|
30
28
|
}
|
|
31
29
|
declare const _InMemory: {
|
|
32
30
|
readonly name: "InMemory";
|
|
@@ -39,14 +37,14 @@ declare const _InMemory: {
|
|
|
39
37
|
readonly type: "string";
|
|
40
38
|
readonly required: false;
|
|
41
39
|
};
|
|
42
|
-
readonly name: {
|
|
43
|
-
readonly type: "string";
|
|
44
|
-
readonly required: false;
|
|
45
|
-
};
|
|
46
40
|
};
|
|
47
|
-
readonly create: ({ maxSize, label
|
|
41
|
+
readonly create: ({ maxSize, label }: InMemoryOptions) => StoreFS<InMemoryStore>;
|
|
48
42
|
};
|
|
49
43
|
type _InMemory = typeof _InMemory;
|
|
44
|
+
/**
|
|
45
|
+
* A backend that uses an in-memory store for storing data
|
|
46
|
+
* @category Backends and Configuration
|
|
47
|
+
*/
|
|
50
48
|
export interface InMemory extends _InMemory {
|
|
51
49
|
}
|
|
52
50
|
/**
|
package/dist/backends/memory.js
CHANGED
|
@@ -35,10 +35,9 @@ const _InMemory = {
|
|
|
35
35
|
options: {
|
|
36
36
|
maxSize: { type: 'number', required: false },
|
|
37
37
|
label: { type: 'string', required: false },
|
|
38
|
-
name: { type: 'string', required: false },
|
|
39
38
|
},
|
|
40
|
-
create({ maxSize, label
|
|
41
|
-
const fs = new StoreFS(new InMemoryStore(maxSize, label
|
|
39
|
+
create({ maxSize, label }) {
|
|
40
|
+
const fs = new StoreFS(new InMemoryStore(maxSize, label));
|
|
42
41
|
fs.checkRootSync();
|
|
43
42
|
return fs;
|
|
44
43
|
},
|