@zenfs/core 1.9.3 → 1.9.5
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/fetch.d.ts +3 -0
- package/dist/backends/fetch.js +3 -0
- package/dist/backends/memory.d.ts +1 -1
- package/dist/backends/memory.js +1 -3
- package/dist/backends/overlay.d.ts +1 -0
- package/dist/backends/overlay.js +1 -0
- package/dist/backends/port/fs.d.ts +8 -2
- package/dist/backends/port/fs.js +7 -1
- package/dist/backends/port/rpc.d.ts +6 -2
- package/dist/backends/port/rpc.js +15 -4
- package/dist/backends/store/fs.d.ts +1 -4
- package/dist/backends/store/fs.js +1 -4
- package/dist/config.d.ts +0 -15
- package/dist/config.js +2 -5
- package/dist/internal/file_index.d.ts +1 -1
- package/dist/internal/file_index.js +1 -1
- package/dist/internal/index_fs.d.ts +1 -1
- package/dist/internal/index_fs.js +1 -1
- package/dist/utils.d.ts +1 -2
- package/dist/utils.js +10 -2
- package/dist/vfs/promises.d.ts +2 -2
- package/dist/vfs/promises.js +75 -84
- package/dist/vfs/shared.d.ts +10 -0
- package/dist/vfs/shared.js +1 -5
- package/dist/vfs/sync.d.ts +2 -2
- package/dist/vfs/sync.js +53 -53
- package/dist/vfs/types.d.ts +1 -13
- package/package.json +1 -1
- package/scripts/test.js +7 -4
- package/tests/backend/port.test.ts +11 -9
- package/tests/common/path.test.ts +12 -0
- package/tests/fs/links.test.ts +25 -0
- package/dist/vfs/cache.d.ts +0 -46
- package/dist/vfs/cache.js +0 -75
package/dist/backends/fetch.d.ts
CHANGED
package/dist/backends/fetch.js
CHANGED
|
@@ -10,7 +10,6 @@ export declare class InMemoryStore extends Map<number, Uint8Array> implements Sy
|
|
|
10
10
|
readonly name = "tmpfs";
|
|
11
11
|
constructor(label?: string | undefined);
|
|
12
12
|
sync(): Promise<void>;
|
|
13
|
-
clearSync(): void;
|
|
14
13
|
transaction(): SyncMapTransaction;
|
|
15
14
|
}
|
|
16
15
|
declare const _InMemory: {
|
|
@@ -31,6 +30,7 @@ export interface InMemory extends _InMemory {
|
|
|
31
30
|
/**
|
|
32
31
|
* A simple in-memory file system backed by an InMemoryStore.
|
|
33
32
|
* Files are not persisted across page loads.
|
|
33
|
+
* @category Backends and Configuration
|
|
34
34
|
*/
|
|
35
35
|
export declare const InMemory: InMemory;
|
|
36
36
|
export {};
|
package/dist/backends/memory.js
CHANGED
|
@@ -12,9 +12,6 @@ export class InMemoryStore extends Map {
|
|
|
12
12
|
this.name = 'tmpfs';
|
|
13
13
|
}
|
|
14
14
|
async sync() { }
|
|
15
|
-
clearSync() {
|
|
16
|
-
this.clear();
|
|
17
|
-
}
|
|
18
15
|
transaction() {
|
|
19
16
|
return new SyncMapTransaction(this);
|
|
20
17
|
}
|
|
@@ -33,5 +30,6 @@ const _InMemory = {
|
|
|
33
30
|
/**
|
|
34
31
|
* A simple in-memory file system backed by an InMemoryStore.
|
|
35
32
|
* Files are not persisted across page loads.
|
|
33
|
+
* @category Backends and Configuration
|
|
36
34
|
*/
|
|
37
35
|
export const InMemory = _InMemory;
|
|
@@ -117,6 +117,7 @@ export interface Overlay extends _Overlay {
|
|
|
117
117
|
/**
|
|
118
118
|
* Overlay makes a read-only filesystem writable by storing writes on a second, writable file system.
|
|
119
119
|
* Deletes are persisted via metadata stored on the writable file system.
|
|
120
|
+
* @category Backends and Configuration
|
|
120
121
|
* @internal
|
|
121
122
|
*/
|
|
122
123
|
export declare const Overlay: Overlay;
|
package/dist/backends/overlay.js
CHANGED
|
@@ -550,6 +550,7 @@ const _Overlay = {
|
|
|
550
550
|
/**
|
|
551
551
|
* Overlay makes a read-only filesystem writable by storing writes on a second, writable file system.
|
|
552
552
|
* Deletes are persisted via metadata stored on the writable file system.
|
|
553
|
+
* @category Backends and Configuration
|
|
553
554
|
* @internal
|
|
554
555
|
*/
|
|
555
556
|
export const Overlay = _Overlay;
|
|
@@ -2,12 +2,12 @@ import type { ExtractProperties } from 'utilium';
|
|
|
2
2
|
import type { Inode, InodeLike } from '../..//internal/inode.js';
|
|
3
3
|
import type { MountConfiguration } from '../../config.js';
|
|
4
4
|
import type { File } from '../../internal/file.js';
|
|
5
|
-
import type { CreationOptions,
|
|
5
|
+
import type { CreationOptions, UsageInfo } from '../../internal/filesystem.js';
|
|
6
6
|
import type { Backend, FilesystemOf } from '../backend.js';
|
|
7
7
|
import { FileSystem } from '../../internal/filesystem.js';
|
|
8
8
|
import { Stats } from '../../stats.js';
|
|
9
9
|
import * as RPC from './rpc.js';
|
|
10
|
-
type FSMethods = ExtractProperties<FileSystem, (...args: any[]) => Promise<any> |
|
|
10
|
+
type FSMethods = ExtractProperties<FileSystem, (...args: any[]) => Promise<any> | UsageInfo>;
|
|
11
11
|
type FSMethod = keyof FSMethods;
|
|
12
12
|
export type FSRequest<TMethod extends FSMethod = FSMethod> = RPC.Message & {
|
|
13
13
|
[M in TMethod]: {
|
|
@@ -73,6 +73,12 @@ declare const _Port: {
|
|
|
73
73
|
type _Port = typeof _Port;
|
|
74
74
|
export interface Port extends _Port {
|
|
75
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* @category Backends and Configuration
|
|
78
|
+
*/
|
|
76
79
|
export declare const Port: Port;
|
|
80
|
+
/**
|
|
81
|
+
* @category Backends and Configuration
|
|
82
|
+
*/
|
|
77
83
|
export declare function resolveRemoteMount<T extends Backend>(port: RPC.Port, config: MountConfiguration<T>, _depth?: number): Promise<FilesystemOf<T>>;
|
|
78
84
|
export {};
|
package/dist/backends/port/fs.js
CHANGED
|
@@ -134,12 +134,18 @@ const _Port = {
|
|
|
134
134
|
return new PortFS(options);
|
|
135
135
|
},
|
|
136
136
|
};
|
|
137
|
+
/**
|
|
138
|
+
* @category Backends and Configuration
|
|
139
|
+
*/
|
|
137
140
|
export const Port = _Port;
|
|
141
|
+
/**
|
|
142
|
+
* @category Backends and Configuration
|
|
143
|
+
*/
|
|
138
144
|
export async function resolveRemoteMount(port, config, _depth = 0) {
|
|
139
145
|
const stopAndReplay = RPC.catchMessages(port);
|
|
140
146
|
const fs = await resolveMountConfig(config, _depth);
|
|
141
147
|
attachFS(port, fs);
|
|
142
|
-
stopAndReplay(fs);
|
|
148
|
+
await stopAndReplay(fs);
|
|
143
149
|
info('Resolved remote mount: ' + fs.toString());
|
|
144
150
|
return fs;
|
|
145
151
|
}
|
|
@@ -10,7 +10,7 @@ type _MessageEvent<T = any> = T | {
|
|
|
10
10
|
/** @internal */
|
|
11
11
|
export interface Port {
|
|
12
12
|
postMessage(value: unknown, transfer?: TransferListItem[]): void;
|
|
13
|
-
on?(event: 'message', listener: (value: unknown) => void): this;
|
|
13
|
+
on?(event: 'message' | 'online', listener: (value: unknown) => void): this;
|
|
14
14
|
off?(event: 'message', listener: (value: unknown) => void): this;
|
|
15
15
|
addEventListener?(type: 'message', listener: (ev: _MessageEvent) => void): void;
|
|
16
16
|
removeEventListener?(type: 'message', listener: (ev: _MessageEvent) => void): void;
|
|
@@ -70,4 +70,8 @@ export declare function request<const TRequest extends Request, TValue>(request:
|
|
|
70
70
|
export declare function handleResponse<const TResponse extends Response>(response: TResponse): void;
|
|
71
71
|
export declare function attach<T extends Message>(port: Port, handler: (message: T) => unknown): void;
|
|
72
72
|
export declare function detach<T extends Message>(port: Port, handler: (message: T) => unknown): void;
|
|
73
|
-
export declare function catchMessages<T extends Backend>(port: Port): (fs: FilesystemOf<T>) => void
|
|
73
|
+
export declare function catchMessages<T extends Backend>(port: Port): (fs: FilesystemOf<T>) => Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
export declare function waitOnline(port: Port): Promise<void>;
|
|
@@ -64,7 +64,7 @@ export function attach(port, handler) {
|
|
|
64
64
|
throw err(new ErrnoError(Errno.EINVAL, 'Cannot attach to non-existent port'));
|
|
65
65
|
info('Attached handler to port: ' + handler.name);
|
|
66
66
|
port['on' in port ? 'on' : 'addEventListener']('message', (message) => {
|
|
67
|
-
handler('data' in message ? message.data : message);
|
|
67
|
+
handler(typeof message == 'object' && message !== null && 'data' in message ? message.data : message);
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
export function detach(port, handler) {
|
|
@@ -72,18 +72,29 @@ export function detach(port, handler) {
|
|
|
72
72
|
throw err(new ErrnoError(Errno.EINVAL, 'Cannot detach from non-existent port'));
|
|
73
73
|
info('Detached handler from port: ' + handler.name);
|
|
74
74
|
port['off' in port ? 'off' : 'removeEventListener']('message', (message) => {
|
|
75
|
-
handler('data' in message ? message.data : message);
|
|
75
|
+
handler(typeof message == 'object' && message !== null && 'data' in message ? message.data : message);
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
export function catchMessages(port) {
|
|
79
79
|
const events = [];
|
|
80
80
|
const handler = events.push.bind(events);
|
|
81
81
|
attach(port, handler);
|
|
82
|
-
return function (fs) {
|
|
82
|
+
return async function (fs) {
|
|
83
83
|
detach(port, handler);
|
|
84
84
|
for (const event of events) {
|
|
85
85
|
const request = 'data' in event ? event.data : event;
|
|
86
|
-
|
|
86
|
+
await handleRequest(port, fs, request);
|
|
87
87
|
}
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* @internal
|
|
92
|
+
*/
|
|
93
|
+
export async function waitOnline(port) {
|
|
94
|
+
if (!('on' in port))
|
|
95
|
+
return; // Only need to wait in Node.js
|
|
96
|
+
const online = Promise.withResolvers();
|
|
97
|
+
setTimeout(online.reject, 500);
|
|
98
|
+
port.on('online', online.resolve);
|
|
99
|
+
await online.promise;
|
|
100
|
+
}
|
|
@@ -6,11 +6,8 @@ import { Inode, type InodeLike } from '../../internal/inode.js';
|
|
|
6
6
|
import type { Stats } from '../../stats.js';
|
|
7
7
|
import { WrappedTransaction, type Store } from './store.js';
|
|
8
8
|
/**
|
|
9
|
-
* A file system which uses a
|
|
9
|
+
* A file system which uses a `Store`
|
|
10
10
|
*
|
|
11
|
-
* We use a unique ID for each node in the file system. The root node has a fixed ID.
|
|
12
|
-
*
|
|
13
|
-
* @todo Introduce Node ID caching?
|
|
14
11
|
* @todo Check modes?
|
|
15
12
|
* @category Stores and Transactions
|
|
16
13
|
* @internal
|
|
@@ -63,11 +63,8 @@ import { S_IFDIR, S_IFREG, S_ISGID, S_ISUID, size_max } from '../../vfs/constant
|
|
|
63
63
|
import { basename, dirname, join, parse, relative } from '../../vfs/path.js';
|
|
64
64
|
import { WrappedTransaction } from './store.js';
|
|
65
65
|
/**
|
|
66
|
-
* A file system which uses a
|
|
66
|
+
* A file system which uses a `Store`
|
|
67
67
|
*
|
|
68
|
-
* We use a unique ID for each node in the file system. The root node has a fixed ID.
|
|
69
|
-
*
|
|
70
|
-
* @todo Introduce Node ID caching?
|
|
71
68
|
* @todo Check modes?
|
|
72
69
|
* @category Stores and Transactions
|
|
73
70
|
* @internal
|
package/dist/config.d.ts
CHANGED
|
@@ -45,21 +45,6 @@ export interface Configuration<T extends ConfigMounts> extends SharedConfig {
|
|
|
45
45
|
* @default false
|
|
46
46
|
*/
|
|
47
47
|
addDevices: boolean;
|
|
48
|
-
/**
|
|
49
|
-
* If true, enables caching stats for certain operations.
|
|
50
|
-
* This should reduce the number of stat calls performed.
|
|
51
|
-
* @experimental
|
|
52
|
-
* @default false
|
|
53
|
-
*/
|
|
54
|
-
cacheStats: boolean;
|
|
55
|
-
/**
|
|
56
|
-
* If true, enables caching realpath output
|
|
57
|
-
*
|
|
58
|
-
* This can increase performance.
|
|
59
|
-
* @experimental
|
|
60
|
-
* @default false
|
|
61
|
-
*/
|
|
62
|
-
cachePaths: boolean;
|
|
63
48
|
/**
|
|
64
49
|
* If true, disables *all* permissions checking.
|
|
65
50
|
*
|
package/dist/config.js
CHANGED
|
@@ -4,7 +4,6 @@ import { DeviceFS } from './internal/devices.js';
|
|
|
4
4
|
import { Errno, ErrnoError } from './internal/error.js';
|
|
5
5
|
import { FileSystem } from './internal/filesystem.js';
|
|
6
6
|
import { configure as configureLog, crit, err, info } from './internal/log.js';
|
|
7
|
-
import * as cache from './vfs/cache.js';
|
|
8
7
|
import { config } from './vfs/config.js';
|
|
9
8
|
import * as fs from './vfs/index.js';
|
|
10
9
|
import { mounts } from './vfs/shared.js';
|
|
@@ -99,12 +98,10 @@ export function addDevice(driver, options) {
|
|
|
99
98
|
* @see Configuration
|
|
100
99
|
*/
|
|
101
100
|
export async function configure(configuration) {
|
|
102
|
-
var _a
|
|
101
|
+
var _a;
|
|
103
102
|
const uid = 'uid' in configuration ? configuration.uid || 0 : 0;
|
|
104
103
|
const gid = 'gid' in configuration ? configuration.gid || 0 : 0;
|
|
105
104
|
useCredentials({ uid, gid });
|
|
106
|
-
cache.stats.isEnabled = (_a = configuration.cacheStats) !== null && _a !== void 0 ? _a : false;
|
|
107
|
-
cache.paths.isEnabled = (_b = configuration.cachePaths) !== null && _b !== void 0 ? _b : false;
|
|
108
105
|
config.checkAccess = !configuration.disableAccessChecks;
|
|
109
106
|
config.updateOnRead = !configuration.disableUpdateOnRead;
|
|
110
107
|
config.syncImmediately = !configuration.onlySyncOnClose;
|
|
@@ -115,7 +112,7 @@ export async function configure(configuration) {
|
|
|
115
112
|
for (const [_point, mountConfig] of Object.entries(configuration.mounts).sort(([a], [b]) => (a.length > b.length ? 1 : -1))) {
|
|
116
113
|
const point = _point.startsWith('/') ? _point : '/' + _point;
|
|
117
114
|
if (isBackendConfig(mountConfig)) {
|
|
118
|
-
(
|
|
115
|
+
(_a = mountConfig.disableAsyncCache) !== null && _a !== void 0 ? _a : (mountConfig.disableAsyncCache = configuration.disableAsyncCache || false);
|
|
119
116
|
}
|
|
120
117
|
if (point == '/')
|
|
121
118
|
fs.umount('/');
|
|
@@ -4,7 +4,7 @@ import { Index } from './file_index.js';
|
|
|
4
4
|
import { FileSystem, type CreationOptions, type PureCreationOptions } from './filesystem.js';
|
|
5
5
|
import { Inode, type InodeLike } from './inode.js';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* A file system that uses an `Index` for metadata.
|
|
8
8
|
* @category Internals
|
|
9
9
|
* @internal
|
|
10
10
|
*/
|
|
@@ -9,7 +9,7 @@ import { Index } from './file_index.js';
|
|
|
9
9
|
import { FileSystem } from './filesystem.js';
|
|
10
10
|
import { Inode } from './inode.js';
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* A file system that uses an `Index` for metadata.
|
|
13
13
|
* @category Internals
|
|
14
14
|
* @internal
|
|
15
15
|
*/
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type * as fs from 'node:fs';
|
|
2
2
|
import type { ClassLike, OptionalTuple } from 'utilium';
|
|
3
3
|
import { ErrnoError } from './internal/error.js';
|
|
4
|
-
import type { AbsolutePath } from './vfs/path.js';
|
|
5
4
|
declare global {
|
|
6
5
|
function atob(data: string): string;
|
|
7
6
|
function btoa(data: string): string;
|
|
@@ -54,7 +53,7 @@ export declare function normalizeTime(time: string | number | Date): number;
|
|
|
54
53
|
* Normalizes a path
|
|
55
54
|
* @internal
|
|
56
55
|
*/
|
|
57
|
-
export declare function normalizePath(p: fs.PathLike):
|
|
56
|
+
export declare function normalizePath(p: fs.PathLike, noResolve?: boolean): string;
|
|
58
57
|
/**
|
|
59
58
|
* Normalizes options
|
|
60
59
|
* @param options options to normalize
|
package/dist/utils.js
CHANGED
|
@@ -101,15 +101,23 @@ export function normalizeTime(time) {
|
|
|
101
101
|
* Normalizes a path
|
|
102
102
|
* @internal
|
|
103
103
|
*/
|
|
104
|
-
export function normalizePath(p) {
|
|
104
|
+
export function normalizePath(p, noResolve = false) {
|
|
105
|
+
if (p instanceof URL) {
|
|
106
|
+
if (p.protocol != 'file:')
|
|
107
|
+
throw new ErrnoError(Errno.EINVAL, 'URLs must use the file: protocol');
|
|
108
|
+
p = p.pathname;
|
|
109
|
+
}
|
|
105
110
|
p = p.toString();
|
|
111
|
+
if (p.startsWith('file://'))
|
|
112
|
+
p = p.slice('file://'.length);
|
|
106
113
|
if (p.includes('\x00')) {
|
|
107
114
|
throw new ErrnoError(Errno.EINVAL, 'Path can not contain null character');
|
|
108
115
|
}
|
|
109
116
|
if (p.length == 0) {
|
|
110
117
|
throw new ErrnoError(Errno.EINVAL, 'Path can not be empty');
|
|
111
118
|
}
|
|
112
|
-
|
|
119
|
+
p = p.replaceAll(/[/\\]+/g, '/');
|
|
120
|
+
return noResolve ? p : resolve(p);
|
|
113
121
|
}
|
|
114
122
|
/**
|
|
115
123
|
* Normalizes options
|
package/dist/vfs/promises.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { Interface as ReadlineInterface } from 'readline';
|
|
|
6
6
|
import type { V_Context } from '../context.js';
|
|
7
7
|
import type { File } from '../internal/file.js';
|
|
8
8
|
import type { Stats } from '../stats.js';
|
|
9
|
-
import type { FileContents,
|
|
9
|
+
import type { FileContents, NullEnc, ReaddirOptions, ReaddirOptsI, ReaddirOptsU } from './types.js';
|
|
10
10
|
import { Buffer } from 'buffer';
|
|
11
11
|
import '../polyfills.js';
|
|
12
12
|
import { BigIntStats } from '../stats.js';
|
|
@@ -304,7 +304,7 @@ export declare function access(this: V_Context, path: fs.PathLike, mode?: number
|
|
|
304
304
|
* Asynchronous `rm`. Removes files or directories (recursively).
|
|
305
305
|
* @param path The path to the file or directory to remove.
|
|
306
306
|
*/
|
|
307
|
-
export declare function rm(this: V_Context, path: fs.PathLike, options?: fs.RmOptions
|
|
307
|
+
export declare function rm(this: V_Context, path: fs.PathLike, options?: fs.RmOptions): Promise<void>;
|
|
308
308
|
/**
|
|
309
309
|
* Asynchronous `mkdtemp`. Creates a unique temporary directory.
|
|
310
310
|
* @param prefix The directory prefix.
|