@zenfs/core 1.3.6 → 1.4.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/memory.d.ts +4 -4
- package/dist/backends/memory.js +4 -4
- package/dist/backends/overlay.d.ts +5 -2
- package/dist/backends/overlay.js +7 -10
- package/dist/backends/port/fs.js +1 -4
- package/dist/config.js +4 -8
- package/dist/context.d.ts +32 -0
- package/dist/context.js +23 -0
- package/dist/credentials.d.ts +5 -5
- package/dist/credentials.js +10 -6
- package/dist/emulation/async.d.ts +90 -89
- package/dist/emulation/async.js +76 -75
- package/dist/emulation/dir.d.ts +3 -1
- package/dist/emulation/dir.js +6 -7
- package/dist/emulation/index.d.ts +1 -1
- package/dist/emulation/index.js +1 -1
- package/dist/emulation/promises.d.ts +50 -48
- package/dist/emulation/promises.js +78 -77
- package/dist/emulation/shared.d.ts +35 -8
- package/dist/emulation/shared.js +37 -11
- package/dist/emulation/sync.d.ts +63 -62
- package/dist/emulation/sync.js +72 -73
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/stats.d.ts +2 -1
- package/dist/stats.js +5 -4
- package/package.json +3 -5
- package/scripts/test.js +78 -17
- package/tests/assignment.ts +1 -1
- package/tests/common/context.test.ts +19 -0
- package/tests/{devices.test.ts → common/devices.test.ts} +3 -3
- package/tests/{handle.test.ts → common/handle.test.ts} +1 -1
- package/tests/common/mounts.test.ts +36 -0
- package/tests/{mutex.test.ts → common/mutex.test.ts} +3 -3
- package/tests/common/path.test.ts +34 -0
- package/tests/common.ts +4 -3
- package/tests/fs/dir.test.ts +11 -11
- package/tests/fs/directory.test.ts +17 -17
- package/tests/fs/errors.test.ts +29 -39
- package/tests/fs/watch.test.ts +2 -2
- package/tests/setup/context.ts +9 -0
- package/tests/setup/cow+fetch.ts +1 -1
- package/tests/setup/memory.ts +1 -1
- package/tests/{setup/common.ts → setup.ts} +6 -5
- package/src/backends/backend.ts +0 -161
- package/src/backends/fetch.ts +0 -180
- package/src/backends/file_index.ts +0 -206
- package/src/backends/memory.ts +0 -45
- package/src/backends/overlay.ts +0 -560
- package/src/backends/port/fs.ts +0 -329
- package/src/backends/port/readme.md +0 -54
- package/src/backends/port/rpc.ts +0 -167
- package/src/backends/readme.md +0 -3
- package/src/backends/store/fs.ts +0 -667
- package/src/backends/store/readme.md +0 -9
- package/src/backends/store/simple.ts +0 -154
- package/src/backends/store/store.ts +0 -189
- package/src/config.ts +0 -227
- package/src/credentials.ts +0 -49
- package/src/devices.ts +0 -521
- package/src/emulation/async.ts +0 -834
- package/src/emulation/cache.ts +0 -86
- package/src/emulation/config.ts +0 -21
- package/src/emulation/constants.ts +0 -182
- package/src/emulation/dir.ts +0 -138
- package/src/emulation/index.ts +0 -8
- package/src/emulation/path.ts +0 -440
- package/src/emulation/promises.ts +0 -1140
- package/src/emulation/shared.ts +0 -172
- package/src/emulation/streams.ts +0 -34
- package/src/emulation/sync.ts +0 -863
- package/src/emulation/watchers.ts +0 -194
- package/src/error.ts +0 -307
- package/src/file.ts +0 -631
- package/src/filesystem.ts +0 -174
- package/src/index.ts +0 -35
- package/src/inode.ts +0 -128
- package/src/mixins/async.ts +0 -230
- package/src/mixins/index.ts +0 -5
- package/src/mixins/mutexed.ts +0 -257
- package/src/mixins/readonly.ts +0 -96
- package/src/mixins/shared.ts +0 -25
- package/src/mixins/sync.ts +0 -58
- package/src/polyfills.ts +0 -21
- package/src/stats.ts +0 -405
- package/src/utils.ts +0 -276
- package/tests/mounts.test.ts +0 -18
- package/tests/path.test.ts +0 -34
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import { SyncTransaction, type Store } from './store.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* An interface for simple synchronous stores that don't have special support for transactions and such.
|
|
5
|
-
*/
|
|
6
|
-
export interface SimpleSyncStore extends Store {
|
|
7
|
-
keys(): Iterable<bigint>;
|
|
8
|
-
get(id: bigint): Uint8Array | undefined;
|
|
9
|
-
set(id: bigint, data: Uint8Array): void;
|
|
10
|
-
delete(id: bigint): void;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* An interface for simple asynchronous stores that don't have special support for transactions and such.
|
|
15
|
-
* This class adds caching at the store level.
|
|
16
|
-
*/
|
|
17
|
-
export abstract class SimpleAsyncStore implements SimpleSyncStore {
|
|
18
|
-
public abstract name: string;
|
|
19
|
-
|
|
20
|
-
protected cache: Map<bigint, Uint8Array> = new Map();
|
|
21
|
-
|
|
22
|
-
protected queue: Set<Promise<unknown>> = new Set();
|
|
23
|
-
|
|
24
|
-
protected abstract entries(): Promise<Iterable<[bigint, Uint8Array]>>;
|
|
25
|
-
|
|
26
|
-
public keys(): Iterable<bigint> {
|
|
27
|
-
return this.cache.keys();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public get(id: bigint): Uint8Array | undefined {
|
|
31
|
-
return this.cache.get(id);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public set(id: bigint, data: Uint8Array): void {
|
|
35
|
-
this.cache.set(id, data);
|
|
36
|
-
this.queue.add(this._set(id, data));
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
protected abstract _set(ino: bigint, data: Uint8Array): Promise<void>;
|
|
40
|
-
|
|
41
|
-
public delete(id: bigint): void {
|
|
42
|
-
this.cache.delete(id);
|
|
43
|
-
this.queue.add(this._delete(id));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
protected abstract _delete(ino: bigint): Promise<void>;
|
|
47
|
-
|
|
48
|
-
public clearSync(): void {
|
|
49
|
-
this.cache.clear();
|
|
50
|
-
this.queue.add(this.clear());
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public abstract clear(): Promise<void>;
|
|
54
|
-
|
|
55
|
-
public async sync(): Promise<void> {
|
|
56
|
-
for (const [ino, data] of await this.entries()) {
|
|
57
|
-
if (!this.cache.has(ino)) {
|
|
58
|
-
this.cache.set(ino, data);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
for (const promise of this.queue) {
|
|
62
|
-
await promise;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
public transaction(): SimpleTransaction {
|
|
67
|
-
return new SimpleTransaction(this);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Transaction for simple stores.
|
|
73
|
-
* @see SimpleSyncStore
|
|
74
|
-
* @see SimpleAsyncStore
|
|
75
|
-
*/
|
|
76
|
-
export class SimpleTransaction extends SyncTransaction<SimpleSyncStore> {
|
|
77
|
-
/**
|
|
78
|
-
* Stores data in the keys we modify prior to modifying them.
|
|
79
|
-
* Allows us to roll back commits.
|
|
80
|
-
*/
|
|
81
|
-
protected originalData: Map<bigint, Uint8Array | void> = new Map();
|
|
82
|
-
/**
|
|
83
|
-
* List of keys modified in this transaction, if any.
|
|
84
|
-
*/
|
|
85
|
-
protected modifiedKeys: Set<bigint> = new Set();
|
|
86
|
-
|
|
87
|
-
protected declare store: SimpleSyncStore;
|
|
88
|
-
|
|
89
|
-
public keysSync(): Iterable<bigint> {
|
|
90
|
-
return this.store.keys();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
public getSync(id: bigint): Uint8Array {
|
|
94
|
-
const val = this.store.get(id);
|
|
95
|
-
this.stashOldValue(id, val);
|
|
96
|
-
return val!;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
public setSync(id: bigint, data: Uint8Array): void {
|
|
100
|
-
this.markModified(id);
|
|
101
|
-
return this.store.set(id, data);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
public removeSync(id: bigint): void {
|
|
105
|
-
this.markModified(id);
|
|
106
|
-
this.store.delete(id);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
public commitSync(): void {
|
|
110
|
-
this.done = true;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
public abortSync(): void {
|
|
114
|
-
if (!this.done) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
// Rollback old values.
|
|
118
|
-
for (const key of this.modifiedKeys) {
|
|
119
|
-
const value = this.originalData.get(key);
|
|
120
|
-
if (!value) {
|
|
121
|
-
// Key didn't exist.
|
|
122
|
-
this.store.delete(key);
|
|
123
|
-
} else {
|
|
124
|
-
// Key existed. Store old value.
|
|
125
|
-
this.store.set(key, value);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
this.done = true;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Stashes given key value pair into `originalData` if it doesn't already
|
|
133
|
-
* exist. Allows us to stash values the program is requesting anyway to
|
|
134
|
-
* prevent needless `get` requests if the program modifies the data later
|
|
135
|
-
* on during the transaction.
|
|
136
|
-
*/
|
|
137
|
-
protected stashOldValue(id: bigint, value?: Uint8Array): void {
|
|
138
|
-
// Keep only the earliest value in the transaction.
|
|
139
|
-
if (!this.originalData.has(id)) {
|
|
140
|
-
this.originalData.set(id, value);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Marks `ino` as modified, and stashes its value if it has not been
|
|
146
|
-
* stashed already.
|
|
147
|
-
*/
|
|
148
|
-
protected markModified(id: bigint): void {
|
|
149
|
-
this.modifiedKeys.add(id);
|
|
150
|
-
if (!this.originalData.has(id)) {
|
|
151
|
-
this.originalData.set(id, this.store.get(id));
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import { ErrnoError } from '../../error.js';
|
|
2
|
-
import '../../polyfills.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Represents a key-value store.
|
|
6
|
-
*/
|
|
7
|
-
export interface Store {
|
|
8
|
-
/**
|
|
9
|
-
* The name of the store.
|
|
10
|
-
*/
|
|
11
|
-
readonly name: string;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Syncs the store
|
|
15
|
-
*/
|
|
16
|
-
sync(): Promise<void>;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Empties the store completely.
|
|
20
|
-
*/
|
|
21
|
-
clear(): Promise<void> | void;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Empties the store completely.
|
|
25
|
-
*/
|
|
26
|
-
clearSync(): void;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Begins a new transaction.
|
|
30
|
-
*/
|
|
31
|
-
transaction(): Transaction;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* A transaction for a store.
|
|
36
|
-
*/
|
|
37
|
-
export abstract class Transaction<T extends Store = Store> {
|
|
38
|
-
public constructor(protected store: T) {}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Whether the transaction was committed or aborted
|
|
42
|
-
*/
|
|
43
|
-
protected done: boolean = false;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Gets all of the keys
|
|
47
|
-
*/
|
|
48
|
-
public abstract keys(): Promise<Iterable<bigint>>;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Gets all of the keys
|
|
52
|
-
*/
|
|
53
|
-
public abstract keysSync(): Iterable<bigint>;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Retrieves data.
|
|
57
|
-
* @param id The key to look under for data.
|
|
58
|
-
*/
|
|
59
|
-
public abstract get(id: bigint): Promise<Uint8Array>;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Retrieves data.
|
|
63
|
-
* Throws an error if an error occurs or if the key does not exist.
|
|
64
|
-
* @param id The key to look under for data.
|
|
65
|
-
* @return The data stored under the key, or undefined if not present.
|
|
66
|
-
*/
|
|
67
|
-
public abstract getSync(id: bigint): Uint8Array;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Adds the data to the store under an id. Overwrites any existing data.
|
|
71
|
-
* @param id The key to add the data under.
|
|
72
|
-
* @param data The data to add to the store.
|
|
73
|
-
*/
|
|
74
|
-
public abstract set(id: bigint, data: Uint8Array): Promise<void>;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Adds the data to the store under and id.
|
|
78
|
-
* @param id The key to add the data under.
|
|
79
|
-
* @param data The data to add to the store.
|
|
80
|
-
*/
|
|
81
|
-
public abstract setSync(id: bigint, data: Uint8Array): void;
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Deletes the data at `ino`.
|
|
85
|
-
* @param id The key to delete from the store.
|
|
86
|
-
*/
|
|
87
|
-
public abstract remove(id: bigint): Promise<void>;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Deletes the data at `ino`.
|
|
91
|
-
* @param id The key to delete from the store.
|
|
92
|
-
*/
|
|
93
|
-
public abstract removeSync(id: bigint): void;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Commits the transaction.
|
|
97
|
-
*/
|
|
98
|
-
public abstract commit(): Promise<void>;
|
|
99
|
-
|
|
100
|
-
public async [Symbol.asyncDispose]() {
|
|
101
|
-
if (this.done) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
await this.abort();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Commits the transaction.
|
|
110
|
-
*/
|
|
111
|
-
public abstract commitSync(): void;
|
|
112
|
-
|
|
113
|
-
public [Symbol.dispose]() {
|
|
114
|
-
if (this.done) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
this.abortSync();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Aborts and rolls back the transaction.
|
|
123
|
-
*/
|
|
124
|
-
public abstract abort(): Promise<void>;
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Aborts and rolls back the transaction.
|
|
128
|
-
*/
|
|
129
|
-
public abstract abortSync(): void;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Transaction that implements asynchronous operations with synchronous ones
|
|
134
|
-
*/
|
|
135
|
-
export abstract class SyncTransaction<T extends Store = Store> extends Transaction<T> {
|
|
136
|
-
/* eslint-disable @typescript-eslint/require-await */
|
|
137
|
-
public async keys(): Promise<Iterable<bigint>> {
|
|
138
|
-
return this.keysSync();
|
|
139
|
-
}
|
|
140
|
-
public async get(id: bigint): Promise<Uint8Array> {
|
|
141
|
-
return this.getSync(id);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
public async set(id: bigint, data: Uint8Array): Promise<void> {
|
|
145
|
-
return this.setSync(id, data);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
public async remove(id: bigint): Promise<void> {
|
|
149
|
-
return this.removeSync(id);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
public async commit(): Promise<void> {
|
|
153
|
-
return this.commitSync();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
public async abort(): Promise<void> {
|
|
157
|
-
return this.abortSync();
|
|
158
|
-
}
|
|
159
|
-
/* eslint-enable @typescript-eslint/require-await */
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Transaction that only supports asynchronous operations
|
|
164
|
-
*/
|
|
165
|
-
export abstract class AsyncTransaction<T extends Store = Store> extends Transaction<T> {
|
|
166
|
-
public keysSync(): never {
|
|
167
|
-
throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.keysSync');
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
public getSync(): never {
|
|
171
|
-
throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.getSync');
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
public setSync(): never {
|
|
175
|
-
throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.setSync');
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
public removeSync(): never {
|
|
179
|
-
throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.removeSync');
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
public commitSync(): never {
|
|
183
|
-
throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.commitSync');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
public abortSync(): never {
|
|
187
|
-
throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.abortSync');
|
|
188
|
-
}
|
|
189
|
-
}
|
package/src/config.ts
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import type { Backend, BackendConfiguration, FilesystemOf, SharedConfig } from './backends/backend.js';
|
|
2
|
-
import { checkOptions, isBackend, isBackendConfig } from './backends/backend.js';
|
|
3
|
-
import { useCredentials } from './credentials.js';
|
|
4
|
-
import { DeviceFS } from './devices.js';
|
|
5
|
-
import * as cache from './emulation/cache.js';
|
|
6
|
-
import { config } from './emulation/config.js';
|
|
7
|
-
import * as fs from './emulation/index.js';
|
|
8
|
-
import { Errno, ErrnoError } from './error.js';
|
|
9
|
-
import { FileSystem } from './filesystem.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Configuration for a specific mount point
|
|
13
|
-
*/
|
|
14
|
-
export type MountConfiguration<T extends Backend> = FilesystemOf<T> | BackendConfiguration<T> | T;
|
|
15
|
-
|
|
16
|
-
function isMountConfig<T extends Backend>(arg: unknown): arg is MountConfiguration<T> {
|
|
17
|
-
return isBackendConfig(arg) || isBackend(arg) || arg instanceof FileSystem;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Retrieve a file system with `configuration`.
|
|
22
|
-
* @see MountConfiguration
|
|
23
|
-
*/
|
|
24
|
-
export async function resolveMountConfig<T extends Backend>(configuration: MountConfiguration<T>, _depth = 0): Promise<FilesystemOf<T>> {
|
|
25
|
-
if (typeof configuration !== 'object' || configuration == null) {
|
|
26
|
-
throw new ErrnoError(Errno.EINVAL, 'Invalid options on mount configuration');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (!isMountConfig(configuration)) {
|
|
30
|
-
throw new ErrnoError(Errno.EINVAL, 'Invalid mount configuration');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (configuration instanceof FileSystem) {
|
|
34
|
-
await configuration.ready();
|
|
35
|
-
return configuration;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (isBackend(configuration)) {
|
|
39
|
-
configuration = { backend: configuration } as BackendConfiguration<T>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
for (const [key, value] of Object.entries(configuration)) {
|
|
43
|
-
if (key == 'backend') {
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (!isMountConfig(value)) {
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (_depth > 10) {
|
|
52
|
-
throw new ErrnoError(Errno.EINVAL, 'Invalid configuration, too deep and possibly infinite');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
(configuration as Record<string, FileSystem>)[key] = await resolveMountConfig(value, ++_depth);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const { backend } = configuration;
|
|
59
|
-
|
|
60
|
-
if (!(await backend.isAvailable())) {
|
|
61
|
-
throw new ErrnoError(Errno.EPERM, 'Backend not available: ' + backend.name);
|
|
62
|
-
}
|
|
63
|
-
await checkOptions(backend, configuration);
|
|
64
|
-
const mount = (await backend.create(configuration)) as FilesystemOf<T>;
|
|
65
|
-
mount._disableSync = configuration.disableAsyncCache || false;
|
|
66
|
-
await mount.ready();
|
|
67
|
-
return mount;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* An object mapping mount points to backends
|
|
72
|
-
*/
|
|
73
|
-
export interface ConfigMounts {
|
|
74
|
-
[K: string]: Backend;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Configuration
|
|
79
|
-
*/
|
|
80
|
-
export interface Configuration<T extends ConfigMounts> extends SharedConfig {
|
|
81
|
-
/**
|
|
82
|
-
* An object mapping mount points to mount configuration
|
|
83
|
-
*/
|
|
84
|
-
mounts: { [K in keyof T]: MountConfiguration<T[K]> };
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* The uid to use
|
|
88
|
-
* @default 0
|
|
89
|
-
*/
|
|
90
|
-
uid: number;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* The gid to use
|
|
94
|
-
* @default 0
|
|
95
|
-
*/
|
|
96
|
-
gid: number;
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Whether to automatically add normal Linux devices
|
|
100
|
-
* @experimental
|
|
101
|
-
* @default false
|
|
102
|
-
*/
|
|
103
|
-
addDevices: boolean;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* If true, enables caching stats for certain operations.
|
|
107
|
-
* This should reduce the number of stat calls performed.
|
|
108
|
-
* @experimental
|
|
109
|
-
* @default false
|
|
110
|
-
*/
|
|
111
|
-
cacheStats: boolean;
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* If true, enables caching realpath output
|
|
115
|
-
*
|
|
116
|
-
* This can increase performance.
|
|
117
|
-
* @experimental
|
|
118
|
-
* @default false
|
|
119
|
-
*/
|
|
120
|
-
cachePaths: boolean;
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* If true, disables *all* permissions checking.
|
|
124
|
-
*
|
|
125
|
-
* This can increase performance.
|
|
126
|
-
* @experimental
|
|
127
|
-
* @default false
|
|
128
|
-
*/
|
|
129
|
-
disableAccessChecks: boolean;
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* If true, disables `read` and `readSync` from updating the atime.
|
|
133
|
-
*
|
|
134
|
-
* This can increase performance.
|
|
135
|
-
* @experimental
|
|
136
|
-
* @default false
|
|
137
|
-
*/
|
|
138
|
-
disableUpdateOnRead: boolean;
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* If true, files will only sync to the file system when closed.
|
|
142
|
-
*
|
|
143
|
-
* This can increase performance.
|
|
144
|
-
* @experimental
|
|
145
|
-
* @overrides `disableUpdateOnRead`
|
|
146
|
-
* @default false
|
|
147
|
-
*/
|
|
148
|
-
onlySyncOnClose: boolean;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Configures ZenFS with single mount point /
|
|
153
|
-
*/
|
|
154
|
-
export async function configureSingle<T extends Backend>(configuration: MountConfiguration<T>): Promise<void> {
|
|
155
|
-
if (!isBackendConfig(configuration)) {
|
|
156
|
-
throw new TypeError('Invalid single mount point configuration');
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const resolved = await resolveMountConfig(configuration);
|
|
160
|
-
fs.umount('/');
|
|
161
|
-
fs.mount('/', resolved);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Like `fs.mount`, but it also creates missing directories.
|
|
166
|
-
* @privateRemarks
|
|
167
|
-
* This is implemented as a separate function to avoid a circular dependency between emulation/shared.ts and other emulation layer files.
|
|
168
|
-
* @internal
|
|
169
|
-
*/
|
|
170
|
-
async function mount(path: string, mount: FileSystem): Promise<void> {
|
|
171
|
-
if (path == '/') {
|
|
172
|
-
fs.mount(path, mount);
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const stats = await fs.promises.stat(path).catch(() => null);
|
|
177
|
-
if (!stats) {
|
|
178
|
-
await fs.promises.mkdir(path, { recursive: true });
|
|
179
|
-
} else if (!stats.isDirectory()) {
|
|
180
|
-
throw ErrnoError.With('ENOTDIR', path, 'configure');
|
|
181
|
-
}
|
|
182
|
-
fs.mount(path, mount);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Configures ZenFS with `configuration`
|
|
187
|
-
* @see Configuration
|
|
188
|
-
*/
|
|
189
|
-
export async function configure<T extends ConfigMounts>(configuration: Partial<Configuration<T>>): Promise<void> {
|
|
190
|
-
const uid = 'uid' in configuration ? configuration.uid || 0 : 0;
|
|
191
|
-
const gid = 'gid' in configuration ? configuration.gid || 0 : 0;
|
|
192
|
-
|
|
193
|
-
useCredentials({ uid, gid });
|
|
194
|
-
|
|
195
|
-
cache.stats.isEnabled = configuration.cacheStats ?? false;
|
|
196
|
-
cache.paths.isEnabled = configuration.cachePaths ?? false;
|
|
197
|
-
config.checkAccess = !configuration.disableAccessChecks;
|
|
198
|
-
config.updateOnRead = !configuration.disableUpdateOnRead;
|
|
199
|
-
config.syncImmediately = !configuration.onlySyncOnClose;
|
|
200
|
-
|
|
201
|
-
if (configuration.mounts) {
|
|
202
|
-
const toMount: [string, FileSystem][] = [];
|
|
203
|
-
let unmountRoot = false;
|
|
204
|
-
|
|
205
|
-
for (const [_point, mountConfig] of Object.entries(configuration.mounts)) {
|
|
206
|
-
const point = _point.startsWith('/') ? _point : '/' + _point;
|
|
207
|
-
|
|
208
|
-
if (isBackendConfig(mountConfig)) {
|
|
209
|
-
mountConfig.disableAsyncCache ??= configuration.disableAsyncCache || false;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (point == '/') unmountRoot = true;
|
|
213
|
-
toMount.push([point, await resolveMountConfig(mountConfig)]);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (unmountRoot) fs.umount('/');
|
|
217
|
-
|
|
218
|
-
await Promise.all(toMount.map(([point, fs]) => mount(point, fs)));
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (configuration.addDevices) {
|
|
222
|
-
const devfs = new DeviceFS();
|
|
223
|
-
devfs.addDefaults();
|
|
224
|
-
await devfs.ready();
|
|
225
|
-
await mount('/dev', devfs);
|
|
226
|
-
}
|
|
227
|
-
}
|
package/src/credentials.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Credentials used for various operations.
|
|
3
|
-
* Similar to Linux's cred struct.
|
|
4
|
-
* @see https://github.com/torvalds/linux/blob/master/include/linux/cred.h
|
|
5
|
-
*/
|
|
6
|
-
export interface Credentials {
|
|
7
|
-
uid: number;
|
|
8
|
-
gid: number;
|
|
9
|
-
suid: number;
|
|
10
|
-
sgid: number;
|
|
11
|
-
euid: number;
|
|
12
|
-
egid: number;
|
|
13
|
-
/**
|
|
14
|
-
* List of group IDs.
|
|
15
|
-
*/
|
|
16
|
-
groups: number[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const credentials: Credentials = {
|
|
20
|
-
uid: 0,
|
|
21
|
-
gid: 0,
|
|
22
|
-
suid: 0,
|
|
23
|
-
sgid: 0,
|
|
24
|
-
euid: 0,
|
|
25
|
-
egid: 0,
|
|
26
|
-
groups: [],
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export interface CredentialInit {
|
|
30
|
-
uid: number;
|
|
31
|
-
gid: number;
|
|
32
|
-
suid?: number;
|
|
33
|
-
sgid?: number;
|
|
34
|
-
euid?: number;
|
|
35
|
-
egid?: number;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Uses credentials from the provided uid and gid.
|
|
40
|
-
*/
|
|
41
|
-
export function useCredentials(source: CredentialInit): void {
|
|
42
|
-
Object.assign(credentials, {
|
|
43
|
-
suid: source.uid,
|
|
44
|
-
sgid: source.gid,
|
|
45
|
-
euid: source.uid,
|
|
46
|
-
egid: source.gid,
|
|
47
|
-
...source,
|
|
48
|
-
});
|
|
49
|
-
}
|