@zenfs/core 1.11.4 → 2.1.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.
Files changed (135) hide show
  1. package/dist/backends/backend.d.ts +19 -15
  2. package/dist/backends/backend.js +36 -19
  3. package/dist/backends/cow.d.ts +20 -30
  4. package/dist/backends/cow.js +83 -192
  5. package/dist/backends/fetch.d.ts +1 -0
  6. package/dist/backends/fetch.js +30 -30
  7. package/dist/backends/index.d.ts +1 -1
  8. package/dist/backends/index.js +1 -1
  9. package/dist/backends/memory.d.ts +5 -7
  10. package/dist/backends/memory.js +2 -3
  11. package/dist/backends/passthrough.d.ts +19 -23
  12. package/dist/backends/passthrough.js +98 -288
  13. package/dist/backends/port.d.ts +220 -0
  14. package/dist/backends/port.js +328 -0
  15. package/dist/backends/single_buffer.d.ts +59 -47
  16. package/dist/backends/single_buffer.js +468 -219
  17. package/dist/backends/store/fs.d.ts +25 -35
  18. package/dist/backends/store/fs.js +276 -315
  19. package/dist/backends/store/store.d.ts +10 -15
  20. package/dist/backends/store/store.js +11 -10
  21. package/dist/config.d.ts +3 -12
  22. package/dist/config.js +17 -19
  23. package/dist/context.d.ts +8 -21
  24. package/dist/context.js +33 -10
  25. package/dist/index.d.ts +2 -1
  26. package/dist/index.js +2 -1
  27. package/dist/internal/contexts.d.ts +63 -0
  28. package/dist/internal/contexts.js +15 -0
  29. package/dist/internal/credentials.d.ts +2 -11
  30. package/dist/internal/credentials.js +0 -19
  31. package/dist/internal/devices.d.ts +18 -80
  32. package/dist/internal/devices.js +103 -316
  33. package/dist/internal/error.d.ts +9 -204
  34. package/dist/internal/error.js +19 -288
  35. package/dist/internal/file_index.d.ts +1 -1
  36. package/dist/internal/file_index.js +11 -11
  37. package/dist/internal/filesystem.d.ts +51 -94
  38. package/dist/internal/filesystem.js +21 -20
  39. package/dist/internal/index.d.ts +1 -2
  40. package/dist/internal/index.js +1 -2
  41. package/dist/internal/index_fs.d.ts +12 -30
  42. package/dist/internal/index_fs.js +37 -69
  43. package/dist/internal/inode.d.ts +140 -24
  44. package/dist/internal/inode.js +515 -66
  45. package/dist/mixins/async.js +52 -112
  46. package/dist/mixins/mutexed.d.ts +19 -18
  47. package/dist/mixins/mutexed.js +62 -64
  48. package/dist/mixins/readonly.d.ts +7 -6
  49. package/dist/mixins/readonly.js +24 -18
  50. package/dist/mixins/sync.js +8 -8
  51. package/dist/{vfs/path.d.ts → path.d.ts} +3 -4
  52. package/dist/{vfs/path.js → path.js} +6 -9
  53. package/dist/polyfills.js +1 -1
  54. package/dist/readline.d.ts +134 -0
  55. package/dist/readline.js +623 -0
  56. package/dist/utils.d.ts +9 -37
  57. package/dist/utils.js +17 -85
  58. package/dist/vfs/acl.d.ts +42 -0
  59. package/dist/vfs/acl.js +268 -0
  60. package/dist/vfs/async.d.ts +9 -23
  61. package/dist/vfs/async.js +25 -27
  62. package/dist/vfs/config.d.ts +6 -18
  63. package/dist/vfs/config.js +8 -18
  64. package/dist/vfs/dir.d.ts +3 -3
  65. package/dist/vfs/dir.js +12 -12
  66. package/dist/vfs/file.d.ts +106 -0
  67. package/dist/vfs/file.js +244 -0
  68. package/dist/vfs/flags.d.ts +19 -0
  69. package/dist/vfs/flags.js +62 -0
  70. package/dist/vfs/index.d.ts +4 -10
  71. package/dist/vfs/index.js +4 -13
  72. package/dist/vfs/ioctl.d.ts +88 -0
  73. package/dist/vfs/ioctl.js +409 -0
  74. package/dist/vfs/promises.d.ts +81 -19
  75. package/dist/vfs/promises.js +404 -288
  76. package/dist/vfs/shared.d.ts +7 -37
  77. package/dist/vfs/shared.js +29 -85
  78. package/dist/{stats.d.ts → vfs/stats.d.ts} +14 -28
  79. package/dist/{stats.js → vfs/stats.js} +11 -66
  80. package/dist/vfs/streams.d.ts +1 -0
  81. package/dist/vfs/streams.js +32 -27
  82. package/dist/vfs/sync.d.ts +3 -3
  83. package/dist/vfs/sync.js +263 -260
  84. package/dist/vfs/watchers.d.ts +2 -2
  85. package/dist/vfs/watchers.js +12 -12
  86. package/dist/vfs/xattr.d.ts +116 -0
  87. package/dist/vfs/xattr.js +201 -0
  88. package/package.json +5 -3
  89. package/readme.md +1 -1
  90. package/scripts/test.js +2 -2
  91. package/tests/assignment.ts +1 -1
  92. package/tests/backend/config.worker.js +4 -1
  93. package/tests/backend/fetch.test.ts +3 -0
  94. package/tests/backend/port.test.ts +19 -33
  95. package/tests/backend/remote.worker.js +4 -1
  96. package/tests/backend/single-buffer.test.ts +53 -0
  97. package/tests/backend/single-buffer.worker.js +30 -0
  98. package/tests/common/context.test.ts +3 -3
  99. package/tests/common/handle.test.ts +17 -12
  100. package/tests/common/mutex.test.ts +9 -9
  101. package/tests/common/path.test.ts +1 -1
  102. package/tests/common/readline.test.ts +104 -0
  103. package/tests/common.ts +4 -19
  104. package/tests/fetch/fetch.ts +2 -2
  105. package/tests/fs/append.test.ts +4 -4
  106. package/tests/fs/directory.test.ts +25 -25
  107. package/tests/fs/errors.test.ts +15 -19
  108. package/tests/fs/links.test.ts +4 -3
  109. package/tests/fs/open.test.ts +4 -21
  110. package/tests/fs/permissions.test.ts +14 -18
  111. package/tests/fs/read.test.ts +10 -9
  112. package/tests/fs/readFile.test.ts +10 -26
  113. package/tests/fs/rename.test.ts +4 -9
  114. package/tests/fs/stat.test.ts +8 -8
  115. package/tests/fs/streams.test.ts +2 -11
  116. package/tests/fs/times.test.ts +7 -7
  117. package/tests/fs/truncate.test.ts +8 -36
  118. package/tests/fs/watch.test.ts +10 -10
  119. package/tests/fs/write.test.ts +77 -13
  120. package/tests/fs/xattr.test.ts +85 -0
  121. package/tests/logs.js +22 -0
  122. package/tests/setup/context.ts +1 -1
  123. package/tests/setup/index.ts +3 -3
  124. package/tests/setup/port.ts +7 -1
  125. package/dist/backends/port/fs.d.ts +0 -84
  126. package/dist/backends/port/fs.js +0 -151
  127. package/dist/backends/port/rpc.d.ts +0 -77
  128. package/dist/backends/port/rpc.js +0 -100
  129. package/dist/backends/store/simple.d.ts +0 -20
  130. package/dist/backends/store/simple.js +0 -13
  131. package/dist/internal/file.d.ts +0 -359
  132. package/dist/internal/file.js +0 -751
  133. package/dist/internal/log.d.ts +0 -133
  134. package/dist/internal/log.js +0 -218
  135. package/tests/fs/writeFile.test.ts +0 -70
@@ -1,6 +1,9 @@
1
1
  import type { RequiredKeys } from 'utilium';
2
2
  import type { FileSystem } from '../internal/filesystem.js';
3
- type OptionType = 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | (abstract new (...args: any[]) => any);
3
+ type OptionType = 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | string | ((arg: any) => boolean) | {
4
+ [Symbol.hasInstance](instance: any): boolean;
5
+ toString(): string;
6
+ };
4
7
  /**
5
8
  * Resolves the type of Backend.options from the options interface
6
9
  * @category Backends and Configuration
@@ -8,24 +11,17 @@ type OptionType = 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undef
8
11
  export type OptionsConfig<T> = {
9
12
  [K in keyof T]: {
10
13
  /**
11
- * The basic JavaScript type(s) for this option.
14
+ * The type of the option. Can be a:
15
+ * - string given by `typeof`
16
+ * - string that is the name of the class (e.g. `'Map'`)
17
+ * - object with a `Symbol.hasInstance` property
18
+ * - function that returns a boolean
12
19
  */
13
20
  type: OptionType | readonly OptionType[];
14
- /**
15
- * Description of the option. Used in error messages and documentation.
16
- * @deprecated
17
- */
18
- description?: string;
19
21
  /**
20
22
  * Whether or not the option is required (optional can be set to null or undefined). Defaults to false.
21
23
  */
22
24
  required: K extends RequiredKeys<T> ? true : false;
23
- /**
24
- * A custom validation function to check if the option is valid.
25
- * When async, resolves if valid and rejects if not.
26
- * When sync, it will throw an error if not valid.
27
- */
28
- validator?(opt: T[K]): void | Promise<void>;
29
25
  };
30
26
  };
31
27
  /**
@@ -64,7 +60,7 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
64
60
  * 'false' if the API is unavailable
65
61
  *
66
62
  */
67
- isAvailable?(): boolean | Promise<boolean>;
63
+ isAvailable?(config: TOptions): boolean | Promise<boolean>;
68
64
  }
69
65
  /**
70
66
  * Gets the options type of a backend
@@ -83,12 +79,20 @@ export type FilesystemOf<T extends Backend> = T extends Backend<infer FS> ? FS :
83
79
  * @internal
84
80
  */
85
81
  export declare function isBackend(arg: unknown): arg is Backend;
82
+ /**
83
+ * Use a function as the type of an option, but don't treat it as a class.
84
+ *
85
+ * Optionally sets the name of a function, useful for error messages.
86
+ * @category Backends and Configuration
87
+ * @internal
88
+ */
89
+ export declare function _fnOpt<const T>(name: string | null | undefined, fn: (arg: T) => boolean): (arg: T) => boolean;
86
90
  /**
87
91
  * Checks that `options` object is valid for the file system options.
88
92
  * @category Backends and Configuration
89
93
  * @internal
90
94
  */
91
- export declare function checkOptions<T extends Backend>(backend: T, options: Record<string, unknown>): Promise<void>;
95
+ export declare function checkOptions<T extends Backend>(backend: T, options: Record<string, unknown>): void;
92
96
  /**
93
97
  * Specifies a file system backend type and its options.
94
98
  *
@@ -1,5 +1,6 @@
1
- import { Errno, ErrnoError } from '../internal/error.js';
2
- import { debug, err } from '../internal/log.js';
1
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-redundant-type-constituents */
2
+ import { withErrno } from 'kerium';
3
+ import { debug, err } from 'kerium/log';
3
4
  /**
4
5
  * @category Backends and Configuration
5
6
  * @internal
@@ -7,38 +8,54 @@ import { debug, err } from '../internal/log.js';
7
8
  export function isBackend(arg) {
8
9
  return arg != null && typeof arg == 'object' && 'create' in arg && typeof arg.create == 'function';
9
10
  }
11
+ /**
12
+ * Use a function as the type of an option, but don't treat it as a class.
13
+ *
14
+ * Optionally sets the name of a function, useful for error messages.
15
+ * @category Backends and Configuration
16
+ * @internal
17
+ */
18
+ export function _fnOpt(name, fn) {
19
+ Object.defineProperty(fn, 'prototype', { value: undefined });
20
+ if (name)
21
+ Object.defineProperty(fn, 'name', { value: name });
22
+ return fn;
23
+ }
10
24
  /**
11
25
  * Checks that `options` object is valid for the file system options.
12
26
  * @category Backends and Configuration
13
27
  * @internal
14
28
  */
15
- export async function checkOptions(backend, options) {
29
+ export function checkOptions(backend, options) {
16
30
  if (typeof options != 'object' || options === null) {
17
- throw err(new ErrnoError(Errno.EINVAL, 'Invalid options'));
31
+ throw err(withErrno('EINVAL', 'Invalid options'));
18
32
  }
19
33
  // Check for required options.
20
34
  for (const [optName, opt] of Object.entries(backend.options)) {
21
35
  const value = options === null || options === void 0 ? void 0 : options[optName];
22
36
  if (value === undefined || value === null) {
23
37
  if (!opt.required) {
24
- debug('Missing non-required option: ' + optName);
38
+ debug('Using default for option: ' + optName);
25
39
  continue;
26
40
  }
27
- throw err(new ErrnoError(Errno.EINVAL, 'Missing required option: ' + optName));
28
- }
29
- const isType = (type, _ = value) => (typeof type == 'function' ? value instanceof type : typeof value === type);
30
- if (Array.isArray(opt.type) ? !opt.type.some(v => isType(v)) : !isType(opt.type)) {
31
- // The type of the value as a string
32
- const type = typeof value == 'object' && 'constructor' in value ? value.constructor.name : typeof value;
33
- // The expected type (as a string)
34
- const name = (type) => (typeof type == 'function' ? type.name : type);
35
- const expected = Array.isArray(opt.type) ? `one of ${opt.type.map(name).join(', ')}` : name(opt.type);
36
- throw err(new ErrnoError(Errno.EINVAL, `Incorrect type for "${optName}": ${type} (expected ${expected})`));
41
+ throw err(withErrno('EINVAL', 'Missing required option: ' + optName));
37
42
  }
38
- debug('Using custom validator for option: ' + optName);
39
- if (opt.validator)
40
- await opt.validator(value);
41
- // Otherwise: All good!
43
+ const isType = (type, _ = value) => {
44
+ var _a;
45
+ return typeof type == 'function'
46
+ ? Symbol.hasInstance in type && type.prototype
47
+ ? value instanceof type
48
+ : type(value)
49
+ : typeof value === type || ((_a = value === null || value === void 0 ? void 0 : value.constructor) === null || _a === void 0 ? void 0 : _a.name) === type;
50
+ };
51
+ if (Array.isArray(opt.type) ? opt.type.some(v => isType(v)) : isType(opt.type))
52
+ continue;
53
+ // The type of the value as a string
54
+ const type = typeof value == 'object' && 'constructor' in value ? value.constructor.name : typeof value;
55
+ // The expected type (as a string)
56
+ const name = (type) => (typeof type == 'function' ? (type.name != 'type' ? type.name : type.toString()) : type);
57
+ const expected = Array.isArray(opt.type) ? `one of ${opt.type.map(name).join(', ')}` : name(opt.type);
58
+ throw err(withErrno('EINVAL', `Incorrect type for "${optName}": ${type} (expected ${expected})`));
42
59
  }
43
60
  }
44
61
  /**
@@ -1,10 +1,8 @@
1
- import type { File } from '../internal/file.js';
2
1
  import type { CreationOptions, StreamOptions, UsageInfo } from '../internal/filesystem.js';
3
2
  import type { InodeLike } from '../internal/inode.js';
4
- import type { Stats } from '../stats.js';
5
- import { FileSystem } from '../internal/filesystem.js';
6
3
  import { EventEmitter } from 'eventemitter3';
7
4
  import { type MountConfiguration } from '../config.js';
5
+ import { FileSystem } from '../internal/filesystem.js';
8
6
  /**
9
7
  * Configuration options for CoW.
10
8
  * @category Backends and Configuration
@@ -17,16 +15,14 @@ export interface CopyOnWriteOptions {
17
15
  /** @see {@link Journal} */
18
16
  journal?: Journal;
19
17
  }
20
- /**
21
- * @hidden @deprecated use `CopyOnWriteOptions`
22
- */
23
- export type OverlayOptions = CopyOnWriteOptions;
24
18
  declare const journalOperations: readonly ["delete"];
25
19
  /**
20
+ * @category Internals
26
21
  * @internal
27
22
  */
28
23
  export type JournalOperation = (typeof journalOperations)[number];
29
24
  /**
25
+ * @category Internals
30
26
  * @internal
31
27
  */
32
28
  export interface JournalEntry {
@@ -35,6 +31,7 @@ export interface JournalEntry {
35
31
  }
36
32
  /**
37
33
  * Tracks various operations for the CoW backend
34
+ * @category Internals
38
35
  * @internal
39
36
  */
40
37
  export declare class Journal extends EventEmitter<{
@@ -54,6 +51,7 @@ export declare class Journal extends EventEmitter<{
54
51
  /**
55
52
  * Using a readable file system as a base, writes are done to a writable file system.
56
53
  * @internal
54
+ * @category Internals
57
55
  */
58
56
  export declare class CopyOnWriteFS extends FileSystem {
59
57
  /** The file system that initially populates this file system. */
@@ -75,28 +73,28 @@ export declare class CopyOnWriteFS extends FileSystem {
75
73
  * @todo Consider trying to track information on the writable as well
76
74
  */
77
75
  usage(): UsageInfo;
78
- sync(path: string, data: Uint8Array, stats: Readonly<InodeLike>): Promise<void>;
79
- syncSync(path: string, data: Uint8Array, stats: Readonly<InodeLike>): void;
76
+ sync(): Promise<void>;
77
+ syncSync(): void;
80
78
  read(path: string, buffer: Uint8Array, offset: number, end: number): Promise<void>;
81
79
  readSync(path: string, buffer: Uint8Array, offset: number, end: number): void;
82
80
  write(path: string, buffer: Uint8Array, offset: number): Promise<void>;
83
81
  writeSync(path: string, buffer: Uint8Array, offset: number): void;
84
82
  rename(oldPath: string, newPath: string): Promise<void>;
85
83
  renameSync(oldPath: string, newPath: string): void;
86
- stat(path: string): Promise<Stats>;
87
- statSync(path: string): Stats;
88
- openFile(path: string, flag: string): Promise<File>;
89
- openFileSync(path: string, flag: string): File;
90
- createFile(path: string, flag: string, mode: number, options: CreationOptions): Promise<File>;
91
- createFileSync(path: string, flag: string, mode: number, options: CreationOptions): File;
84
+ stat(path: string): Promise<InodeLike>;
85
+ statSync(path: string): InodeLike;
86
+ touch(path: string, metadata: InodeLike): Promise<void>;
87
+ touchSync(path: string, metadata: InodeLike): void;
88
+ createFile(path: string, options: CreationOptions): Promise<InodeLike>;
89
+ createFileSync(path: string, options: CreationOptions): InodeLike;
92
90
  link(srcpath: string, dstpath: string): Promise<void>;
93
91
  linkSync(srcpath: string, dstpath: string): void;
94
92
  unlink(path: string): Promise<void>;
95
93
  unlinkSync(path: string): void;
96
94
  rmdir(path: string): Promise<void>;
97
95
  rmdirSync(path: string): void;
98
- mkdir(path: string, mode: number, options: CreationOptions): Promise<void>;
99
- mkdirSync(path: string, mode: number, options: CreationOptions): void;
96
+ mkdir(path: string, options: CreationOptions): Promise<InodeLike>;
97
+ mkdirSync(path: string, options: CreationOptions): InodeLike;
100
98
  readdir(path: string): Promise<string[]>;
101
99
  readdirSync(path: string): string[];
102
100
  streamRead(path: string, options: StreamOptions): ReadableStream;
@@ -125,11 +123,6 @@ export declare class CopyOnWriteFS extends FileSystem {
125
123
  private copyToWritableSync;
126
124
  private copyToWritable;
127
125
  }
128
- /**
129
- * @hidden @deprecated use `CopyOnWriteFS`
130
- */
131
- export declare class OverlayFS extends CopyOnWriteFS {
132
- }
133
126
  declare const _CopyOnWrite: {
134
127
  readonly name: "CopyOnWrite";
135
128
  readonly options: {
@@ -149,21 +142,18 @@ declare const _CopyOnWrite: {
149
142
  readonly create: (options: CopyOnWriteOptions) => Promise<CopyOnWriteFS>;
150
143
  };
151
144
  type _CopyOnWrite = typeof _CopyOnWrite;
152
- export interface CopyOnWrite extends _CopyOnWrite {
153
- }
154
145
  /**
155
146
  * Overlay makes a read-only filesystem writable by storing writes on a second, writable file system.
156
147
  * Deletes are persisted via metadata stored on the writable file system.
157
148
  * @category Backends and Configuration
158
- * @internal
159
149
  */
160
- export declare const CopyOnWrite: CopyOnWrite;
161
- export interface Overlay extends _CopyOnWrite {
150
+ export interface CopyOnWrite extends _CopyOnWrite {
162
151
  }
163
152
  /**
164
- * @deprecated Use `CopyOnWrite`
153
+ * Overlay makes a read-only filesystem writable by storing writes on a second, writable file system.
154
+ * Deletes are persisted via metadata stored on the writable file system.
165
155
  * @category Backends and Configuration
166
- * @internal @hidden
156
+ * @internal
167
157
  */
168
- export declare const Overlay: Overlay;
158
+ export declare const CopyOnWrite: CopyOnWrite;
169
159
  export {};