@zenfs/core 0.16.4 → 0.17.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.
Files changed (80) hide show
  1. package/dist/backends/backend.d.ts +3 -4
  2. package/dist/backends/fetch.d.ts +8 -3
  3. package/dist/backends/fetch.js +3 -2
  4. package/dist/backends/{index/fs.d.ts → file_index.d.ts} +49 -10
  5. package/dist/backends/{index/fs.js → file_index.js} +84 -5
  6. package/dist/backends/memory.d.ts +6 -1
  7. package/dist/backends/memory.js +2 -1
  8. package/dist/backends/overlay.d.ts +16 -16
  9. package/dist/backends/overlay.js +59 -82
  10. package/dist/backends/port/fs.d.ts +6 -2
  11. package/dist/backends/port/fs.js +4 -2
  12. package/dist/backends/store/fs.js +484 -304
  13. package/dist/backends/store/simple.js +5 -1
  14. package/dist/backends/store/store.d.ts +4 -1
  15. package/dist/backends/store/store.js +9 -5
  16. package/dist/browser.min.js +4 -4
  17. package/dist/browser.min.js.map +4 -4
  18. package/dist/config.d.ts +3 -3
  19. package/dist/emulation/async.d.ts +1 -4
  20. package/dist/emulation/async.js +9 -4
  21. package/dist/emulation/dir.d.ts +4 -0
  22. package/dist/emulation/dir.js +8 -6
  23. package/dist/emulation/promises.d.ts +1 -3
  24. package/dist/emulation/promises.js +25 -2
  25. package/dist/emulation/sync.js +0 -1
  26. package/dist/emulation/watchers.d.ts +9 -4
  27. package/dist/emulation/watchers.js +7 -0
  28. package/dist/file.d.ts +17 -1
  29. package/dist/file.js +86 -1
  30. package/dist/filesystem.d.ts +4 -67
  31. package/dist/filesystem.js +2 -313
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.js +2 -2
  34. package/dist/mixins/async.d.ts +39 -0
  35. package/dist/mixins/async.js +216 -0
  36. package/dist/mixins/index.d.ts +4 -0
  37. package/dist/mixins/index.js +4 -0
  38. package/dist/mixins/mutexed.d.ts +33 -0
  39. package/dist/mixins/mutexed.js +465 -0
  40. package/dist/mixins/readonly.d.ts +25 -0
  41. package/dist/mixins/readonly.js +57 -0
  42. package/dist/mixins/shared.d.ts +12 -0
  43. package/dist/mixins/shared.js +4 -0
  44. package/dist/mixins/sync.d.ts +6 -0
  45. package/dist/mixins/sync.js +43 -0
  46. package/dist/utils.d.ts +0 -5
  47. package/dist/utils.js +0 -7
  48. package/package.json +3 -2
  49. package/src/backends/backend.ts +3 -4
  50. package/src/backends/fetch.ts +7 -3
  51. package/src/backends/{index/fs.ts → file_index.ts} +106 -8
  52. package/src/backends/memory.ts +5 -1
  53. package/src/backends/overlay.ts +64 -90
  54. package/src/backends/port/fs.ts +7 -2
  55. package/src/backends/{index/readme.md → readme.md} +1 -1
  56. package/src/backends/store/fs.ts +97 -155
  57. package/src/backends/store/simple.ts +5 -1
  58. package/src/backends/store/store.ts +10 -5
  59. package/src/config.ts +3 -1
  60. package/src/emulation/async.ts +20 -9
  61. package/src/emulation/dir.ts +19 -16
  62. package/src/emulation/promises.ts +28 -6
  63. package/src/emulation/sync.ts +1 -2
  64. package/src/emulation/watchers.ts +10 -4
  65. package/src/file.ts +94 -1
  66. package/src/filesystem.ts +5 -368
  67. package/src/index.ts +2 -2
  68. package/src/mixins/async.ts +211 -0
  69. package/src/mixins/index.ts +4 -0
  70. package/src/mixins/mutexed.ts +245 -0
  71. package/src/mixins/readonly.ts +97 -0
  72. package/src/mixins/shared.ts +20 -0
  73. package/src/mixins/sync.ts +59 -0
  74. package/src/utils.ts +0 -8
  75. package/dist/backends/index/index.d.ts +0 -43
  76. package/dist/backends/index/index.js +0 -83
  77. package/dist/backends/locked.d.ts +0 -92
  78. package/dist/backends/locked.js +0 -487
  79. package/src/backends/index/index.ts +0 -104
  80. package/src/backends/locked.ts +0 -264
@@ -0,0 +1,245 @@
1
+ import type { Cred } from '../cred.js';
2
+ import { ErrnoError } from '../error.js';
3
+ import type { File } from '../file.js';
4
+ import type { FileSystem } from '../filesystem.js';
5
+ import '../polyfills.js';
6
+ import type { Stats } from '../stats.js';
7
+ import type { Mixin } from './shared.js';
8
+
9
+ export class MutexLock {
10
+ protected current = Promise.withResolvers<void>();
11
+
12
+ protected _isLocked: boolean = true;
13
+ public get isLocked(): boolean {
14
+ return this._isLocked;
15
+ }
16
+
17
+ public constructor(
18
+ public readonly path: string,
19
+ protected readonly previous?: MutexLock
20
+ ) {}
21
+
22
+ public async done(): Promise<void> {
23
+ await this.previous?.done();
24
+ await this.current.promise;
25
+ }
26
+
27
+ public unlock(): void {
28
+ this.current.resolve();
29
+ this._isLocked = false;
30
+ }
31
+
32
+ public [Symbol.dispose](): void {
33
+ this.unlock();
34
+ }
35
+ }
36
+
37
+ /**
38
+ * This serializes access to an underlying async filesystem.
39
+ * For example, on an OverlayFS instance with an async lower
40
+ * directory operations like rename and rmdir may involve multiple
41
+ * requests involving both the upper and lower filesystems -- they
42
+ * are not executed in a single atomic step. OverlayFS uses this
43
+ * to avoid having to reason about the correctness of
44
+ * multiple requests interleaving.
45
+ *
46
+ * Note: `@ts-expect-error 2513` is needed because `FS` is not properly detected as being concrete
47
+ *
48
+ * @todo Change `using _` to `using void` pending https://github.com/tc39/proposal-discard-binding
49
+ * @internal
50
+ */
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ export function Mutexed<T extends new (...args: any[]) => FileSystem>(
53
+ FS: T
54
+ ): Mixin<
55
+ T,
56
+ {
57
+ lock(path: string): Promise<MutexLock>;
58
+ lockSync(path: string): MutexLock;
59
+ isLocked(path: string): boolean;
60
+ }
61
+ > {
62
+ class MutexedFS extends FS {
63
+ /**
64
+ * The current locks
65
+ */
66
+ private locks: Map<string, MutexLock> = new Map();
67
+
68
+ /**
69
+ * Adds a lock for a path
70
+ */
71
+ protected addLock(path: string): MutexLock {
72
+ const previous = this.locks.get(path);
73
+ const lock = new MutexLock(path, previous?.isLocked ? previous : undefined);
74
+ this.locks.set(path, lock);
75
+ return lock;
76
+ }
77
+
78
+ /**
79
+ * Locks `path` asynchronously.
80
+ * If the path is currently locked, waits for it to be unlocked.
81
+ * @internal
82
+ */
83
+ public async lock(path: string): Promise<MutexLock> {
84
+ const previous = this.locks.get(path);
85
+ const lock = this.addLock(path);
86
+ await previous?.done();
87
+ return lock;
88
+ }
89
+
90
+ /**
91
+ * Locks `path` asynchronously.
92
+ * If the path is currently locked, an error will be thrown
93
+ * @internal
94
+ */
95
+ public lockSync(path: string): MutexLock {
96
+ if (this.locks.has(path)) {
97
+ // Non-null assertion: we already checked locks has path
98
+ throw ErrnoError.With('EBUSY', path, 'lockSync');
99
+ }
100
+
101
+ return this.addLock(path);
102
+ }
103
+
104
+ /**
105
+ * Whether `path` is locked
106
+ * @internal
107
+ */
108
+ public isLocked(path: string): boolean {
109
+ return !!this.locks.get(path)?.isLocked;
110
+ }
111
+
112
+ /* eslint-disable @typescript-eslint/no-unused-vars */
113
+ public async rename(oldPath: string, newPath: string, cred: Cred): Promise<void> {
114
+ using _ = await this.lock(oldPath);
115
+ // @ts-expect-error 2513
116
+ await super.rename(oldPath, newPath, cred);
117
+ }
118
+
119
+ public renameSync(oldPath: string, newPath: string, cred: Cred): void {
120
+ using _ = this.lockSync(oldPath);
121
+ // @ts-expect-error 2513
122
+ return super.renameSync(oldPath, newPath, cred);
123
+ }
124
+
125
+ public async stat(path: string, cred: Cred): Promise<Stats> {
126
+ using _ = await this.lock(path);
127
+ // @ts-expect-error 2513
128
+ return await super.stat(path, cred);
129
+ }
130
+
131
+ public statSync(path: string, cred: Cred): Stats {
132
+ using _ = this.lockSync(path);
133
+ // @ts-expect-error 2513
134
+ return super.statSync(path, cred);
135
+ }
136
+
137
+ public async openFile(path: string, flag: string, cred: Cred): Promise<File> {
138
+ using _ = await this.lock(path);
139
+ // @ts-expect-error 2513
140
+ return await super.openFile(path, flag, cred);
141
+ }
142
+
143
+ public openFileSync(path: string, flag: string, cred: Cred): File {
144
+ using _ = this.lockSync(path);
145
+ // @ts-expect-error 2513
146
+ return super.openFileSync(path, flag, cred);
147
+ }
148
+
149
+ public async createFile(path: string, flag: string, mode: number, cred: Cred): Promise<File> {
150
+ using _ = await this.lock(path);
151
+ // @ts-expect-error 2513
152
+ return await super.createFile(path, flag, mode, cred);
153
+ }
154
+
155
+ public createFileSync(path: string, flag: string, mode: number, cred: Cred): File {
156
+ using _ = this.lockSync(path);
157
+ // @ts-expect-error 2513
158
+ return super.createFileSync(path, flag, mode, cred);
159
+ }
160
+
161
+ public async unlink(path: string, cred: Cred): Promise<void> {
162
+ using _ = await this.lock(path);
163
+ // @ts-expect-error 2513
164
+ await super.unlink(path, cred);
165
+ }
166
+
167
+ public unlinkSync(path: string, cred: Cred): void {
168
+ using _ = this.lockSync(path);
169
+ // @ts-expect-error 2513
170
+ return super.unlinkSync(path, cred);
171
+ }
172
+
173
+ public async rmdir(path: string, cred: Cred): Promise<void> {
174
+ using _ = await this.lock(path);
175
+ // @ts-expect-error 2513
176
+ await super.rmdir(path, cred);
177
+ }
178
+
179
+ public rmdirSync(path: string, cred: Cred): void {
180
+ using _ = this.lockSync(path);
181
+ // @ts-expect-error 2513
182
+ return super.rmdirSync(path, cred);
183
+ }
184
+
185
+ public async mkdir(path: string, mode: number, cred: Cred): Promise<void> {
186
+ using _ = await this.lock(path);
187
+ // @ts-expect-error 2513
188
+ await super.mkdir(path, mode, cred);
189
+ }
190
+
191
+ public mkdirSync(path: string, mode: number, cred: Cred): void {
192
+ using _ = this.lockSync(path);
193
+ // @ts-expect-error 2513
194
+ return super.mkdirSync(path, mode, cred);
195
+ }
196
+
197
+ public async readdir(path: string, cred: Cred): Promise<string[]> {
198
+ using _ = await this.lock(path);
199
+ // @ts-expect-error 2513
200
+ return await super.readdir(path, cred);
201
+ }
202
+
203
+ public readdirSync(path: string, cred: Cred): string[] {
204
+ using _ = this.lockSync(path);
205
+ // @ts-expect-error 2513
206
+ return super.readdirSync(path, cred);
207
+ }
208
+
209
+ public async exists(path: string, cred: Cred): Promise<boolean> {
210
+ using _ = await this.lock(path);
211
+ return await super.exists(path, cred);
212
+ }
213
+
214
+ public existsSync(path: string, cred: Cred): boolean {
215
+ using _ = this.lockSync(path);
216
+ return super.existsSync(path, cred);
217
+ }
218
+
219
+ public async link(srcpath: string, dstpath: string, cred: Cred): Promise<void> {
220
+ using _ = await this.lock(srcpath);
221
+ // @ts-expect-error 2513
222
+ await super.link(srcpath, dstpath, cred);
223
+ }
224
+
225
+ public linkSync(srcpath: string, dstpath: string, cred: Cred): void {
226
+ using _ = this.lockSync(srcpath);
227
+ // @ts-expect-error 2513
228
+ return super.linkSync(srcpath, dstpath, cred);
229
+ }
230
+
231
+ public async sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void> {
232
+ using _ = await this.lock(path);
233
+ // @ts-expect-error 2513
234
+ await super.sync(path, data, stats);
235
+ }
236
+
237
+ public syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void {
238
+ using _ = this.lockSync(path);
239
+ // @ts-expect-error 2513
240
+ return super.syncSync(path, data, stats);
241
+ }
242
+ /* eslint-enable @typescript-eslint/no-unused-vars */
243
+ }
244
+ return MutexedFS;
245
+ }
@@ -0,0 +1,97 @@
1
+ import type { Cred } from '../cred.js';
2
+ import { Errno, ErrnoError } from '../error.js';
3
+ import type { File } from '../file.js';
4
+ import type { FileSystem, FileSystemMetadata } from '../filesystem.js';
5
+ import type { Stats } from '../stats.js';
6
+ import type { Mixin } from './shared.js';
7
+
8
+ /**
9
+ * Implements the non-readonly methods to throw `EROFS`
10
+ */
11
+ /* eslint-disable @typescript-eslint/require-await */
12
+ export function Readonly<T extends typeof FileSystem>(
13
+ FS: T
14
+ ): Mixin<
15
+ T,
16
+ {
17
+ metadata(): FileSystemMetadata;
18
+ rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
19
+ renameSync(oldPath: string, newPath: string, cred: Cred): void;
20
+ createFile(path: string, flag: string, mode: number, cred: Cred): Promise<File>;
21
+ createFileSync(path: string, flag: string, mode: number, cred: Cred): File;
22
+ unlink(path: string, cred: Cred): Promise<void>;
23
+ unlinkSync(path: string, cred: Cred): void;
24
+ rmdir(path: string, cred: Cred): Promise<void>;
25
+ rmdirSync(path: string, cred: Cred): void;
26
+ mkdir(path: string, mode: number, cred: Cred): Promise<void>;
27
+ mkdirSync(path: string, mode: number, cred: Cred): void;
28
+ link(srcpath: string, dstpath: string, cred: Cred): Promise<void>;
29
+ linkSync(srcpath: string, dstpath: string, cred: Cred): void;
30
+ sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
31
+ syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
32
+ }
33
+ > {
34
+ abstract class ReadonlyFS extends FS {
35
+ public metadata(): FileSystemMetadata {
36
+ return { ...super.metadata(), readonly: true };
37
+ }
38
+ /* eslint-disable @typescript-eslint/no-unused-vars */
39
+ public async rename(oldPath: string, newPath: string, cred: Cred): Promise<void> {
40
+ throw new ErrnoError(Errno.EROFS);
41
+ }
42
+
43
+ public renameSync(oldPath: string, newPath: string, cred: Cred): void {
44
+ throw new ErrnoError(Errno.EROFS);
45
+ }
46
+
47
+ public async createFile(path: string, flag: string, mode: number, cred: Cred): Promise<File> {
48
+ throw new ErrnoError(Errno.EROFS);
49
+ }
50
+
51
+ public createFileSync(path: string, flag: string, mode: number, cred: Cred): File {
52
+ throw new ErrnoError(Errno.EROFS);
53
+ }
54
+
55
+ public async unlink(path: string, cred: Cred): Promise<void> {
56
+ throw new ErrnoError(Errno.EROFS);
57
+ }
58
+
59
+ public unlinkSync(path: string, cred: Cred): void {
60
+ throw new ErrnoError(Errno.EROFS);
61
+ }
62
+
63
+ public async rmdir(path: string, cred: Cred): Promise<void> {
64
+ throw new ErrnoError(Errno.EROFS);
65
+ }
66
+
67
+ public rmdirSync(path: string, cred: Cred): void {
68
+ throw new ErrnoError(Errno.EROFS);
69
+ }
70
+
71
+ public async mkdir(path: string, mode: number, cred: Cred): Promise<void> {
72
+ throw new ErrnoError(Errno.EROFS);
73
+ }
74
+
75
+ public mkdirSync(path: string, mode: number, cred: Cred): void {
76
+ throw new ErrnoError(Errno.EROFS);
77
+ }
78
+
79
+ public async link(srcpath: string, dstpath: string, cred: Cred): Promise<void> {
80
+ throw new ErrnoError(Errno.EROFS);
81
+ }
82
+
83
+ public linkSync(srcpath: string, dstpath: string, cred: Cred): void {
84
+ throw new ErrnoError(Errno.EROFS);
85
+ }
86
+
87
+ public async sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void> {
88
+ throw new ErrnoError(Errno.EROFS);
89
+ }
90
+
91
+ public syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void {
92
+ throw new ErrnoError(Errno.EROFS);
93
+ }
94
+ }
95
+ return ReadonlyFS;
96
+ }
97
+ /* eslint-enable @typescript-eslint/require-await */
@@ -0,0 +1,20 @@
1
+ /*
2
+ Code shared by various mixins
3
+ */
4
+
5
+ import type { ExtractProperties } from 'utilium';
6
+ import type { FileSystem } from '../filesystem.js';
7
+
8
+ /**
9
+ * `TBase` with `TMixin` mixed-in.
10
+ * @internal @experimental
11
+ */
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ export type Mixin<TBase extends typeof FileSystem, TMixin> = (abstract new (...args: any[]) => TMixin) & TBase;
14
+
15
+ /**
16
+ * Asynchronous `FileSystem` methods. This is a convience type.
17
+ * @internal
18
+ */
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ export type _AsyncFSMethods = ExtractProperties<FileSystem, (...args: any[]) => Promise<unknown>>;
@@ -0,0 +1,59 @@
1
+ import type { Cred } from '../cred.js';
2
+ import type { File } from '../file.js';
3
+ import type { Stats } from '../stats.js';
4
+ import type { FileSystem } from '../filesystem.js';
5
+ import type { Mixin, _AsyncFSMethods } from './shared.js';
6
+
7
+ /**
8
+ * Implements the asynchronous API in terms of the synchronous API.
9
+ */
10
+ /* eslint-disable @typescript-eslint/require-await */
11
+ export function Sync<T extends typeof FileSystem>(FS: T): Mixin<T, _AsyncFSMethods> {
12
+ abstract class SyncFS extends FS implements _AsyncFSMethods {
13
+ public async exists(path: string, cred: Cred): Promise<boolean> {
14
+ return this.existsSync(path, cred);
15
+ }
16
+
17
+ public async rename(oldPath: string, newPath: string, cred: Cred): Promise<void> {
18
+ return this.renameSync(oldPath, newPath, cred);
19
+ }
20
+
21
+ public async stat(path: string, cred: Cred): Promise<Stats> {
22
+ return this.statSync(path, cred);
23
+ }
24
+
25
+ public async createFile(path: string, flag: string, mode: number, cred: Cred): Promise<File> {
26
+ return this.createFileSync(path, flag, mode, cred);
27
+ }
28
+
29
+ public async openFile(path: string, flag: string, cred: Cred): Promise<File> {
30
+ return this.openFileSync(path, flag, cred);
31
+ }
32
+
33
+ public async unlink(path: string, cred: Cred): Promise<void> {
34
+ return this.unlinkSync(path, cred);
35
+ }
36
+
37
+ public async rmdir(path: string, cred: Cred): Promise<void> {
38
+ return this.rmdirSync(path, cred);
39
+ }
40
+
41
+ public async mkdir(path: string, mode: number, cred: Cred): Promise<void> {
42
+ return this.mkdirSync(path, mode, cred);
43
+ }
44
+
45
+ public async readdir(path: string, cred: Cred): Promise<string[]> {
46
+ return this.readdirSync(path, cred);
47
+ }
48
+
49
+ public async link(srcpath: string, dstpath: string, cred: Cred): Promise<void> {
50
+ return this.linkSync(srcpath, dstpath, cred);
51
+ }
52
+
53
+ public async sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void> {
54
+ return this.syncSync(path, data, stats);
55
+ }
56
+ }
57
+ return SyncFS;
58
+ }
59
+ /* eslint-enable @typescript-eslint/require-await */
package/src/utils.ts CHANGED
@@ -279,11 +279,3 @@ export function normalizeOptions(
279
279
  mode: normalizeMode('mode' in options ? options?.mode : null, mode),
280
280
  };
281
281
  }
282
-
283
- /**
284
- * Do nothing
285
- * @internal
286
- */
287
- export function nop() {
288
- // do nothing
289
- }
@@ -1,43 +0,0 @@
1
- import type { StatsLike } from '../../stats.js';
2
- import { Stats } from '../../stats.js';
3
- /**
4
- * An Index in JSON form
5
- * @internal
6
- */
7
- export interface IndexData {
8
- version: 1;
9
- entries: Record<string, StatsLike<number>>;
10
- }
11
- export declare const version = 1;
12
- /**
13
- * An index of files
14
- * @internal
15
- */
16
- export declare class Index extends Map<string, Stats> {
17
- constructor();
18
- /**
19
- * Convience method
20
- */
21
- files(): Map<string, Stats>;
22
- /**
23
- * Converts the index to JSON
24
- */
25
- toJSON(): IndexData;
26
- /**
27
- * Converts the index to a string
28
- */
29
- toString(): string;
30
- /**
31
- * Returns the files in the directory `dir`.
32
- * This is expensive so it is only called once per directory.
33
- */
34
- protected dirEntries(dir: string): string[];
35
- /**
36
- * Loads the index from JSON data
37
- */
38
- fromJSON(json: IndexData): void;
39
- /**
40
- * Parses an index from a string
41
- */
42
- static parse(data: string): Index;
43
- }
@@ -1,83 +0,0 @@
1
- import { isJSON } from 'utilium';
2
- import { Errno, ErrnoError } from '../../error.js';
3
- import { Stats } from '../../stats.js';
4
- import { encode } from '../../utils.js';
5
- import { basename, dirname } from '../../emulation/path.js';
6
- export const version = 1;
7
- /**
8
- * An index of files
9
- * @internal
10
- */
11
- export class Index extends Map {
12
- constructor() {
13
- super();
14
- }
15
- /**
16
- * Convience method
17
- */
18
- files() {
19
- const files = new Map();
20
- for (const [path, stats] of this) {
21
- if (stats.isFile()) {
22
- files.set(path, stats);
23
- }
24
- }
25
- return files;
26
- }
27
- /**
28
- * Converts the index to JSON
29
- */
30
- toJSON() {
31
- return {
32
- version,
33
- entries: Object.fromEntries(this),
34
- };
35
- }
36
- /**
37
- * Converts the index to a string
38
- */
39
- toString() {
40
- return JSON.stringify(this.toJSON());
41
- }
42
- /**
43
- * Returns the files in the directory `dir`.
44
- * This is expensive so it is only called once per directory.
45
- */
46
- dirEntries(dir) {
47
- const entries = [];
48
- for (const entry of this.keys()) {
49
- if (dirname(entry) == dir) {
50
- entries.push(basename(entry));
51
- }
52
- }
53
- return entries;
54
- }
55
- /**
56
- * Loads the index from JSON data
57
- */
58
- fromJSON(json) {
59
- if (json.version != version) {
60
- throw new ErrnoError(Errno.EINVAL, 'Index version mismatch');
61
- }
62
- this.clear();
63
- for (const [path, data] of Object.entries(json.entries)) {
64
- const stats = new Stats(data);
65
- if (stats.isDirectory()) {
66
- stats.fileData = encode(JSON.stringify(this.dirEntries(path)));
67
- }
68
- this.set(path, stats);
69
- }
70
- }
71
- /**
72
- * Parses an index from a string
73
- */
74
- static parse(data) {
75
- if (!isJSON(data)) {
76
- throw new ErrnoError(Errno.EINVAL, 'Invalid JSON');
77
- }
78
- const json = JSON.parse(data);
79
- const index = new Index();
80
- index.fromJSON(json);
81
- return index;
82
- }
83
- }
@@ -1,92 +0,0 @@
1
- import type { Cred } from '../cred.js';
2
- import type { File } from '../file.js';
3
- import type { FileSystemMetadata } from '../filesystem.js';
4
- import { FileSystem } from '../filesystem.js';
5
- import type { Stats } from '../stats.js';
6
- import '../polyfills.js';
7
- export interface MutexLock extends PromiseWithResolvers<void> {
8
- [Symbol.dispose](): void;
9
- }
10
- /**
11
- * This class serializes access to an underlying async filesystem.
12
- * For example, on an OverlayFS instance with an async lower
13
- * directory operations like rename and rmdir may involve multiple
14
- * requests involving both the upper and lower filesystems -- they
15
- * are not executed in a single atomic step. OverlayFS uses this
16
- * LockedFS to avoid having to reason about the correctness of
17
- * multiple requests interleaving.
18
- * @internal
19
- */
20
- export declare class LockedFS<FS extends FileSystem> implements FileSystem {
21
- readonly fs: FS;
22
- constructor(fs: FS);
23
- /**
24
- * The current locks
25
- */
26
- private locks;
27
- protected addLock(path: string): MutexLock;
28
- /**
29
- * Locks `path` asynchronously.
30
- * If the path is currently locked, waits for it to be unlocked.
31
- * @internal
32
- */
33
- lock(path: string): Promise<MutexLock>;
34
- /**
35
- * Locks `path` asynchronously.
36
- * If the path is currently locked, an error will be thrown
37
- * @internal
38
- */
39
- lockSync(path: string): MutexLock;
40
- /**
41
- * Unlocks a path
42
- * @param path The path to lock
43
- * @param noThrow If true, an error will not be thrown if the path is already unlocked
44
- * @returns Whether the path was unlocked
45
- * @internal
46
- */
47
- unlock(path: string, noThrow?: boolean): boolean;
48
- /**
49
- * Whether `path` is locked
50
- * @internal
51
- */
52
- isLocked(path: string): boolean;
53
- ready(): Promise<void>;
54
- metadata(): FileSystemMetadata;
55
- rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
56
- renameSync(oldPath: string, newPath: string, cred: Cred): void;
57
- stat(path: string, cred: Cred): Promise<Stats>;
58
- statSync(path: string, cred: Cred): Stats;
59
- openFile(path: string, flag: string, cred: Cred): Promise<File>;
60
- openFileSync(path: string, flag: string, cred: Cred): File;
61
- createFile(path: string, flag: string, mode: number, cred: Cred): Promise<File>;
62
- createFileSync(path: string, flag: string, mode: number, cred: Cred): File;
63
- unlink(path: string, cred: Cred): Promise<void>;
64
- unlinkSync(path: string, cred: Cred): void;
65
- rmdir(path: string, cred: Cred): Promise<void>;
66
- rmdirSync(path: string, cred: Cred): void;
67
- mkdir(path: string, mode: number, cred: Cred): Promise<void>;
68
- mkdirSync(path: string, mode: number, cred: Cred): void;
69
- readdir(path: string, cred: Cred): Promise<string[]>;
70
- readdirSync(path: string, cred: Cred): string[];
71
- exists(path: string, cred: Cred): Promise<boolean>;
72
- existsSync(path: string, cred: Cred): boolean;
73
- link(srcpath: string, dstpath: string, cred: Cred): Promise<void>;
74
- linkSync(srcpath: string, dstpath: string, cred: Cred): void;
75
- sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
76
- syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
77
- }
78
- export declare const Locked: {
79
- name: string;
80
- options: {
81
- fs: {
82
- type: "object";
83
- required: true;
84
- description: string;
85
- validator(fs: FileSystem): void;
86
- };
87
- };
88
- isAvailable(): true;
89
- create({ fs }: {
90
- fs: FileSystem;
91
- } & Partial<import("./backend.js").SharedConfig>): LockedFS<FileSystem>;
92
- };