@zenfs/core 1.8.7 → 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 +33 -49
- 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/mixins/sync.js +6 -0
- 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/write.test.ts +1 -1
- 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
package/dist/backends/port/fs.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { pick } from 'utilium';
|
|
2
2
|
import { resolveMountConfig } from '../../config.js';
|
|
3
|
-
import { Errno, ErrnoError } from '../../error.js';
|
|
4
|
-
import { FileSystem } from '../../filesystem.js';
|
|
3
|
+
import { Errno, ErrnoError } from '../../internal/error.js';
|
|
4
|
+
import { FileSystem } from '../../internal/filesystem.js';
|
|
5
|
+
import { err, info } from '../../internal/log.js';
|
|
5
6
|
import { Async } from '../../mixins/async.js';
|
|
6
7
|
import { Stats } from '../../stats.js';
|
|
7
|
-
import { decodeUTF8 } from '../../utils.js';
|
|
8
8
|
import { InMemory } from '../memory.js';
|
|
9
9
|
import * as RPC from './rpc.js';
|
|
10
10
|
/**
|
|
@@ -18,21 +18,15 @@ export class PortFS extends Async(FileSystem) {
|
|
|
18
18
|
* Constructs a new PortFS instance that connects with the FS running on `options.port`.
|
|
19
19
|
*/
|
|
20
20
|
constructor(options) {
|
|
21
|
-
super();
|
|
21
|
+
super(0x706f7274, 'portfs');
|
|
22
22
|
this.options = options;
|
|
23
23
|
/**`
|
|
24
24
|
* @hidden
|
|
25
25
|
*/
|
|
26
|
-
this._sync = InMemory.create({ name: 'port
|
|
26
|
+
this._sync = InMemory.create({ name: 'tmpfs:port' });
|
|
27
27
|
this.port = options.port;
|
|
28
28
|
RPC.attach(this.port, RPC.handleResponse);
|
|
29
29
|
}
|
|
30
|
-
metadata() {
|
|
31
|
-
return {
|
|
32
|
-
...super.metadata(),
|
|
33
|
-
name: 'PortFS',
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
30
|
rpc(method, ...args) {
|
|
37
31
|
return RPC.request({ method, args }, {
|
|
38
32
|
...this.options,
|
|
@@ -130,7 +124,7 @@ const _Port = {
|
|
|
130
124
|
validator(port) {
|
|
131
125
|
// Check for a `postMessage` function.
|
|
132
126
|
if (typeof (port === null || port === void 0 ? void 0 : port.postMessage) != 'function') {
|
|
133
|
-
throw new ErrnoError(Errno.EINVAL, 'option must be a port.');
|
|
127
|
+
throw err(new ErrnoError(Errno.EINVAL, 'option must be a port.'));
|
|
134
128
|
}
|
|
135
129
|
},
|
|
136
130
|
},
|
|
@@ -146,5 +140,6 @@ export async function resolveRemoteMount(port, config, _depth = 0) {
|
|
|
146
140
|
const fs = await resolveMountConfig(config, _depth);
|
|
147
141
|
attachFS(port, fs);
|
|
148
142
|
stopAndReplay(fs);
|
|
143
|
+
info('Resolved remote mount: ' + fs.toString());
|
|
149
144
|
return fs;
|
|
150
145
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TransferListItem } from 'node:worker_threads';
|
|
2
2
|
import type { WithOptional } from 'utilium';
|
|
3
|
-
import type { ErrnoErrorJSON } from '../../error.js';
|
|
3
|
+
import type { ErrnoErrorJSON } from '../../internal/error.js';
|
|
4
4
|
import type { Backend, FilesystemOf } from '../backend.js';
|
|
5
5
|
import type { PortFS } from './fs.js';
|
|
6
6
|
import { type StatsLike } from '../../stats.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Errno, ErrnoError } from '../../error.js';
|
|
2
|
-
import { LazyFile } from '../../file.js';
|
|
1
|
+
import { Errno, ErrnoError } from '../../internal/error.js';
|
|
2
|
+
import { LazyFile } from '../../internal/file.js';
|
|
3
|
+
import { err, info } from '../../internal/log.js';
|
|
3
4
|
import { Stats } from '../../stats.js';
|
|
4
5
|
import { handleRequest } from './fs.js';
|
|
5
6
|
function isFileData(value) {
|
|
@@ -12,15 +13,16 @@ export function isMessage(arg) {
|
|
|
12
13
|
const executors = new Map();
|
|
13
14
|
export function request(request, { port, timeout = 1000, fs } = {}) {
|
|
14
15
|
const stack = '\n' + new Error().stack.slice('Error:'.length);
|
|
15
|
-
if (!port)
|
|
16
|
-
throw ErrnoError.
|
|
17
|
-
}
|
|
16
|
+
if (!port)
|
|
17
|
+
throw err(new ErrnoError(Errno.EINVAL, 'Can not make an RPC request without a port'));
|
|
18
18
|
return new Promise((resolve, reject) => {
|
|
19
19
|
const id = Math.random().toString(16).slice(10);
|
|
20
20
|
executors.set(id, { resolve, reject, fs });
|
|
21
21
|
port.postMessage({ ...request, _zenfs: true, id, stack });
|
|
22
22
|
const _ = setTimeout(() => {
|
|
23
|
-
const error = new ErrnoError(Errno.EIO, 'RPC Failed', typeof request.args[0] == 'string' ? request.args[0] : '', request.method)
|
|
23
|
+
const error = err(new ErrnoError(Errno.EIO, 'RPC Failed', typeof request.args[0] == 'string' ? request.args[0] : '', request.method), {
|
|
24
|
+
fs,
|
|
25
|
+
});
|
|
24
26
|
error.stack += stack;
|
|
25
27
|
reject(error);
|
|
26
28
|
if (typeof _ == 'object')
|
|
@@ -34,7 +36,7 @@ export function handleResponse(response) {
|
|
|
34
36
|
}
|
|
35
37
|
const { id, value, error, stack } = response;
|
|
36
38
|
if (!executors.has(id)) {
|
|
37
|
-
const error = new ErrnoError(Errno.EIO, 'Invalid RPC id:' + id);
|
|
39
|
+
const error = err(new ErrnoError(Errno.EIO, 'Invalid RPC id:' + id));
|
|
38
40
|
error.stack += stack;
|
|
39
41
|
throw error;
|
|
40
42
|
}
|
|
@@ -58,17 +60,17 @@ export function handleResponse(response) {
|
|
|
58
60
|
return;
|
|
59
61
|
}
|
|
60
62
|
export function attach(port, handler) {
|
|
61
|
-
if (!port)
|
|
62
|
-
throw ErrnoError.
|
|
63
|
-
|
|
63
|
+
if (!port)
|
|
64
|
+
throw err(new ErrnoError(Errno.EINVAL, 'Cannot attach to non-existent port'));
|
|
65
|
+
info('Attached handler to port: ' + handler.name);
|
|
64
66
|
port['on' in port ? 'on' : 'addEventListener']('message', (message) => {
|
|
65
67
|
handler('data' in message ? message.data : message);
|
|
66
68
|
});
|
|
67
69
|
}
|
|
68
70
|
export function detach(port, handler) {
|
|
69
|
-
if (!port)
|
|
70
|
-
throw ErrnoError.
|
|
71
|
-
|
|
71
|
+
if (!port)
|
|
72
|
+
throw err(new ErrnoError(Errno.EINVAL, 'Cannot detach from non-existent port'));
|
|
73
|
+
info('Detached handler from port: ' + handler.name);
|
|
72
74
|
port['off' in port ? 'off' : 'removeEventListener']('message', (message) => {
|
|
73
75
|
handler('data' in message ? message.data : message);
|
|
74
76
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { File } from '../../file.js';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
1
|
+
import type { File } from '../../internal/file.js';
|
|
2
|
+
import { Index } from '../../internal/file_index.js';
|
|
3
|
+
import type { CreationOptions, PureCreationOptions } from '../../internal/filesystem.js';
|
|
4
|
+
import { FileSystem } from '../../internal/filesystem.js';
|
|
5
|
+
import { Inode, type InodeLike } from '../../internal/inode.js';
|
|
6
|
+
import type { Stats } from '../../stats.js';
|
|
7
|
+
import { WrappedTransaction, type Store } from './store.js';
|
|
8
8
|
/**
|
|
9
9
|
* A file system which uses a key-value store.
|
|
10
10
|
*
|
|
@@ -16,10 +16,35 @@ import type { Store, Transaction } from './store.js';
|
|
|
16
16
|
*/
|
|
17
17
|
export declare class StoreFS<T extends Store = Store> extends FileSystem {
|
|
18
18
|
protected readonly store: T;
|
|
19
|
+
/**
|
|
20
|
+
* A map of paths to inode IDs
|
|
21
|
+
* @internal @hidden
|
|
22
|
+
*/
|
|
23
|
+
readonly _ids: Map<string, number>;
|
|
24
|
+
/**
|
|
25
|
+
* A map of inode IDs to paths
|
|
26
|
+
* @internal @hidden
|
|
27
|
+
*/
|
|
28
|
+
readonly _paths: Map<number, Set<string>>;
|
|
29
|
+
/**
|
|
30
|
+
* Gets the first path associated with an inode
|
|
31
|
+
*/
|
|
32
|
+
_path(id: number): string | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Add a inode/path pair
|
|
35
|
+
*/
|
|
36
|
+
_add(ino: number, path: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Remove a inode/path pair
|
|
39
|
+
*/
|
|
40
|
+
_remove(ino: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* Move paths in the tables
|
|
43
|
+
*/
|
|
44
|
+
_move(from: string, to: string): void;
|
|
19
45
|
protected _initialized: boolean;
|
|
20
46
|
ready(): Promise<void>;
|
|
21
47
|
constructor(store: T);
|
|
22
|
-
metadata(): FileSystemMetadata;
|
|
23
48
|
/**
|
|
24
49
|
* Delete all contents stored in the file system.
|
|
25
50
|
* @deprecated
|
|
@@ -77,6 +102,11 @@ export declare class StoreFS<T extends Store = Store> extends FileSystem {
|
|
|
77
102
|
readSync(path: string, buffer: Uint8Array, offset: number, end: number): void;
|
|
78
103
|
write(path: string, data: Uint8Array, offset: number): Promise<void>;
|
|
79
104
|
writeSync(path: string, data: Uint8Array, offset: number): void;
|
|
105
|
+
/**
|
|
106
|
+
* Wraps a transaction
|
|
107
|
+
* @internal @hidden
|
|
108
|
+
*/
|
|
109
|
+
transaction(): WrappedTransaction;
|
|
80
110
|
/**
|
|
81
111
|
* Checks if the root directory exists. Creates it if it doesn't.
|
|
82
112
|
*/
|
|
@@ -86,75 +116,56 @@ export declare class StoreFS<T extends Store = Store> extends FileSystem {
|
|
|
86
116
|
*/
|
|
87
117
|
checkRootSync(): void;
|
|
88
118
|
/**
|
|
89
|
-
*
|
|
90
|
-
* @param parent The parent directory of the file we are attempting to find.
|
|
91
|
-
* @param filename The filename of the inode we are attempting to find, minus
|
|
92
|
-
* the parent.
|
|
119
|
+
* Populates the `_ids` and `_paths` maps with all existing files stored in the underlying `Store`.
|
|
93
120
|
*/
|
|
94
|
-
private
|
|
95
|
-
/**
|
|
96
|
-
* Helper function for findINode.
|
|
97
|
-
* @param parent The parent directory of the file we are attempting to find.
|
|
98
|
-
* @param filename The filename of the inode we are attempting to find, minus
|
|
99
|
-
* the parent.
|
|
100
|
-
* @return string The ID of the file's inode in the file system.
|
|
101
|
-
*/
|
|
102
|
-
private _findInodeSync;
|
|
121
|
+
private _populate;
|
|
103
122
|
/**
|
|
104
123
|
* Finds the Inode of `path`.
|
|
105
124
|
* @param path The path to look up.
|
|
106
125
|
* @todo memoize/cache
|
|
107
126
|
*/
|
|
108
|
-
|
|
127
|
+
protected findInode(tx: WrappedTransaction, path: string, syscall: string): Promise<Inode>;
|
|
109
128
|
/**
|
|
110
129
|
* Finds the Inode of `path`.
|
|
111
130
|
* @param path The path to look up.
|
|
112
131
|
* @return The Inode of the path p.
|
|
113
132
|
* @todo memoize/cache
|
|
114
133
|
*/
|
|
115
|
-
protected findInodeSync(tx:
|
|
116
|
-
|
|
117
|
-
* Adds a new node under a random ID. Retries before giving up in
|
|
118
|
-
* the exceedingly unlikely chance that we try to reuse a random id.
|
|
119
|
-
*/
|
|
120
|
-
protected allocNew(tx: Transaction, path: string, syscall: string): Promise<number>;
|
|
134
|
+
protected findInodeSync(tx: WrappedTransaction, path: string, syscall: string): Inode;
|
|
135
|
+
private _lastID?;
|
|
121
136
|
/**
|
|
122
|
-
*
|
|
123
|
-
* the exceedingly unlikely chance that we try to reuse a random id.
|
|
124
|
-
* @return The ino that the data was stored under.
|
|
137
|
+
* Allocates a new ID and adds the ID/path
|
|
125
138
|
*/
|
|
126
|
-
protected
|
|
139
|
+
protected allocNew(path: string, syscall: string): number;
|
|
127
140
|
/**
|
|
128
141
|
* Commits a new file (well, a FILE or a DIRECTORY) to the file system with `mode`.
|
|
129
142
|
* Note: This will commit the transaction.
|
|
130
143
|
* @param path The path to the new file.
|
|
131
|
-
* @param
|
|
132
|
-
* @param mode The mode to create the new file with.
|
|
144
|
+
* @param options The options to create the new file with.
|
|
133
145
|
* @param data The data to store at the file's data node.
|
|
134
146
|
*/
|
|
135
|
-
protected commitNew(path: string,
|
|
147
|
+
protected commitNew(path: string, options: PureCreationOptions, data: Uint8Array, syscall: string): Promise<Inode>;
|
|
136
148
|
/**
|
|
137
149
|
* Commits a new file (well, a FILE or a DIRECTORY) to the file system with `mode`.
|
|
138
150
|
* Note: This will commit the transaction.
|
|
139
151
|
* @param path The path to the new file.
|
|
140
|
-
* @param
|
|
141
|
-
* @param mode The mode to create the new file with.
|
|
152
|
+
* @param options The options to create the new file with.
|
|
142
153
|
* @param data The data to store at the file's data node.
|
|
143
154
|
* @return The Inode for the new file.
|
|
144
155
|
*/
|
|
145
|
-
protected commitNewSync(path: string,
|
|
156
|
+
protected commitNewSync(path: string, options: PureCreationOptions, data: Uint8Array, syscall: string): Inode;
|
|
146
157
|
/**
|
|
147
158
|
* Remove all traces of `path` from the file system.
|
|
148
159
|
* @param path The path to remove from the file system.
|
|
149
160
|
* @param isDir Does the path belong to a directory, or a file?
|
|
150
161
|
* @todo Update mtime.
|
|
151
162
|
*/
|
|
152
|
-
protected remove(path: string, isDir: boolean
|
|
163
|
+
protected remove(path: string, isDir: boolean): Promise<void>;
|
|
153
164
|
/**
|
|
154
165
|
* Remove all traces of `path` from the file system.
|
|
155
166
|
* @param path The path to remove from the file system.
|
|
156
167
|
* @param isDir Does the path belong to a directory, or a file?
|
|
157
168
|
* @todo Update mtime.
|
|
158
169
|
*/
|
|
159
|
-
protected removeSync(path: string, isDir: boolean
|
|
170
|
+
protected removeSync(path: string, isDir: boolean): void;
|
|
160
171
|
}
|