@zenfs/core 0.9.5 → 0.9.7

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 (56) hide show
  1. package/dist/ApiError.d.ts +4 -3
  2. package/dist/ApiError.js +1 -1
  3. package/dist/backends/AsyncStore.d.ts +3 -2
  4. package/dist/backends/AsyncStore.js +12 -5
  5. package/dist/backends/InMemory.d.ts +1 -1
  6. package/dist/backends/Index.d.ts +7 -10
  7. package/dist/backends/Index.js +7 -5
  8. package/dist/backends/Overlay.js +1 -1
  9. package/dist/backends/SyncStore.d.ts +6 -6
  10. package/dist/backends/SyncStore.js +4 -4
  11. package/dist/backends/backend.d.ts +5 -4
  12. package/dist/backends/backend.js +2 -2
  13. package/dist/browser.min.js +4 -4
  14. package/dist/browser.min.js.map +3 -3
  15. package/dist/config.d.ts +1 -1
  16. package/dist/config.js +2 -2
  17. package/dist/emulation/async.d.ts +76 -77
  18. package/dist/emulation/async.js +42 -42
  19. package/dist/emulation/dir.js +6 -5
  20. package/dist/emulation/promises.d.ts +106 -102
  21. package/dist/emulation/promises.js +61 -65
  22. package/dist/emulation/shared.d.ts +1 -7
  23. package/dist/emulation/shared.js +1 -1
  24. package/dist/emulation/streams.js +3 -2
  25. package/dist/emulation/sync.d.ts +71 -64
  26. package/dist/emulation/sync.js +39 -40
  27. package/dist/file.d.ts +4 -4
  28. package/dist/file.js +7 -5
  29. package/dist/filesystem.d.ts +1 -1
  30. package/dist/filesystem.js +3 -0
  31. package/dist/mutex.js +2 -2
  32. package/dist/stats.d.ts +7 -7
  33. package/dist/stats.js +50 -10
  34. package/dist/utils.d.ts +5 -5
  35. package/dist/utils.js +4 -3
  36. package/package.json +3 -3
  37. package/readme.md +2 -2
  38. package/src/ApiError.ts +3 -1
  39. package/src/backends/AsyncStore.ts +14 -8
  40. package/src/backends/Index.ts +14 -10
  41. package/src/backends/Overlay.ts +3 -3
  42. package/src/backends/SyncStore.ts +8 -8
  43. package/src/backends/backend.ts +7 -5
  44. package/src/config.ts +5 -5
  45. package/src/emulation/async.ts +188 -196
  46. package/src/emulation/dir.ts +6 -6
  47. package/src/emulation/promises.ts +181 -173
  48. package/src/emulation/shared.ts +2 -9
  49. package/src/emulation/streams.ts +9 -8
  50. package/src/emulation/sync.ts +159 -159
  51. package/src/file.ts +11 -9
  52. package/src/filesystem.ts +11 -7
  53. package/src/mutex.ts +3 -3
  54. package/src/stats.ts +32 -23
  55. package/src/utils.ts +10 -9
  56. package/tsconfig.json +13 -0
@@ -175,11 +175,12 @@ interface ApiErrorJSON {
175
175
  */
176
176
  export declare class ApiError extends Error implements NodeJS.ErrnoException {
177
177
  errno: ErrorCode;
178
- path?: string;
178
+ path?: string | undefined;
179
179
  syscall: string;
180
180
  static fromJSON(json: ApiErrorJSON): ApiError;
181
- static With(code: keyof typeof ErrorCode, path: string, syscall?: string): ApiError;
181
+ static With(code: keyof typeof ErrorCode, path?: string, syscall?: string): ApiError;
182
182
  code: keyof typeof ErrorCode;
183
+ stack: string;
183
184
  /**
184
185
  * Represents a ZenFS error. Passed back to applications after a failed
185
186
  * call to the ZenFS API.
@@ -190,7 +191,7 @@ export declare class ApiError extends Error implements NodeJS.ErrnoException {
190
191
  * @param type The type of the error.
191
192
  * @param message A descriptive error message.
192
193
  */
193
- constructor(errno: ErrorCode, message?: string, path?: string, syscall?: string);
194
+ constructor(errno: ErrorCode, message?: string, path?: string | undefined, syscall?: string);
194
195
  /**
195
196
  * @return A friendly error message.
196
197
  */
package/dist/ApiError.js CHANGED
@@ -153,7 +153,7 @@ export var ErrorCode;
153
153
  ErrorCode[ErrorCode["EREMOTEIO"] = 121] = "EREMOTEIO";
154
154
  /** Disk quota exceeded */
155
155
  ErrorCode[ErrorCode["EDQUOT"] = 122] = "EDQUOT";
156
- })(ErrorCode = ErrorCode || (ErrorCode = {}));
156
+ })(ErrorCode || (ErrorCode = {}));
157
157
  /**
158
158
  * Strings associated with each error code.
159
159
  * @internal
@@ -11,7 +11,7 @@ declare class LRUCache<K, V> {
11
11
  private cache;
12
12
  constructor(limit: number);
13
13
  set(key: K, value: V): void;
14
- get(key: K): V | null;
14
+ get(key: K): V | void;
15
15
  remove(key: K): void;
16
16
  reset(): void;
17
17
  }
@@ -113,7 +113,8 @@ declare const AsyncStoreFS_base: (abstract new (...args: any[]) => {
113
113
  */
114
114
  export declare class AsyncStoreFS extends AsyncStoreFS_base {
115
115
  protected _options: AsyncStoreOptions;
116
- protected store: AsyncStore;
116
+ protected _store?: AsyncStore;
117
+ protected get store(): AsyncStore;
117
118
  protected _cache?: LRUCache<string, Ino>;
118
119
  private _initialized;
119
120
  _sync: FileSystem;
@@ -51,16 +51,22 @@ class LRUCache {
51
51
  * @internal
52
52
  */
53
53
  export class AsyncStoreFS extends Async(FileSystem) {
54
+ get store() {
55
+ if (!this._store) {
56
+ throw new ReferenceError('AsyncStoreFS not attached to a store');
57
+ }
58
+ return this._store;
59
+ }
54
60
  async ready() {
55
61
  if (this._initialized) {
56
62
  return this;
57
63
  }
58
64
  this._initialized = true;
59
- if (this._options.lruCacheSize > 0) {
65
+ if (this._options.lruCacheSize) {
60
66
  this._cache = new LRUCache(this._options.lruCacheSize);
61
67
  }
62
- this.store = await this._options.store;
63
- this._sync = this._options.sync || InMemory.create({ name: 'test' });
68
+ this._store = await this._options.store;
69
+ this._sync = this._options.sync || this._sync;
64
70
  await this.makeRootDirectory();
65
71
  await super.ready();
66
72
  return this;
@@ -75,6 +81,7 @@ export class AsyncStoreFS extends Async(FileSystem) {
75
81
  super();
76
82
  this._options = _options;
77
83
  this._initialized = false;
84
+ this._sync = InMemory.create({ name: 'test' });
78
85
  }
79
86
  /**
80
87
  * Delete all contents stored in the file system.
@@ -95,8 +102,8 @@ export class AsyncStoreFS extends Async(FileSystem) {
95
102
  const c = this._cache;
96
103
  if (this._cache) {
97
104
  // Clear and disable cache during renaming process.
98
- this._cache = null;
99
- c.reset();
105
+ delete this._cache;
106
+ c?.reset();
100
107
  }
101
108
  try {
102
109
  const tx = this.store.beginTransaction(), oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath),
@@ -9,7 +9,7 @@ export declare class InMemoryStore implements SyncStore, SimpleSyncStore {
9
9
  constructor(name?: string);
10
10
  clear(): void;
11
11
  beginTransaction(): SyncTransaction;
12
- get(key: Ino): Uint8Array;
12
+ get(key: Ino): Uint8Array | undefined;
13
13
  put(key: Ino, data: Uint8Array, overwrite: boolean): boolean;
14
14
  remove(key: Ino): void;
15
15
  }
@@ -68,25 +68,25 @@ export declare class FileIndex<TData> {
68
68
  * @return The removed item,
69
69
  * or null if it did not exist.
70
70
  */
71
- remove(path: string): IndexInode<TData> | null;
71
+ remove(path: string): IndexInode<TData> | void;
72
72
  /**
73
73
  * Retrieves the directory listing of the given path.
74
74
  * @return An array of files in the given path, or 'null' if it does not exist.
75
75
  */
76
- ls(path: string): string[] | null;
76
+ ls(path: string): string[] | void;
77
77
  /**
78
78
  * Returns the inode of the given item.
79
79
  * @return Returns null if the item does not exist.
80
80
  */
81
- get(path: string): IndexInode<TData> | null;
81
+ get(path: string): IndexInode<TData> | void | null;
82
82
  }
83
83
  /**
84
84
  * Generic interface for file/directory inodes.
85
85
  * Note that Stats objects are what we use for file inodes.
86
86
  */
87
87
  export declare abstract class IndexInode<TData> {
88
- data?: TData;
89
- constructor(data?: TData);
88
+ data?: TData | undefined;
89
+ constructor(data?: TData | undefined);
90
90
  /**
91
91
  * Whether this inode is for a file
92
92
  */
@@ -135,7 +135,7 @@ export declare class IndexDirInode<TData> extends IndexInode<TData> {
135
135
  * Returns the inode for the indicated item, or null if it does not exist.
136
136
  * @param path Name of item in this directory.
137
137
  */
138
- get(path: string): IndexInode<TData> | null;
138
+ get(path: string): IndexInode<TData> | void;
139
139
  /**
140
140
  * Add the given item to the directory listing. Note that the given inode is
141
141
  * not copied, and will be mutated by the DirInode if it is a DirInode.
@@ -151,7 +151,7 @@ export declare class IndexDirInode<TData> extends IndexInode<TData> {
151
151
  * @return Returns the item
152
152
  * removed, or null if the item did not exist.
153
153
  */
154
- remove(p: string): IndexInode<TData> | null;
154
+ remove(p: string): IndexInode<TData> | void;
155
155
  }
156
156
  declare const IndexFS_base: (abstract new (...args: any[]) => {
157
157
  metadata(): import("../filesystem.js").FileSystemMetadata;
@@ -173,9 +173,6 @@ declare const IndexFS_base: (abstract new (...args: any[]) => {
173
173
  stat(path: string, cred: Cred): Promise<Stats>;
174
174
  statSync(path: string, cred: Cred): Stats;
175
175
  openFile(path: string, flag: string, cred: Cred): Promise<import("../file.js").File>;
176
- /**
177
- * Constructs a new FileIndex.
178
- */
179
176
  openFileSync(path: string, flag: string, cred: Cred): import("../file.js").File;
180
177
  readdir(path: string, cred: Cred): Promise<string[]>;
181
178
  readdirSync(path: string, cred: Cred): string[];
@@ -66,7 +66,10 @@ export class FileIndex {
66
66
  for (const dir of this._index.values()) {
67
67
  for (const file of dir.listing) {
68
68
  const item = dir.get(file);
69
- if (!item?.isFile()) {
69
+ if (!item) {
70
+ continue;
71
+ }
72
+ if (!item.isFile()) {
70
73
  continue;
71
74
  }
72
75
  files.push(item);
@@ -98,11 +101,10 @@ export class FileIndex {
98
101
  return this._index.get(path) === inode;
99
102
  }
100
103
  const dirpath = dirname(path);
104
+ const hasParent = this._index.has(dirpath);
105
+ const parent = hasParent ? this._index.get(dirpath) : new IndexDirInode();
101
106
  // Try to add to its parent directory first.
102
- let parent = this._index.get(dirpath);
103
- if (!parent && path != '/') {
104
- // Create parent.
105
- parent = new IndexDirInode();
107
+ if (!hasParent && path != '/') {
106
108
  if (!this.add(dirpath, parent)) {
107
109
  return false;
108
110
  }
@@ -370,7 +370,7 @@ export class UnlockedOverlayFS extends FileSystem {
370
370
  return;
371
371
  }
372
372
  const error = this._deleteLogError;
373
- this._deleteLogError = null;
373
+ delete this._deleteLogError;
374
374
  throw error;
375
375
  }
376
376
  checkPath(path) {
@@ -30,7 +30,7 @@ export interface SyncTransaction {
30
30
  * @param ino The key to look under for data.
31
31
  * @return The data stored under the key, or undefined if not present.
32
32
  */
33
- get(ino: Ino): Uint8Array | undefined;
33
+ get(ino: Ino): Uint8Array | void;
34
34
  /**
35
35
  * Adds the data to the store under the given key.
36
36
  * @param ino The key to add the data under.
@@ -72,13 +72,13 @@ export declare class SimpleSyncTransaction implements SyncTransaction {
72
72
  * Stores data in the keys we modify prior to modifying them.
73
73
  * Allows us to roll back commits.
74
74
  */
75
- protected originalData: Map<Ino, Uint8Array>;
75
+ protected originalData: Map<Ino, Uint8Array | void>;
76
76
  /**
77
77
  * List of keys modified in this transaction, if any.
78
78
  */
79
79
  protected modifiedKeys: Set<Ino>;
80
80
  constructor(store: SimpleSyncStore);
81
- get(ino: Ino): Uint8Array | undefined;
81
+ get(ino: Ino): Uint8Array | void;
82
82
  put(ino: Ino, data: Uint8Array, overwrite: boolean): boolean;
83
83
  remove(ino: Ino): void;
84
84
  commit(): void;
@@ -89,7 +89,7 @@ export declare class SimpleSyncTransaction implements SyncTransaction {
89
89
  * prevent needless `get` requests if the program modifies the data later
90
90
  * on during the transaction.
91
91
  */
92
- protected stashOldValue(ino: Ino, value: Uint8Array | undefined): void;
92
+ protected stashOldValue(ino: Ino, value?: Uint8Array): void;
93
93
  /**
94
94
  * Marks the given key as modified, and stashes its value if it has not been
95
95
  * stashed already.
@@ -176,10 +176,10 @@ export declare class SyncStoreFS extends SyncStoreFS_base {
176
176
  /**
177
177
  * Given the ID of a node, retrieves the corresponding Inode.
178
178
  * @param tx The transaction to use.
179
- * @param p The corresponding path to the file (used for error messages).
179
+ * @param path The corresponding path to the file (used for error messages).
180
180
  * @param id The ID to look up.
181
181
  */
182
- protected getINode(tx: SyncTransaction, id: Ino, p?: string): Inode;
182
+ protected getINode(tx: SyncTransaction, id: Ino, path?: string): Inode;
183
183
  /**
184
184
  * Given the Inode of a directory, retrieves the corresponding directory listing.
185
185
  */
@@ -183,7 +183,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
183
183
  if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
184
184
  throw ApiError.With('EACCES', p, 'openFile');
185
185
  }
186
- if (data === null) {
186
+ if (!data) {
187
187
  throw ApiError.With('ENOENT', p, 'openFile');
188
188
  }
189
189
  return new PreloadFile(this, p, flag, node.toStats(), data);
@@ -318,13 +318,13 @@ export class SyncStoreFS extends Sync(FileSystem) {
318
318
  /**
319
319
  * Given the ID of a node, retrieves the corresponding Inode.
320
320
  * @param tx The transaction to use.
321
- * @param p The corresponding path to the file (used for error messages).
321
+ * @param path The corresponding path to the file (used for error messages).
322
322
  * @param id The ID to look up.
323
323
  */
324
- getINode(tx, id, p) {
324
+ getINode(tx, id, path) {
325
325
  const data = tx.get(id);
326
326
  if (!data) {
327
- throw ApiError.With('ENOENT', p, 'getINode');
327
+ throw ApiError.With('ENOENT', path, 'getINode');
328
328
  }
329
329
  const inode = new Inode(data.buffer);
330
330
  return inode;
@@ -54,6 +54,7 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
54
54
  */
55
55
  isAvailable(): boolean | Promise<boolean>;
56
56
  }
57
+ type OptionsOf<T extends Backend> = T extends Backend<FileSystem, infer TOptions> ? TOptions : never;
57
58
  /**
58
59
  * @internal
59
60
  */
@@ -62,8 +63,8 @@ export declare function isBackend(arg: unknown): arg is Backend;
62
63
  * Checks that the given options object is valid for the file system options.
63
64
  * @internal
64
65
  */
65
- export declare function checkOptions<T extends Backend>(backend: T, opts: object): Promise<void>;
66
- export declare function createBackend<B extends Backend>(backend: B, options?: object): Promise<ReturnType<B['create']>>;
66
+ export declare function checkOptions<T extends Backend>(backend: T, opts: Partial<OptionsOf<T>> & Record<string, unknown>): Promise<void>;
67
+ export declare function createBackend<B extends Backend>(backend: B, options?: Partial<OptionsOf<B>>): Promise<ReturnType<B['create']>>;
67
68
  /**
68
69
  * Specifies a file system backend type and its options.
69
70
  *
@@ -72,8 +73,8 @@ export declare function createBackend<B extends Backend>(backend: B, options?: o
72
73
  *
73
74
  * The option object for each file system corresponds to that file system's option object passed to its `Create()` method.
74
75
  */
75
- export type BackendConfiguration<FS extends FileSystem = FileSystem, TOptions extends object = object> = TOptions & {
76
- backend: Backend<FS, TOptions>;
76
+ export type BackendConfiguration<T extends Backend = Backend> = OptionsOf<T> & {
77
+ backend: T;
77
78
  };
78
79
  /**
79
80
  * @internal
@@ -44,8 +44,8 @@ export async function checkOptions(backend, opts) {
44
44
  // Otherwise: All good!
45
45
  }
46
46
  }
47
- export function createBackend(backend, options) {
48
- checkOptions(backend, options);
47
+ export async function createBackend(backend, options = {}) {
48
+ await checkOptions(backend, options);
49
49
  const fs = backend.create(options);
50
50
  return fs.ready();
51
51
  }