@zenfs/core 0.10.0 → 0.11.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 (63) hide show
  1. package/dist/backends/Index.d.ts +3 -3
  2. package/dist/backends/Index.js +4 -4
  3. package/dist/backends/backend.d.ts +1 -2
  4. package/dist/backends/backend.js +0 -5
  5. package/dist/backends/{Fetch.d.ts → fetch.d.ts} +4 -4
  6. package/dist/backends/{Fetch.js → fetch.js} +6 -7
  7. package/dist/backends/{Locked.d.ts → locked.d.ts} +2 -2
  8. package/dist/backends/{Locked.js → locked.js} +4 -5
  9. package/dist/backends/{InMemory.d.ts → memory.d.ts} +7 -9
  10. package/dist/backends/memory.js +38 -0
  11. package/dist/backends/{Overlay.d.ts → overlay.d.ts} +12 -13
  12. package/dist/backends/{Overlay.js → overlay.js} +98 -103
  13. package/dist/backends/port/fs.d.ts +15 -16
  14. package/dist/backends/port/fs.js +20 -22
  15. package/dist/backends/store/fs.d.ts +169 -0
  16. package/dist/backends/store/fs.js +743 -0
  17. package/dist/backends/store/simple.d.ts +64 -0
  18. package/dist/backends/store/simple.js +111 -0
  19. package/dist/backends/store/store.d.ts +111 -0
  20. package/dist/backends/store/store.js +62 -0
  21. package/dist/browser.min.js +4 -4
  22. package/dist/browser.min.js.map +4 -4
  23. package/dist/config.d.ts +1 -1
  24. package/dist/config.js +1 -1
  25. package/dist/emulation/shared.js +1 -1
  26. package/dist/error.d.ts +0 -1
  27. package/dist/error.js +0 -1
  28. package/dist/file.js +1 -1
  29. package/dist/filesystem.d.ts +3 -3
  30. package/dist/filesystem.js +26 -29
  31. package/dist/index.d.ts +7 -7
  32. package/dist/index.js +7 -7
  33. package/dist/inode.d.ts +1 -1
  34. package/package.json +1 -1
  35. package/src/backends/Index.ts +4 -4
  36. package/src/backends/backend.ts +3 -7
  37. package/src/backends/{Fetch.ts → fetch.ts} +13 -14
  38. package/src/backends/{Locked.ts → locked.ts} +5 -6
  39. package/src/backends/memory.ts +44 -0
  40. package/src/backends/{Overlay.ts → overlay.ts} +99 -105
  41. package/src/backends/port/fs.ts +24 -26
  42. package/src/backends/store/fs.ts +881 -0
  43. package/src/backends/store/readme.md +9 -0
  44. package/src/backends/store/simple.ts +144 -0
  45. package/src/backends/store/store.ts +164 -0
  46. package/src/config.ts +3 -3
  47. package/src/emulation/shared.ts +1 -1
  48. package/src/error.ts +0 -1
  49. package/src/file.ts +1 -1
  50. package/src/filesystem.ts +29 -32
  51. package/src/index.ts +7 -7
  52. package/src/inode.ts +1 -1
  53. package/dist/backends/AsyncStore.d.ts +0 -204
  54. package/dist/backends/AsyncStore.js +0 -509
  55. package/dist/backends/InMemory.js +0 -49
  56. package/dist/backends/SyncStore.d.ts +0 -213
  57. package/dist/backends/SyncStore.js +0 -445
  58. package/dist/backends/port/store.d.ts +0 -30
  59. package/dist/backends/port/store.js +0 -142
  60. package/src/backends/AsyncStore.ts +0 -655
  61. package/src/backends/InMemory.ts +0 -56
  62. package/src/backends/SyncStore.ts +0 -589
  63. package/src/backends/port/store.ts +0 -187
package/dist/config.d.ts CHANGED
@@ -22,4 +22,4 @@ export interface Configuration {
22
22
  * Creates filesystems with the given configuration, and initializes ZenFS with it.
23
23
  * @see Configuration for more info on the configuration object.
24
24
  */
25
- export declare function configure(config: MountConfiguration | Configuration): Promise<void>;
25
+ export declare function configure<T extends MountConfiguration | Configuration>(config: T | Configuration): Promise<void>;
package/dist/config.js CHANGED
@@ -40,7 +40,7 @@ export async function resolveMountConfig(config, _depth = 0) {
40
40
  throw new ErrnoError(Errno.EPERM, 'Backend not available: ' + backend);
41
41
  }
42
42
  checkOptions(backend, config);
43
- const mount = backend.create(config);
43
+ const mount = await backend.create(config);
44
44
  await mount.ready();
45
45
  return mount;
46
46
  }
@@ -1,6 +1,6 @@
1
1
  // Utilities and shared data
2
2
  import { ErrnoError, Errno } from '../error.js';
3
- import { InMemory } from '../backends/InMemory.js';
3
+ import { InMemory } from '../backends/memory.js';
4
4
  import { rootCred } from '../cred.js';
5
5
  import { normalizePath } from '../utils.js';
6
6
  import { resolve } from './path.js';
package/dist/error.d.ts CHANGED
@@ -187,7 +187,6 @@ export declare class ErrnoError extends Error implements NodeJS.ErrnoException {
187
187
  *
188
188
  * Error codes mirror those returned by regular Unix file operations, which is
189
189
  * what Node returns.
190
- * @constructor ApiError
191
190
  * @param type The type of the error.
192
191
  * @param message A descriptive error message.
193
192
  */
package/dist/error.js CHANGED
@@ -254,7 +254,6 @@ export class ErrnoError extends Error {
254
254
  *
255
255
  * Error codes mirror those returned by regular Unix file operations, which is
256
256
  * what Node returns.
257
- * @constructor ApiError
258
257
  * @param type The type of the error.
259
258
  * @param message A descriptive error message.
260
259
  */
package/dist/file.js CHANGED
@@ -404,7 +404,7 @@ export class PreloadFile extends File {
404
404
  // No copy/read. Return immediatly for better performance
405
405
  return bytesRead;
406
406
  }
407
- new Uint8Array(buffer.buffer, 0, length).set(this._buffer.slice(position, end), offset);
407
+ new Uint8Array(buffer.buffer, offset, length).set(this._buffer.slice(position, end));
408
408
  return bytesRead;
409
409
  }
410
410
  /**
@@ -39,7 +39,7 @@ export declare abstract class FileSystem {
39
39
  */
40
40
  metadata(): FileSystemMetadata;
41
41
  constructor(options?: object);
42
- ready(): Promise<this>;
42
+ ready(): Promise<void>;
43
43
  /**
44
44
  * Asynchronous rename. No arguments other than a possible exception
45
45
  * are given to the completion callback.
@@ -149,7 +149,7 @@ export declare abstract class FileSystem {
149
149
  */
150
150
  declare abstract class SyncFileSystem extends FileSystem {
151
151
  metadata(): FileSystemMetadata;
152
- ready(): Promise<this>;
152
+ ready(): Promise<void>;
153
153
  exists(path: string, cred: Cred): Promise<boolean>;
154
154
  rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
155
155
  stat(path: string, cred: Cred): Promise<Stats>;
@@ -176,7 +176,7 @@ declare abstract class AsyncFileSystem extends FileSystem {
176
176
  abstract _sync: FileSystem;
177
177
  queueDone(): Promise<void>;
178
178
  metadata(): FileSystemMetadata;
179
- ready(): Promise<this>;
179
+ ready(): Promise<void>;
180
180
  renameSync(oldPath: string, newPath: string, cred: Cred): void;
181
181
  statSync(path: string, cred: Cred): Stats;
182
182
  createFileSync(path: string, flag: string, mode: number, cred: Cred): File;
@@ -27,9 +27,7 @@ export class FileSystem {
27
27
  constructor(options) {
28
28
  // unused
29
29
  }
30
- async ready() {
31
- return this;
32
- }
30
+ async ready() { }
33
31
  /**
34
32
  * Test whether or not the given path exists by checking with the file system.
35
33
  */
@@ -133,7 +131,7 @@ export function Async(FS) {
133
131
  await this._sync.ready();
134
132
  await super.ready();
135
133
  if (this._isInitialized) {
136
- return this;
134
+ return;
137
135
  }
138
136
  try {
139
137
  await this.crossCopy('/');
@@ -143,14 +141,13 @@ export function Async(FS) {
143
141
  this._isInitialized = false;
144
142
  throw e;
145
143
  }
146
- return this;
147
144
  }
148
145
  renameSync(oldPath, newPath, cred) {
149
146
  this._sync.renameSync(oldPath, newPath, cred);
150
147
  this.queue('rename', oldPath, newPath, cred);
151
148
  }
152
- statSync(p, cred) {
153
- return this._sync.statSync(p, cred);
149
+ statSync(path, cred) {
150
+ return this._sync.statSync(path, cred);
154
151
  }
155
152
  createFileSync(path, flag, mode, cred) {
156
153
  const file = this._sync.createFileSync(path, flag, mode, cred);
@@ -163,20 +160,20 @@ export function Async(FS) {
163
160
  openFileSync(path, flag, cred) {
164
161
  return this._sync.openFileSync(path, flag, cred);
165
162
  }
166
- unlinkSync(p, cred) {
167
- this._sync.unlinkSync(p, cred);
168
- this.queue('unlink', p, cred);
163
+ unlinkSync(path, cred) {
164
+ this._sync.unlinkSync(path, cred);
165
+ this.queue('unlink', path, cred);
169
166
  }
170
- rmdirSync(p, cred) {
171
- this._sync.rmdirSync(p, cred);
172
- this.queue('rmdir', p, cred);
167
+ rmdirSync(path, cred) {
168
+ this._sync.rmdirSync(path, cred);
169
+ this.queue('rmdir', path, cred);
173
170
  }
174
- mkdirSync(p, mode, cred) {
175
- this._sync.mkdirSync(p, mode, cred);
176
- this.queue('mkdir', p, mode, cred);
171
+ mkdirSync(path, mode, cred) {
172
+ this._sync.mkdirSync(path, mode, cred);
173
+ this.queue('mkdir', path, mode, cred);
177
174
  }
178
- readdirSync(p, cred) {
179
- return this._sync.readdirSync(p, cred);
175
+ readdirSync(path, cred) {
176
+ return this._sync.readdirSync(path, cred);
180
177
  }
181
178
  linkSync(srcpath, dstpath, cred) {
182
179
  this._sync.linkSync(srcpath, dstpath, cred);
@@ -186,27 +183,27 @@ export function Async(FS) {
186
183
  this._sync.syncSync(path, data, stats);
187
184
  this.queue('sync', path, data, stats);
188
185
  }
189
- existsSync(p, cred) {
190
- return this._sync.existsSync(p, cred);
186
+ existsSync(path, cred) {
187
+ return this._sync.existsSync(path, cred);
191
188
  }
192
189
  /**
193
190
  * @internal
194
191
  */
195
- async crossCopy(p) {
196
- const stats = await this.stat(p, rootCred);
192
+ async crossCopy(path) {
193
+ const stats = await this.stat(path, rootCred);
197
194
  if (stats.isDirectory()) {
198
- if (p !== '/') {
199
- const stats = await this.stat(p, rootCred);
200
- this._sync.mkdirSync(p, stats.mode, stats.cred());
195
+ if (path !== '/') {
196
+ const stats = await this.stat(path, rootCred);
197
+ this._sync.mkdirSync(path, stats.mode, stats.cred());
201
198
  }
202
- const files = await this.readdir(p, rootCred);
199
+ const files = await this.readdir(path, rootCred);
203
200
  for (const file of files) {
204
- await this.crossCopy(join(p, file));
201
+ await this.crossCopy(join(path, file));
205
202
  }
206
203
  }
207
204
  else {
208
- const asyncFile = await this.openFile(p, parseFlag('r'), rootCred);
209
- const syncFile = this._sync.createFileSync(p, parseFlag('w'), stats.mode, stats.cred());
205
+ const asyncFile = await this.openFile(path, parseFlag('r'), rootCred);
206
+ const syncFile = this._sync.createFileSync(path, parseFlag('w'), stats.mode, stats.cred());
210
207
  try {
211
208
  const buffer = new Uint8Array(stats.size);
212
209
  await asyncFile.read(buffer);
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  export * from './error.js';
2
2
  export * from './backends/port/fs.js';
3
- export * from './backends/port/store.js';
4
- export * from './backends/AsyncStore.js';
5
- export * from './backends/Fetch.js';
6
- export * from './backends/InMemory.js';
3
+ export * from './backends/fetch.js';
4
+ export * from './backends/memory.js';
7
5
  export * from './backends/Index.js';
8
- export * from './backends/Locked.js';
9
- export * from './backends/Overlay.js';
10
- export * from './backends/SyncStore.js';
6
+ export * from './backends/locked.js';
7
+ export * from './backends/overlay.js';
8
+ export * from './backends/store/fs.js';
9
+ export * from './backends/store/simple.js';
10
+ export * from './backends/store/store.js';
11
11
  export * from './backends/backend.js';
12
12
  export * from './config.js';
13
13
  export * from './cred.js';
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  export * from './error.js';
2
2
  export * from './backends/port/fs.js';
3
- export * from './backends/port/store.js';
4
- export * from './backends/AsyncStore.js';
5
- export * from './backends/Fetch.js';
6
- export * from './backends/InMemory.js';
3
+ export * from './backends/fetch.js';
4
+ export * from './backends/memory.js';
7
5
  export * from './backends/Index.js';
8
- export * from './backends/Locked.js';
9
- export * from './backends/Overlay.js';
10
- export * from './backends/SyncStore.js';
6
+ export * from './backends/locked.js';
7
+ export * from './backends/overlay.js';
8
+ export * from './backends/store/fs.js';
9
+ export * from './backends/store/simple.js';
10
+ export * from './backends/store/store.js';
11
11
  export * from './backends/backend.js';
12
12
  export * from './config.js';
13
13
  export * from './cred.js';
package/dist/inode.d.ts CHANGED
@@ -13,7 +13,7 @@ export declare const size_max: number;
13
13
  * Room inode
14
14
  * @hidden
15
15
  */
16
- export declare const rootIno: Ino;
16
+ export declare const rootIno: 0n;
17
17
  /**
18
18
  * Generate a random ino
19
19
  * @internal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/core",
3
- "version": "0.10.0",
3
+ "version": "0.11.1",
4
4
  "description": "A filesystem in your browser",
5
5
  "main": "dist/index.js",
6
6
  "types": "src/index.ts",
@@ -340,16 +340,16 @@ export class IndexDirInode<TData> extends IndexInode<TData> {
340
340
  }
341
341
  /**
342
342
  * Removes the given item from the directory listing.
343
- * @param p Name of item to remove from the directory listing.
343
+ * @param path Name of item to remove from the directory listing.
344
344
  * @return Returns the item
345
345
  * removed, or null if the item did not exist.
346
346
  */
347
- public remove(p: string): IndexInode<TData> | void {
348
- const item = this._listing.get(p);
347
+ public remove(path: string): IndexInode<TData> | void {
348
+ const item = this._listing.get(path);
349
349
  if (!item) {
350
350
  return;
351
351
  }
352
- this._listing.delete(p);
352
+ this._listing.delete(path);
353
353
  return item;
354
354
  }
355
355
  }
@@ -41,7 +41,7 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
41
41
  /**
42
42
  * Create a new instance of the backend
43
43
  */
44
- create(options: TOptions): FS;
44
+ create(options: TOptions): FS | Promise<FS>;
45
45
 
46
46
  /**
47
47
  * A name to identify the backend.
@@ -68,6 +68,8 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
68
68
 
69
69
  type OptionsOf<T extends Backend> = T extends Backend<FileSystem, infer TOptions> ? TOptions : never;
70
70
 
71
+ type FilesystemOf<T extends Backend> = T extends Backend<infer FS> ? FS : never;
72
+
71
73
  /**
72
74
  * @internal
73
75
  */
@@ -128,12 +130,6 @@ export async function checkOptions<T extends Backend>(backend: T, opts: Partial<
128
130
  }
129
131
  }
130
132
 
131
- export async function createBackend<B extends Backend>(backend: B, options: Partial<OptionsOf<B>> = {}): Promise<ReturnType<B['create']>> {
132
- await checkOptions(backend, options);
133
- const fs = <ReturnType<B['create']>>backend.create(options);
134
- return fs.ready();
135
- }
136
-
137
133
  /**
138
134
  * Specifies a file system backend type and its options.
139
135
  *
@@ -19,11 +19,11 @@ function convertError(e: Error): never {
19
19
  * constants.
20
20
  * @hidden
21
21
  */
22
- async function fetchFile(p: string, type: 'buffer'): Promise<Uint8Array>;
23
- async function fetchFile<T extends object>(p: string, type: 'json'): Promise<T>;
24
- async function fetchFile<T extends object>(p: string, type: 'buffer' | 'json'): Promise<T | Uint8Array>;
25
- async function fetchFile<T extends object>(p: string, type: 'buffer' | 'json'): Promise<T | Uint8Array> {
26
- const response = await fetch(p).catch(convertError);
22
+ async function fetchFile(path: string, type: 'buffer'): Promise<Uint8Array>;
23
+ async function fetchFile<T extends object>(path: string, type: 'json'): Promise<T>;
24
+ async function fetchFile<T extends object>(path: string, type: 'buffer' | 'json'): Promise<T | Uint8Array>;
25
+ async function fetchFile<T extends object>(path: string, type: 'buffer' | 'json'): Promise<T | Uint8Array> {
26
+ const response = await fetch(path).catch(convertError);
27
27
  if (!response.ok) {
28
28
  throw new ErrnoError(Errno.EIO, 'fetch failed: response returned code ' + response.status);
29
29
  }
@@ -42,8 +42,8 @@ async function fetchFile<T extends object>(p: string, type: 'buffer' | 'json'):
42
42
  * Asynchronously retrieves the size of the given file in bytes.
43
43
  * @hidden
44
44
  */
45
- async function fetchSize(p: string): Promise<number> {
46
- const response = await fetch(p, { method: 'HEAD' }).catch(convertError);
45
+ async function fetchSize(path: string): Promise<number> {
46
+ const response = await fetch(path, { method: 'HEAD' }).catch(convertError);
47
47
  if (!response.ok) {
48
48
  throw new ErrnoError(Errno.EIO, 'fetch failed: HEAD response returned code ' + response.status);
49
49
  }
@@ -106,9 +106,8 @@ export class FetchFS extends AsyncIndexFS<Stats> {
106
106
  }
107
107
  }
108
108
 
109
- public async ready(): Promise<this> {
109
+ public async ready(): Promise<void> {
110
110
  await this._init;
111
- return this;
112
111
  }
113
112
 
114
113
  constructor({ index = 'index.json', baseUrl = '' }: FetchOptions) {
@@ -189,11 +188,11 @@ export class FetchFS extends AsyncIndexFS<Stats> {
189
188
  /**
190
189
  * Asynchronously download the given file.
191
190
  */
192
- protected _fetchFile(p: string, type: 'buffer'): Promise<Uint8Array>;
193
- protected _fetchFile(p: string, type: 'json'): Promise<object>;
194
- protected _fetchFile(p: string, type: 'buffer' | 'json'): Promise<object>;
195
- protected _fetchFile(p: string, type: 'buffer' | 'json'): Promise<object> {
196
- return fetchFile(this._getRemotePath(p), type);
191
+ protected _fetchFile(path: string, type: 'buffer'): Promise<Uint8Array>;
192
+ protected _fetchFile(path: string, type: 'json'): Promise<object>;
193
+ protected _fetchFile(path: string, type: 'buffer' | 'json'): Promise<object>;
194
+ protected _fetchFile(path: string, type: 'buffer' | 'json'): Promise<object> {
195
+ return fetchFile(this._getRemotePath(path), type);
197
196
  }
198
197
 
199
198
  /**
@@ -20,9 +20,8 @@ export class LockedFS<FS extends FileSystem> implements FileSystem {
20
20
 
21
21
  constructor(public readonly fs: FS) {}
22
22
 
23
- public async ready(): Promise<this> {
23
+ public async ready(): Promise<void> {
24
24
  await this.fs.ready();
25
- return this;
26
25
  }
27
26
 
28
27
  public metadata(): FileSystemMetadata {
@@ -87,10 +86,10 @@ export class LockedFS<FS extends FileSystem> implements FileSystem {
87
86
  return this.fs.createFileSync(path, flag, mode, cred);
88
87
  }
89
88
 
90
- public async unlink(p: string, cred: Cred): Promise<void> {
91
- await this._mu.lock(p);
92
- await this.fs.unlink(p, cred);
93
- this._mu.unlock(p);
89
+ public async unlink(path: string, cred: Cred): Promise<void> {
90
+ await this._mu.lock(path);
91
+ await this.fs.unlink(path, cred);
92
+ this._mu.unlock(path);
94
93
  }
95
94
 
96
95
  public unlinkSync(path: string, cred: Cred): void {
@@ -0,0 +1,44 @@
1
+ import type { Ino } from '../inode.js';
2
+ import type { Backend } from './backend.js';
3
+ import { StoreFS } from './store/fs.js';
4
+ import { SimpleTransaction, type SimpleSyncStore } from './store/simple.js';
5
+
6
+ /**
7
+ * A simple in-memory store
8
+ */
9
+ export class InMemoryStore extends Map<Ino, Uint8Array> implements SimpleSyncStore {
10
+ public constructor(public name: string = 'tmp') {
11
+ super();
12
+ }
13
+
14
+ public async sync(): Promise<void> {}
15
+
16
+ public clearSync(): void {
17
+ this.clear();
18
+ }
19
+
20
+ public transaction(): SimpleTransaction {
21
+ return new SimpleTransaction(this);
22
+ }
23
+ }
24
+
25
+ /**
26
+ * A simple in-memory file system backed by an InMemoryStore.
27
+ * Files are not persisted across page loads.
28
+ */
29
+ export const InMemory = {
30
+ name: 'InMemory',
31
+ isAvailable(): boolean {
32
+ return true;
33
+ },
34
+ options: {
35
+ name: {
36
+ type: 'string',
37
+ required: false,
38
+ description: 'The name of the store',
39
+ },
40
+ },
41
+ create({ name }: { name?: string }) {
42
+ return new StoreFS(new InMemoryStore(name));
43
+ },
44
+ } as const satisfies Backend<StoreFS, { name?: string }>;