@zenfs/core 0.16.3 → 0.17.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 (74) 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 +0 -3
  20. package/dist/emulation/async.js +6 -2
  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 +26 -3
  25. package/dist/emulation/sync.js +1 -2
  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 +0 -63
  31. package/dist/filesystem.js +0 -311
  32. package/dist/index.d.ts +1 -2
  33. package/dist/index.js +1 -2
  34. package/dist/mixins/async.d.ts +39 -0
  35. package/dist/mixins/async.js +216 -0
  36. package/dist/mixins/mutexed.d.ts +33 -0
  37. package/dist/mixins/mutexed.js +465 -0
  38. package/dist/mixins/readonly.d.ts +25 -0
  39. package/dist/mixins/readonly.js +57 -0
  40. package/dist/mixins/shared.d.ts +12 -0
  41. package/dist/mixins/shared.js +4 -0
  42. package/dist/mixins/sync.d.ts +6 -0
  43. package/dist/mixins/sync.js +43 -0
  44. package/package.json +1 -1
  45. package/src/backends/backend.ts +3 -4
  46. package/src/backends/fetch.ts +7 -3
  47. package/src/backends/{index/fs.ts → file_index.ts} +106 -8
  48. package/src/backends/memory.ts +5 -1
  49. package/src/backends/overlay.ts +64 -90
  50. package/src/backends/port/fs.ts +7 -2
  51. package/src/backends/{index/readme.md → readme.md} +1 -1
  52. package/src/backends/store/fs.ts +97 -155
  53. package/src/backends/store/simple.ts +5 -1
  54. package/src/backends/store/store.ts +10 -5
  55. package/src/config.ts +3 -1
  56. package/src/emulation/async.ts +15 -6
  57. package/src/emulation/dir.ts +19 -16
  58. package/src/emulation/promises.ts +30 -8
  59. package/src/emulation/sync.ts +2 -3
  60. package/src/emulation/watchers.ts +10 -4
  61. package/src/file.ts +94 -1
  62. package/src/filesystem.ts +3 -366
  63. package/src/index.ts +1 -2
  64. package/src/mixins/async.ts +211 -0
  65. package/src/mixins/mutexed.ts +245 -0
  66. package/src/mixins/readonly.ts +97 -0
  67. package/src/mixins/shared.ts +20 -0
  68. package/src/mixins/sync.ts +59 -0
  69. package/dist/backends/index/index.d.ts +0 -43
  70. package/dist/backends/index/index.js +0 -83
  71. package/dist/backends/locked.d.ts +0 -92
  72. package/dist/backends/locked.js +0 -487
  73. package/src/backends/index/index.ts +0 -104
  74. package/src/backends/locked.ts +0 -264
@@ -54,12 +54,11 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
54
54
  /**
55
55
  * Whether the backend is available in the current environment.
56
56
  * It supports checking synchronously and asynchronously
57
- * Sync:
57
+ *
58
58
  * Returns 'true' if this backend is available in the current
59
- * environment. For example, a `localStorage`-backed filesystem will return
60
- * 'false' if the browser does not support that API.
59
+ * environment. For example, a backend using a browser API will return
60
+ * 'false' if the API is unavailable
61
61
  *
62
- * Defaults to 'false', as the FileSystem base class isn't usable alone.
63
62
  */
64
63
  isAvailable(): boolean | Promise<boolean>;
65
64
  }
@@ -1,7 +1,7 @@
1
1
  import type { FileSystemMetadata } from '../filesystem.js';
2
2
  import type { Stats } from '../stats.js';
3
- import { IndexFS } from './index/fs.js';
4
- import type { IndexData } from './index/index.js';
3
+ import { IndexFS } from './file_index.js';
4
+ import type { IndexData } from './file_index.js';
5
5
  /**
6
6
  * Configuration options for FetchFS.
7
7
  */
@@ -52,7 +52,7 @@ export declare class FetchFS extends IndexFS {
52
52
  protected getData(path: string, stats: Stats): Promise<Uint8Array>;
53
53
  protected getDataSync(path: string, stats: Stats): Uint8Array;
54
54
  }
55
- export declare const Fetch: {
55
+ declare const _Fetch: {
56
56
  readonly name: "Fetch";
57
57
  readonly options: {
58
58
  readonly index: {
@@ -69,3 +69,8 @@ export declare const Fetch: {
69
69
  readonly isAvailable: () => boolean;
70
70
  readonly create: (options: FetchOptions) => FetchFS;
71
71
  };
72
+ type _fetch = typeof _Fetch;
73
+ interface Fetch extends _fetch {
74
+ }
75
+ export declare const Fetch: Fetch;
76
+ export {};
@@ -1,5 +1,5 @@
1
1
  import { Errno, ErrnoError } from '../error.js';
2
- import { IndexFS } from './index/fs.js';
2
+ import { IndexFS } from './file_index.js';
3
3
  async function fetchFile(path, type) {
4
4
  const response = await fetch(path).catch((e) => {
5
5
  throw new ErrnoError(Errno.EIO, e.message);
@@ -106,7 +106,7 @@ export class FetchFS extends IndexFS {
106
106
  throw new ErrnoError(Errno.ENODATA, '', path, 'getData');
107
107
  }
108
108
  }
109
- export const Fetch = {
109
+ const _Fetch = {
110
110
  name: 'Fetch',
111
111
  options: {
112
112
  index: {
@@ -127,3 +127,4 @@ export const Fetch = {
127
127
  return new FetchFS(options);
128
128
  },
129
129
  };
130
+ export const Fetch = _Fetch;
@@ -1,15 +1,54 @@
1
- import type { Cred } from '../../cred.js';
2
- import { NoSyncFile } from '../../file.js';
3
- import { FileSystem } from '../../filesystem.js';
4
- import type { Stats } from '../../stats.js';
5
- import type { IndexData } from './index.js';
6
- import { Index } from './index.js';
7
- declare const IndexFS_base: import("../../filesystem.js").Mixin<typeof FileSystem, {
8
- metadata(): import("../../filesystem.js").FileSystemMetadata;
1
+ import type { Cred } from '../cred.js';
2
+ import { NoSyncFile } from '../file.js';
3
+ import { FileSystem } from '../filesystem.js';
4
+ import type { StatsLike } from '../stats.js';
5
+ import { Stats } from '../stats.js';
6
+ /**
7
+ * An Index in JSON form
8
+ * @internal
9
+ */
10
+ export interface IndexData {
11
+ version: 1;
12
+ entries: Record<string, StatsLike<number>>;
13
+ }
14
+ export declare const version = 1;
15
+ /**
16
+ * An index of files
17
+ * @internal
18
+ */
19
+ export declare class Index extends Map<string, Stats> {
20
+ /**
21
+ * Convience method
22
+ */
23
+ files(): Map<string, Stats>;
24
+ /**
25
+ * Converts the index to JSON
26
+ */
27
+ toJSON(): IndexData;
28
+ /**
29
+ * Converts the index to a string
30
+ */
31
+ toString(): string;
32
+ /**
33
+ * Returns the files in the directory `dir`.
34
+ * This is expensive so it is only called once per directory.
35
+ */
36
+ protected dirEntries(dir: string): string[];
37
+ /**
38
+ * Loads the index from JSON data
39
+ */
40
+ fromJSON(json: IndexData): void;
41
+ /**
42
+ * Parses an index from a string
43
+ */
44
+ static parse(data: string): Index;
45
+ }
46
+ declare const IndexFS_base: import("../mixins/shared.js").Mixin<typeof FileSystem, {
47
+ metadata(): import("../filesystem.js").FileSystemMetadata;
9
48
  rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
10
49
  renameSync(oldPath: string, newPath: string, cred: Cred): void;
11
- createFile(path: string, flag: string, mode: number, cred: Cred): Promise<import("../../file.js").File>;
12
- createFileSync(path: string, flag: string, mode: number, cred: Cred): import("../../file.js").File;
50
+ createFile(path: string, flag: string, mode: number, cred: Cred): Promise<import("../file.js").File>;
51
+ createFileSync(path: string, flag: string, mode: number, cred: Cred): import("../file.js").File;
13
52
  unlink(path: string, cred: Cred): Promise<void>;
14
53
  unlinkSync(path: string, cred: Cred): void;
15
54
  rmdir(path: string, cred: Cred): Promise<void>;
@@ -1,8 +1,87 @@
1
- import { ErrnoError, Errno } from '../../error.js';
2
- import { NoSyncFile, isWriteable, flagToMode } from '../../file.js';
3
- import { Readonly, FileSystem } from '../../filesystem.js';
4
- import { decode } from '../../utils.js';
5
- import { Index } from './index.js';
1
+ /* Note: this file is named file_index.ts because Typescript has special behavior regarding index.ts which can't be disabled. */
2
+ import { isJSON } from 'utilium';
3
+ import { basename, dirname } from '../emulation/path.js';
4
+ import { Errno, ErrnoError } from '../error.js';
5
+ import { NoSyncFile, flagToMode, isWriteable } from '../file.js';
6
+ import { FileSystem } from '../filesystem.js';
7
+ import { Readonly } from '../mixins/readonly.js';
8
+ import { Stats } from '../stats.js';
9
+ import { decode, encode } from '../utils.js';
10
+ export const version = 1;
11
+ /**
12
+ * An index of files
13
+ * @internal
14
+ */
15
+ export class Index extends Map {
16
+ /**
17
+ * Convience method
18
+ */
19
+ files() {
20
+ const files = new Map();
21
+ for (const [path, stats] of this) {
22
+ if (stats.isFile()) {
23
+ files.set(path, stats);
24
+ }
25
+ }
26
+ return files;
27
+ }
28
+ /**
29
+ * Converts the index to JSON
30
+ */
31
+ toJSON() {
32
+ return {
33
+ version,
34
+ entries: Object.fromEntries(this),
35
+ };
36
+ }
37
+ /**
38
+ * Converts the index to a string
39
+ */
40
+ toString() {
41
+ return JSON.stringify(this.toJSON());
42
+ }
43
+ /**
44
+ * Returns the files in the directory `dir`.
45
+ * This is expensive so it is only called once per directory.
46
+ */
47
+ dirEntries(dir) {
48
+ const entries = [];
49
+ for (const entry of this.keys()) {
50
+ if (dirname(entry) == dir) {
51
+ entries.push(basename(entry));
52
+ }
53
+ }
54
+ return entries;
55
+ }
56
+ /**
57
+ * Loads the index from JSON data
58
+ */
59
+ fromJSON(json) {
60
+ if (json.version != version) {
61
+ throw new ErrnoError(Errno.EINVAL, 'Index version mismatch');
62
+ }
63
+ this.clear();
64
+ for (const [path, data] of Object.entries(json.entries)) {
65
+ const stats = new Stats(data);
66
+ if (stats.isDirectory()) {
67
+ stats.fileData = encode(JSON.stringify(this.dirEntries(path)));
68
+ }
69
+ this.set(path, stats);
70
+ }
71
+ }
72
+ /**
73
+ * Parses an index from a string
74
+ */
75
+ static parse(data) {
76
+ if (!isJSON(data)) {
77
+ throw new ErrnoError(Errno.EINVAL, 'Invalid JSON');
78
+ }
79
+ const json = JSON.parse(data);
80
+ const index = new Index();
81
+ index.fromJSON(json);
82
+ return index;
83
+ }
84
+ }
6
85
  export class IndexFS extends Readonly(FileSystem) {
7
86
  async ready() {
8
87
  await super.ready();
@@ -15,7 +15,7 @@ export declare class InMemoryStore extends Map<Ino, Uint8Array> implements Simpl
15
15
  * A simple in-memory file system backed by an InMemoryStore.
16
16
  * Files are not persisted across page loads.
17
17
  */
18
- export declare const InMemory: {
18
+ export declare const _InMemory: {
19
19
  readonly name: "InMemory";
20
20
  readonly isAvailable: () => boolean;
21
21
  readonly options: {
@@ -29,3 +29,8 @@ export declare const InMemory: {
29
29
  name?: string;
30
30
  }) => StoreFS<InMemoryStore>;
31
31
  };
32
+ type _inmemory = typeof _InMemory;
33
+ interface InMemory extends _inmemory {
34
+ }
35
+ export declare const InMemory: InMemory;
36
+ export {};
@@ -20,7 +20,7 @@ export class InMemoryStore extends Map {
20
20
  * A simple in-memory file system backed by an InMemoryStore.
21
21
  * Files are not persisted across page loads.
22
22
  */
23
- export const InMemory = {
23
+ export const _InMemory = {
24
24
  name: 'InMemory',
25
25
  isAvailable() {
26
26
  return true;
@@ -38,3 +38,4 @@ export const InMemory = {
38
38
  return fs;
39
39
  },
40
40
  };
41
+ export const InMemory = _InMemory;
@@ -2,7 +2,6 @@ import type { FileSystemMetadata } from '../filesystem.js';
2
2
  import { FileSystem } from '../filesystem.js';
3
3
  import type { File } from '../file.js';
4
4
  import { Stats } from '../stats.js';
5
- import { LockedFS } from './locked.js';
6
5
  import type { Cred } from '../cred.js';
7
6
  /**
8
7
  * Configuration options for OverlayFS instances.
@@ -21,14 +20,14 @@ export interface OverlayOptions {
21
20
  * OverlayFS makes a read-only filesystem writable by storing writes on a second, writable file system.
22
21
  * Deletes are persisted via metadata stored on the writable file system.
23
22
  *
24
- * This class contains no locking whatsoever. It is wrapped in a LockedFS to prevent races.
23
+ * This class contains no locking whatsoever. It is mutexed to prevent races.
25
24
  *
26
25
  * @internal
27
26
  */
28
- export declare class UnlockedOverlayFS extends FileSystem {
27
+ export declare class UnmutexedOverlayFS extends FileSystem {
29
28
  ready(): Promise<void>;
30
- private _writable;
31
- private _readable;
29
+ readonly writable: FileSystem;
30
+ readonly readable: FileSystem;
32
31
  private _isInitialized;
33
32
  private _deletedFiles;
34
33
  private _deleteLog;
@@ -38,7 +37,6 @@ export declare class UnlockedOverlayFS extends FileSystem {
38
37
  private _ready;
39
38
  constructor({ writable, readable }: OverlayOptions);
40
39
  metadata(): FileSystemMetadata;
41
- getOverlayedFileSystems(): OverlayOptions;
42
40
  sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
43
41
  syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
44
42
  /**
@@ -91,23 +89,20 @@ export declare class UnlockedOverlayFS extends FileSystem {
91
89
  private copyToWritableSync;
92
90
  private copyToWritable;
93
91
  }
92
+ declare const OverlayFS_base: import("../mixins/shared.js").Mixin<typeof UnmutexedOverlayFS, {
93
+ lock(path: string): Promise<import("../mixins/mutexed.js").MutexLock>;
94
+ lockSync(path: string): import("../mixins/mutexed.js").MutexLock;
95
+ isLocked(path: string): boolean;
96
+ }>;
94
97
  /**
95
98
  * OverlayFS makes a read-only filesystem writable by storing writes on a second,
96
99
  * writable file system. Deletes are persisted via metadata stored on the writable
97
100
  * file system.
98
101
  * @internal
99
102
  */
100
- export declare class OverlayFS extends LockedFS<UnlockedOverlayFS> {
101
- /**
102
- * @param options The options to initialize the OverlayFS with
103
- */
104
- constructor(options: OverlayOptions);
105
- getOverlayedFileSystems(): OverlayOptions;
106
- getDeletionLog(): string;
107
- resDeletionLog(): string;
108
- unwrap(): UnlockedOverlayFS;
103
+ export declare class OverlayFS extends OverlayFS_base {
109
104
  }
110
- export declare const Overlay: {
105
+ declare const _Overlay: {
111
106
  readonly name: "Overlay";
112
107
  readonly options: {
113
108
  readonly writable: {
@@ -124,3 +119,8 @@ export declare const Overlay: {
124
119
  readonly isAvailable: () => boolean;
125
120
  readonly create: (options: OverlayOptions) => OverlayFS;
126
121
  };
122
+ type _overlay = typeof _Overlay;
123
+ interface Overlay extends _overlay {
124
+ }
125
+ export declare const Overlay: Overlay;
126
+ export {};