@zenfs/core 1.8.0 → 1.8.1
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/overlay.d.ts +3 -14
- package/dist/backends/overlay.js +10 -26
- package/dist/backends/passthrough.d.ts +6 -5
- package/dist/backends/passthrough.js +44 -28
- package/dist/backends/port/fs.d.ts +10 -9
- package/dist/backends/port/fs.js +13 -78
- package/dist/backends/port/rpc.d.ts +6 -2
- package/dist/backends/port/rpc.js +3 -3
- package/dist/backends/store/fs.d.ts +2 -18
- package/dist/backends/store/fs.js +21 -36
- package/dist/backends/store/index_fs.js +3 -3
- package/dist/backends/store/inode.d.ts +1 -1
- package/dist/devices.d.ts +37 -15
- package/dist/devices.js +95 -44
- package/dist/file.js +14 -30
- package/dist/filesystem.d.ts +24 -2
- package/dist/mixins/async.js +12 -6
- package/dist/mixins/mutexed.d.ts +3 -3
- package/dist/mixins/mutexed.js +5 -5
- package/dist/mixins/readonly.d.ts +17 -16
- package/dist/mixins/readonly.js +6 -0
- package/dist/utils.d.ts +6 -0
- package/dist/utils.js +26 -0
- package/dist/vfs/async.js +1 -1
- package/dist/vfs/promises.js +2 -2
- package/eslint.shared.js +1 -0
- package/package.json +1 -1
- package/tests/fs/write.test.ts +6 -11
|
@@ -24,7 +24,7 @@ export interface OverlayOptions {
|
|
|
24
24
|
*
|
|
25
25
|
* @internal
|
|
26
26
|
*/
|
|
27
|
-
export declare class
|
|
27
|
+
export declare class OverlayFS extends FileSystem {
|
|
28
28
|
ready(): Promise<void>;
|
|
29
29
|
readonly writable: FileSystem;
|
|
30
30
|
readonly readable: FileSystem;
|
|
@@ -39,8 +39,8 @@ export declare class UnmutexedOverlayFS extends FileSystem {
|
|
|
39
39
|
metadata(): FileSystemMetadata;
|
|
40
40
|
sync(path: string, data: Uint8Array, stats: Readonly<InodeLike>): Promise<void>;
|
|
41
41
|
syncSync(path: string, data: Uint8Array, stats: Readonly<InodeLike>): void;
|
|
42
|
-
read(path: string, offset: number,
|
|
43
|
-
readSync(path: string, offset: number,
|
|
42
|
+
read(path: string, buffer: Uint8Array, offset: number, end: number): Promise<void>;
|
|
43
|
+
readSync(path: string, buffer: Uint8Array, offset: number, end: number): void;
|
|
44
44
|
write(path: string, buffer: Uint8Array, offset: number): Promise<void>;
|
|
45
45
|
writeSync(path: string, buffer: Uint8Array, offset: number): void;
|
|
46
46
|
/**
|
|
@@ -97,17 +97,6 @@ export declare class UnmutexedOverlayFS extends FileSystem {
|
|
|
97
97
|
private copyToWritableSync;
|
|
98
98
|
private copyToWritable;
|
|
99
99
|
}
|
|
100
|
-
declare const OverlayFS_base: {
|
|
101
|
-
new (): import("../mixins/mutexed.js")._MutexedFS<UnmutexedOverlayFS>;
|
|
102
|
-
} & (new (args_0: OverlayOptions) => import("../mixins/mutexed.js")._MutexedFS<UnmutexedOverlayFS>);
|
|
103
|
-
/**
|
|
104
|
-
* OverlayFS makes a read-only filesystem writable by storing writes on a second,
|
|
105
|
-
* writable file system. Deletes are persisted via metadata stored on the writable
|
|
106
|
-
* file system.
|
|
107
|
-
* @internal
|
|
108
|
-
*/
|
|
109
|
-
export declare class OverlayFS extends OverlayFS_base {
|
|
110
|
-
}
|
|
111
100
|
declare const _Overlay: {
|
|
112
101
|
readonly name: "Overlay";
|
|
113
102
|
readonly options: {
|
package/dist/backends/overlay.js
CHANGED
|
@@ -51,9 +51,8 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
53
|
import { Errno, ErrnoError } from '../error.js';
|
|
54
|
-
import {
|
|
54
|
+
import { LazyFile, parseFlag } from '../file.js';
|
|
55
55
|
import { FileSystem } from '../filesystem.js';
|
|
56
|
-
import { Mutexed } from '../mixins/mutexed.js';
|
|
57
56
|
import { canary, decodeUTF8, encodeUTF8 } from '../utils.js';
|
|
58
57
|
import { dirname, join } from '../vfs/path.js';
|
|
59
58
|
/** @internal */
|
|
@@ -66,7 +65,7 @@ const deletionLogPath = '/.deleted';
|
|
|
66
65
|
*
|
|
67
66
|
* @internal
|
|
68
67
|
*/
|
|
69
|
-
export class
|
|
68
|
+
export class OverlayFS extends FileSystem {
|
|
70
69
|
async ready() {
|
|
71
70
|
await this.readable.ready();
|
|
72
71
|
await this.writable.ready();
|
|
@@ -103,11 +102,11 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
103
102
|
this.copyForWriteSync(path);
|
|
104
103
|
this.writable.syncSync(path, data, stats);
|
|
105
104
|
}
|
|
106
|
-
async read(path, offset,
|
|
107
|
-
return (await this.writable.exists(path)) ? await this.writable.read(path, offset,
|
|
105
|
+
async read(path, buffer, offset, end) {
|
|
106
|
+
return (await this.writable.exists(path)) ? await this.writable.read(path, buffer, offset, end) : await this.readable.read(path, buffer, offset, end);
|
|
108
107
|
}
|
|
109
|
-
readSync(path, offset,
|
|
110
|
-
return this.writable.existsSync(path) ? this.writable.readSync(path, offset,
|
|
108
|
+
readSync(path, buffer, offset, end) {
|
|
109
|
+
return this.writable.existsSync(path) ? this.writable.readSync(path, buffer, offset, end) : this.readable.readSync(path, buffer, offset, end);
|
|
111
110
|
}
|
|
112
111
|
async write(path, buffer, offset) {
|
|
113
112
|
await this.copyForWrite(path);
|
|
@@ -210,22 +209,15 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
210
209
|
if (await this.writable.exists(path)) {
|
|
211
210
|
return this.writable.openFile(path, flag);
|
|
212
211
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const stats = await file.stat();
|
|
216
|
-
const { buffer } = await file.read(new Uint8Array(stats.size));
|
|
217
|
-
return new PreloadFile(this, path, flag, stats, buffer);
|
|
212
|
+
const stats = await this.readable.stat(path);
|
|
213
|
+
return new LazyFile(this, path, flag, stats);
|
|
218
214
|
}
|
|
219
215
|
openFileSync(path, flag) {
|
|
220
216
|
if (this.writable.existsSync(path)) {
|
|
221
217
|
return this.writable.openFileSync(path, flag);
|
|
222
218
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const stats = file.statSync();
|
|
226
|
-
const data = new Uint8Array(stats.size);
|
|
227
|
-
file.readSync(data);
|
|
228
|
-
return new PreloadFile(this, path, flag, stats, data);
|
|
219
|
+
const stats = this.readable.statSync(path);
|
|
220
|
+
return new LazyFile(this, path, flag, stats);
|
|
229
221
|
}
|
|
230
222
|
async createFile(path, flag, mode, options) {
|
|
231
223
|
this.checkInitialized();
|
|
@@ -547,14 +539,6 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
547
539
|
}
|
|
548
540
|
}
|
|
549
541
|
}
|
|
550
|
-
/**
|
|
551
|
-
* OverlayFS makes a read-only filesystem writable by storing writes on a second,
|
|
552
|
-
* writable file system. Deletes are persisted via metadata stored on the writable
|
|
553
|
-
* file system.
|
|
554
|
-
* @internal
|
|
555
|
-
*/
|
|
556
|
-
export class OverlayFS extends Mutexed(UnmutexedOverlayFS) {
|
|
557
|
-
}
|
|
558
542
|
const _Overlay = {
|
|
559
543
|
name: 'Overlay',
|
|
560
544
|
options: {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type * as fs from 'node:fs';
|
|
2
|
+
import { File } from '../file.js';
|
|
2
3
|
import { FileSystem } from '../filesystem.js';
|
|
3
4
|
import { Stats } from '../stats.js';
|
|
4
|
-
import {
|
|
5
|
+
import type { InodeLike } from './store/inode.js';
|
|
5
6
|
export type NodeFS = typeof fs;
|
|
6
7
|
export interface PassthroughOptions {
|
|
7
8
|
fs: NodeFS;
|
|
@@ -80,11 +81,11 @@ export declare class PassthroughFS extends FileSystem {
|
|
|
80
81
|
/**
|
|
81
82
|
* Synchronize data to the file system.
|
|
82
83
|
*/
|
|
83
|
-
sync(path: string, data: Uint8Array, stats:
|
|
84
|
+
sync(path: string, data: Uint8Array, stats: Readonly<InodeLike>): Promise<void>;
|
|
84
85
|
/**
|
|
85
86
|
* Synchronize data to the file system synchronously.
|
|
86
87
|
*/
|
|
87
|
-
syncSync(path: string, data: Uint8Array, stats:
|
|
88
|
+
syncSync(path: string, data: Uint8Array, stats: Readonly<InodeLike>): void;
|
|
88
89
|
/**
|
|
89
90
|
* Create a hard link.
|
|
90
91
|
*/
|
|
@@ -93,8 +94,8 @@ export declare class PassthroughFS extends FileSystem {
|
|
|
93
94
|
* Create a hard link synchronously.
|
|
94
95
|
*/
|
|
95
96
|
linkSync(target: string, link: string): void;
|
|
96
|
-
read(path: string, offset: number,
|
|
97
|
-
readSync(path: string, offset: number,
|
|
97
|
+
read(path: string, buffer: Uint8Array, offset: number, end: number): Promise<void>;
|
|
98
|
+
readSync(path: string, buffer: Uint8Array, offset: number, end: number): void;
|
|
98
99
|
write(path: string, buffer: Uint8Array, offset: number): Promise<void>;
|
|
99
100
|
writeSync(path: string, buffer: Uint8Array, offset: number): void;
|
|
100
101
|
}
|
|
@@ -50,10 +50,10 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
50
50
|
var e = new Error(message);
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
|
-
import { FileSystem } from '../filesystem.js';
|
|
54
53
|
import { ErrnoError } from '../error.js';
|
|
55
|
-
import { Stats } from '../stats.js';
|
|
56
54
|
import { File } from '../file.js';
|
|
55
|
+
import { FileSystem } from '../filesystem.js';
|
|
56
|
+
import { Stats } from '../stats.js';
|
|
57
57
|
import { join, resolve } from '../vfs/path.js';
|
|
58
58
|
class PassthroughFile extends File {
|
|
59
59
|
constructor(fs, path, fd) {
|
|
@@ -333,7 +333,23 @@ export class PassthroughFS extends FileSystem {
|
|
|
333
333
|
*/
|
|
334
334
|
async sync(path, data, stats) {
|
|
335
335
|
try {
|
|
336
|
-
|
|
336
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
337
|
+
try {
|
|
338
|
+
const handle = __addDisposableResource(env_1, await this.nodeFS.promises.open(this.path(path), 'w'), true);
|
|
339
|
+
await handle.writeFile(data);
|
|
340
|
+
await handle.chmod(stats.mode);
|
|
341
|
+
await handle.chown(stats.uid, stats.gid);
|
|
342
|
+
await handle.utimes(stats.atimeMs, stats.mtimeMs);
|
|
343
|
+
}
|
|
344
|
+
catch (e_1) {
|
|
345
|
+
env_1.error = e_1;
|
|
346
|
+
env_1.hasError = true;
|
|
347
|
+
}
|
|
348
|
+
finally {
|
|
349
|
+
const result_1 = __disposeResources(env_1);
|
|
350
|
+
if (result_1)
|
|
351
|
+
await result_1;
|
|
352
|
+
}
|
|
337
353
|
}
|
|
338
354
|
catch (err) {
|
|
339
355
|
this.error(err, path);
|
|
@@ -344,7 +360,11 @@ export class PassthroughFS extends FileSystem {
|
|
|
344
360
|
*/
|
|
345
361
|
syncSync(path, data, stats) {
|
|
346
362
|
try {
|
|
347
|
-
this.
|
|
363
|
+
const p = this.path(path);
|
|
364
|
+
this.nodeFS.writeFileSync(p, data);
|
|
365
|
+
this.nodeFS.chmodSync(p, stats.mode);
|
|
366
|
+
this.nodeFS.chownSync(p, stats.uid, stats.gid);
|
|
367
|
+
this.nodeFS.utimesSync(p, stats.atimeMs, stats.mtimeMs);
|
|
348
368
|
}
|
|
349
369
|
catch (err) {
|
|
350
370
|
this.error(err, path);
|
|
@@ -372,36 +392,32 @@ export class PassthroughFS extends FileSystem {
|
|
|
372
392
|
this.error(err, target);
|
|
373
393
|
}
|
|
374
394
|
}
|
|
375
|
-
async read(path, offset,
|
|
395
|
+
async read(path, buffer, offset, end) {
|
|
376
396
|
try {
|
|
377
|
-
const
|
|
397
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
378
398
|
try {
|
|
379
|
-
const handle = __addDisposableResource(
|
|
380
|
-
|
|
381
|
-
await handle.read({ buffer, offset, length });
|
|
382
|
-
return buffer;
|
|
399
|
+
const handle = __addDisposableResource(env_2, await this.nodeFS.promises.open(this.path(path), 'r'), true);
|
|
400
|
+
await handle.read({ buffer, offset, length: end - offset });
|
|
383
401
|
}
|
|
384
|
-
catch (
|
|
385
|
-
|
|
386
|
-
|
|
402
|
+
catch (e_2) {
|
|
403
|
+
env_2.error = e_2;
|
|
404
|
+
env_2.hasError = true;
|
|
387
405
|
}
|
|
388
406
|
finally {
|
|
389
|
-
const
|
|
390
|
-
if (
|
|
391
|
-
await
|
|
407
|
+
const result_2 = __disposeResources(env_2);
|
|
408
|
+
if (result_2)
|
|
409
|
+
await result_2;
|
|
392
410
|
}
|
|
393
411
|
}
|
|
394
412
|
catch (err) {
|
|
395
413
|
this.error(err, path);
|
|
396
414
|
}
|
|
397
415
|
}
|
|
398
|
-
readSync(path, offset,
|
|
416
|
+
readSync(path, buffer, offset, end) {
|
|
399
417
|
let fd;
|
|
400
418
|
try {
|
|
401
419
|
fd = this.nodeFS.openSync(this.path(path), 'r');
|
|
402
|
-
|
|
403
|
-
this.nodeFS.readSync(fd, buffer, { offset, length });
|
|
404
|
-
return buffer;
|
|
420
|
+
this.nodeFS.readSync(fd, buffer, { offset, length: end - offset });
|
|
405
421
|
}
|
|
406
422
|
catch (err) {
|
|
407
423
|
this.error(err, path);
|
|
@@ -415,19 +431,19 @@ export class PassthroughFS extends FileSystem {
|
|
|
415
431
|
}
|
|
416
432
|
async write(path, buffer, offset) {
|
|
417
433
|
try {
|
|
418
|
-
const
|
|
434
|
+
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
419
435
|
try {
|
|
420
|
-
const handle = __addDisposableResource(
|
|
436
|
+
const handle = __addDisposableResource(env_3, await this.nodeFS.promises.open(this.path(path), 'w'), true);
|
|
421
437
|
await handle.write(buffer, offset);
|
|
422
438
|
}
|
|
423
|
-
catch (
|
|
424
|
-
|
|
425
|
-
|
|
439
|
+
catch (e_3) {
|
|
440
|
+
env_3.error = e_3;
|
|
441
|
+
env_3.hasError = true;
|
|
426
442
|
}
|
|
427
443
|
finally {
|
|
428
|
-
const
|
|
429
|
-
if (
|
|
430
|
-
await
|
|
444
|
+
const result_3 = __disposeResources(env_3);
|
|
445
|
+
if (result_3)
|
|
446
|
+
await result_3;
|
|
431
447
|
}
|
|
432
448
|
}
|
|
433
449
|
catch (err) {
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ExtractProperties } from 'utilium';
|
|
2
2
|
import type { MountConfiguration } from '../../config.js';
|
|
3
3
|
import type { CreationOptions, FileSystemMetadata } from '../../filesystem.js';
|
|
4
4
|
import type { Backend, FilesystemOf } from '../backend.js';
|
|
5
|
-
import {
|
|
5
|
+
import type { Inode, InodeLike } from '../store/inode.js';
|
|
6
|
+
import type { File } from '../../file.js';
|
|
6
7
|
import { FileSystem } from '../../filesystem.js';
|
|
7
8
|
import { Stats } from '../../stats.js';
|
|
8
|
-
import type { Inode, InodeLike } from '../store/inode.js';
|
|
9
9
|
import * as RPC from './rpc.js';
|
|
10
10
|
type FSMethods = ExtractProperties<FileSystem, (...args: any[]) => Promise<any> | FileSystemMetadata>;
|
|
11
11
|
type FSMethod = keyof FSMethods;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
12
|
+
export type FSRequest<TMethod extends FSMethod = FSMethod> = RPC.Message & {
|
|
13
|
+
[M in TMethod]: {
|
|
14
|
+
method: M;
|
|
15
|
+
args: Parameters<FSMethods[M]>;
|
|
16
|
+
};
|
|
17
|
+
}[TMethod];
|
|
17
18
|
declare const PortFS_base: import("../../index.js").Mixin<typeof FileSystem, import("../../mixins/async.js").AsyncMixin>;
|
|
18
19
|
/**
|
|
19
20
|
* PortFS lets you access an FS instance that is running in a port, or the other way around.
|
|
@@ -46,7 +47,7 @@ export declare class PortFS extends PortFS_base {
|
|
|
46
47
|
readdir(path: string): Promise<string[]>;
|
|
47
48
|
exists(path: string): Promise<boolean>;
|
|
48
49
|
link(srcpath: string, dstpath: string): Promise<void>;
|
|
49
|
-
read(path: string, offset: number, length: number): Promise<
|
|
50
|
+
read(path: string, buffer: Uint8Array, offset: number, length: number): Promise<void>;
|
|
50
51
|
write(path: string, buffer: Uint8Array, offset: number): Promise<void>;
|
|
51
52
|
}
|
|
52
53
|
/** @internal */
|
package/dist/backends/port/fs.js
CHANGED
|
@@ -1,60 +1,6 @@
|
|
|
1
|
-
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
-
if (value !== null && value !== void 0) {
|
|
3
|
-
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
-
var dispose, inner;
|
|
5
|
-
if (async) {
|
|
6
|
-
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
-
dispose = value[Symbol.asyncDispose];
|
|
8
|
-
}
|
|
9
|
-
if (dispose === void 0) {
|
|
10
|
-
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
-
dispose = value[Symbol.dispose];
|
|
12
|
-
if (async) inner = dispose;
|
|
13
|
-
}
|
|
14
|
-
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
-
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
-
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
-
}
|
|
18
|
-
else if (async) {
|
|
19
|
-
env.stack.push({ async: true });
|
|
20
|
-
}
|
|
21
|
-
return value;
|
|
22
|
-
};
|
|
23
|
-
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
-
return function (env) {
|
|
25
|
-
function fail(e) {
|
|
26
|
-
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
-
env.hasError = true;
|
|
28
|
-
}
|
|
29
|
-
var r, s = 0;
|
|
30
|
-
function next() {
|
|
31
|
-
while (r = env.stack.pop()) {
|
|
32
|
-
try {
|
|
33
|
-
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
-
if (r.dispose) {
|
|
35
|
-
var result = r.dispose.call(r.value);
|
|
36
|
-
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
-
}
|
|
38
|
-
else s |= 1;
|
|
39
|
-
}
|
|
40
|
-
catch (e) {
|
|
41
|
-
fail(e);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
-
if (env.hasError) throw env.error;
|
|
46
|
-
}
|
|
47
|
-
return next();
|
|
48
|
-
};
|
|
49
|
-
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
-
var e = new Error(message);
|
|
51
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
-
});
|
|
53
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
54
1
|
import { pick } from 'utilium';
|
|
55
2
|
import { resolveMountConfig } from '../../config.js';
|
|
56
3
|
import { Errno, ErrnoError } from '../../error.js';
|
|
57
|
-
import { File } from '../../file.js';
|
|
58
4
|
import { FileSystem } from '../../filesystem.js';
|
|
59
5
|
import { Async } from '../../mixins/async.js';
|
|
60
6
|
import { Stats } from '../../stats.js';
|
|
@@ -127,8 +73,9 @@ export class PortFS extends Async(FileSystem) {
|
|
|
127
73
|
link(srcpath, dstpath) {
|
|
128
74
|
return this.rpc('link', srcpath, dstpath);
|
|
129
75
|
}
|
|
130
|
-
read(path, offset, length) {
|
|
131
|
-
|
|
76
|
+
async read(path, buffer, offset, length) {
|
|
77
|
+
const _buf = (await this.rpc('read', path, buffer, offset, length));
|
|
78
|
+
buffer.set(_buf);
|
|
132
79
|
}
|
|
133
80
|
write(path, buffer, offset) {
|
|
134
81
|
return this.rpc('write', path, buffer, offset);
|
|
@@ -140,41 +87,29 @@ export async function handleRequest(port, fs, request) {
|
|
|
140
87
|
return;
|
|
141
88
|
const { method, args, id, stack } = request;
|
|
142
89
|
let value, error = false;
|
|
143
|
-
const transfer = [];
|
|
144
90
|
try {
|
|
145
91
|
// @ts-expect-error 2556
|
|
146
92
|
value = await fs[method](...args);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const file = __addDisposableResource(env_1, await fs.openFile(args[0], 'r+'), true);
|
|
151
|
-
const stats = await file.stat();
|
|
152
|
-
const data = new Uint8Array(stats.size);
|
|
153
|
-
await file.read(data);
|
|
93
|
+
switch (method) {
|
|
94
|
+
case 'openFile':
|
|
95
|
+
case 'createFile': {
|
|
154
96
|
value = {
|
|
155
|
-
path:
|
|
97
|
+
path: args[0],
|
|
156
98
|
flag: args[1],
|
|
157
|
-
stats,
|
|
158
|
-
buffer: data.buffer,
|
|
99
|
+
stats: await fs.stat(args[0]),
|
|
159
100
|
};
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
catch (e_1) {
|
|
163
|
-
env_1.error = e_1;
|
|
164
|
-
env_1.hasError = true;
|
|
165
|
-
}
|
|
166
|
-
finally {
|
|
167
|
-
const result_1 = __disposeResources(env_1);
|
|
168
|
-
if (result_1)
|
|
169
|
-
await result_1;
|
|
101
|
+
break;
|
|
170
102
|
}
|
|
103
|
+
case 'read':
|
|
104
|
+
value = args[1];
|
|
105
|
+
break;
|
|
171
106
|
}
|
|
172
107
|
}
|
|
173
108
|
catch (e) {
|
|
174
109
|
value = e instanceof ErrnoError ? e.toJSON() : pick(e, 'message', 'stack');
|
|
175
110
|
error = true;
|
|
176
111
|
}
|
|
177
|
-
port.postMessage({ _zenfs: true, id, error, method, stack, value }
|
|
112
|
+
port.postMessage({ _zenfs: true, id, error, method, stack, value });
|
|
178
113
|
}
|
|
179
114
|
export function attachFS(port, fs) {
|
|
180
115
|
RPC.attach(port, request => handleRequest(port, fs, request));
|
|
@@ -45,12 +45,16 @@ interface _ResponseWithValue<T> extends Message {
|
|
|
45
45
|
error: false;
|
|
46
46
|
value: Awaited<T> extends File ? FileData : Awaited<T>;
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
interface _ResponseRead extends Message {
|
|
49
|
+
error: false;
|
|
50
|
+
method: 'read';
|
|
51
|
+
value: Uint8Array;
|
|
52
|
+
}
|
|
53
|
+
export type Response<T = unknown> = _ResponseWithError | _ResponseWithValue<T> | _ResponseRead;
|
|
49
54
|
export interface FileData {
|
|
50
55
|
path: string;
|
|
51
56
|
flag: string;
|
|
52
57
|
stats: StatsLike<number>;
|
|
53
|
-
buffer: ArrayBuffer;
|
|
54
58
|
}
|
|
55
59
|
export { FileData as File };
|
|
56
60
|
export declare function isMessage(arg: unknown): arg is Message;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Errno, ErrnoError } from '../../error.js';
|
|
2
|
-
import {
|
|
2
|
+
import { LazyFile } from '../../file.js';
|
|
3
3
|
import { Stats } from '../../stats.js';
|
|
4
4
|
import { handleRequest } from './fs.js';
|
|
5
5
|
function isFileData(value) {
|
|
@@ -47,8 +47,8 @@ export function handleResponse(response) {
|
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
if (isFileData(value)) {
|
|
50
|
-
const { path, flag, stats
|
|
51
|
-
const file = new
|
|
50
|
+
const { path, flag, stats } = value;
|
|
51
|
+
const file = new LazyFile(fs, path, flag, new Stats(stats));
|
|
52
52
|
resolve(file);
|
|
53
53
|
executors.delete(id);
|
|
54
54
|
return;
|
|
@@ -73,25 +73,9 @@ export declare class StoreFS<T extends Store = Store> extends FileSystem {
|
|
|
73
73
|
syncSync(path: string, data?: Uint8Array, metadata?: Readonly<InodeLike>): void;
|
|
74
74
|
link(target: string, link: string): Promise<void>;
|
|
75
75
|
linkSync(target: string, link: string): void;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
* @internal
|
|
79
|
-
*/
|
|
80
|
-
read(path: string, offset: number, length: number): Promise<Uint8Array>;
|
|
81
|
-
/**
|
|
82
|
-
* Used by lazy file
|
|
83
|
-
* @internal
|
|
84
|
-
*/
|
|
85
|
-
readSync(path: string, offset: number, length: number): Uint8Array;
|
|
86
|
-
/**
|
|
87
|
-
* Used by lazy file
|
|
88
|
-
* @internal
|
|
89
|
-
*/
|
|
76
|
+
read(path: string, buffer: Uint8Array, offset: number, end: number): Promise<void>;
|
|
77
|
+
readSync(path: string, buffer: Uint8Array, offset: number, end: number): void;
|
|
90
78
|
write(path: string, data: Uint8Array, offset: number): Promise<void>;
|
|
91
|
-
/**
|
|
92
|
-
* Used by lazy file
|
|
93
|
-
* @internal
|
|
94
|
-
*/
|
|
95
79
|
writeSync(path: string, data: Uint8Array, offset: number): void;
|
|
96
80
|
/**
|
|
97
81
|
* Checks if the root directory exists. Creates it if it doesn't.
|
|
@@ -52,9 +52,9 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
52
52
|
});
|
|
53
53
|
import { randomInt, serialize } from 'utilium';
|
|
54
54
|
import { Errno, ErrnoError } from '../../error.js';
|
|
55
|
-
import {
|
|
55
|
+
import { LazyFile } from '../../file.js';
|
|
56
56
|
import { FileSystem } from '../../filesystem.js';
|
|
57
|
-
import { _throw, canary, decodeDirListing, encodeDirListing, encodeUTF8 } from '../../utils.js';
|
|
57
|
+
import { _throw, canary, decodeDirListing, encodeDirListing, encodeUTF8, growBuffer } from '../../utils.js';
|
|
58
58
|
import { S_IFDIR, S_IFREG, S_ISGID, S_ISUID, size_max } from '../../vfs/constants.js';
|
|
59
59
|
import { basename, dirname, join, parse, resolve } from '../../vfs/path.js';
|
|
60
60
|
import { Index } from './file_index.js';
|
|
@@ -354,20 +354,19 @@ export class StoreFS extends FileSystem {
|
|
|
354
354
|
}
|
|
355
355
|
async createFile(path, flag, mode, options) {
|
|
356
356
|
const node = await this.commitNew(path, S_IFREG, { mode, ...options }, new Uint8Array(), 'createFile');
|
|
357
|
-
return new
|
|
357
|
+
return new LazyFile(this, path, flag, node.toStats());
|
|
358
358
|
}
|
|
359
359
|
createFileSync(path, flag, mode, options) {
|
|
360
360
|
const node = this.commitNewSync(path, S_IFREG, { mode, ...options }, new Uint8Array(), 'createFile');
|
|
361
|
-
return new
|
|
361
|
+
return new LazyFile(this, path, flag, node.toStats());
|
|
362
362
|
}
|
|
363
363
|
async openFile(path, flag) {
|
|
364
|
-
var _a;
|
|
365
364
|
const env_9 = { stack: [], error: void 0, hasError: false };
|
|
366
365
|
try {
|
|
367
366
|
const tx = __addDisposableResource(env_9, this.store.transaction(), true);
|
|
368
367
|
const node = await this.findInode(tx, path, 'openFile');
|
|
369
|
-
const data = (
|
|
370
|
-
return new
|
|
368
|
+
//const data = (await tx.get(node.data)) ?? _throw(ErrnoError.With('ENODATA', path, 'openFile'));
|
|
369
|
+
return new LazyFile(this, path, flag, node.toStats());
|
|
371
370
|
}
|
|
372
371
|
catch (e_9) {
|
|
373
372
|
env_9.error = e_9;
|
|
@@ -380,13 +379,12 @@ export class StoreFS extends FileSystem {
|
|
|
380
379
|
}
|
|
381
380
|
}
|
|
382
381
|
openFileSync(path, flag) {
|
|
383
|
-
var _a;
|
|
384
382
|
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
385
383
|
try {
|
|
386
384
|
const tx = __addDisposableResource(env_10, this.store.transaction(), false);
|
|
387
385
|
const node = this.findInodeSync(tx, path, 'openFile');
|
|
388
|
-
const data =
|
|
389
|
-
return new
|
|
386
|
+
//const data = tx.getSync(node.data) ?? _throw(ErrnoError.With('ENODATA', path, 'openFile'));
|
|
387
|
+
return new LazyFile(this, path, flag, node.toStats());
|
|
390
388
|
}
|
|
391
389
|
catch (e_10) {
|
|
392
390
|
env_10.error = e_10;
|
|
@@ -546,18 +544,14 @@ export class StoreFS extends FileSystem {
|
|
|
546
544
|
__disposeResources(env_16);
|
|
547
545
|
}
|
|
548
546
|
}
|
|
549
|
-
|
|
550
|
-
* Used by lazy file
|
|
551
|
-
* @internal
|
|
552
|
-
*/
|
|
553
|
-
async read(path, offset, length) {
|
|
547
|
+
async read(path, buffer, offset, end) {
|
|
554
548
|
var _a;
|
|
555
549
|
const env_17 = { stack: [], error: void 0, hasError: false };
|
|
556
550
|
try {
|
|
557
551
|
const tx = __addDisposableResource(env_17, this.store.transaction(), true);
|
|
558
552
|
const inode = await this.findInode(tx, path, 'read');
|
|
559
|
-
const
|
|
560
|
-
|
|
553
|
+
const data = (_a = (await tx.get(inode.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENODATA', path, 'read'));
|
|
554
|
+
buffer.set(data.subarray(offset, end));
|
|
561
555
|
}
|
|
562
556
|
catch (e_17) {
|
|
563
557
|
env_17.error = e_17;
|
|
@@ -569,18 +563,14 @@ export class StoreFS extends FileSystem {
|
|
|
569
563
|
await result_9;
|
|
570
564
|
}
|
|
571
565
|
}
|
|
572
|
-
|
|
573
|
-
* Used by lazy file
|
|
574
|
-
* @internal
|
|
575
|
-
*/
|
|
576
|
-
readSync(path, offset, length) {
|
|
566
|
+
readSync(path, buffer, offset, end) {
|
|
577
567
|
var _a;
|
|
578
568
|
const env_18 = { stack: [], error: void 0, hasError: false };
|
|
579
569
|
try {
|
|
580
570
|
const tx = __addDisposableResource(env_18, this.store.transaction(), false);
|
|
581
571
|
const inode = this.findInodeSync(tx, path, 'read');
|
|
582
|
-
const
|
|
583
|
-
|
|
572
|
+
const data = (_a = tx.getSync(inode.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENODATA', path, 'read'));
|
|
573
|
+
buffer.set(data.subarray(offset, end));
|
|
584
574
|
}
|
|
585
575
|
catch (e_18) {
|
|
586
576
|
env_18.error = e_18;
|
|
@@ -590,18 +580,17 @@ export class StoreFS extends FileSystem {
|
|
|
590
580
|
__disposeResources(env_18);
|
|
591
581
|
}
|
|
592
582
|
}
|
|
593
|
-
/**
|
|
594
|
-
* Used by lazy file
|
|
595
|
-
* @internal
|
|
596
|
-
*/
|
|
597
583
|
async write(path, data, offset) {
|
|
598
584
|
const env_19 = { stack: [], error: void 0, hasError: false };
|
|
599
585
|
try {
|
|
600
586
|
const tx = __addDisposableResource(env_19, this.store.transaction(), true);
|
|
601
587
|
const inode = await this.findInode(tx, path, 'write');
|
|
602
|
-
const buffer = await tx.get(inode.data);
|
|
588
|
+
const buffer = growBuffer(await tx.get(inode.data), offset + data.byteLength);
|
|
603
589
|
buffer.set(data, offset);
|
|
604
|
-
|
|
590
|
+
inode.update({ mtimeMs: Date.now(), size: buffer.byteLength });
|
|
591
|
+
await tx.set(inode.ino, serialize(inode));
|
|
592
|
+
await tx.set(inode.data, buffer);
|
|
593
|
+
await tx.commit();
|
|
605
594
|
}
|
|
606
595
|
catch (e_19) {
|
|
607
596
|
env_19.error = e_19;
|
|
@@ -613,18 +602,14 @@ export class StoreFS extends FileSystem {
|
|
|
613
602
|
await result_10;
|
|
614
603
|
}
|
|
615
604
|
}
|
|
616
|
-
/**
|
|
617
|
-
* Used by lazy file
|
|
618
|
-
* @internal
|
|
619
|
-
*/
|
|
620
605
|
writeSync(path, data, offset) {
|
|
621
606
|
const env_20 = { stack: [], error: void 0, hasError: false };
|
|
622
607
|
try {
|
|
623
608
|
const tx = __addDisposableResource(env_20, this.store.transaction(), false);
|
|
624
609
|
const inode = this.findInodeSync(tx, path, 'write');
|
|
625
|
-
|
|
626
|
-
const buffer = tx.getSync(inode.data);
|
|
610
|
+
const buffer = growBuffer(tx.getSync(inode.data), offset + data.byteLength);
|
|
627
611
|
buffer.set(data, offset);
|
|
612
|
+
inode.update({ mtimeMs: Date.now(), size: buffer.byteLength });
|
|
628
613
|
tx.setSync(inode.ino, serialize(inode));
|
|
629
614
|
tx.setSync(inode.data, buffer);
|
|
630
615
|
tx.commitSync();
|