@zenfs/core 1.8.8 → 1.9.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 +1 -1
- package/dist/backends/backend.js +7 -4
- package/dist/backends/fetch.d.ts +23 -32
- package/dist/backends/fetch.js +94 -134
- package/dist/backends/index.d.ts +1 -4
- package/dist/backends/index.js +1 -4
- package/dist/backends/memory.d.ts +7 -5
- package/dist/backends/memory.js +6 -4
- package/dist/backends/overlay.d.ts +4 -5
- package/dist/backends/overlay.js +16 -20
- package/dist/backends/passthrough.d.ts +3 -3
- package/dist/backends/passthrough.js +4 -6
- package/dist/backends/port/fs.d.ts +4 -5
- package/dist/backends/port/fs.js +7 -12
- package/dist/backends/port/rpc.d.ts +1 -1
- package/dist/backends/port/rpc.js +15 -13
- package/dist/backends/store/fs.d.ts +51 -40
- package/dist/backends/store/fs.js +347 -241
- package/dist/backends/store/map.d.ts +41 -0
- package/dist/backends/store/map.js +45 -0
- package/dist/backends/store/simple.d.ts +10 -58
- package/dist/backends/store/simple.js +8 -115
- package/dist/backends/store/store.d.ts +111 -44
- package/dist/backends/store/store.js +230 -38
- package/dist/config.d.ts +7 -3
- package/dist/config.js +17 -14
- package/dist/context.d.ts +1 -1
- package/dist/context.js +1 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.js +1 -5
- package/dist/{devices.d.ts → internal/devices.d.ts} +4 -4
- package/dist/{devices.js → internal/devices.js} +18 -14
- package/dist/{file.d.ts → internal/file.d.ts} +3 -2
- package/dist/{file.js → internal/file.js} +17 -12
- package/dist/{backends/store → internal}/file_index.d.ts +13 -3
- package/dist/{backends/store → internal}/file_index.js +28 -5
- package/dist/{filesystem.d.ts → internal/filesystem.d.ts} +99 -32
- package/dist/internal/filesystem.js +83 -0
- package/dist/internal/index.d.ts +9 -0
- package/dist/internal/index.js +9 -0
- package/dist/internal/index_fs.d.ts +56 -0
- package/dist/internal/index_fs.js +184 -0
- package/dist/{backends/store → internal}/inode.d.ts +6 -1
- package/dist/{backends/store → internal}/inode.js +14 -6
- package/dist/internal/log.d.ts +132 -0
- package/dist/internal/log.js +177 -0
- package/dist/mixins/async.d.ts +2 -2
- package/dist/mixins/async.js +19 -16
- package/dist/mixins/mutexed.d.ts +9 -3
- package/dist/mixins/mutexed.js +22 -3
- package/dist/mixins/readonly.d.ts +2 -2
- package/dist/mixins/readonly.js +4 -3
- package/dist/mixins/shared.d.ts +1 -1
- package/dist/mixins/sync.d.ts +2 -2
- package/dist/stats.d.ts +2 -3
- package/dist/stats.js +7 -5
- package/dist/utils.d.ts +2 -15
- package/dist/utils.js +10 -47
- package/dist/vfs/async.d.ts +2 -2
- package/dist/vfs/async.js +3 -3
- package/dist/vfs/dir.js +1 -1
- package/dist/vfs/promises.d.ts +6 -6
- package/dist/vfs/promises.js +54 -49
- package/dist/vfs/shared.d.ts +3 -3
- package/dist/vfs/shared.js +16 -10
- package/dist/vfs/streams.js +1 -1
- package/dist/vfs/sync.d.ts +1 -2
- package/dist/vfs/sync.js +14 -15
- package/dist/vfs/types.d.ts +1 -0
- package/dist/vfs/watchers.d.ts +5 -1
- package/dist/vfs/watchers.js +16 -19
- package/package.json +3 -3
- package/readme.md +12 -12
- package/scripts/test.js +15 -3
- package/tests/backend/fetch.test.ts +49 -0
- package/tests/backend/port.test.ts +130 -0
- package/tests/common/context.test.ts +9 -4
- package/tests/common.ts +21 -3
- package/tests/data/image.jpg +0 -0
- package/tests/data/utf8.txt +1 -0
- package/tests/fetch/config.js +40 -0
- package/tests/fetch/fetch.ts +20 -0
- package/tests/fetch/run.sh +3 -3
- package/tests/fetch/{server.ts → server.js} +15 -11
- package/tests/fs/directory.test.ts +1 -1
- package/tests/fs/errors.test.ts +1 -1
- package/tests/fs/links.test.ts +1 -1
- package/tests/fs/open.test.ts +1 -1
- package/tests/fs/permissions.test.ts +2 -3
- package/tests/fs/rename.test.ts +1 -1
- package/tests/fs/stat.test.ts +1 -1
- package/tests/fs/times.test.ts +1 -1
- package/tests/fs/watch.test.ts +21 -22
- package/tests/fs/writeFile.test.ts +8 -7
- package/tests/readme.md +3 -3
- package/tests/setup/_overlay.ts +7 -0
- package/tests/setup/context.ts +2 -2
- package/tests/setup/index.ts +3 -3
- package/tests/setup/memory.ts +2 -2
- package/tests/setup/port.ts +2 -2
- package/tests/setup.ts +25 -5
- package/tests/tsconfig.json +3 -2
- package/dist/backends/store/index_fs.d.ts +0 -34
- package/dist/backends/store/index_fs.js +0 -67
- package/dist/filesystem.js +0 -52
- package/tests/fetch/cow+fetch.ts +0 -13
- package/tests/port/channel.test.ts +0 -39
- package/tests/port/config.test.ts +0 -30
- package/tests/port/remote.test.ts +0 -32
- package/tests/port/timeout.test.ts +0 -48
- /package/dist/{credentials.d.ts → internal/credentials.d.ts} +0 -0
- /package/dist/{credentials.js → internal/credentials.js} +0 -0
- /package/dist/{error.d.ts → internal/error.d.ts} +0 -0
- /package/dist/{error.js → internal/error.js} +0 -0
- /package/tests/{port → backend}/config.worker.js +0 -0
- /package/tests/{port → backend}/remote.worker.js +0 -0
|
@@ -37,8 +37,9 @@ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, p
|
|
|
37
37
|
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
38
38
|
};
|
|
39
39
|
import { deserialize, pick, randomInt, sizeof, struct, types as t } from 'utilium';
|
|
40
|
-
import { Stats } from '
|
|
41
|
-
import { size_max } from '
|
|
40
|
+
import { Stats } from '../stats.js';
|
|
41
|
+
import { size_max } from '../vfs/constants.js';
|
|
42
|
+
import { crit, debug } from './log.js';
|
|
42
43
|
/**
|
|
43
44
|
* Root inode
|
|
44
45
|
* @hidden
|
|
@@ -132,17 +133,21 @@ let Inode = (() => {
|
|
|
132
133
|
return;
|
|
133
134
|
}
|
|
134
135
|
if (data.byteLength < 58) {
|
|
135
|
-
throw new RangeError('Can not create an inode from a buffer less than 58 bytes');
|
|
136
|
+
throw crit(new RangeError('Can not create an inode from a buffer less than 58 bytes'));
|
|
136
137
|
}
|
|
137
138
|
// Expand the buffer so it is the right size
|
|
138
|
-
if (data.byteLength <
|
|
139
|
+
if (data.byteLength < __inode_sz) {
|
|
139
140
|
const buf = ArrayBuffer.isView(data) ? data.buffer : data;
|
|
140
|
-
const newBuffer = new Uint8Array(
|
|
141
|
+
const newBuffer = new Uint8Array(__inode_sz);
|
|
141
142
|
newBuffer.set(new Uint8Array(buf));
|
|
143
|
+
debug('Extending undersized buffer for inode');
|
|
142
144
|
data = newBuffer;
|
|
143
145
|
}
|
|
144
146
|
deserialize(this, data);
|
|
145
147
|
}
|
|
148
|
+
toString() {
|
|
149
|
+
return `<Inode ${this.ino}>`;
|
|
150
|
+
}
|
|
146
151
|
toJSON() {
|
|
147
152
|
return pick(this, _inode_fields);
|
|
148
153
|
}
|
|
@@ -221,4 +226,7 @@ let Inode = (() => {
|
|
|
221
226
|
return Inode = _classThis;
|
|
222
227
|
})();
|
|
223
228
|
export { Inode };
|
|
224
|
-
|
|
229
|
+
/**
|
|
230
|
+
* @internal @hidden
|
|
231
|
+
*/
|
|
232
|
+
export const __inode_sz = sizeof(Inode);
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { List } from 'utilium';
|
|
2
|
+
import { ErrnoError } from './error.js';
|
|
3
|
+
import type { FileSystem } from './filesystem.js';
|
|
4
|
+
export declare const enum Level {
|
|
5
|
+
/** Emergency */
|
|
6
|
+
EMERG = 0,
|
|
7
|
+
/** Alert */
|
|
8
|
+
ALERT = 1,
|
|
9
|
+
/** Critical */
|
|
10
|
+
CRIT = 2,
|
|
11
|
+
/** Error */
|
|
12
|
+
ERR = 3,
|
|
13
|
+
/** Warning */
|
|
14
|
+
WARN = 4,
|
|
15
|
+
/** Notice */
|
|
16
|
+
NOTICE = 5,
|
|
17
|
+
/** Informational */
|
|
18
|
+
INFO = 6,
|
|
19
|
+
/** Debug */
|
|
20
|
+
DEBUG = 7
|
|
21
|
+
}
|
|
22
|
+
/** An object mapping log levels to a textual representation of them */
|
|
23
|
+
export declare const levels: {
|
|
24
|
+
readonly 0: "emergency";
|
|
25
|
+
readonly 1: "alert";
|
|
26
|
+
readonly 2: "critical";
|
|
27
|
+
readonly 3: "error";
|
|
28
|
+
readonly 4: "warning";
|
|
29
|
+
readonly 5: "notice";
|
|
30
|
+
readonly 6: "info";
|
|
31
|
+
readonly 7: "debug";
|
|
32
|
+
};
|
|
33
|
+
export declare function levelOf(value: (typeof levels)[Level]): Level;
|
|
34
|
+
/** A log entry */
|
|
35
|
+
export interface Entry {
|
|
36
|
+
level: Level;
|
|
37
|
+
timestamp: Date;
|
|
38
|
+
elapsedMs: number;
|
|
39
|
+
message: string;
|
|
40
|
+
}
|
|
41
|
+
/** The list of log entries */
|
|
42
|
+
export declare const entries: List<Entry>;
|
|
43
|
+
export declare function log(level: Level, message: string): void;
|
|
44
|
+
interface LogShortcutOptions {
|
|
45
|
+
fs?: FileSystem;
|
|
46
|
+
}
|
|
47
|
+
/** Shortcut for logging emergencies */
|
|
48
|
+
export declare const emerg: <T extends {
|
|
49
|
+
toString(): string;
|
|
50
|
+
} | ErrnoError>(message: T, options?: LogShortcutOptions) => T;
|
|
51
|
+
/** Shortcut for logging alerts */
|
|
52
|
+
export declare const alert: <T extends {
|
|
53
|
+
toString(): string;
|
|
54
|
+
} | ErrnoError>(message: T, options?: LogShortcutOptions) => T;
|
|
55
|
+
/** Shortcut for logging critical errors */
|
|
56
|
+
export declare const crit: <T extends {
|
|
57
|
+
toString(): string;
|
|
58
|
+
} | ErrnoError>(message: T, options?: LogShortcutOptions) => T;
|
|
59
|
+
/** Shortcut for logging non-critical errors */
|
|
60
|
+
export declare const err: <T extends {
|
|
61
|
+
toString(): string;
|
|
62
|
+
} | ErrnoError>(message: T, options?: LogShortcutOptions) => T;
|
|
63
|
+
/** Shortcut for logging warnings */
|
|
64
|
+
export declare const warn: <T extends {
|
|
65
|
+
toString(): string;
|
|
66
|
+
} | ErrnoError>(message: T, options?: LogShortcutOptions) => T;
|
|
67
|
+
/** Shortcut for logging notices */
|
|
68
|
+
export declare const notice: <T extends {
|
|
69
|
+
toString(): string;
|
|
70
|
+
} | ErrnoError>(message: T, options?: LogShortcutOptions) => T;
|
|
71
|
+
/** Shortcut for logging informational messages */
|
|
72
|
+
export declare const info: <T extends {
|
|
73
|
+
toString(): string;
|
|
74
|
+
} | ErrnoError>(message: T, options?: LogShortcutOptions) => T;
|
|
75
|
+
/** Shortcut for logging debug messages */
|
|
76
|
+
export declare const debug: <T extends {
|
|
77
|
+
toString(): string;
|
|
78
|
+
} | ErrnoError>(message: T, options?: LogShortcutOptions) => T;
|
|
79
|
+
/**
|
|
80
|
+
* Shortcut for logging usage of deprecated functions at runtime
|
|
81
|
+
* @param symbol The thing that is deprecated
|
|
82
|
+
* @internal @hidden
|
|
83
|
+
*/
|
|
84
|
+
export declare function log_deprecated(symbol: string): void;
|
|
85
|
+
/**
|
|
86
|
+
* Various format functions included to make using the logger easier.
|
|
87
|
+
* These are not the only formats you can use.
|
|
88
|
+
*/
|
|
89
|
+
export declare const formats: {
|
|
90
|
+
/** Format with a timestamp and the level, colorized with ANSI escape codes */
|
|
91
|
+
readonly ansi_level: (this: void, entry: Entry) => string;
|
|
92
|
+
/**
|
|
93
|
+
* Format with a timestamp and colorize the message with ANSI escape codes.
|
|
94
|
+
* For EMERG and ALERT, the levels are included
|
|
95
|
+
*/
|
|
96
|
+
readonly ansi_message: (this: void, entry: Entry) => string;
|
|
97
|
+
/** Uncolored format with a timestamp */
|
|
98
|
+
readonly default: (this: void, entry: Entry) => string;
|
|
99
|
+
};
|
|
100
|
+
export declare function format(entry: Entry): string;
|
|
101
|
+
/** Whether log entries are being recorded */
|
|
102
|
+
export declare let isEnabled: boolean;
|
|
103
|
+
export interface LogConfiguration {
|
|
104
|
+
/**
|
|
105
|
+
* If false, log messages will not be recorded or outputted
|
|
106
|
+
* @default false
|
|
107
|
+
*/
|
|
108
|
+
enabled?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* The minimum level needed to output a message
|
|
111
|
+
* @default Level.ALERT
|
|
112
|
+
*/
|
|
113
|
+
level?: Level | (typeof levels)[Level];
|
|
114
|
+
/**
|
|
115
|
+
* Formats a log entry into a string
|
|
116
|
+
* @default `[${ms / 1000}] ${message}`
|
|
117
|
+
*/
|
|
118
|
+
format?(this: void, entry: Entry): string;
|
|
119
|
+
/**
|
|
120
|
+
* Outputs a log message
|
|
121
|
+
* @default console.error()
|
|
122
|
+
*/
|
|
123
|
+
output?(this: void, message: string): unknown;
|
|
124
|
+
/**
|
|
125
|
+
* If set, output() all current entries after `configure` is done
|
|
126
|
+
* @default false
|
|
127
|
+
*/
|
|
128
|
+
dumpBacklog?: boolean;
|
|
129
|
+
}
|
|
130
|
+
/** Configure logging behavior */
|
|
131
|
+
export declare function configure(options: LogConfiguration): void;
|
|
132
|
+
export {};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/* Logging utilities. The things in this file are named to work nicely when you import as a namespace. */
|
|
2
|
+
import { List } from 'utilium';
|
|
3
|
+
import { join } from '../vfs/path.js';
|
|
4
|
+
import { ErrnoError } from './error.js';
|
|
5
|
+
export var Level;
|
|
6
|
+
(function (Level) {
|
|
7
|
+
/** Emergency */
|
|
8
|
+
Level[Level["EMERG"] = 0] = "EMERG";
|
|
9
|
+
/** Alert */
|
|
10
|
+
Level[Level["ALERT"] = 1] = "ALERT";
|
|
11
|
+
/** Critical */
|
|
12
|
+
Level[Level["CRIT"] = 2] = "CRIT";
|
|
13
|
+
/** Error */
|
|
14
|
+
Level[Level["ERR"] = 3] = "ERR";
|
|
15
|
+
/** Warning */
|
|
16
|
+
Level[Level["WARN"] = 4] = "WARN";
|
|
17
|
+
/** Notice */
|
|
18
|
+
Level[Level["NOTICE"] = 5] = "NOTICE";
|
|
19
|
+
/** Informational */
|
|
20
|
+
Level[Level["INFO"] = 6] = "INFO";
|
|
21
|
+
/** Debug */
|
|
22
|
+
Level[Level["DEBUG"] = 7] = "DEBUG";
|
|
23
|
+
})(Level || (Level = {}));
|
|
24
|
+
/** An object mapping log levels to a textual representation of them */
|
|
25
|
+
export const levels = {
|
|
26
|
+
[Level.EMERG]: 'emergency',
|
|
27
|
+
[Level.ALERT]: 'alert',
|
|
28
|
+
[Level.CRIT]: 'critical',
|
|
29
|
+
[Level.ERR]: 'error',
|
|
30
|
+
[Level.WARN]: 'warning',
|
|
31
|
+
[Level.NOTICE]: 'notice',
|
|
32
|
+
[Level.INFO]: 'info',
|
|
33
|
+
[Level.DEBUG]: 'debug',
|
|
34
|
+
};
|
|
35
|
+
export function levelOf(value) {
|
|
36
|
+
return Object.values(levels).indexOf(value);
|
|
37
|
+
}
|
|
38
|
+
/** The list of log entries */
|
|
39
|
+
export const entries = new List();
|
|
40
|
+
export function log(level, message) {
|
|
41
|
+
if (!isEnabled)
|
|
42
|
+
return;
|
|
43
|
+
const entry = {
|
|
44
|
+
level,
|
|
45
|
+
message,
|
|
46
|
+
timestamp: new Date(),
|
|
47
|
+
elapsedMs: performance.now(),
|
|
48
|
+
};
|
|
49
|
+
entries.add(entry);
|
|
50
|
+
output(entry);
|
|
51
|
+
}
|
|
52
|
+
function _messageString(msg, options) {
|
|
53
|
+
var _a, _b;
|
|
54
|
+
if (!(msg instanceof ErrnoError))
|
|
55
|
+
return msg.toString();
|
|
56
|
+
const beforePath = msg.code + ': ' + msg.message;
|
|
57
|
+
if (!msg.path)
|
|
58
|
+
return beforePath;
|
|
59
|
+
const mountPoint = typeof options.fs == 'string' ? options.fs : ((_b = (_a = options.fs) === null || _a === void 0 ? void 0 : _a._mountPoint) !== null && _b !== void 0 ? _b : '<unknown>');
|
|
60
|
+
return beforePath + ': ' + join(mountPoint, msg.path);
|
|
61
|
+
}
|
|
62
|
+
function _shortcut(level) {
|
|
63
|
+
return function (message, options = {}) {
|
|
64
|
+
log(level, _messageString(message, options));
|
|
65
|
+
return message;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// Shortcuts
|
|
69
|
+
/** Shortcut for logging emergencies */
|
|
70
|
+
export const emerg = _shortcut(Level.EMERG);
|
|
71
|
+
/** Shortcut for logging alerts */
|
|
72
|
+
export const alert = _shortcut(Level.ALERT);
|
|
73
|
+
/** Shortcut for logging critical errors */
|
|
74
|
+
export const crit = _shortcut(Level.CRIT);
|
|
75
|
+
/** Shortcut for logging non-critical errors */
|
|
76
|
+
export const err = _shortcut(Level.ERR);
|
|
77
|
+
/** Shortcut for logging warnings */
|
|
78
|
+
export const warn = _shortcut(Level.WARN);
|
|
79
|
+
/** Shortcut for logging notices */
|
|
80
|
+
export const notice = _shortcut(Level.NOTICE);
|
|
81
|
+
/** Shortcut for logging informational messages */
|
|
82
|
+
export const info = _shortcut(Level.INFO);
|
|
83
|
+
/** Shortcut for logging debug messages */
|
|
84
|
+
export const debug = _shortcut(Level.DEBUG);
|
|
85
|
+
/**
|
|
86
|
+
* Shortcut for logging usage of deprecated functions at runtime
|
|
87
|
+
* @param symbol The thing that is deprecated
|
|
88
|
+
* @internal @hidden
|
|
89
|
+
*/
|
|
90
|
+
export function log_deprecated(symbol) {
|
|
91
|
+
log(Level.WARN, symbol + ' is deprecated and should not be used.');
|
|
92
|
+
}
|
|
93
|
+
// Formatting and output
|
|
94
|
+
/**
|
|
95
|
+
* @internal @hidden
|
|
96
|
+
*/
|
|
97
|
+
function ansi(text, format) {
|
|
98
|
+
return `\x1b[${format}m${text}\x1b[0m`;
|
|
99
|
+
}
|
|
100
|
+
function _prettyMs(entry, useANSI = false) {
|
|
101
|
+
const text = '[' + (entry.elapsedMs / 1000).toFixed(3).padStart(10) + '] ';
|
|
102
|
+
return useANSI ? ansi(text, '2;37') : text;
|
|
103
|
+
}
|
|
104
|
+
const _ansiLevelColor = {
|
|
105
|
+
[Level.EMERG]: '1;4;37;41',
|
|
106
|
+
[Level.ALERT]: '1;37;41',
|
|
107
|
+
[Level.CRIT]: '1;35',
|
|
108
|
+
[Level.ERR]: '1;31',
|
|
109
|
+
[Level.WARN]: '1;33',
|
|
110
|
+
[Level.NOTICE]: '1;36',
|
|
111
|
+
[Level.INFO]: '1;37',
|
|
112
|
+
[Level.DEBUG]: '0;2;37',
|
|
113
|
+
};
|
|
114
|
+
const _ansiMessageColor = {
|
|
115
|
+
[Level.EMERG]: '1;31',
|
|
116
|
+
[Level.ALERT]: '1;31',
|
|
117
|
+
[Level.CRIT]: '1;31',
|
|
118
|
+
[Level.ERR]: '31',
|
|
119
|
+
[Level.WARN]: '33',
|
|
120
|
+
[Level.NOTICE]: '1;37',
|
|
121
|
+
[Level.INFO]: '37',
|
|
122
|
+
[Level.DEBUG]: '2;37',
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Various format functions included to make using the logger easier.
|
|
126
|
+
* These are not the only formats you can use.
|
|
127
|
+
*/
|
|
128
|
+
export const formats = {
|
|
129
|
+
/** Format with a timestamp and the level, colorized with ANSI escape codes */
|
|
130
|
+
ansi_level(entry) {
|
|
131
|
+
const levelText = ansi(levels[entry.level].toUpperCase(), _ansiLevelColor[entry.level]);
|
|
132
|
+
return [_prettyMs(entry, true), levelText, entry.message].join(' ');
|
|
133
|
+
},
|
|
134
|
+
/**
|
|
135
|
+
* Format with a timestamp and colorize the message with ANSI escape codes.
|
|
136
|
+
* For EMERG and ALERT, the levels are included
|
|
137
|
+
*/
|
|
138
|
+
ansi_message(entry) {
|
|
139
|
+
let msg = _prettyMs(entry, true);
|
|
140
|
+
const isImportant = entry.level < Level.CRIT;
|
|
141
|
+
if (isImportant)
|
|
142
|
+
msg += ansi(levels[entry.level].toUpperCase(), _ansiLevelColor[entry.level]) + ': ';
|
|
143
|
+
msg += ansi(entry.message, _ansiMessageColor[entry.level]);
|
|
144
|
+
return msg;
|
|
145
|
+
},
|
|
146
|
+
/** Uncolored format with a timestamp */
|
|
147
|
+
default(entry) {
|
|
148
|
+
return `[${_prettyMs(entry)}] ${entry.message}`;
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
let _format = formats.default;
|
|
152
|
+
export function format(entry) {
|
|
153
|
+
return _format(entry);
|
|
154
|
+
}
|
|
155
|
+
let _output = console.error;
|
|
156
|
+
function output(entry) {
|
|
157
|
+
if (entry.level > minLevel)
|
|
158
|
+
return;
|
|
159
|
+
_output(format(entry));
|
|
160
|
+
}
|
|
161
|
+
let minLevel = Level.ALERT;
|
|
162
|
+
// Configuration
|
|
163
|
+
/** Whether log entries are being recorded */
|
|
164
|
+
export let isEnabled = true;
|
|
165
|
+
/** Configure logging behavior */
|
|
166
|
+
export function configure(options) {
|
|
167
|
+
var _a, _b, _c, _d;
|
|
168
|
+
_format = (_a = options.format) !== null && _a !== void 0 ? _a : _format;
|
|
169
|
+
_output = (_b = options.output) !== null && _b !== void 0 ? _b : _output;
|
|
170
|
+
minLevel = typeof options.level == 'string' ? levelOf(options.level) : ((_c = options.level) !== null && _c !== void 0 ? _c : minLevel);
|
|
171
|
+
isEnabled = (_d = options.enabled) !== null && _d !== void 0 ? _d : isEnabled;
|
|
172
|
+
if (!options.dumpBacklog)
|
|
173
|
+
return;
|
|
174
|
+
for (const entry of entries) {
|
|
175
|
+
output(entry);
|
|
176
|
+
}
|
|
177
|
+
}
|
package/dist/mixins/async.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FileSystem } from '../filesystem.js';
|
|
1
|
+
import type { FileSystem } from '../internal/filesystem.js';
|
|
2
2
|
import type { _SyncFSKeys, AsyncFSMethods, Mixin } from './shared.js';
|
|
3
3
|
/** @internal */
|
|
4
4
|
export type AsyncOperation = {
|
|
@@ -25,4 +25,4 @@ export interface AsyncMixin extends Pick<FileSystem, Exclude<_SyncFSKeys, 'exist
|
|
|
25
25
|
* During loading, the contents of the async file system are preloaded into the synchronous store.
|
|
26
26
|
*
|
|
27
27
|
*/
|
|
28
|
-
export declare function Async<const T extends
|
|
28
|
+
export declare function Async<const T extends abstract new (...args: any[]) => FileSystem>(FS: T): Mixin<T, AsyncMixin>;
|
package/dist/mixins/async.js
CHANGED
|
@@ -51,8 +51,9 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
53
|
import { StoreFS } from '../backends/store/fs.js';
|
|
54
|
-
import { Errno, ErrnoError } from '../error.js';
|
|
55
|
-
import { LazyFile, parseFlag } from '../file.js';
|
|
54
|
+
import { Errno, ErrnoError } from '../internal/error.js';
|
|
55
|
+
import { LazyFile, parseFlag } from '../internal/file.js';
|
|
56
|
+
import { crit, err, notice } from '../internal/log.js';
|
|
56
57
|
import { join } from '../vfs/path.js';
|
|
57
58
|
/**
|
|
58
59
|
* Async() implements synchronous methods on an asynchronous file system
|
|
@@ -73,29 +74,25 @@ export function Async(FS) {
|
|
|
73
74
|
return this.done();
|
|
74
75
|
}
|
|
75
76
|
_async(promise) {
|
|
76
|
-
if (!this._promise) {
|
|
77
|
-
this._promise = promise;
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
77
|
this._promise = this._promise.then(() => promise);
|
|
81
78
|
}
|
|
82
79
|
constructor(...args) {
|
|
83
80
|
super(...args);
|
|
81
|
+
this._promise = Promise.resolve();
|
|
84
82
|
this._isInitialized = false;
|
|
85
83
|
this._patchAsync();
|
|
86
84
|
}
|
|
87
85
|
async ready() {
|
|
88
86
|
await super.ready();
|
|
89
87
|
await this.queueDone();
|
|
90
|
-
if (this._isInitialized || this.
|
|
88
|
+
if (this._isInitialized || this.attributes.has('no_async'))
|
|
91
89
|
return;
|
|
92
|
-
}
|
|
93
90
|
this.checkSync();
|
|
94
91
|
await this._sync.ready();
|
|
95
92
|
// optimization: for 2 storeFS', we copy at a lower abstraction level.
|
|
96
93
|
if (this._sync instanceof StoreFS && this instanceof StoreFS) {
|
|
97
|
-
const sync = this._sync
|
|
98
|
-
const async = this
|
|
94
|
+
const sync = this._sync.transaction();
|
|
95
|
+
const async = this.transaction();
|
|
99
96
|
const promises = [];
|
|
100
97
|
for (const key of await async.keys()) {
|
|
101
98
|
promises.push(async.get(key).then(data => sync.setSync(key, data)));
|
|
@@ -110,15 +107,17 @@ export function Async(FS) {
|
|
|
110
107
|
}
|
|
111
108
|
catch (e) {
|
|
112
109
|
this._isInitialized = false;
|
|
113
|
-
throw e;
|
|
110
|
+
throw crit(e, { fs: this });
|
|
114
111
|
}
|
|
115
112
|
}
|
|
116
113
|
checkSync(path, syscall) {
|
|
117
|
-
if (this.
|
|
118
|
-
throw new ErrnoError(Errno.ENOTSUP, 'Sync
|
|
114
|
+
if (this.attributes.has('no_async')) {
|
|
115
|
+
throw crit(new ErrnoError(Errno.ENOTSUP, 'Sync preloading has been disabled for this async file system', path, syscall), {
|
|
116
|
+
fs: this,
|
|
117
|
+
});
|
|
119
118
|
}
|
|
120
119
|
if (!this._sync) {
|
|
121
|
-
throw new ErrnoError(Errno.ENOTSUP, 'No sync cache is attached to this async file system', path, syscall);
|
|
120
|
+
throw crit(new ErrnoError(Errno.ENOTSUP, 'No sync cache is attached to this async file system', path, syscall), { fs: this });
|
|
122
121
|
}
|
|
123
122
|
}
|
|
124
123
|
renameSync(oldPath, newPath) {
|
|
@@ -244,14 +243,18 @@ export function Async(FS) {
|
|
|
244
243
|
this[key] = async (...args) => {
|
|
245
244
|
var _a, _b;
|
|
246
245
|
const result = await originalMethod.apply(this, args);
|
|
247
|
-
if (new Error().stack.includes(`at <computed> [as ${key}]`)
|
|
246
|
+
if (new Error().stack.includes(`at <computed> [as ${key}]`))
|
|
248
247
|
return result;
|
|
248
|
+
if (!this._isInitialized) {
|
|
249
|
+
notice('Skipping sync cache update for Async#' + key);
|
|
250
|
+
return result;
|
|
251
|
+
}
|
|
249
252
|
try {
|
|
250
253
|
// @ts-expect-error 2556
|
|
251
254
|
(_b = (_a = this._sync) === null || _a === void 0 ? void 0 : _a[`${key}Sync`]) === null || _b === void 0 ? void 0 : _b.call(_a, ...args);
|
|
252
255
|
}
|
|
253
256
|
catch (e) {
|
|
254
|
-
throw new ErrnoError(e.errno, e.message + ' (Out of sync!)', e.path, key);
|
|
257
|
+
throw err(new ErrnoError(e.errno, e.message + ' (Out of sync!)', e.path, key), { fs: this });
|
|
255
258
|
}
|
|
256
259
|
return result;
|
|
257
260
|
};
|
package/dist/mixins/mutexed.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { File } from '../file.js';
|
|
2
|
-
import type { CreationOptions, FileSystem, FileSystemMetadata } from '../filesystem.js';
|
|
1
|
+
import type { File } from '../internal/file.js';
|
|
2
|
+
import type { CreationOptions, FileSystem, FileSystemMetadata, UsageInfo } from '../internal/filesystem.js';
|
|
3
|
+
import type { InodeLike } from '../internal/inode.js';
|
|
3
4
|
import type { Stats } from '../stats.js';
|
|
4
5
|
import type { Concrete } from '../utils.js';
|
|
5
6
|
import '../polyfills.js';
|
|
6
|
-
import type { InodeLike } from '../backends/index.js';
|
|
7
7
|
export declare class MutexLock {
|
|
8
8
|
protected readonly previous?: MutexLock | undefined;
|
|
9
9
|
protected current: PromiseWithResolvers<void>;
|
|
@@ -22,7 +22,13 @@ export declare class _MutexedFS<T extends FileSystem> implements FileSystem {
|
|
|
22
22
|
* @internal
|
|
23
23
|
*/
|
|
24
24
|
_fs: T;
|
|
25
|
+
get id(): number;
|
|
26
|
+
get name(): string;
|
|
27
|
+
get label(): string | undefined;
|
|
28
|
+
set label(value: string | undefined);
|
|
29
|
+
get attributes(): import("utilium").ConstMap<import("../internal/filesystem.js").FileSystemAttributes, keyof import("../internal/filesystem.js").FileSystemAttributes, void>;
|
|
25
30
|
ready(): Promise<void>;
|
|
31
|
+
usage(): UsageInfo;
|
|
26
32
|
metadata(): FileSystemMetadata;
|
|
27
33
|
/**
|
|
28
34
|
* The current locks
|
package/dist/mixins/mutexed.js
CHANGED
|
@@ -50,7 +50,8 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
50
50
|
var e = new Error(message);
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
|
-
import { ErrnoError } from '../error.js';
|
|
53
|
+
import { ErrnoError } from '../internal/error.js';
|
|
54
|
+
import { err } from '../internal/log.js';
|
|
54
55
|
import '../polyfills.js';
|
|
55
56
|
export class MutexLock {
|
|
56
57
|
get isLocked() {
|
|
@@ -78,9 +79,27 @@ export class MutexLock {
|
|
|
78
79
|
* @hidden
|
|
79
80
|
*/
|
|
80
81
|
export class _MutexedFS {
|
|
82
|
+
get id() {
|
|
83
|
+
return this._fs.id;
|
|
84
|
+
}
|
|
85
|
+
get name() {
|
|
86
|
+
return this._fs.name;
|
|
87
|
+
}
|
|
88
|
+
get label() {
|
|
89
|
+
return this._fs.label;
|
|
90
|
+
}
|
|
91
|
+
set label(value) {
|
|
92
|
+
this._fs.label = value;
|
|
93
|
+
}
|
|
94
|
+
get attributes() {
|
|
95
|
+
return this._fs.attributes;
|
|
96
|
+
}
|
|
81
97
|
async ready() {
|
|
82
98
|
return await this._fs.ready();
|
|
83
99
|
}
|
|
100
|
+
usage() {
|
|
101
|
+
return this._fs.usage();
|
|
102
|
+
}
|
|
84
103
|
metadata() {
|
|
85
104
|
return this._fs.metadata();
|
|
86
105
|
}
|
|
@@ -105,7 +124,7 @@ export class _MutexedFS {
|
|
|
105
124
|
if (lock.isLocked) {
|
|
106
125
|
const error = ErrnoError.With('EDEADLK', path, syscall);
|
|
107
126
|
error.stack += stack === null || stack === void 0 ? void 0 : stack.slice('Error'.length);
|
|
108
|
-
throw error;
|
|
127
|
+
throw err(error, { fs: this });
|
|
109
128
|
}
|
|
110
129
|
}, 5000);
|
|
111
130
|
await (previous === null || previous === void 0 ? void 0 : previous.done());
|
|
@@ -119,7 +138,7 @@ export class _MutexedFS {
|
|
|
119
138
|
lockSync(path, syscall) {
|
|
120
139
|
var _a;
|
|
121
140
|
if ((_a = this.currentLock) === null || _a === void 0 ? void 0 : _a.isLocked) {
|
|
122
|
-
throw ErrnoError.With('EBUSY', path, syscall);
|
|
141
|
+
throw err(ErrnoError.With('EBUSY', path, syscall), { fs: this });
|
|
123
142
|
}
|
|
124
143
|
return this.addLock();
|
|
125
144
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FileSystem, FileSystemMetadata } from '../filesystem.js';
|
|
1
|
+
import type { FileSystem, FileSystemMetadata } from '../internal/filesystem.js';
|
|
2
2
|
import type { StatsLike } from '../stats.js';
|
|
3
3
|
import type { Mixin } from './shared.js';
|
|
4
4
|
/**
|
|
@@ -26,4 +26,4 @@ export interface ReadonlyMixin {
|
|
|
26
26
|
/**
|
|
27
27
|
* Implements the non-readonly methods to throw `EROFS`
|
|
28
28
|
*/
|
|
29
|
-
export declare function Readonly<T extends
|
|
29
|
+
export declare function Readonly<T extends abstract new (...args: any[]) => FileSystem>(FS: T): Mixin<T, ReadonlyMixin>;
|
package/dist/mixins/readonly.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { Errno, ErrnoError } from '../error.js';
|
|
1
|
+
import { Errno, ErrnoError } from '../internal/error.js';
|
|
2
2
|
/**
|
|
3
3
|
* Implements the non-readonly methods to throw `EROFS`
|
|
4
4
|
*/
|
|
5
5
|
/* eslint-disable @typescript-eslint/require-await */
|
|
6
6
|
export function Readonly(FS) {
|
|
7
7
|
class ReadonlyFS extends FS {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
constructor(...args) {
|
|
9
|
+
super(...args);
|
|
10
|
+
this.attributes.set('no_write');
|
|
10
11
|
}
|
|
11
12
|
async rename() {
|
|
12
13
|
throw new ErrnoError(Errno.EROFS);
|
package/dist/mixins/shared.d.ts
CHANGED
package/dist/mixins/sync.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { FileSystem } from '../filesystem.js';
|
|
1
|
+
import type { FileSystem } from '../internal/filesystem.js';
|
|
2
2
|
import type { AsyncFSMethods, Mixin } from './shared.js';
|
|
3
3
|
/**
|
|
4
4
|
* Implements the asynchronous API in terms of the synchronous API.
|
|
5
5
|
*/
|
|
6
|
-
export declare function Sync<T extends
|
|
6
|
+
export declare function Sync<T extends abstract new (...args: any[]) => FileSystem>(FS: T): Mixin<T, AsyncFSMethods>;
|
package/dist/stats.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as Node from 'node:fs';
|
|
2
2
|
import type { V_Context } from './context.js';
|
|
3
|
+
import type { InodeFields, InodeLike } from './internal/inode.js';
|
|
3
4
|
import * as c from './vfs/constants.js';
|
|
4
|
-
import type { InodeFields, InodeLike } from './backends/store/inode.js';
|
|
5
5
|
/**
|
|
6
6
|
* Indicates the type of a file. Applied to 'mode'.
|
|
7
7
|
*/
|
|
@@ -57,6 +57,7 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
|
|
|
57
57
|
protected abstract _isBigint: T extends bigint ? true : false;
|
|
58
58
|
protected _convert(arg: number | bigint | string | boolean): T;
|
|
59
59
|
get blocks(): T;
|
|
60
|
+
set blocks(value: T);
|
|
60
61
|
/**
|
|
61
62
|
* Unix-style file mode (e.g. 0o644) that includes the type of the item.
|
|
62
63
|
* Type of the item can be FILE, DIRECTORY, SYMLINK, or SOCKET
|
|
@@ -150,14 +151,12 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
|
|
|
150
151
|
* Change the mode of the file.
|
|
151
152
|
* We use this helper function to prevent messing up the type of the file.
|
|
152
153
|
* @internal @deprecated
|
|
153
|
-
* @todo [BREAKING] Remove
|
|
154
154
|
*/
|
|
155
155
|
chmod(mode: number): void;
|
|
156
156
|
/**
|
|
157
157
|
* Change the owner user/group of the file.
|
|
158
158
|
* This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)
|
|
159
159
|
* @internal @deprecated
|
|
160
|
-
* @todo [BREAKING] Remove
|
|
161
160
|
*/
|
|
162
161
|
chown(uid: number, gid: number): void;
|
|
163
162
|
get atimeNs(): bigint;
|
package/dist/stats.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { credentials } from './credentials.js';
|
|
2
|
-
import * as c from './vfs/constants.js';
|
|
3
1
|
import { pick } from 'utilium';
|
|
4
|
-
import {
|
|
2
|
+
import { credentials } from './internal/credentials.js';
|
|
3
|
+
import { _inode_fields } from './internal/inode.js';
|
|
4
|
+
import { log_deprecated } from './internal/log.js';
|
|
5
|
+
import * as c from './vfs/constants.js';
|
|
5
6
|
const n1000 = BigInt(1000);
|
|
6
7
|
/**
|
|
7
8
|
* Provides information about a particular entry in the file system.
|
|
@@ -14,6 +15,7 @@ export class StatsCommon {
|
|
|
14
15
|
get blocks() {
|
|
15
16
|
return this._convert(Math.ceil(Number(this.size) / 512));
|
|
16
17
|
}
|
|
18
|
+
set blocks(value) { }
|
|
17
19
|
get atime() {
|
|
18
20
|
return new Date(Number(this.atimeMs));
|
|
19
21
|
}
|
|
@@ -153,18 +155,18 @@ export class StatsCommon {
|
|
|
153
155
|
* Change the mode of the file.
|
|
154
156
|
* We use this helper function to prevent messing up the type of the file.
|
|
155
157
|
* @internal @deprecated
|
|
156
|
-
* @todo [BREAKING] Remove
|
|
157
158
|
*/
|
|
158
159
|
chmod(mode) {
|
|
160
|
+
log_deprecated('StatsCommon#chmod');
|
|
159
161
|
this.mode = this._convert((this.mode & c.S_IFMT) | mode);
|
|
160
162
|
}
|
|
161
163
|
/**
|
|
162
164
|
* Change the owner user/group of the file.
|
|
163
165
|
* This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)
|
|
164
166
|
* @internal @deprecated
|
|
165
|
-
* @todo [BREAKING] Remove
|
|
166
167
|
*/
|
|
167
168
|
chown(uid, gid) {
|
|
169
|
+
log_deprecated('StatsCommon#chown');
|
|
168
170
|
uid = Number(uid);
|
|
169
171
|
gid = Number(gid);
|
|
170
172
|
if (!isNaN(uid) && 0 <= uid && uid < 2 ** 32) {
|