@zenfs/core 1.6.12 → 1.6.14
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/emulation/async.js
CHANGED
|
@@ -365,7 +365,7 @@ export function watchFile(path, options, listener) {
|
|
|
365
365
|
}
|
|
366
366
|
return;
|
|
367
367
|
}
|
|
368
|
-
const watcher = new StatWatcher(normalizedPath, opts);
|
|
368
|
+
const watcher = new StatWatcher(this, normalizedPath, opts);
|
|
369
369
|
watcher.on('change', (curr, prev) => {
|
|
370
370
|
const entry = statWatchers.get(normalizedPath);
|
|
371
371
|
if (!entry) {
|
|
@@ -407,7 +407,7 @@ export function unwatchFile(path, listener = nop) {
|
|
|
407
407
|
}
|
|
408
408
|
unwatchFile;
|
|
409
409
|
export function watch(path, options, listener) {
|
|
410
|
-
const watcher = new FSWatcher(normalizePath(path), typeof options == 'object' ? options : {});
|
|
410
|
+
const watcher = new FSWatcher(this, normalizePath(path), typeof options == 'object' ? options : {});
|
|
411
411
|
listener = typeof options == 'function' ? options : listener;
|
|
412
412
|
watcher.on('change', listener || nop);
|
|
413
413
|
return watcher;
|
|
@@ -295,9 +295,9 @@ export declare function lutimes(this: V_Context, path: fs.PathLike, atime: fs.Ti
|
|
|
295
295
|
*/
|
|
296
296
|
export declare function realpath(this: V_Context, path: fs.PathLike, options: fs.BufferEncodingOption): Promise<Buffer>;
|
|
297
297
|
export declare function realpath(this: V_Context, path: fs.PathLike, options?: fs.EncodingOption | BufferEncoding): Promise<string>;
|
|
298
|
-
export declare function watch(filename: fs.PathLike, options?: fs.WatchOptions | BufferEncoding): AsyncIterable<promises.FileChangeInfo<string>>;
|
|
299
|
-
export declare function watch(filename: fs.PathLike, options: fs.WatchOptions | fs.BufferEncodingOption): AsyncIterable<promises.FileChangeInfo<Buffer>>;
|
|
300
|
-
export declare function watch(filename: fs.PathLike, options?: fs.WatchOptions | string): AsyncIterable<promises.FileChangeInfo<string>> | AsyncIterable<promises.FileChangeInfo<Buffer>>;
|
|
298
|
+
export declare function watch(this: V_Context, filename: fs.PathLike, options?: fs.WatchOptions | BufferEncoding): AsyncIterable<promises.FileChangeInfo<string>>;
|
|
299
|
+
export declare function watch(this: V_Context, filename: fs.PathLike, options: fs.WatchOptions | fs.BufferEncodingOption): AsyncIterable<promises.FileChangeInfo<Buffer>>;
|
|
300
|
+
export declare function watch(this: V_Context, filename: fs.PathLike, options?: fs.WatchOptions | string): AsyncIterable<promises.FileChangeInfo<string>> | AsyncIterable<promises.FileChangeInfo<Buffer>>;
|
|
301
301
|
export declare function access(this: V_Context, path: fs.PathLike, mode?: number): Promise<void>;
|
|
302
302
|
/**
|
|
303
303
|
* Asynchronous `rm`. Removes files or directories (recursively).
|
|
@@ -928,7 +928,7 @@ realpath;
|
|
|
928
928
|
export function watch(filename, options = {}) {
|
|
929
929
|
return {
|
|
930
930
|
[Symbol.asyncIterator]() {
|
|
931
|
-
const watcher = new FSWatcher(filename.toString(), typeof options !== 'string' ? options : { encoding: options });
|
|
931
|
+
const watcher = new FSWatcher(this, filename.toString(), typeof options !== 'string' ? options : { encoding: options });
|
|
932
932
|
// A queue to hold change events, since we need to resolve them in the async iterator
|
|
933
933
|
const eventQueue = [];
|
|
934
934
|
watcher.on('change', (eventType, filename) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from 'eventemitter3';
|
|
2
2
|
import type { EventEmitter as NodeEventEmitter } from 'node:events';
|
|
3
3
|
import type * as fs from 'node:fs';
|
|
4
|
+
import type { V_Context } from '../context.js';
|
|
4
5
|
import { type Stats } from '../stats.js';
|
|
5
6
|
/**
|
|
6
7
|
* Base class for file system watchers.
|
|
@@ -9,10 +10,18 @@ import { type Stats } from '../stats.js';
|
|
|
9
10
|
* @template TEvents The type of events emitted by the watcher.
|
|
10
11
|
*/
|
|
11
12
|
declare class Watcher<TEvents extends Record<string, unknown[]> = Record<string, unknown[]>> extends EventEmitter<TEvents> implements NodeEventEmitter {
|
|
13
|
+
/**
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
readonly _context: V_Context;
|
|
12
17
|
readonly path: string;
|
|
13
18
|
off<T extends EventEmitter.EventNames<TEvents>>(event: T, fn?: (...args: any[]) => void, context?: any, once?: boolean): this;
|
|
14
19
|
removeListener<T extends EventEmitter.EventNames<TEvents>>(event: T, fn?: (...args: any[]) => void, context?: any, once?: boolean): this;
|
|
15
|
-
constructor(
|
|
20
|
+
constructor(
|
|
21
|
+
/**
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
_context: V_Context, path: string);
|
|
16
25
|
setMaxListeners(): never;
|
|
17
26
|
getMaxListeners(): never;
|
|
18
27
|
prependListener(): never;
|
|
@@ -32,7 +41,7 @@ export declare class FSWatcher<T extends string | Buffer = string | Buffer> exte
|
|
|
32
41
|
error: [error: Error];
|
|
33
42
|
}> implements fs.FSWatcher {
|
|
34
43
|
readonly options: fs.WatchOptions;
|
|
35
|
-
constructor(path: string, options: fs.WatchOptions);
|
|
44
|
+
constructor(context: V_Context, path: string, options: fs.WatchOptions);
|
|
36
45
|
close(): void;
|
|
37
46
|
[Symbol.dispose](): void;
|
|
38
47
|
}
|
|
@@ -49,7 +58,7 @@ export declare class StatWatcher extends Watcher<{
|
|
|
49
58
|
private options;
|
|
50
59
|
private intervalId?;
|
|
51
60
|
private previous?;
|
|
52
|
-
constructor(path: string, options: {
|
|
61
|
+
constructor(context: V_Context, path: string, options: {
|
|
53
62
|
persistent?: boolean;
|
|
54
63
|
interval?: number;
|
|
55
64
|
});
|
|
@@ -19,8 +19,13 @@ class Watcher extends EventEmitter {
|
|
|
19
19
|
return super.removeListener(event, fn, context, once);
|
|
20
20
|
}
|
|
21
21
|
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
22
|
-
constructor(
|
|
22
|
+
constructor(
|
|
23
|
+
/**
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
_context, path) {
|
|
23
27
|
super();
|
|
28
|
+
this._context = _context;
|
|
24
29
|
this.path = path;
|
|
25
30
|
}
|
|
26
31
|
setMaxListeners() {
|
|
@@ -51,8 +56,8 @@ class Watcher extends EventEmitter {
|
|
|
51
56
|
* @template T The type of the filename, either `string` or `Buffer`.
|
|
52
57
|
*/
|
|
53
58
|
export class FSWatcher extends Watcher {
|
|
54
|
-
constructor(path, options) {
|
|
55
|
-
super(path);
|
|
59
|
+
constructor(context, path, options) {
|
|
60
|
+
super(context, path);
|
|
56
61
|
this.options = options;
|
|
57
62
|
addWatcher(path.toString(), this);
|
|
58
63
|
}
|
|
@@ -70,8 +75,8 @@ export class FSWatcher extends Watcher {
|
|
|
70
75
|
* Instances of `StatWatcher` are used by `fs.watchFile()` to monitor changes to a file's statistics.
|
|
71
76
|
*/
|
|
72
77
|
export class StatWatcher extends Watcher {
|
|
73
|
-
constructor(path, options) {
|
|
74
|
-
super(path);
|
|
78
|
+
constructor(context, path, options) {
|
|
79
|
+
super(context, path);
|
|
75
80
|
this.options = options;
|
|
76
81
|
this.start();
|
|
77
82
|
}
|
|
@@ -130,6 +135,7 @@ export function removeWatcher(path, watcher) {
|
|
|
130
135
|
}
|
|
131
136
|
}
|
|
132
137
|
export function emitChange(eventType, filename) {
|
|
138
|
+
var _a;
|
|
133
139
|
filename = normalizePath(filename);
|
|
134
140
|
// Notify watchers on the specific file
|
|
135
141
|
if (watchers.has(filename)) {
|
|
@@ -142,10 +148,14 @@ export function emitChange(eventType, filename) {
|
|
|
142
148
|
while (parent !== normalizedFilename) {
|
|
143
149
|
normalizedFilename = parent;
|
|
144
150
|
parent = dirname(parent);
|
|
145
|
-
if (watchers.has(parent))
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
if (!watchers.has(parent))
|
|
152
|
+
continue;
|
|
153
|
+
for (const watcher of watchers.get(parent)) {
|
|
154
|
+
// Strip the context root from the path if the watcher has a context
|
|
155
|
+
const root = (_a = watcher._context) === null || _a === void 0 ? void 0 : _a.root;
|
|
156
|
+
const contextPath = root && filename.startsWith(root) ? filename.slice(root.length) : filename;
|
|
157
|
+
const relativePath = contextPath.slice(parent.length + (parent == '/' ? 0 : 1));
|
|
158
|
+
watcher.emit('change', eventType, relativePath);
|
|
149
159
|
}
|
|
150
160
|
}
|
|
151
161
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenfs/core",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.14",
|
|
4
4
|
"description": "A filesystem, anywhere",
|
|
5
5
|
"funding": {
|
|
6
6
|
"type": "individual",
|
|
@@ -59,11 +59,6 @@
|
|
|
59
59
|
"dev": "npm run build -- --watch",
|
|
60
60
|
"prepublishOnly": "npm run build"
|
|
61
61
|
},
|
|
62
|
-
"lint-staged": {
|
|
63
|
-
"*": [
|
|
64
|
-
"prettier --write"
|
|
65
|
-
]
|
|
66
|
-
},
|
|
67
62
|
"dependencies": {
|
|
68
63
|
"@types/node": "^22.10.1",
|
|
69
64
|
"@types/readable-stream": "^4.0.10",
|
|
@@ -73,7 +68,6 @@
|
|
|
73
68
|
"utilium": "^1.1.1"
|
|
74
69
|
},
|
|
75
70
|
"optionalDependencies": {
|
|
76
|
-
"minimatch": "^9.0.3",
|
|
77
71
|
"c8": "^10.1.2"
|
|
78
72
|
},
|
|
79
73
|
"devDependencies": {
|
|
@@ -81,7 +75,6 @@
|
|
|
81
75
|
"@types/eslint__js": "^8.42.3",
|
|
82
76
|
"eslint": "^9.15.0",
|
|
83
77
|
"globals": "^15.9.0",
|
|
84
|
-
"lint-staged": "^15.2.7",
|
|
85
78
|
"prettier": "^3.2.5",
|
|
86
79
|
"tsx": "^4.19.1",
|
|
87
80
|
"typedoc": "^0.27.1",
|
package/scripts/make-index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readdirSync, statSync, writeFileSync } from 'node:fs';
|
|
3
|
-
import
|
|
3
|
+
import { matchesGlob, relative, join, resolve } from 'node:path/posix';
|
|
4
4
|
import { parseArgs } from 'node:util';
|
|
5
5
|
|
|
6
6
|
const { values: options, positionals } = parseArgs({
|
|
@@ -36,24 +36,6 @@ if (options.quiet && options.verbose) {
|
|
|
36
36
|
process.exit();
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
let matchesGlob = _path.matchesGlob;
|
|
40
|
-
|
|
41
|
-
if (matchesGlob && options.verbose) {
|
|
42
|
-
console.debug('[debug] path.matchesGlob is available.');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!matchesGlob) {
|
|
46
|
-
console.warn('Warning: path.matchesGlob is not available, falling back to minimatch. (Node 20.17.0+ or 22.5.0+ needed)');
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
const { minimatch } = await import('minimatch');
|
|
50
|
-
matchesGlob = minimatch;
|
|
51
|
-
} catch {
|
|
52
|
-
console.error('Fatal error: Failed to fall back to minimatch (is it installed?)');
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
39
|
function fixSlash(path) {
|
|
58
40
|
return path.replaceAll('\\', '/');
|
|
59
41
|
}
|
|
@@ -96,7 +78,7 @@ function computeEntries(path) {
|
|
|
96
78
|
const stats = statSync(path);
|
|
97
79
|
|
|
98
80
|
if (stats.isFile()) {
|
|
99
|
-
entries.set('/' +
|
|
81
|
+
entries.set('/' + relative(resolvedRoot, path), stats);
|
|
100
82
|
if (options.verbose) {
|
|
101
83
|
console.log(`${color('green', 'file')} ${path}`);
|
|
102
84
|
}
|
|
@@ -104,9 +86,9 @@ function computeEntries(path) {
|
|
|
104
86
|
}
|
|
105
87
|
|
|
106
88
|
for (const file of readdirSync(path)) {
|
|
107
|
-
computeEntries(
|
|
89
|
+
computeEntries(join(path, file));
|
|
108
90
|
}
|
|
109
|
-
entries.set('/' +
|
|
91
|
+
entries.set('/' + relative(resolvedRoot, path), stats);
|
|
110
92
|
if (options.verbose) {
|
|
111
93
|
console.log(`${color('bright_green', ' dir')} ${path}`);
|
|
112
94
|
}
|
|
@@ -119,7 +101,7 @@ function computeEntries(path) {
|
|
|
119
101
|
|
|
120
102
|
computeEntries(resolvedRoot);
|
|
121
103
|
if (!options.quiet) {
|
|
122
|
-
console.log('Generated listing for ' + fixSlash(
|
|
104
|
+
console.log('Generated listing for ' + fixSlash(resolve(root)));
|
|
123
105
|
}
|
|
124
106
|
|
|
125
107
|
const index = {
|