@zenfs/core 0.9.7 → 0.11.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/Index.d.ts +3 -3
- package/dist/backends/Index.js +23 -23
- package/dist/backends/backend.js +6 -5
- package/dist/backends/fetch.d.ts +84 -0
- package/dist/backends/fetch.js +170 -0
- package/dist/backends/{Locked.d.ts → locked.d.ts} +13 -13
- package/dist/backends/{Locked.js → locked.js} +54 -54
- package/dist/backends/{InMemory.d.ts → memory.d.ts} +7 -9
- package/dist/backends/memory.js +38 -0
- package/dist/backends/{Overlay.d.ts → overlay.d.ts} +12 -13
- package/dist/backends/{Overlay.js → overlay.js} +105 -110
- package/dist/backends/port/fs.d.ts +123 -0
- package/dist/backends/port/fs.js +239 -0
- package/dist/backends/port/rpc.d.ts +60 -0
- package/dist/backends/port/rpc.js +71 -0
- package/dist/backends/store/fs.d.ts +169 -0
- package/dist/backends/store/fs.js +743 -0
- package/dist/backends/store/simple.d.ts +64 -0
- package/dist/backends/store/simple.js +111 -0
- package/dist/backends/store/store.d.ts +111 -0
- package/dist/backends/store/store.js +62 -0
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/config.d.ts +8 -10
- package/dist/config.js +11 -11
- package/dist/emulation/async.js +6 -6
- package/dist/emulation/dir.js +2 -2
- package/dist/emulation/index.d.ts +1 -1
- package/dist/emulation/index.js +1 -1
- package/dist/emulation/path.d.ts +3 -2
- package/dist/emulation/path.js +19 -45
- package/dist/emulation/promises.d.ts +7 -12
- package/dist/emulation/promises.js +144 -146
- package/dist/emulation/shared.d.ts +5 -10
- package/dist/emulation/shared.js +9 -9
- package/dist/emulation/streams.js +3 -3
- package/dist/emulation/sync.js +25 -25
- package/dist/{ApiError.d.ts → error.d.ts} +13 -15
- package/dist/error.js +291 -0
- package/dist/file.d.ts +2 -0
- package/dist/file.js +11 -5
- package/dist/filesystem.d.ts +3 -3
- package/dist/filesystem.js +41 -44
- package/dist/index.d.ts +7 -6
- package/dist/index.js +7 -6
- package/dist/inode.d.ts +1 -1
- package/dist/mutex.js +2 -1
- package/dist/utils.d.ts +8 -7
- package/dist/utils.js +11 -12
- package/package.json +3 -3
- package/readme.md +17 -9
- package/src/backends/Index.ts +23 -23
- package/src/backends/backend.ts +8 -7
- package/src/backends/fetch.ts +229 -0
- package/src/backends/{Locked.ts → locked.ts} +55 -55
- package/src/backends/memory.ts +44 -0
- package/src/backends/{Overlay.ts → overlay.ts} +108 -114
- package/src/backends/port/fs.ts +306 -0
- package/src/backends/port/readme.md +59 -0
- package/src/backends/port/rpc.ts +144 -0
- package/src/backends/store/fs.ts +881 -0
- package/src/backends/store/readme.md +9 -0
- package/src/backends/store/simple.ts +144 -0
- package/src/backends/store/store.ts +164 -0
- package/src/config.ts +21 -25
- package/src/emulation/async.ts +6 -6
- package/src/emulation/dir.ts +2 -2
- package/src/emulation/index.ts +1 -1
- package/src/emulation/path.ts +25 -49
- package/src/emulation/promises.ts +150 -159
- package/src/emulation/shared.ts +13 -15
- package/src/emulation/streams.ts +3 -3
- package/src/emulation/sync.ts +28 -28
- package/src/{ApiError.ts → error.ts} +89 -90
- package/src/file.ts +13 -5
- package/src/filesystem.ts +44 -47
- package/src/index.ts +7 -6
- package/src/inode.ts +1 -1
- package/src/mutex.ts +3 -1
- package/src/utils.ts +16 -18
- package/tsconfig.json +2 -2
- package/dist/ApiError.js +0 -292
- package/dist/backends/AsyncStore.d.ts +0 -204
- package/dist/backends/AsyncStore.js +0 -509
- package/dist/backends/InMemory.js +0 -49
- package/dist/backends/SyncStore.d.ts +0 -213
- package/dist/backends/SyncStore.js +0 -445
- package/src/backends/AsyncStore.ts +0 -655
- package/src/backends/InMemory.ts +0 -56
- package/src/backends/SyncStore.ts +0 -589
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { Errno, ErrnoError } from '../../error.js';
|
|
2
|
+
import { File } from '../../file.js';
|
|
3
|
+
import { Async, FileSystem } from '../../filesystem.js';
|
|
4
|
+
import { Stats } from '../../stats.js';
|
|
5
|
+
import { InMemory } from '../memory.js';
|
|
6
|
+
import * as RPC from './rpc.js';
|
|
7
|
+
export class PortFile extends File {
|
|
8
|
+
constructor(fs, fd, path, position) {
|
|
9
|
+
super();
|
|
10
|
+
this.fs = fs;
|
|
11
|
+
this.fd = fd;
|
|
12
|
+
this.path = path;
|
|
13
|
+
this.position = position;
|
|
14
|
+
}
|
|
15
|
+
rpc(method, ...args) {
|
|
16
|
+
return RPC.request({
|
|
17
|
+
scope: 'file',
|
|
18
|
+
fd: this.fd,
|
|
19
|
+
method,
|
|
20
|
+
args,
|
|
21
|
+
}, this.fs.options);
|
|
22
|
+
}
|
|
23
|
+
stat() {
|
|
24
|
+
return this.rpc('stat');
|
|
25
|
+
}
|
|
26
|
+
statSync() {
|
|
27
|
+
throw ErrnoError.With('ENOSYS', this.path, 'PortFile.stat');
|
|
28
|
+
}
|
|
29
|
+
truncate(len) {
|
|
30
|
+
return this.rpc('truncate', len);
|
|
31
|
+
}
|
|
32
|
+
truncateSync() {
|
|
33
|
+
throw ErrnoError.With('ENOSYS', this.path, 'PortFile.truncate');
|
|
34
|
+
}
|
|
35
|
+
write(buffer, offset, length, position) {
|
|
36
|
+
return this.rpc('write', buffer, offset, length, position);
|
|
37
|
+
}
|
|
38
|
+
writeSync() {
|
|
39
|
+
throw ErrnoError.With('ENOSYS', this.path, 'PortFile.write');
|
|
40
|
+
}
|
|
41
|
+
async read(buffer, offset, length, position) {
|
|
42
|
+
return (await this.rpc('read', buffer, offset, length, position));
|
|
43
|
+
}
|
|
44
|
+
readSync() {
|
|
45
|
+
throw ErrnoError.With('ENOSYS', this.path, 'PortFile.read');
|
|
46
|
+
}
|
|
47
|
+
chown(uid, gid) {
|
|
48
|
+
return this.rpc('chown', uid, gid);
|
|
49
|
+
}
|
|
50
|
+
chownSync() {
|
|
51
|
+
throw ErrnoError.With('ENOSYS', this.path, 'PortFile.chown');
|
|
52
|
+
}
|
|
53
|
+
chmod(mode) {
|
|
54
|
+
return this.rpc('chmod', mode);
|
|
55
|
+
}
|
|
56
|
+
chmodSync() {
|
|
57
|
+
throw ErrnoError.With('ENOSYS', this.path, 'PortFile.chmod');
|
|
58
|
+
}
|
|
59
|
+
utimes(atime, mtime) {
|
|
60
|
+
return this.rpc('utimes', atime, mtime);
|
|
61
|
+
}
|
|
62
|
+
utimesSync() {
|
|
63
|
+
throw ErrnoError.With('ENOSYS', this.path, 'PortFile.utimes');
|
|
64
|
+
}
|
|
65
|
+
_setType(type) {
|
|
66
|
+
return this.rpc('_setType', type);
|
|
67
|
+
}
|
|
68
|
+
_setTypeSync() {
|
|
69
|
+
throw ErrnoError.With('ENOSYS', this.path, 'PortFile._setType');
|
|
70
|
+
}
|
|
71
|
+
close() {
|
|
72
|
+
return this.rpc('close');
|
|
73
|
+
}
|
|
74
|
+
closeSync() {
|
|
75
|
+
throw ErrnoError.With('ENOSYS', this.path, 'PortFile.close');
|
|
76
|
+
}
|
|
77
|
+
sync() {
|
|
78
|
+
return this.rpc('sync');
|
|
79
|
+
}
|
|
80
|
+
syncSync() {
|
|
81
|
+
throw ErrnoError.With('ENOSYS', this.path, 'PortFile.sync');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* PortFS lets you access a ZenFS instance that is running in a port, or the other way around.
|
|
86
|
+
*
|
|
87
|
+
* Note that synchronous operations are not permitted on the PortFS, regardless
|
|
88
|
+
* of the configuration option of the remote FS.
|
|
89
|
+
*/
|
|
90
|
+
export class PortFS extends Async(FileSystem) {
|
|
91
|
+
/**
|
|
92
|
+
* Constructs a new PortFS instance that connects with ZenFS running on
|
|
93
|
+
* the specified port.
|
|
94
|
+
*/
|
|
95
|
+
constructor(options) {
|
|
96
|
+
super();
|
|
97
|
+
this.options = options;
|
|
98
|
+
/**
|
|
99
|
+
* @hidden
|
|
100
|
+
*/
|
|
101
|
+
this._sync = InMemory.create({ name: 'port-tmpfs' });
|
|
102
|
+
this.port = options.port;
|
|
103
|
+
RPC.attach(this.port, RPC.handleResponse);
|
|
104
|
+
}
|
|
105
|
+
metadata() {
|
|
106
|
+
return {
|
|
107
|
+
...super.metadata(),
|
|
108
|
+
name: 'PortFS',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
rpc(method, ...args) {
|
|
112
|
+
return RPC.request({
|
|
113
|
+
scope: 'fs',
|
|
114
|
+
method,
|
|
115
|
+
args,
|
|
116
|
+
}, { ...this.options, fs: this });
|
|
117
|
+
}
|
|
118
|
+
async ready() {
|
|
119
|
+
await this.rpc('ready');
|
|
120
|
+
await super.ready();
|
|
121
|
+
}
|
|
122
|
+
rename(oldPath, newPath, cred) {
|
|
123
|
+
return this.rpc('rename', oldPath, newPath, cred);
|
|
124
|
+
}
|
|
125
|
+
async stat(path, cred) {
|
|
126
|
+
return new Stats(await this.rpc('stat', path, cred));
|
|
127
|
+
}
|
|
128
|
+
sync(path, data, stats) {
|
|
129
|
+
return this.rpc('sync', path, data, stats);
|
|
130
|
+
}
|
|
131
|
+
openFile(path, flag, cred) {
|
|
132
|
+
return this.rpc('openFile', path, flag, cred);
|
|
133
|
+
}
|
|
134
|
+
createFile(path, flag, mode, cred) {
|
|
135
|
+
return this.rpc('createFile', path, flag, mode, cred);
|
|
136
|
+
}
|
|
137
|
+
unlink(path, cred) {
|
|
138
|
+
return this.rpc('unlink', path, cred);
|
|
139
|
+
}
|
|
140
|
+
rmdir(path, cred) {
|
|
141
|
+
return this.rpc('rmdir', path, cred);
|
|
142
|
+
}
|
|
143
|
+
mkdir(path, mode, cred) {
|
|
144
|
+
return this.rpc('mkdir', path, mode, cred);
|
|
145
|
+
}
|
|
146
|
+
readdir(path, cred) {
|
|
147
|
+
return this.rpc('readdir', path, cred);
|
|
148
|
+
}
|
|
149
|
+
exists(path, cred) {
|
|
150
|
+
return this.rpc('exists', path, cred);
|
|
151
|
+
}
|
|
152
|
+
link(srcpath, dstpath, cred) {
|
|
153
|
+
return this.rpc('link', srcpath, dstpath, cred);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
let nextFd = 0;
|
|
157
|
+
const descriptors = new Map();
|
|
158
|
+
async function handleRequest(port, fs, request) {
|
|
159
|
+
if (!RPC.isMessage(request)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const { method, args, id, scope, stack } = request;
|
|
163
|
+
let value, error = false;
|
|
164
|
+
try {
|
|
165
|
+
switch (scope) {
|
|
166
|
+
case 'fs':
|
|
167
|
+
// @ts-expect-error 2556
|
|
168
|
+
value = await fs[method](...args);
|
|
169
|
+
if (value instanceof File) {
|
|
170
|
+
descriptors.set(++nextFd, value);
|
|
171
|
+
value = {
|
|
172
|
+
fd: nextFd,
|
|
173
|
+
path: value.path,
|
|
174
|
+
position: value.position,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
break;
|
|
178
|
+
case 'file':
|
|
179
|
+
const { fd } = request;
|
|
180
|
+
if (!descriptors.has(fd)) {
|
|
181
|
+
throw new ErrnoError(Errno.EBADF);
|
|
182
|
+
}
|
|
183
|
+
// @ts-expect-error 2556
|
|
184
|
+
value = await descriptors.get(fd)[method](...args);
|
|
185
|
+
if (method == 'close') {
|
|
186
|
+
descriptors.delete(fd);
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
default:
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
value = e;
|
|
195
|
+
error = true;
|
|
196
|
+
}
|
|
197
|
+
port.postMessage({
|
|
198
|
+
_zenfs: true,
|
|
199
|
+
scope,
|
|
200
|
+
id,
|
|
201
|
+
error,
|
|
202
|
+
method,
|
|
203
|
+
stack,
|
|
204
|
+
value: value instanceof ErrnoError ? value.toJSON() : value,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
export function attachFS(port, fs) {
|
|
208
|
+
RPC.attach(port, request => handleRequest(port, fs, request));
|
|
209
|
+
}
|
|
210
|
+
export function detachFS(port, fs) {
|
|
211
|
+
RPC.detach(port, request => handleRequest(port, fs, request));
|
|
212
|
+
}
|
|
213
|
+
export const Port = {
|
|
214
|
+
name: 'Port',
|
|
215
|
+
options: {
|
|
216
|
+
port: {
|
|
217
|
+
type: 'object',
|
|
218
|
+
required: true,
|
|
219
|
+
description: 'The target port that you want to connect to',
|
|
220
|
+
validator(port) {
|
|
221
|
+
// Check for a `postMessage` function.
|
|
222
|
+
if (typeof port?.postMessage != 'function') {
|
|
223
|
+
throw new ErrnoError(Errno.EINVAL, 'option must be a port.');
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
timeout: {
|
|
228
|
+
type: 'number',
|
|
229
|
+
required: false,
|
|
230
|
+
description: 'How long to wait before the request times out',
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
async isAvailable() {
|
|
234
|
+
return true;
|
|
235
|
+
},
|
|
236
|
+
create(options) {
|
|
237
|
+
return new PortFS(options);
|
|
238
|
+
},
|
|
239
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
3
|
+
import type { TransferListItem } from 'worker_threads';
|
|
4
|
+
import { type PortFS } from './fs.js';
|
|
5
|
+
type _MessageEvent<T = any> = T | {
|
|
6
|
+
data: T;
|
|
7
|
+
};
|
|
8
|
+
export interface Port {
|
|
9
|
+
postMessage(value: unknown, transferList?: ReadonlyArray<TransferListItem>): void;
|
|
10
|
+
on?(event: 'message', listener: (value: unknown) => void): this;
|
|
11
|
+
off?(event: 'message', listener: (value: unknown) => void): this;
|
|
12
|
+
addEventListener?(type: 'message', listener: (this: Port, ev: _MessageEvent) => void): void;
|
|
13
|
+
removeEventListener?(type: 'message', listener: (this: Port, ev: _MessageEvent) => void): void;
|
|
14
|
+
}
|
|
15
|
+
export interface Options {
|
|
16
|
+
/**
|
|
17
|
+
* The target port that you want to connect to, or the current port if in a port context.
|
|
18
|
+
*/
|
|
19
|
+
port: Port;
|
|
20
|
+
/**
|
|
21
|
+
* How long to wait for a request to complete
|
|
22
|
+
*/
|
|
23
|
+
timeout?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* An RPC message
|
|
27
|
+
*/
|
|
28
|
+
export interface Message<TScope extends string = string, TMethod extends string = string> {
|
|
29
|
+
_zenfs: true;
|
|
30
|
+
scope: TScope;
|
|
31
|
+
id: string;
|
|
32
|
+
method: TMethod;
|
|
33
|
+
stack: string;
|
|
34
|
+
}
|
|
35
|
+
export interface Request<TScope extends string = string, TMethod extends string = string, TArgs extends unknown[] = unknown[]> extends Message<TScope, TMethod> {
|
|
36
|
+
args: TArgs;
|
|
37
|
+
}
|
|
38
|
+
export interface Response<TScope extends string = string, TMethod extends string = string, TValue = unknown> extends Message<TScope, TMethod> {
|
|
39
|
+
error: boolean;
|
|
40
|
+
value: Awaited<TValue> extends File ? FileData : Awaited<TValue>;
|
|
41
|
+
}
|
|
42
|
+
export interface FileData {
|
|
43
|
+
fd: number;
|
|
44
|
+
path: string;
|
|
45
|
+
position: number;
|
|
46
|
+
}
|
|
47
|
+
export { FileData as File };
|
|
48
|
+
export declare function isMessage(arg: unknown): arg is Message<string, string>;
|
|
49
|
+
type _Executor = Parameters<ConstructorParameters<typeof Promise<any>>[0]>;
|
|
50
|
+
export interface Executor {
|
|
51
|
+
resolve: _Executor[0];
|
|
52
|
+
reject: _Executor[1];
|
|
53
|
+
fs?: PortFS;
|
|
54
|
+
}
|
|
55
|
+
export declare function request<const TRequest extends Request, TValue>(request: Omit<TRequest, 'id' | 'stack' | '_zenfs'>, { port, timeout, fs }?: Partial<Options> & {
|
|
56
|
+
fs?: PortFS;
|
|
57
|
+
}): Promise<TValue>;
|
|
58
|
+
export declare function handleResponse<const TResponse extends Response>(response: TResponse): void;
|
|
59
|
+
export declare function attach<T extends Message>(port: Port, handler: (message: T) => unknown): void;
|
|
60
|
+
export declare function detach<T extends Message>(port: Port, handler: (message: T) => unknown): void;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ErrnoError, Errno } from '../../error.js';
|
|
2
|
+
import { PortFile } from './fs.js';
|
|
3
|
+
function isFileData(value) {
|
|
4
|
+
return typeof value == 'object' && value != null && 'fd' in value && 'path' in value && 'position' in value;
|
|
5
|
+
}
|
|
6
|
+
// general types
|
|
7
|
+
export function isMessage(arg) {
|
|
8
|
+
return typeof arg == 'object' && arg != null && '_zenfs' in arg && !!arg._zenfs;
|
|
9
|
+
}
|
|
10
|
+
const executors = new Map();
|
|
11
|
+
export function request(request, { port, timeout = 1000, fs } = {}) {
|
|
12
|
+
const stack = new Error().stack.slice('Error:'.length);
|
|
13
|
+
if (!port) {
|
|
14
|
+
throw ErrnoError.With('EINVAL');
|
|
15
|
+
}
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const id = Math.random().toString(16).slice(10);
|
|
18
|
+
executors.set(id, { resolve, reject, fs });
|
|
19
|
+
port.postMessage({ ...request, _zenfs: true, id, stack });
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
const error = new ErrnoError(Errno.EIO, 'RPC Failed');
|
|
22
|
+
error.stack += stack;
|
|
23
|
+
reject(error);
|
|
24
|
+
}, timeout);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export function handleResponse(response) {
|
|
28
|
+
if (!isMessage(response)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const { id, value, error, stack } = response;
|
|
32
|
+
if (!executors.has(id)) {
|
|
33
|
+
const error = new ErrnoError(Errno.EIO, 'Invalid RPC id:' + id);
|
|
34
|
+
error.stack += stack;
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
const { resolve, reject, fs } = executors.get(id);
|
|
38
|
+
if (error) {
|
|
39
|
+
const e = ErrnoError.fromJSON(value);
|
|
40
|
+
e.stack += stack;
|
|
41
|
+
reject(e);
|
|
42
|
+
executors.delete(id);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (isFileData(value)) {
|
|
46
|
+
const { fd, path, position } = value;
|
|
47
|
+
const file = new PortFile(fs, fd, path, position);
|
|
48
|
+
resolve(file);
|
|
49
|
+
executors.delete(id);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
resolve(value);
|
|
53
|
+
executors.delete(id);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
export function attach(port, handler) {
|
|
57
|
+
if (!port) {
|
|
58
|
+
throw ErrnoError.With('EINVAL');
|
|
59
|
+
}
|
|
60
|
+
port['on' in port ? 'on' : 'addEventListener']('message', (message) => {
|
|
61
|
+
handler('data' in message ? message.data : message);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export function detach(port, handler) {
|
|
65
|
+
if (!port) {
|
|
66
|
+
throw ErrnoError.With('EINVAL');
|
|
67
|
+
}
|
|
68
|
+
port['off' in port ? 'off' : 'removeEventListener']('message', (message) => {
|
|
69
|
+
handler('data' in message ? message.data : message);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { Cred } from '../../cred.js';
|
|
2
|
+
import { PreloadFile } from '../../file.js';
|
|
3
|
+
import { FileSystem, type FileSystemMetadata } from '../../filesystem.js';
|
|
4
|
+
import { type Ino, Inode } from '../../inode.js';
|
|
5
|
+
import { type Stats, FileType } from '../../stats.js';
|
|
6
|
+
import type { Store, Transaction } from './store.js';
|
|
7
|
+
/**
|
|
8
|
+
* A synchronous key-value file system. Uses a SyncStore to store the data.
|
|
9
|
+
*
|
|
10
|
+
* We use a unique ID for each node in the file system. The root node has a fixed ID.
|
|
11
|
+
* @todo Introduce Node ID caching.
|
|
12
|
+
* @todo Check modes.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export declare class StoreFS extends FileSystem {
|
|
16
|
+
private $store;
|
|
17
|
+
protected get store(): Store;
|
|
18
|
+
protected _store?: Store;
|
|
19
|
+
private _initialized;
|
|
20
|
+
ready(): Promise<void>;
|
|
21
|
+
constructor($store: Store | Promise<Store>);
|
|
22
|
+
metadata(): FileSystemMetadata;
|
|
23
|
+
/**
|
|
24
|
+
* Delete all contents stored in the file system.
|
|
25
|
+
*/
|
|
26
|
+
empty(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Delete all contents stored in the file system.
|
|
29
|
+
*/
|
|
30
|
+
emptySync(): void;
|
|
31
|
+
/**
|
|
32
|
+
* @todo Make rename compatible with the cache.
|
|
33
|
+
*/
|
|
34
|
+
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
|
|
35
|
+
renameSync(oldPath: string, newPath: string, cred: Cred): void;
|
|
36
|
+
stat(path: string, cred: Cred): Promise<Stats>;
|
|
37
|
+
statSync(path: string, cred: Cred): Stats;
|
|
38
|
+
createFile(path: string, flag: string, mode: number, cred: Cred): Promise<PreloadFile<this>>;
|
|
39
|
+
createFileSync(path: string, flag: string, mode: number, cred: Cred): PreloadFile<this>;
|
|
40
|
+
openFile(path: string, flag: string, cred: Cred): Promise<PreloadFile<this>>;
|
|
41
|
+
openFileSync(path: string, flag: string, cred: Cred): PreloadFile<this>;
|
|
42
|
+
unlink(path: string, cred: Cred): Promise<void>;
|
|
43
|
+
unlinkSync(path: string, cred: Cred): void;
|
|
44
|
+
rmdir(path: string, cred: Cred): Promise<void>;
|
|
45
|
+
rmdirSync(path: string, cred: Cred): void;
|
|
46
|
+
mkdir(path: string, mode: number, cred: Cred): Promise<void>;
|
|
47
|
+
mkdirSync(path: string, mode: number, cred: Cred): void;
|
|
48
|
+
readdir(path: string, cred: Cred): Promise<string[]>;
|
|
49
|
+
readdirSync(path: string, cred: Cred): string[];
|
|
50
|
+
/**
|
|
51
|
+
* Updated the inode and data node at the given path
|
|
52
|
+
* @todo Ensure mtime updates properly, and use that to determine if a data update is required.
|
|
53
|
+
*/
|
|
54
|
+
sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Updated the inode and data node at the given path
|
|
57
|
+
* @todo Ensure mtime updates properly, and use that to determine if a data update is required.
|
|
58
|
+
*/
|
|
59
|
+
syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
|
|
60
|
+
link(existing: string, newpath: string, cred: Cred): Promise<void>;
|
|
61
|
+
linkSync(existing: string, newpath: string, cred: Cred): void;
|
|
62
|
+
/**
|
|
63
|
+
* Checks if the root directory exists. Creates it if it doesn't.
|
|
64
|
+
*/
|
|
65
|
+
private makeRootDirectory;
|
|
66
|
+
/**
|
|
67
|
+
* Checks if the root directory exists. Creates it if it doesn't.
|
|
68
|
+
*/
|
|
69
|
+
protected makeRootDirectorySync(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Helper function for findINode.
|
|
72
|
+
* @param parent The parent directory of the file we are attempting to find.
|
|
73
|
+
* @param filename The filename of the inode we are attempting to find, minus
|
|
74
|
+
* the parent.
|
|
75
|
+
*/
|
|
76
|
+
private _findINode;
|
|
77
|
+
/**
|
|
78
|
+
* Helper function for findINode.
|
|
79
|
+
* @param parent The parent directory of the file we are attempting to find.
|
|
80
|
+
* @param filename The filename of the inode we are attempting to find, minus
|
|
81
|
+
* the parent.
|
|
82
|
+
* @return string The ID of the file's inode in the file system.
|
|
83
|
+
*/
|
|
84
|
+
protected _findINodeSync(tx: Transaction, parent: string, filename: string, visited?: Set<string>): Ino;
|
|
85
|
+
/**
|
|
86
|
+
* Finds the Inode of the given path.
|
|
87
|
+
* @param path The path to look up.
|
|
88
|
+
* @todo memoize/cache
|
|
89
|
+
*/
|
|
90
|
+
private findINode;
|
|
91
|
+
/**
|
|
92
|
+
* Finds the Inode of the given path.
|
|
93
|
+
* @param path The path to look up.
|
|
94
|
+
* @return The Inode of the path p.
|
|
95
|
+
* @todo memoize/cache
|
|
96
|
+
*/
|
|
97
|
+
protected findINodeSync(tx: Transaction, path: string, visited?: Set<string>): Inode;
|
|
98
|
+
/**
|
|
99
|
+
* Given the ID of a node, retrieves the corresponding Inode.
|
|
100
|
+
* @param tx The transaction to use.
|
|
101
|
+
* @param path The corresponding path to the file (used for error messages).
|
|
102
|
+
* @param id The ID to look up.
|
|
103
|
+
*/
|
|
104
|
+
private getINode;
|
|
105
|
+
/**
|
|
106
|
+
* Given the ID of a node, retrieves the corresponding Inode.
|
|
107
|
+
* @param tx The transaction to use.
|
|
108
|
+
* @param path The corresponding path to the file (used for error messages).
|
|
109
|
+
* @param id The ID to look up.
|
|
110
|
+
*/
|
|
111
|
+
protected getINodeSync(tx: Transaction, id: Ino, path: string): Inode;
|
|
112
|
+
/**
|
|
113
|
+
* Given the Inode of a directory, retrieves the corresponding directory
|
|
114
|
+
* listing.
|
|
115
|
+
*/
|
|
116
|
+
private getDirListing;
|
|
117
|
+
/**
|
|
118
|
+
* Given the Inode of a directory, retrieves the corresponding directory listing.
|
|
119
|
+
*/
|
|
120
|
+
protected getDirListingSync(tx: Transaction, inode: Inode, p?: string): {
|
|
121
|
+
[fileName: string]: Ino;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Adds a new node under a random ID. Retries before giving up in
|
|
125
|
+
* the exceedingly unlikely chance that we try to reuse a random ino.
|
|
126
|
+
*/
|
|
127
|
+
private addNew;
|
|
128
|
+
/**
|
|
129
|
+
* Creates a new node under a random ID. Retries before giving up in
|
|
130
|
+
* the exceedingly unlikely chance that we try to reuse a random ino.
|
|
131
|
+
* @return The ino that the data was stored under.
|
|
132
|
+
*/
|
|
133
|
+
protected addNewSync(tx: Transaction, data: Uint8Array, path: string): Ino;
|
|
134
|
+
/**
|
|
135
|
+
* Commits a new file (well, a FILE or a DIRECTORY) to the file system with
|
|
136
|
+
* the given mode.
|
|
137
|
+
* Note: This will commit the transaction.
|
|
138
|
+
* @param path The path to the new file.
|
|
139
|
+
* @param type The type of the new file.
|
|
140
|
+
* @param mode The mode to create the new file with.
|
|
141
|
+
* @param cred The UID/GID to create the file with
|
|
142
|
+
* @param data The data to store at the file's data node.
|
|
143
|
+
*/
|
|
144
|
+
private commitNew;
|
|
145
|
+
/**
|
|
146
|
+
* Commits a new file (well, a FILE or a DIRECTORY) to the file system with the given mode.
|
|
147
|
+
* Note: This will commit the transaction.
|
|
148
|
+
* @param path The path to the new file.
|
|
149
|
+
* @param type The type of the new file.
|
|
150
|
+
* @param mode The mode to create the new file with.
|
|
151
|
+
* @param data The data to store at the file's data node.
|
|
152
|
+
* @return The Inode for the new file.
|
|
153
|
+
*/
|
|
154
|
+
protected commitNewSync(path: string, type: FileType, mode: number, cred: Cred, data?: Uint8Array): Inode;
|
|
155
|
+
/**
|
|
156
|
+
* Remove all traces of the given path from the file system.
|
|
157
|
+
* @param path The path to remove from the file system.
|
|
158
|
+
* @param isDir Does the path belong to a directory, or a file?
|
|
159
|
+
* @todo Update mtime.
|
|
160
|
+
*/
|
|
161
|
+
private remove;
|
|
162
|
+
/**
|
|
163
|
+
* Remove all traces of the given path from the file system.
|
|
164
|
+
* @param path The path to remove from the file system.
|
|
165
|
+
* @param isDir Does the path belong to a directory, or a file?
|
|
166
|
+
* @todo Update mtime.
|
|
167
|
+
*/
|
|
168
|
+
protected removeSync(path: string, isDir: boolean, cred: Cred): void;
|
|
169
|
+
}
|