@zenfs/dom 0.2.6 → 0.2.8

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.
@@ -1,34 +1,33 @@
1
- import type { AsyncStore, AsyncStoreOptions, AsyncTransaction, Ino } from '@zenfs/core';
2
- import { AsyncStoreFS } from '@zenfs/core';
1
+ import type { Store } from '@zenfs/core/backends/store/store.js';
2
+ import { AsyncTransaction } from '@zenfs/core/backends/store/store.js';
3
+ import type { Ino } from '@zenfs/core';
4
+ import { StoreFS } from '@zenfs/core';
3
5
  /**
4
6
  * @hidden
5
7
  */
6
- export declare class IndexedDBTransaction implements AsyncTransaction {
8
+ export declare class IndexedDBTransaction extends AsyncTransaction {
7
9
  tx: IDBTransaction;
8
10
  store: IDBObjectStore;
9
11
  constructor(tx: IDBTransaction, store: IDBObjectStore);
10
12
  get(key: Ino): Promise<Uint8Array>;
11
- /**
12
- * @todo return false when add has a key conflict (no error)
13
- */
14
- put(key: Ino, data: Uint8Array, overwrite: boolean): Promise<boolean>;
13
+ set(key: Ino, data: Uint8Array): Promise<void>;
15
14
  remove(key: Ino): Promise<void>;
16
15
  commit(): Promise<void>;
17
16
  abort(): Promise<void>;
18
17
  }
19
- export declare class IndexedDBStore implements AsyncStore {
18
+ export declare class IndexedDBStore implements Store {
20
19
  protected db: IDBDatabase;
21
- protected storeName: string;
22
- static create(storeName: string, indexedDB?: IDBFactory): Promise<IndexedDBStore>;
23
- constructor(db: IDBDatabase, storeName: string);
20
+ constructor(db: IDBDatabase);
21
+ sync(): Promise<void>;
24
22
  get name(): string;
25
23
  clear(): Promise<void>;
26
- beginTransaction(): IndexedDBTransaction;
24
+ clearSync(): void;
25
+ transaction(): IndexedDBTransaction;
27
26
  }
28
27
  /**
29
28
  * Configuration options for the IndexedDB file system.
30
29
  */
31
- export interface IndexedDBOptions extends Omit<AsyncStoreOptions, 'store'> {
30
+ export interface IndexedDBOptions {
32
31
  /**
33
32
  * The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.
34
33
  */
@@ -49,11 +48,6 @@ export declare const IndexedDB: {
49
48
  readonly required: false;
50
49
  readonly description: "The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.";
51
50
  };
52
- readonly cacheSize: {
53
- readonly type: "number";
54
- readonly required: false;
55
- readonly description: "The size of the inode cache. Defaults to 100. A size of 0 or below disables caching.";
56
- };
57
51
  readonly idbFactory: {
58
52
  readonly type: "object";
59
53
  readonly required: false;
@@ -61,5 +55,5 @@ export declare const IndexedDB: {
61
55
  };
62
56
  };
63
57
  readonly isAvailable: (idbFactory?: IDBFactory) => Promise<boolean>;
64
- readonly create: (options: IndexedDBOptions) => AsyncStoreFS;
58
+ readonly create: (options: IndexedDBOptions) => Promise<StoreFS>;
65
59
  };
package/dist/IndexedDB.js CHANGED
@@ -1,4 +1,5 @@
1
- import { AsyncStoreFS } from '@zenfs/core';
1
+ import { AsyncTransaction } from '@zenfs/core/backends/store/store.js';
2
+ import { ErrnoError, StoreFS } from '@zenfs/core';
2
3
  import { convertException } from './utils.js';
3
4
  function wrap(request) {
4
5
  return new Promise((resolve, reject) => {
@@ -12,26 +13,23 @@ function wrap(request) {
12
13
  /**
13
14
  * @hidden
14
15
  */
15
- export class IndexedDBTransaction {
16
+ export class IndexedDBTransaction extends AsyncTransaction {
16
17
  constructor(tx, store) {
18
+ super();
17
19
  this.tx = tx;
18
20
  this.store = store;
19
21
  }
20
22
  get(key) {
21
23
  return wrap(this.store.get(key.toString()));
22
24
  }
23
- /**
24
- * @todo return false when add has a key conflict (no error)
25
- */
26
- async put(key, data, overwrite) {
27
- await wrap(this.store[overwrite ? 'put' : 'add'](data, key.toString()));
28
- return true;
25
+ async set(key, data) {
26
+ await wrap(this.store.put(data, key.toString()));
29
27
  }
30
28
  remove(key) {
31
29
  return wrap(this.store.delete(key.toString()));
32
30
  }
33
31
  async commit() {
34
- return;
32
+ this.tx.commit();
35
33
  }
36
34
  async abort() {
37
35
  try {
@@ -42,33 +40,38 @@ export class IndexedDBTransaction {
42
40
  }
43
41
  }
44
42
  }
43
+ async function createDB(name, indexedDB = globalThis.indexedDB) {
44
+ const req = indexedDB.open(name);
45
+ req.onupgradeneeded = () => {
46
+ const db = req.result;
47
+ // This should never happen; we're at version 1. Why does another database exist?
48
+ if (db.objectStoreNames.contains(name)) {
49
+ db.deleteObjectStore(name);
50
+ }
51
+ db.createObjectStore(name);
52
+ };
53
+ const result = await wrap(req);
54
+ return result;
55
+ }
45
56
  export class IndexedDBStore {
46
- static async create(storeName, indexedDB = globalThis.indexedDB) {
47
- const req = indexedDB.open(storeName, 1);
48
- req.onupgradeneeded = () => {
49
- const db = req.result;
50
- // This should never happen; we're at version 1. Why does another database exist?
51
- if (db.objectStoreNames.contains(storeName)) {
52
- db.deleteObjectStore(storeName);
53
- }
54
- db.createObjectStore(storeName);
55
- };
56
- const result = await wrap(req);
57
- return new IndexedDBStore(result, storeName);
58
- }
59
- constructor(db, storeName) {
57
+ constructor(db) {
60
58
  this.db = db;
61
- this.storeName = storeName;
59
+ }
60
+ sync() {
61
+ throw new Error('Method not implemented.');
62
62
  }
63
63
  get name() {
64
- return IndexedDB.name + ':' + this.storeName;
64
+ return IndexedDB.name + ':' + this.db.name;
65
65
  }
66
66
  clear() {
67
- return wrap(this.db.transaction(this.storeName, 'readwrite').objectStore(this.storeName).clear());
67
+ return wrap(this.db.transaction(this.db.name, 'readwrite').objectStore(this.db.name).clear());
68
+ }
69
+ clearSync() {
70
+ throw ErrnoError.With('ENOSYS', undefined, 'IndexedDBStore.clearSync');
68
71
  }
69
- beginTransaction() {
70
- const tx = this.db.transaction(this.storeName, 'readwrite');
71
- return new IndexedDBTransaction(tx, tx.objectStore(this.storeName));
72
+ transaction() {
73
+ const tx = this.db.transaction(this.db.name, 'readwrite');
74
+ return new IndexedDBTransaction(tx, tx.objectStore(this.db.name));
72
75
  }
73
76
  }
74
77
  /**
@@ -82,11 +85,6 @@ export const IndexedDB = {
82
85
  required: false,
83
86
  description: 'The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.',
84
87
  },
85
- cacheSize: {
86
- type: 'number',
87
- required: false,
88
- description: 'The size of the inode cache. Defaults to 100. A size of 0 or below disables caching.',
89
- },
90
88
  idbFactory: {
91
89
  type: 'object',
92
90
  required: false,
@@ -108,9 +106,10 @@ export const IndexedDB = {
108
106
  return false;
109
107
  }
110
108
  },
111
- create(options) {
112
- const store = IndexedDBStore.create(options.storeName || 'zenfs', options.idbFactory);
113
- const fs = new AsyncStoreFS({ ...options, store });
109
+ async create(options) {
110
+ const db = await createDB(options.storeName || 'zenfs', options.idbFactory);
111
+ const store = new IndexedDBStore(db);
112
+ const fs = new StoreFS(store);
114
113
  return fs;
115
114
  },
116
115
  };
package/dist/Storage.d.ts CHANGED
@@ -1,17 +1,19 @@
1
- import type { Ino, SimpleSyncStore, SyncStore } from '@zenfs/core';
2
- import { SimpleSyncTransaction, SyncStoreFS } from '@zenfs/core';
1
+ import type { Ino, SimpleSyncStore, Store } from '@zenfs/core';
2
+ import { SimpleTransaction, StoreFS } from '@zenfs/core';
3
3
  /**
4
4
  * A synchronous key-value store backed by Storage.
5
5
  */
6
- export declare class WebStorageStore implements SyncStore, SimpleSyncStore {
6
+ export declare class WebStorageStore implements Store, SimpleSyncStore {
7
7
  protected _storage: Storage;
8
8
  get name(): string;
9
9
  constructor(_storage: Storage);
10
10
  clear(): void;
11
- beginTransaction(): SimpleSyncTransaction;
11
+ clearSync(): void;
12
+ sync(): Promise<void>;
13
+ transaction(): SimpleTransaction;
12
14
  get(key: Ino): Uint8Array | undefined;
13
- put(key: Ino, data: Uint8Array, overwrite: boolean): boolean;
14
- remove(key: Ino): void;
15
+ set(key: Ino, data: Uint8Array): void;
16
+ delete(key: Ino): void;
15
17
  }
16
18
  /**
17
19
  * Options to pass to the StorageFileSystem
@@ -35,5 +37,5 @@ export declare const WebStorage: {
35
37
  };
36
38
  };
37
39
  readonly isAvailable: (storage?: Storage) => boolean;
38
- readonly create: ({ storage }: WebStorageOptions) => SyncStoreFS;
40
+ readonly create: ({ storage }: WebStorageOptions) => StoreFS;
39
41
  };
package/dist/Storage.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ApiError, ErrorCode, SimpleSyncTransaction, SyncStoreFS, decode, encode } from '@zenfs/core';
1
+ import { ErrnoError, Errno, SimpleTransaction, StoreFS, decode, encode } from '@zenfs/core';
2
2
  /**
3
3
  * A synchronous key-value store backed by Storage.
4
4
  */
@@ -12,9 +12,13 @@ export class WebStorageStore {
12
12
  clear() {
13
13
  this._storage.clear();
14
14
  }
15
- beginTransaction() {
15
+ clearSync() {
16
+ this._storage.clear();
17
+ }
18
+ async sync() { }
19
+ transaction() {
16
20
  // No need to differentiate.
17
- return new SimpleSyncTransaction(this);
21
+ return new SimpleTransaction(this);
18
22
  }
19
23
  get(key) {
20
24
  const data = this._storage.getItem(key.toString());
@@ -23,25 +27,20 @@ export class WebStorageStore {
23
27
  }
24
28
  return encode(data);
25
29
  }
26
- put(key, data, overwrite) {
30
+ set(key, data) {
27
31
  try {
28
- if (!overwrite && this._storage.getItem(key.toString()) !== null) {
29
- // Don't want to overwrite the key!
30
- return false;
31
- }
32
32
  this._storage.setItem(key.toString(), decode(data));
33
- return true;
34
33
  }
35
34
  catch (e) {
36
- throw new ApiError(ErrorCode.ENOSPC, 'Storage is full.');
35
+ throw new ErrnoError(Errno.ENOSPC, 'Storage is full.');
37
36
  }
38
37
  }
39
- remove(key) {
38
+ delete(key) {
40
39
  try {
41
40
  this._storage.removeItem(key.toString());
42
41
  }
43
42
  catch (e) {
44
- throw new ApiError(ErrorCode.EIO, 'Unable to delete key ' + key + ': ' + e);
43
+ throw new ErrnoError(Errno.EIO, 'Unable to delete key ' + key + ': ' + e);
45
44
  }
46
45
  }
47
46
  }
@@ -61,6 +60,6 @@ export const WebStorage = {
61
60
  return storage instanceof globalThis.Storage;
62
61
  },
63
62
  create({ storage = globalThis.localStorage }) {
64
- return new SyncStoreFS({ store: new WebStorageStore(storage) });
63
+ return new StoreFS(new WebStorageStore(storage));
65
64
  },
66
65
  };
package/dist/access.d.ts CHANGED
@@ -15,7 +15,7 @@ declare const WebAccessFS_base: (abstract new (...args: any[]) => {
15
15
  _sync: FileSystem;
16
16
  queueDone(): Promise<void>;
17
17
  metadata(): FileSystemMetadata;
18
- ready(): Promise<any>;
18
+ ready(): Promise<void>;
19
19
  renameSync(oldPath: string, newPath: string, cred: import("@zenfs/core").Cred): void;
20
20
  statSync(path: string, cred: import("@zenfs/core").Cred): Stats;
21
21
  createFileSync(path: string, flag: string, mode: number, cred: import("@zenfs/core").Cred): import("@zenfs/core").File;
@@ -47,7 +47,7 @@ export declare class WebAccessFS extends WebAccessFS_base {
47
47
  _sync: FileSystem;
48
48
  constructor({ handle }: WebAccessOptions);
49
49
  metadata(): FileSystemMetadata;
50
- sync(p: string, data: Uint8Array, stats: Stats): Promise<void>;
50
+ sync(path: string, data: Uint8Array, stats: Stats): Promise<void>;
51
51
  rename(oldPath: string, newPath: string): Promise<void>;
52
52
  writeFile(fname: string, data: Uint8Array): Promise<void>;
53
53
  createFile(path: string, flag: string): Promise<PreloadFile<this>>;
package/dist/access.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ApiError, Async, ErrorCode, FileSystem, FileType, InMemory, PreloadFile, Stats } from '@zenfs/core';
1
+ import { ErrnoError, Async, Errno, FileSystem, FileType, InMemory, PreloadFile, Stats } from '@zenfs/core';
2
2
  import { basename, dirname, join } from '@zenfs/core/emulation/path.js';
3
3
  import { convertException } from './utils.js';
4
4
  export class WebAccessFS extends Async(FileSystem) {
@@ -14,10 +14,10 @@ export class WebAccessFS extends Async(FileSystem) {
14
14
  name: 'WebAccess',
15
15
  };
16
16
  }
17
- async sync(p, data, stats) {
18
- const currentStats = await this.stat(p);
17
+ async sync(path, data, stats) {
18
+ const currentStats = await this.stat(path);
19
19
  if (stats.mtime !== currentStats.mtime) {
20
- await this.writeFile(p, data);
20
+ await this.writeFile(path, data);
21
21
  }
22
22
  }
23
23
  async rename(oldPath, newPath) {
@@ -70,7 +70,7 @@ export class WebAccessFS extends Async(FileSystem) {
70
70
  async stat(path) {
71
71
  const handle = await this.getHandle(path);
72
72
  if (!handle) {
73
- throw ApiError.With('ENOENT', path, 'stat');
73
+ throw ErrnoError.With('ENOENT', path, 'stat');
74
74
  }
75
75
  if (handle instanceof FileSystemDirectoryHandle) {
76
76
  return new Stats({ mode: 0o777 | FileType.DIRECTORY, size: 4096 });
@@ -79,12 +79,12 @@ export class WebAccessFS extends Async(FileSystem) {
79
79
  const { lastModified, size } = await handle.getFile();
80
80
  return new Stats({ mode: 0o777 | FileType.FILE, size, mtimeMs: lastModified });
81
81
  }
82
- throw new ApiError(ErrorCode.EBADE, 'Handle is not a directory or file', path, 'stat');
82
+ throw new ErrnoError(Errno.EBADE, 'Handle is not a directory or file', path, 'stat');
83
83
  }
84
84
  async openFile(path, flag) {
85
85
  const handle = await this.getHandle(path);
86
86
  if (!(handle instanceof FileSystemFileHandle)) {
87
- throw ApiError.With('EISDIR', path, 'openFile');
87
+ throw ErrnoError.With('EISDIR', path, 'openFile');
88
88
  }
89
89
  try {
90
90
  const file = await handle.getFile();
@@ -108,7 +108,7 @@ export class WebAccessFS extends Async(FileSystem) {
108
108
  }
109
109
  }
110
110
  async link(srcpath) {
111
- throw ApiError.With('ENOSYS', srcpath, 'WebAccessFS.link');
111
+ throw ErrnoError.With('ENOSYS', srcpath, 'WebAccessFS.link');
112
112
  }
113
113
  async rmdir(path) {
114
114
  return this.unlink(path);
@@ -116,18 +116,18 @@ export class WebAccessFS extends Async(FileSystem) {
116
116
  async mkdir(path) {
117
117
  const existingHandle = await this.getHandle(path);
118
118
  if (existingHandle) {
119
- throw ApiError.With('EEXIST', path, 'mkdir');
119
+ throw ErrnoError.With('EEXIST', path, 'mkdir');
120
120
  }
121
121
  const handle = await this.getHandle(dirname(path));
122
122
  if (!(handle instanceof FileSystemDirectoryHandle)) {
123
- throw ApiError.With('ENOTDIR', path, 'mkdir');
123
+ throw ErrnoError.With('ENOTDIR', path, 'mkdir');
124
124
  }
125
125
  await handle.getDirectoryHandle(basename(path), { create: true });
126
126
  }
127
127
  async readdir(path) {
128
128
  const handle = await this.getHandle(path);
129
129
  if (!(handle instanceof FileSystemDirectoryHandle)) {
130
- throw ApiError.With('ENOTDIR', path, 'readdir');
130
+ throw ErrnoError.With('ENOTDIR', path, 'readdir');
131
131
  }
132
132
  const _keys = [];
133
133
  for await (const key of handle.keys()) {
@@ -143,7 +143,7 @@ export class WebAccessFS extends Async(FileSystem) {
143
143
  for (const part of path.split('/').slice(1)) {
144
144
  const handle = this._handles.get(walked);
145
145
  if (!(handle instanceof FileSystemDirectoryHandle)) {
146
- throw ApiError.With('ENOTDIR', walked, 'getHandle');
146
+ throw ErrnoError.With('ENOTDIR', walked, 'getHandle');
147
147
  }
148
148
  walked = join(walked, part);
149
149
  try {
@@ -162,7 +162,7 @@ export class WebAccessFS extends Async(FileSystem) {
162
162
  }
163
163
  }
164
164
  if (ex.name === 'TypeError') {
165
- throw new ApiError(ErrorCode.ENOENT, ex.message, walked, 'getHandle');
165
+ throw new ErrnoError(Errno.ENOENT, ex.message, walked, 'getHandle');
166
166
  }
167
167
  convertException(ex, walked, 'getHandle');
168
168
  }
@@ -1,2 +1,2 @@
1
- "use strict";var ZenFS_DOM=(()=>{var F=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var c=(r,e)=>F(r,"name",{value:e,configurable:!0});var R=(r,e)=>{for(var t in e)F(r,t,{get:e[t],enumerable:!0})},U=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of z(e))!W.call(r,i)&&i!==t&&F(r,i,{get:()=>e[i],enumerable:!(n=P(e,i))||n.enumerable});return r};var $=r=>U(F({},"__esModule",{value:!0}),r);var V={};R(V,{IndexedDB:()=>M,IndexedDBStore:()=>u,IndexedDBTransaction:()=>E,WebAccess:()=>Y,WebAccessFS:()=>b,WebStorage:()=>_,WebStorageStore:()=>w});var Z=ZenFS,{ActionType:Q,ApiError:l,Async:v,AsyncIndexFS:G,AsyncStoreFS:k,BigIntStats:J,BigIntStatsFs:K,Dir:ee,Dirent:te,ErrorCode:d,File:re,FileIndex:ne,FileSystem:T,FileType:x,InMemory:A,InMemoryStore:ie,IndexDirInode:oe,IndexFS:se,IndexFileInode:ae,IndexInode:ce,Inode:le,LockedFS:de,Mutex:fe,NoSyncFile:ue,Overlay:me,OverlayFS:ye,PreloadFile:H,ReadStream:Se,Readonly:ge,SimpleSyncTransaction:O,Stats:I,StatsCommon:pe,StatsFs:he,Sync:be,SyncIndexFS:Ee,SyncStoreFS:N,UnlockedOverlayFS:we,WriteStream:Fe,_toUnixTimestamp:xe,access:Ie,accessSync:De,appendFile:ve,appendFileSync:ke,checkOptions:Te,chmod:Ae,chmodSync:He,chown:Oe,chownSync:Ne,close:Be,closeSync:Ce,configure:Me,constants:_e,copyFile:Pe,copyFileSync:ze,cp:We,cpSync:Re,createBackend:Ue,createReadStream:$e,createWriteStream:je,decode:B,decodeDirListing:Le,encode:C,encodeDirListing:qe,errorMessages:Ye,exists:Ve,existsSync:Xe,fchmod:Ze,fchmodSync:Qe,fchown:Ge,fchownSync:Je,fdatasync:Ke,fdatasyncSync:et,flagToMode:tt,flagToNumber:rt,flagToString:nt,fs:it,fstat:ot,fstatSync:st,fsync:at,fsyncSync:ct,ftruncate:lt,ftruncateSync:dt,futimes:ft,futimesSync:ut,isAppendable:mt,isBackend:yt,isBackendConfig:St,isExclusive:gt,isReadable:pt,isSynchronous:ht,isTruncating:bt,isWriteable:Et,lchmod:wt,lchmodSync:Ft,lchown:xt,lchownSync:It,levenshtein:Dt,link:vt,linkSync:kt,lopenSync:Tt,lstat:At,lstatSync:Ht,lutimes:Ot,lutimesSync:Nt,mkdir:Bt,mkdirSync:Ct,mkdirpSync:Mt,mkdtemp:_t,mkdtempSync:Pt,mount:zt,mountMapping:Wt,mounts:Rt,nop:Ut,normalizeMode:$t,normalizeOptions:jt,normalizePath:Lt,normalizeTime:qt,open:Yt,openAsBlob:Vt,openSync:Xt,opendir:Zt,opendirSync:Qt,parseFlag:Gt,pathExistsAction:Jt,pathNotExistsAction:Kt,promises:er,randomIno:tr,read:rr,readFile:nr,readFileSync:ir,readSync:or,readdir:sr,readdirSync:ar,readlink:cr,readlinkSync:lr,readv:dr,readvSync:fr,realpath:ur,realpathSync:mr,rename:yr,renameSync:Sr,resolveMountConfig:gr,rm:pr,rmSync:hr,rmdir:br,rmdirSync:Er,rootCred:wr,rootIno:Fr,setImmediate:xr,size_max:Ir,stat:Dr,statSync:vr,statfs:kr,statfsSync:Tr,symlink:Ar,symlinkSync:Hr,truncate:Or,truncateSync:Nr,umount:Br,unlink:Cr,unlinkSync:Mr,unwatchFile:_r,utimes:Pr,utimesSync:zr,watch:Wr,watchFile:Rr,write:Ur,writeFile:$r,writeFileSync:jr,writeSync:Lr,writev:qr,writevSync:Yr}=ZenFS;function S(r,e){if(typeof r!="string")throw new TypeError(`"${e}" is not a string`)}c(S,"validateString");function j(r,e){let t="",n=0,i=-1,o=0,a="\0";for(let s=0;s<=r.length;++s){if(s<r.length)a=r[s];else{if(a=="/")break;a="/"}if(a=="/"){if(!(i===s-1||o===1))if(o===2){if(t.length<2||n!==2||t.at(-1)!=="."||t.at(-2)!=="."){if(t.length>2){let y=t.lastIndexOf("/");y===-1?(t="",n=0):(t=t.slice(0,y),n=t.length-1-t.lastIndexOf("/")),i=s,o=0;continue}else if(t.length!==0){t="",n=0,i=s,o=0;continue}}e&&(t+=t.length>0?"/..":"..",n=2)}else t.length>0?t+="/"+r.slice(i+1,s):t=r.slice(i+1,s),n=s-i-1;i=s,o=0}else a==="."&&o!==-1?++o:o=-1}return t}c(j,"normalizeString");function L(r){if(S(r,"path"),r.length===0)return".";let e=r[0]==="/",t=r.at(-1)==="/";return r=j(r,!e),r.length===0?e?"/":t?"./":".":(t&&(r+="/"),e?`/${r}`:r)}c(L,"normalize");function g(...r){if(r.length===0)return".";let e;for(let t=0;t<r.length;++t){let n=r[t];S(n,"path"),n.length>0&&(e===void 0?e=n:e+=`/${n}`)}return e===void 0?".":L(e)}c(g,"join");function p(r){if(S(r,"path"),r.length===0)return".";let e=r[0]==="/",t=-1,n=!0;for(let i=r.length-1;i>=1;--i)if(r[i]==="/"){if(!n){t=i;break}}else n=!1;return t===-1?e?"/":".":e&&t===1?"//":r.slice(0,t)}c(p,"dirname");function h(r,e){e!==void 0&&S(e,"ext"),S(r,"path");let t=0,n=-1,i=!0;if(e!==void 0&&e.length>0&&e.length<=r.length){if(e===r)return"";let o=e.length-1,a=-1;for(let s=r.length-1;s>=0;--s)if(r[s]==="/"){if(!i){t=s+1;break}}else a===-1&&(i=!1,a=s+1),o>=0&&(r[s]===e[o]?--o===-1&&(n=s):(o=-1,n=a));return t===n?n=a:n===-1&&(n=r.length),r.slice(t,n)}for(let o=r.length-1;o>=0;--o)if(r[o]==="/"){if(!i){t=o+1;break}}else n===-1&&(i=!1,n=o+1);return n===-1?"":r.slice(t,n)}c(h,"basename");function q(r){switch(r.name){case"IndexSizeError":case"HierarchyRequestError":case"InvalidCharacterError":case"InvalidStateError":case"SyntaxError":case"NamespaceError":case"TypeMismatchError":case"ConstraintError":case"VersionError":case"URLMismatchError":case"InvalidNodeTypeError":return"EINVAL";case"WrongDocumentError":return"EXDEV";case"NoModificationAllowedError":case"InvalidModificationError":case"InvalidAccessError":case"SecurityError":case"NotAllowedError":return"EACCES";case"NotFoundError":return"ENOENT";case"NotSupportedError":return"ENOTSUP";case"InUseAttributeError":return"EBUSY";case"NetworkError":return"ENETDOWN";case"AbortError":return"EINTR";case"QuotaExceededError":return"ENOSPC";case"TimeoutError":return"ETIMEDOUT";case"ReadOnlyError":return"EROFS";case"DataCloneError":case"EncodingError":case"NotReadableError":case"DataError":case"TransactionInactiveError":case"OperationError":case"UnknownError":default:return"EIO"}}c(q,"errnoForDOMException");function f(r,e,t){if(r instanceof l)return r;let n=r instanceof DOMException?d[q(r)]:d.EIO,i=new l(n,r.message,e,t);return i.stack=r.stack,i.cause=r.cause,i}c(f,"convertException");var b=class extends v(T){_handles=new Map;_sync;constructor({handle:e}){super(),this._handles.set("/",e),this._sync=A.create({name:"accessfs-cache"})}metadata(){return{...super.metadata(),name:"WebAccess"}}async sync(e,t,n){let i=await this.stat(e);n.mtime!==i.mtime&&await this.writeFile(e,t)}async rename(e,t){try{let n=await this.getHandle(e);if(n instanceof FileSystemDirectoryHandle){let y=await this.readdir(e);if(await this.mkdir(t),y.length==0)await this.unlink(e);else for(let D of y)await this.rename(g(e,D),g(t,D)),await this.unlink(e)}if(!(n instanceof FileSystemFileHandle))return;let i=await n.getFile(),o=await this.getHandle(p(t));if(!(o instanceof FileSystemDirectoryHandle))return;let s=await(await o.getFileHandle(h(t),{create:!0})).createWritable();await s.write(await i.arrayBuffer()),s.close(),await this.unlink(e)}catch(n){throw f(n,e,"rename")}}async writeFile(e,t){let n=await this.getHandle(p(e));if(!(n instanceof FileSystemDirectoryHandle))return;let o=await(await n.getFileHandle(h(e),{create:!0})).createWritable();await o.write(t),await o.close()}async createFile(e,t){return await this.writeFile(e,new Uint8Array),this.openFile(e,t)}async stat(e){let t=await this.getHandle(e);if(!t)throw l.With("ENOENT",e,"stat");if(t instanceof FileSystemDirectoryHandle)return new I({mode:511|x.DIRECTORY,size:4096});if(t instanceof FileSystemFileHandle){let{lastModified:n,size:i}=await t.getFile();return new I({mode:511|x.FILE,size:i,mtimeMs:n})}throw new l(d.EBADE,"Handle is not a directory or file",e,"stat")}async openFile(e,t){let n=await this.getHandle(e);if(!(n instanceof FileSystemFileHandle))throw l.With("EISDIR",e,"openFile");try{let i=await n.getFile(),o=new Uint8Array(await i.arrayBuffer()),a=new I({mode:511|x.FILE,size:i.size,mtimeMs:i.lastModified});return new H(this,e,t,a,o)}catch(i){throw f(i,e,"openFile")}}async unlink(e){let t=await this.getHandle(p(e));if(t instanceof FileSystemDirectoryHandle)try{await t.removeEntry(h(e),{recursive:!0})}catch(n){throw f(n,e,"unlink")}}async link(e){throw l.With("ENOSYS",e,"WebAccessFS.link")}async rmdir(e){return this.unlink(e)}async mkdir(e){if(await this.getHandle(e))throw l.With("EEXIST",e,"mkdir");let n=await this.getHandle(p(e));if(!(n instanceof FileSystemDirectoryHandle))throw l.With("ENOTDIR",e,"mkdir");await n.getDirectoryHandle(h(e),{create:!0})}async readdir(e){let t=await this.getHandle(e);if(!(t instanceof FileSystemDirectoryHandle))throw l.With("ENOTDIR",e,"readdir");let n=[];for await(let i of t.keys())n.push(g(e,i));return n}async getHandle(e){if(this._handles.has(e))return this._handles.get(e);let t="/";for(let n of e.split("/").slice(1)){let i=this._handles.get(t);if(!(i instanceof FileSystemDirectoryHandle))throw l.With("ENOTDIR",t,"getHandle");t=g(t,n);try{let o=await i.getDirectoryHandle(n);this._handles.set(t,o)}catch(o){let a=o;if(a.name=="TypeMismatchError")try{let s=await i.getFileHandle(n);this._handles.set(t,s)}catch(s){f(s,t,"getHandle")}if(a.name==="TypeError")throw new l(d.ENOENT,a.message,t,"getHandle");f(a,t,"getHandle")}}return this._handles.get(e)}};c(b,"WebAccessFS");var Y={name:"WebAccess",options:{handle:{type:"object",required:!0,description:"The directory handle to use for the root"}},isAvailable(){return typeof FileSystemHandle=="function"},create(r){return new b(r)}};function m(r){return new Promise((e,t)=>{r.onsuccess=()=>e(r.result),r.onerror=n=>{n.preventDefault(),t(f(r.error))}})}c(m,"wrap");var E=class{constructor(e,t){this.tx=e;this.store=t}get(e){return m(this.store.get(e.toString()))}async put(e,t,n){return await m(this.store[n?"put":"add"](t,e.toString())),!0}remove(e){return m(this.store.delete(e.toString()))}async commit(){}async abort(){try{this.tx.abort()}catch(e){throw f(e)}}};c(E,"IndexedDBTransaction");var u=class{constructor(e,t){this.db=e;this.storeName=t}static async create(e,t=globalThis.indexedDB){let n=t.open(e,1);n.onupgradeneeded=()=>{let o=n.result;o.objectStoreNames.contains(e)&&o.deleteObjectStore(e),o.createObjectStore(e)};let i=await m(n);return new u(i,e)}get name(){return M.name+":"+this.storeName}clear(){return m(this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).clear())}beginTransaction(){let e=this.db.transaction(this.storeName,"readwrite");return new E(e,e.objectStore(this.storeName))}};c(u,"IndexedDBStore");var M={name:"IndexedDB",options:{storeName:{type:"string",required:!1,description:"The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name."},cacheSize:{type:"number",required:!1,description:"The size of the inode cache. Defaults to 100. A size of 0 or below disables caching."},idbFactory:{type:"object",required:!1,description:"The IDBFactory to use. Defaults to globalThis.indexedDB."}},async isAvailable(r=globalThis.indexedDB){try{if(!(r instanceof IDBFactory))return!1;let e=r.open("__zenfs_test");return await m(e),r.deleteDatabase("__zenfs_test"),!0}catch{return r.deleteDatabase("__zenfs_test"),!1}},create(r){let e=u.create(r.storeName||"zenfs",r.idbFactory);return new k({...r,store:e})}};var w=class{constructor(e){this._storage=e}get name(){return _.name}clear(){this._storage.clear()}beginTransaction(){return new O(this)}get(e){let t=this._storage.getItem(e.toString());if(typeof t=="string")return C(t)}put(e,t,n){try{return!n&&this._storage.getItem(e.toString())!==null?!1:(this._storage.setItem(e.toString(),B(t)),!0)}catch{throw new l(d.ENOSPC,"Storage is full.")}}remove(e){try{this._storage.removeItem(e.toString())}catch(t){throw new l(d.EIO,"Unable to delete key "+e+": "+t)}}};c(w,"WebStorageStore");var _={name:"WebStorage",options:{storage:{type:"object",required:!1,description:"The Storage to use. Defaults to globalThis.localStorage."}},isAvailable(r=globalThis.localStorage){return r instanceof globalThis.Storage},create({storage:r=globalThis.localStorage}){return new N({store:new w(r)})}};return $(V);})();
1
+ "use strict";var ZenFS_DOM=(()=>{var b=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var c=(e,t)=>b(e,"name",{value:t,configurable:!0});var G=(e,t)=>{for(var i in t)b(e,i,{get:t[i],enumerable:!0})},z=(e,t,i,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Y(t))!_.call(e,r)&&r!==i&&b(e,r,{get:()=>t[r],enumerable:!(n=W(t,r))||n.enumerable});return e};var K=e=>z(b({},"__esModule",{value:!0}),e);var j={};G(j,{IndexedDB:()=>H,IndexedDBStore:()=>T,IndexedDBTransaction:()=>g,WebAccess:()=>q,WebAccessFS:()=>h,WebStorage:()=>U,WebStorageStore:()=>I});var J=ZenFS,{ActionType:ee,Async:x,AsyncIndexFS:te,AsyncTransaction:ie,BigIntStats:se,BigIntStatsFs:ne,Dir:re,Dirent:ae,Errno:S,ErrnoError:d,Fetch:oe,FetchFS:ce,File:le,FileIndex:de,FileSystem:P,FileType:D,InMemory:v,InMemoryStore:Ee,IndexDirInode:Se,IndexFS:ue,IndexFileInode:me,IndexInode:fe,Inode:ye,LockedFS:Oe,Mutex:pe,NoSyncFile:he,Overlay:Ne,OverlayFS:ge,Port:Te,PortFS:Ie,PortFile:be,PreloadFile:M,ReadStream:De,Readonly:Fe,SimpleAsyncStore:we,SimpleTransaction:k,Stats:F,StatsCommon:Ae,StatsFs:Re,StoreFS:w,Sync:xe,SyncIndexFS:Pe,SyncTransaction:ve,Transaction:Me,UnlockedOverlayFS:ke,WriteStream:Be,_toUnixTimestamp:Ce,access:Le,accessSync:He,appendFile:Ue,appendFileSync:We,attachFS:Ye,checkOptions:_e,chmod:Ge,chmodSync:ze,chown:Ke,chownSync:$e,close:Xe,closeSync:Ve,configure:qe,constants:Qe,copyFile:je,copyFileSync:Ze,cp:Je,cpSync:et,createReadStream:tt,createWriteStream:it,decode:B,decodeDirListing:st,detachFS:nt,encode:C,encodeDirListing:rt,errorMessages:at,exists:ot,existsSync:ct,fchmod:lt,fchmodSync:dt,fchown:Et,fchownSync:St,fdatasync:ut,fdatasyncSync:mt,flagToMode:ft,flagToNumber:yt,flagToString:Ot,fs:pt,fstat:ht,fstatSync:Nt,fsync:gt,fsyncSync:Tt,ftruncate:It,ftruncateSync:bt,futimes:Dt,futimesSync:Ft,isAppendable:wt,isBackend:At,isBackendConfig:Rt,isExclusive:xt,isReadable:Pt,isSynchronous:vt,isTruncating:Mt,isWriteable:kt,lchmod:Bt,lchmodSync:Ct,lchown:Lt,lchownSync:Ht,levenshtein:Ut,link:Wt,linkSync:Yt,lopenSync:_t,lstat:Gt,lstatSync:zt,lutimes:Kt,lutimesSync:$t,mkdir:Xt,mkdirSync:Vt,mkdirpSync:qt,mkdtemp:Qt,mkdtempSync:jt,mount:Zt,mountObject:Jt,mounts:ei,nop:ti,normalizeMode:ii,normalizeOptions:si,normalizePath:ni,normalizeTime:ri,open:ai,openAsBlob:oi,openSync:ci,opendir:li,opendirSync:di,parseFlag:Ei,pathExistsAction:Si,pathNotExistsAction:ui,promises:mi,randomIno:fi,read:yi,readFile:Oi,readFileSync:pi,readSync:hi,readdir:Ni,readdirSync:gi,readlink:Ti,readlinkSync:Ii,readv:bi,readvSync:Di,realpath:Fi,realpathSync:wi,rename:Ai,renameSync:Ri,resolveMountConfig:xi,rm:Pi,rmSync:vi,rmdir:Mi,rmdirSync:ki,rootCred:Bi,rootIno:Ci,setImmediate:Li,size_max:Hi,stat:Ui,statSync:Wi,statfs:Yi,statfsSync:_i,symlink:Gi,symlinkSync:zi,truncate:Ki,truncateSync:$i,umount:Xi,unlink:Vi,unlinkSync:qi,unwatchFile:Qi,utimes:ji,utimesSync:Zi,watch:Ji,watchFile:es,write:ts,writeFile:is,writeFileSync:ss,writeSync:ns,writev:rs,writevSync:as}=ZenFS;function $(e,t){let i="",n=0,r=-1,a=0,l="\0";for(let o=0;o<=e.length;++o){if(o<e.length)l=e[o];else{if(l=="/")break;l="/"}if(l=="/"){if(!(r===o-1||a===1))if(a===2){if(i.length<2||n!==2||i.at(-1)!=="."||i.at(-2)!=="."){if(i.length>2){let f=i.lastIndexOf("/");f===-1?(i="",n=0):(i=i.slice(0,f),n=i.length-1-i.lastIndexOf("/")),r=o,a=0;continue}else if(i.length!==0){i="",n=0,r=o,a=0;continue}}t&&(i+=i.length>0?"/..":"..",n=2)}else i.length>0?i+="/"+e.slice(r+1,o):i=e.slice(r+1,o),n=o-r-1;r=o,a=0}else l==="."&&a!==-1?++a:a=-1}return i}c($,"normalizeString");function X(e){if(!e.length)return".";let t=e.startsWith("/"),i=e.endsWith("/");return e=$(e,!t),e.length?(i&&(e+="/"),t?`/${e}`:e):t?"/":i?"./":"."}c(X,"normalize");function y(...e){if(!e.length)return".";let t=e.join("/");return t?.length?X(t):"."}c(y,"join");function O(e){if(e.length===0)return".";let t=e[0]==="/",i=-1,n=!0;for(let r=e.length-1;r>=1;--r)if(e[r]==="/"){if(!n){i=r;break}}else n=!1;return i===-1?t?"/":".":t&&i===1?"//":e.slice(0,i)}c(O,"dirname");function p(e,t){let i=0,n=-1,r=!0;if(t!==void 0&&t.length>0&&t.length<=e.length){if(t===e)return"";let a=t.length-1,l=-1;for(let o=e.length-1;o>=0;--o)if(e[o]==="/"){if(!r){i=o+1;break}}else l===-1&&(r=!1,l=o+1),a>=0&&(e[o]===t[a]?--a===-1&&(n=o):(a=-1,n=l));return i===n?n=l:n===-1&&(n=e.length),e.slice(i,n)}for(let a=e.length-1;a>=0;--a)if(e[a]==="/"){if(!r){i=a+1;break}}else n===-1&&(r=!1,n=a+1);return n===-1?"":e.slice(i,n)}c(p,"basename");function V(e){switch(e.name){case"IndexSizeError":case"HierarchyRequestError":case"InvalidCharacterError":case"InvalidStateError":case"SyntaxError":case"NamespaceError":case"TypeMismatchError":case"ConstraintError":case"VersionError":case"URLMismatchError":case"InvalidNodeTypeError":return"EINVAL";case"WrongDocumentError":return"EXDEV";case"NoModificationAllowedError":case"InvalidModificationError":case"InvalidAccessError":case"SecurityError":case"NotAllowedError":return"EACCES";case"NotFoundError":return"ENOENT";case"NotSupportedError":return"ENOTSUP";case"InUseAttributeError":return"EBUSY";case"NetworkError":return"ENETDOWN";case"AbortError":return"EINTR";case"QuotaExceededError":return"ENOSPC";case"TimeoutError":return"ETIMEDOUT";case"ReadOnlyError":return"EROFS";case"DataCloneError":case"EncodingError":case"NotReadableError":case"DataError":case"TransactionInactiveError":case"OperationError":case"UnknownError":default:return"EIO"}}c(V,"errnoForDOMException");function u(e,t,i){if(e instanceof d)return e;let n=e instanceof DOMException?S[V(e)]:S.EIO,r=new d(n,e.message,t,i);return r.stack=e.stack,r.cause=e.cause,r}c(u,"convertException");var h=class extends x(P){_handles=new Map;_sync;constructor({handle:t}){super(),this._handles.set("/",t),this._sync=v.create({name:"accessfs-cache"})}metadata(){return{...super.metadata(),name:"WebAccess"}}async sync(t,i,n){let r=await this.stat(t);n.mtime!==r.mtime&&await this.writeFile(t,i)}async rename(t,i){try{let n=await this.getHandle(t);if(n instanceof FileSystemDirectoryHandle){let f=await this.readdir(t);if(await this.mkdir(i),f.length==0)await this.unlink(t);else for(let R of f)await this.rename(y(t,R),y(i,R)),await this.unlink(t)}if(!(n instanceof FileSystemFileHandle))return;let r=await n.getFile(),a=await this.getHandle(O(i));if(!(a instanceof FileSystemDirectoryHandle))return;let o=await(await a.getFileHandle(p(i),{create:!0})).createWritable();await o.write(await r.arrayBuffer()),o.close(),await this.unlink(t)}catch(n){throw u(n,t,"rename")}}async writeFile(t,i){let n=await this.getHandle(O(t));if(!(n instanceof FileSystemDirectoryHandle))return;let a=await(await n.getFileHandle(p(t),{create:!0})).createWritable();await a.write(i),await a.close()}async createFile(t,i){return await this.writeFile(t,new Uint8Array),this.openFile(t,i)}async stat(t){let i=await this.getHandle(t);if(!i)throw d.With("ENOENT",t,"stat");if(i instanceof FileSystemDirectoryHandle)return new F({mode:511|D.DIRECTORY,size:4096});if(i instanceof FileSystemFileHandle){let{lastModified:n,size:r}=await i.getFile();return new F({mode:511|D.FILE,size:r,mtimeMs:n})}throw new d(S.EBADE,"Handle is not a directory or file",t,"stat")}async openFile(t,i){let n=await this.getHandle(t);if(!(n instanceof FileSystemFileHandle))throw d.With("EISDIR",t,"openFile");try{let r=await n.getFile(),a=new Uint8Array(await r.arrayBuffer()),l=new F({mode:511|D.FILE,size:r.size,mtimeMs:r.lastModified});return new M(this,t,i,l,a)}catch(r){throw u(r,t,"openFile")}}async unlink(t){let i=await this.getHandle(O(t));if(i instanceof FileSystemDirectoryHandle)try{await i.removeEntry(p(t),{recursive:!0})}catch(n){throw u(n,t,"unlink")}}async link(t){throw d.With("ENOSYS",t,"WebAccessFS.link")}async rmdir(t){return this.unlink(t)}async mkdir(t){if(await this.getHandle(t))throw d.With("EEXIST",t,"mkdir");let n=await this.getHandle(O(t));if(!(n instanceof FileSystemDirectoryHandle))throw d.With("ENOTDIR",t,"mkdir");await n.getDirectoryHandle(p(t),{create:!0})}async readdir(t){let i=await this.getHandle(t);if(!(i instanceof FileSystemDirectoryHandle))throw d.With("ENOTDIR",t,"readdir");let n=[];for await(let r of i.keys())n.push(y(t,r));return n}async getHandle(t){if(this._handles.has(t))return this._handles.get(t);let i="/";for(let n of t.split("/").slice(1)){let r=this._handles.get(i);if(!(r instanceof FileSystemDirectoryHandle))throw d.With("ENOTDIR",i,"getHandle");i=y(i,n);try{let a=await r.getDirectoryHandle(n);this._handles.set(i,a)}catch(a){let l=a;if(l.name=="TypeMismatchError")try{let o=await r.getFileHandle(n);this._handles.set(i,o)}catch(o){u(o,i,"getHandle")}if(l.name==="TypeError")throw new d(S.ENOENT,l.message,i,"getHandle");u(l,i,"getHandle")}}return this._handles.get(t)}};c(h,"WebAccessFS");var q={name:"WebAccess",options:{handle:{type:"object",required:!0,description:"The directory handle to use for the root"}},isAvailable(){return typeof FileSystemHandle=="function"},create(e){return new h(e)}};var s;(function(e){e[e.EPERM=1]="EPERM",e[e.ENOENT=2]="ENOENT",e[e.EINTR=4]="EINTR",e[e.EIO=5]="EIO",e[e.ENXIO=6]="ENXIO",e[e.EBADF=9]="EBADF",e[e.EAGAIN=11]="EAGAIN",e[e.ENOMEM=12]="ENOMEM",e[e.EACCES=13]="EACCES",e[e.EFAULT=14]="EFAULT",e[e.ENOTBLK=15]="ENOTBLK",e[e.EBUSY=16]="EBUSY",e[e.EEXIST=17]="EEXIST",e[e.EXDEV=18]="EXDEV",e[e.ENODEV=19]="ENODEV",e[e.ENOTDIR=20]="ENOTDIR",e[e.EISDIR=21]="EISDIR",e[e.EINVAL=22]="EINVAL",e[e.ENFILE=23]="ENFILE",e[e.EMFILE=24]="EMFILE",e[e.ETXTBSY=26]="ETXTBSY",e[e.EFBIG=27]="EFBIG",e[e.ENOSPC=28]="ENOSPC",e[e.ESPIPE=29]="ESPIPE",e[e.EROFS=30]="EROFS",e[e.EMLINK=31]="EMLINK",e[e.EPIPE=32]="EPIPE",e[e.EDOM=33]="EDOM",e[e.ERANGE=34]="ERANGE",e[e.EDEADLK=35]="EDEADLK",e[e.ENAMETOOLONG=36]="ENAMETOOLONG",e[e.ENOLCK=37]="ENOLCK",e[e.ENOSYS=38]="ENOSYS",e[e.ENOTEMPTY=39]="ENOTEMPTY",e[e.ELOOP=40]="ELOOP",e[e.ENOMSG=42]="ENOMSG",e[e.EBADE=52]="EBADE",e[e.EBADR=53]="EBADR",e[e.EXFULL=54]="EXFULL",e[e.ENOANO=55]="ENOANO",e[e.EBADRQC=56]="EBADRQC",e[e.ENOSTR=60]="ENOSTR",e[e.ENODATA=61]="ENODATA",e[e.ETIME=62]="ETIME",e[e.ENOSR=63]="ENOSR",e[e.ENONET=64]="ENONET",e[e.EREMOTE=66]="EREMOTE",e[e.ENOLINK=67]="ENOLINK",e[e.ECOMM=70]="ECOMM",e[e.EPROTO=71]="EPROTO",e[e.EBADMSG=74]="EBADMSG",e[e.EOVERFLOW=75]="EOVERFLOW",e[e.EBADFD=77]="EBADFD",e[e.ESTRPIPE=86]="ESTRPIPE",e[e.ENOTSOCK=88]="ENOTSOCK",e[e.EDESTADDRREQ=89]="EDESTADDRREQ",e[e.EMSGSIZE=90]="EMSGSIZE",e[e.EPROTOTYPE=91]="EPROTOTYPE",e[e.ENOPROTOOPT=92]="ENOPROTOOPT",e[e.EPROTONOSUPPORT=93]="EPROTONOSUPPORT",e[e.ESOCKTNOSUPPORT=94]="ESOCKTNOSUPPORT",e[e.ENOTSUP=95]="ENOTSUP",e[e.ENETDOWN=100]="ENETDOWN",e[e.ENETUNREACH=101]="ENETUNREACH",e[e.ENETRESET=102]="ENETRESET",e[e.ETIMEDOUT=110]="ETIMEDOUT",e[e.ECONNREFUSED=111]="ECONNREFUSED",e[e.EHOSTDOWN=112]="EHOSTDOWN",e[e.EHOSTUNREACH=113]="EHOSTUNREACH",e[e.EALREADY=114]="EALREADY",e[e.EINPROGRESS=115]="EINPROGRESS",e[e.ESTALE=116]="ESTALE",e[e.EREMOTEIO=121]="EREMOTEIO",e[e.EDQUOT=122]="EDQUOT"})(s||(s={}));var L={[s.EPERM]:"Operation not permitted",[s.ENOENT]:"No such file or directory",[s.EINTR]:"Interrupted system call",[s.EIO]:"Input/output error",[s.ENXIO]:"No such device or address",[s.EBADF]:"Bad file descriptor",[s.EAGAIN]:"Resource temporarily unavailable",[s.ENOMEM]:"Cannot allocate memory",[s.EACCES]:"Permission denied",[s.EFAULT]:"Bad address",[s.ENOTBLK]:"Block device required",[s.EBUSY]:"Resource busy or locked",[s.EEXIST]:"File exists",[s.EXDEV]:"Invalid cross-device link",[s.ENODEV]:"No such device",[s.ENOTDIR]:"File is not a directory",[s.EISDIR]:"File is a directory",[s.EINVAL]:"Invalid argument",[s.ENFILE]:"Too many open files in system",[s.EMFILE]:"Too many open files",[s.ETXTBSY]:"Text file busy",[s.EFBIG]:"File is too big",[s.ENOSPC]:"No space left on disk",[s.ESPIPE]:"Illegal seek",[s.EROFS]:"Cannot modify a read-only file system",[s.EMLINK]:"Too many links",[s.EPIPE]:"Broken pipe",[s.EDOM]:"Numerical argument out of domain",[s.ERANGE]:"Numerical result out of range",[s.EDEADLK]:"Resource deadlock would occur",[s.ENAMETOOLONG]:"File name too long",[s.ENOLCK]:"No locks available",[s.ENOSYS]:"Function not implemented",[s.ENOTEMPTY]:"Directory is not empty",[s.ELOOP]:"Too many levels of symbolic links",[s.ENOMSG]:"No message of desired type",[s.EBADE]:"Invalid exchange",[s.EBADR]:"Invalid request descriptor",[s.EXFULL]:"Exchange full",[s.ENOANO]:"No anode",[s.EBADRQC]:"Invalid request code",[s.ENOSTR]:"Device not a stream",[s.ENODATA]:"No data available",[s.ETIME]:"Timer expired",[s.ENOSR]:"Out of streams resources",[s.ENONET]:"Machine is not on the network",[s.EREMOTE]:"Object is remote",[s.ENOLINK]:"Link has been severed",[s.ECOMM]:"Communication error on send",[s.EPROTO]:"Protocol error",[s.EBADMSG]:"Bad message",[s.EOVERFLOW]:"Value too large for defined data type",[s.EBADFD]:"File descriptor in bad state",[s.ESTRPIPE]:"Streams pipe error",[s.ENOTSOCK]:"Socket operation on non-socket",[s.EDESTADDRREQ]:"Destination address required",[s.EMSGSIZE]:"Message too long",[s.EPROTOTYPE]:"Protocol wrong type for socket",[s.ENOPROTOOPT]:"Protocol not available",[s.EPROTONOSUPPORT]:"Protocol not supported",[s.ESOCKTNOSUPPORT]:"Socket type not supported",[s.ENOTSUP]:"Operation is not supported",[s.ENETDOWN]:"Network is down",[s.ENETUNREACH]:"Network is unreachable",[s.ENETRESET]:"Network dropped connection on reset",[s.ETIMEDOUT]:"Connection timed out",[s.ECONNREFUSED]:"Connection refused",[s.EHOSTDOWN]:"Host is down",[s.EHOSTUNREACH]:"No route to host",[s.EALREADY]:"Operation already in progress",[s.EINPROGRESS]:"Operation now in progress",[s.ESTALE]:"Stale file handle",[s.EREMOTEIO]:"Remote I/O error",[s.EDQUOT]:"Disk quota exceeded"},E=class extends Error{static fromJSON(t){let i=new E(t.errno,t.message,t.path,t.syscall);return i.code=t.code,i.stack=t.stack,i}static With(t,i,n){return new E(s[t],L[s[t]],i,n)}constructor(t,i=L[t],n,r=""){super(i),this.errno=t,this.path=n,this.syscall=r,this.code=s[t],this.message=`${this.code}: ${i}${this.path?`, '${this.path}'`:""}`}toString(){return this.message}toJSON(){return{errno:this.errno,code:this.code,path:this.path,stack:this.stack,message:this.message,syscall:this.syscall}}bufferSize(){return 4+JSON.stringify(this.toJSON()).length}};c(E,"ErrnoError");var A=class{constructor(){this.aborted=!1}async[Symbol.asyncDispose](){this.aborted||await this.commit()}[Symbol.dispose](){this.aborted||this.commitSync()}};c(A,"Transaction");var N=class extends A{getSync(t){throw E.With("ENOSYS",void 0,"AsyncTransaction.getSync")}setSync(t,i){throw E.With("ENOSYS",void 0,"AsyncTransaction.setSync")}removeSync(t){throw E.With("ENOSYS",void 0,"AsyncTransaction.removeSync")}commitSync(){throw E.With("ENOSYS",void 0,"AsyncTransaction.commitSync")}abortSync(){throw E.With("ENOSYS",void 0,"AsyncTransaction.abortSync")}};c(N,"AsyncTransaction");function m(e){return new Promise((t,i)=>{e.onsuccess=()=>t(e.result),e.onerror=n=>{n.preventDefault(),i(u(e.error))}})}c(m,"wrap");var g=class extends N{constructor(i,n){super();this.tx=i;this.store=n}get(i){return m(this.store.get(i.toString()))}async set(i,n){await m(this.store.put(n,i.toString()))}remove(i){return m(this.store.delete(i.toString()))}async commit(){this.tx.commit()}async abort(){try{this.tx.abort()}catch(i){throw u(i)}}};c(g,"IndexedDBTransaction");async function Q(e,t=globalThis.indexedDB){let i=t.open(e);return i.onupgradeneeded=()=>{let r=i.result;r.objectStoreNames.contains(e)&&r.deleteObjectStore(e),r.createObjectStore(e)},await m(i)}c(Q,"createDB");var T=class{constructor(t){this.db=t}sync(){throw new Error("Method not implemented.")}get name(){return H.name+":"+this.db.name}clear(){return m(this.db.transaction(this.db.name,"readwrite").objectStore(this.db.name).clear())}clearSync(){throw d.With("ENOSYS",void 0,"IndexedDBStore.clearSync")}transaction(){let t=this.db.transaction(this.db.name,"readwrite");return new g(t,t.objectStore(this.db.name))}};c(T,"IndexedDBStore");var H={name:"IndexedDB",options:{storeName:{type:"string",required:!1,description:"The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name."},idbFactory:{type:"object",required:!1,description:"The IDBFactory to use. Defaults to globalThis.indexedDB."}},async isAvailable(e=globalThis.indexedDB){try{if(!(e instanceof IDBFactory))return!1;let t=e.open("__zenfs_test");return await m(t),e.deleteDatabase("__zenfs_test"),!0}catch{return e.deleteDatabase("__zenfs_test"),!1}},async create(e){let t=await Q(e.storeName||"zenfs",e.idbFactory),i=new T(t);return new w(i)}};var I=class{constructor(t){this._storage=t}get name(){return U.name}clear(){this._storage.clear()}clearSync(){this._storage.clear()}async sync(){}transaction(){return new k(this)}get(t){let i=this._storage.getItem(t.toString());if(typeof i=="string")return C(i)}set(t,i){try{this._storage.setItem(t.toString(),B(i))}catch{throw new d(S.ENOSPC,"Storage is full.")}}delete(t){try{this._storage.removeItem(t.toString())}catch(i){throw new d(S.EIO,"Unable to delete key "+t+": "+i)}}};c(I,"WebStorageStore");var U={name:"WebStorage",options:{storage:{type:"object",required:!1,description:"The Storage to use. Defaults to globalThis.localStorage."}},isAvailable(e=globalThis.localStorage){return e instanceof globalThis.Storage},create({storage:e=globalThis.localStorage}){return new w(new I(e))}};return K(j);})();
2
2
  //# sourceMappingURL=browser.min.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "global-externals:@zenfs/core", "../node_modules/@zenfs/core/dist/emulation/path.js", "../src/utils.ts", "../src/access.ts", "../src/IndexedDB.ts", "../src/Storage.ts"],
4
- "sourcesContent": ["export * from './access.js';\nexport * from './IndexedDB.js';\nexport * from './Storage.js';\n", "export default ZenFS;\nconst { ActionType, ApiError, Async, AsyncIndexFS, AsyncStoreFS, BigIntStats, BigIntStatsFs, Dir, Dirent, ErrorCode, File, FileIndex, FileSystem, FileType, InMemory, InMemoryStore, IndexDirInode, IndexFS, IndexFileInode, IndexInode, Inode, LockedFS, Mutex, NoSyncFile, Overlay, OverlayFS, PreloadFile, ReadStream, Readonly, SimpleSyncTransaction, Stats, StatsCommon, StatsFs, Sync, SyncIndexFS, SyncStoreFS, UnlockedOverlayFS, WriteStream, _toUnixTimestamp, access, accessSync, appendFile, appendFileSync, checkOptions, chmod, chmodSync, chown, chownSync, close, closeSync, configure, constants, copyFile, copyFileSync, cp, cpSync, createBackend, createReadStream, createWriteStream, decode, decodeDirListing, encode, encodeDirListing, errorMessages, exists, existsSync, fchmod, fchmodSync, fchown, fchownSync, fdatasync, fdatasyncSync, flagToMode, flagToNumber, flagToString, fs, fstat, fstatSync, fsync, fsyncSync, ftruncate, ftruncateSync, futimes, futimesSync, isAppendable, isBackend, isBackendConfig, isExclusive, isReadable, isSynchronous, isTruncating, isWriteable, lchmod, lchmodSync, lchown, lchownSync, levenshtein, link, linkSync, lopenSync, lstat, lstatSync, lutimes, lutimesSync, mkdir, mkdirSync, mkdirpSync, mkdtemp, mkdtempSync, mount, mountMapping, mounts, nop, normalizeMode, normalizeOptions, normalizePath, normalizeTime, open, openAsBlob, openSync, opendir, opendirSync, parseFlag, pathExistsAction, pathNotExistsAction, promises, randomIno, read, readFile, readFileSync, readSync, readdir, readdirSync, readlink, readlinkSync, readv, readvSync, realpath, realpathSync, rename, renameSync, resolveMountConfig, rm, rmSync, rmdir, rmdirSync, rootCred, rootIno, setImmediate, size_max, stat, statSync, statfs, statfsSync, symlink, symlinkSync, truncate, truncateSync, umount, unlink, unlinkSync, unwatchFile, utimes, utimesSync, watch, watchFile, write, writeFile, writeFileSync, writeSync, writev, writevSync } = ZenFS;\nexport { ActionType, ApiError, Async, AsyncIndexFS, AsyncStoreFS, BigIntStats, BigIntStatsFs, Dir, Dirent, ErrorCode, File, FileIndex, FileSystem, FileType, InMemory, InMemoryStore, IndexDirInode, IndexFS, IndexFileInode, IndexInode, Inode, LockedFS, Mutex, NoSyncFile, Overlay, OverlayFS, PreloadFile, ReadStream, Readonly, SimpleSyncTransaction, Stats, StatsCommon, StatsFs, Sync, SyncIndexFS, SyncStoreFS, UnlockedOverlayFS, WriteStream, _toUnixTimestamp, access, accessSync, appendFile, appendFileSync, checkOptions, chmod, chmodSync, chown, chownSync, close, closeSync, configure, constants, copyFile, copyFileSync, cp, cpSync, createBackend, createReadStream, createWriteStream, decode, decodeDirListing, encode, encodeDirListing, errorMessages, exists, existsSync, fchmod, fchmodSync, fchown, fchownSync, fdatasync, fdatasyncSync, flagToMode, flagToNumber, flagToString, fs, fstat, fstatSync, fsync, fsyncSync, ftruncate, ftruncateSync, futimes, futimesSync, isAppendable, isBackend, isBackendConfig, isExclusive, isReadable, isSynchronous, isTruncating, isWriteable, lchmod, lchmodSync, lchown, lchownSync, levenshtein, link, linkSync, lopenSync, lstat, lstatSync, lutimes, lutimesSync, mkdir, mkdirSync, mkdirpSync, mkdtemp, mkdtempSync, mount, mountMapping, mounts, nop, normalizeMode, normalizeOptions, normalizePath, normalizeTime, open, openAsBlob, openSync, opendir, opendirSync, parseFlag, pathExistsAction, pathNotExistsAction, promises, randomIno, read, readFile, readFileSync, readSync, readdir, readdirSync, readlink, readlinkSync, readv, readvSync, realpath, realpathSync, rename, renameSync, resolveMountConfig, rm, rmSync, rmdir, rmdirSync, rootCred, rootIno, setImmediate, size_max, stat, statSync, statfs, statfsSync, symlink, symlinkSync, truncate, truncateSync, umount, unlink, unlinkSync, unwatchFile, utimes, utimesSync, watch, watchFile, write, writeFile, writeFileSync, writeSync, writev, writevSync };", "/*\nCopyright Joyent, Inc. and other Node contributors.\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the\nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\nNO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\nexport let cwd = '/';\nexport function cd(path) {\n cwd = resolve(cwd, path);\n}\nexport const sep = '/';\nfunction validateString(str, name) {\n if (typeof str != 'string') {\n throw new TypeError(`\"${name}\" is not a string`);\n }\n}\nfunction validateObject(str, name) {\n if (typeof str != 'object') {\n throw new TypeError(`\"${name}\" is not an object`);\n }\n}\n// Resolves . and .. elements in a path with directory names\nexport function normalizeString(path, allowAboveRoot) {\n let res = '';\n let lastSegmentLength = 0;\n let lastSlash = -1;\n let dots = 0;\n let char = '\\x00';\n for (let i = 0; i <= path.length; ++i) {\n if (i < path.length) {\n char = path[i];\n }\n else if (char == '/') {\n break;\n }\n else {\n char = '/';\n }\n if (char == '/') {\n if (lastSlash === i - 1 || dots === 1) {\n // NOOP\n }\n else if (dots === 2) {\n if (res.length < 2 || lastSegmentLength !== 2 || res.at(-1) !== '.' || res.at(-2) !== '.') {\n if (res.length > 2) {\n const lastSlashIndex = res.lastIndexOf('/');\n if (lastSlashIndex === -1) {\n res = '';\n lastSegmentLength = 0;\n }\n else {\n res = res.slice(0, lastSlashIndex);\n lastSegmentLength = res.length - 1 - res.lastIndexOf('/');\n }\n lastSlash = i;\n dots = 0;\n continue;\n }\n else if (res.length !== 0) {\n res = '';\n lastSegmentLength = 0;\n lastSlash = i;\n dots = 0;\n continue;\n }\n }\n if (allowAboveRoot) {\n res += res.length > 0 ? '/..' : '..';\n lastSegmentLength = 2;\n }\n }\n else {\n if (res.length > 0)\n res += '/' + path.slice(lastSlash + 1, i);\n else\n res = path.slice(lastSlash + 1, i);\n lastSegmentLength = i - lastSlash - 1;\n }\n lastSlash = i;\n dots = 0;\n }\n else if (char === '.' && dots !== -1) {\n ++dots;\n }\n else {\n dots = -1;\n }\n }\n return res;\n}\nexport function formatExt(ext) {\n return ext ? `${ext[0] === '.' ? '' : '.'}${ext}` : '';\n}\nexport function resolve(...args) {\n let resolved = '';\n let absolute = false;\n for (let i = args.length - 1; i >= -1 && !absolute; i--) {\n const path = i >= 0 ? args[i] : cwd;\n validateString(path, `paths[${i}]`);\n // Skip empty entries\n if (!path.length) {\n continue;\n }\n resolved = `${path}/${resolved}`;\n absolute = path[0] == '/';\n }\n // At this point the path should be resolved to a full absolute path, but\n // handle relative paths to be safe (might happen when cwd fails)\n // Normalize the path\n resolved = normalizeString(resolved, !absolute);\n if (absolute) {\n return `/${resolved}`;\n }\n return resolved.length > 0 ? resolved : '/';\n}\nexport function normalize(path) {\n validateString(path, 'path');\n if (path.length === 0)\n return '.';\n const isAbsolute = path[0] === '/';\n const trailingSeparator = path.at(-1) === '/';\n // Normalize the path\n path = normalizeString(path, !isAbsolute);\n if (path.length === 0) {\n if (isAbsolute)\n return '/';\n return trailingSeparator ? './' : '.';\n }\n if (trailingSeparator)\n path += '/';\n return isAbsolute ? `/${path}` : path;\n}\nexport function isAbsolute(path) {\n validateString(path, 'path');\n return path.length > 0 && path[0] === '/';\n}\nexport function join(...args) {\n if (args.length === 0)\n return '.';\n let joined;\n for (let i = 0; i < args.length; ++i) {\n const arg = args[i];\n validateString(arg, 'path');\n if (arg.length > 0) {\n if (joined === undefined)\n joined = arg;\n else\n joined += `/${arg}`;\n }\n }\n if (joined === undefined)\n return '.';\n return normalize(joined);\n}\nexport function relative(from, to) {\n validateString(from, 'from');\n validateString(to, 'to');\n if (from === to)\n return '';\n // Trim leading forward slashes.\n from = resolve(from);\n to = resolve(to);\n if (from === to)\n return '';\n const fromStart = 1;\n const fromEnd = from.length;\n const fromLen = fromEnd - fromStart;\n const toStart = 1;\n const toLen = to.length - toStart;\n // Compare paths to find the longest common path from root\n const length = fromLen < toLen ? fromLen : toLen;\n let lastCommonSep = -1;\n let i = 0;\n for (; i < length; i++) {\n const fromCode = from[fromStart + i];\n if (fromCode !== to[toStart + i])\n break;\n else if (fromCode === '/')\n lastCommonSep = i;\n }\n if (i === length) {\n if (toLen > length) {\n if (to[toStart + i] === '/') {\n // We get here if `from` is the exact base path for `to`.\n // For example: from='/foo/bar'; to='/foo/bar/baz'\n return to.slice(toStart + i + 1);\n }\n if (i === 0) {\n // We get here if `from` is the root\n // For example: from='/'; to='/foo'\n return to.slice(toStart + i);\n }\n }\n else if (fromLen > length) {\n if (from[fromStart + i] === '/') {\n // We get here if `to` is the exact base path for `from`.\n // For example: from='/foo/bar/baz'; to='/foo/bar'\n lastCommonSep = i;\n }\n else if (i === 0) {\n // We get here if `to` is the root.\n // For example: from='/foo/bar'; to='/'\n lastCommonSep = 0;\n }\n }\n }\n let out = '';\n // Generate the relative path based on the path difference between `to`\n // and `from`.\n for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {\n if (i === fromEnd || from[i] === '/') {\n out += out.length === 0 ? '..' : '/..';\n }\n }\n // Lastly, append the rest of the destination (`to`) path that comes after\n // the common path parts.\n return `${out}${to.slice(toStart + lastCommonSep)}`;\n}\nexport function dirname(path) {\n validateString(path, 'path');\n if (path.length === 0)\n return '.';\n const hasRoot = path[0] === '/';\n let end = -1;\n let matchedSlash = true;\n for (let i = path.length - 1; i >= 1; --i) {\n if (path[i] === '/') {\n if (!matchedSlash) {\n end = i;\n break;\n }\n }\n else {\n // We saw the first non-path separator\n matchedSlash = false;\n }\n }\n if (end === -1)\n return hasRoot ? '/' : '.';\n if (hasRoot && end === 1)\n return '//';\n return path.slice(0, end);\n}\nexport function basename(path, suffix) {\n if (suffix !== undefined)\n validateString(suffix, 'ext');\n validateString(path, 'path');\n let start = 0;\n let end = -1;\n let matchedSlash = true;\n if (suffix !== undefined && suffix.length > 0 && suffix.length <= path.length) {\n if (suffix === path)\n return '';\n let extIdx = suffix.length - 1;\n let firstNonSlashEnd = -1;\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n }\n else {\n if (firstNonSlashEnd === -1) {\n // We saw the first non-path separator, remember this index in case\n // we need it if the extension ends up not matching\n matchedSlash = false;\n firstNonSlashEnd = i + 1;\n }\n if (extIdx >= 0) {\n // Try to match the explicit extension\n if (path[i] === suffix[extIdx]) {\n if (--extIdx === -1) {\n // We matched the extension, so mark this as the end of our path\n // component\n end = i;\n }\n }\n else {\n // Extension does not match, so our result is the entire path\n // component\n extIdx = -1;\n end = firstNonSlashEnd;\n }\n }\n }\n }\n if (start === end)\n end = firstNonSlashEnd;\n else if (end === -1)\n end = path.length;\n return path.slice(start, end);\n }\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n }\n else if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // path component\n matchedSlash = false;\n end = i + 1;\n }\n }\n if (end === -1)\n return '';\n return path.slice(start, end);\n}\nexport function extname(path) {\n validateString(path, 'path');\n let startDot = -1;\n let startPart = 0;\n let end = -1;\n let matchedSlash = true;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n let preDotState = 0;\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (path[i] === '.') {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1)\n startDot = i;\n else if (preDotState !== 1)\n preDotState = 1;\n }\n else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n if (startDot === -1 ||\n end === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) {\n return '';\n }\n return path.slice(startDot, end);\n}\nexport function format(pathObject) {\n validateObject(pathObject, 'pathObject');\n const dir = pathObject.dir || pathObject.root;\n const base = pathObject.base || `${pathObject.name || ''}${formatExt(pathObject.ext)}`;\n if (!dir) {\n return base;\n }\n return dir === pathObject.root ? `${dir}${base}` : `${dir}/${base}`;\n}\nexport function parse(path) {\n validateString(path, 'path');\n const isAbsolute = path[0] === '/';\n const ret = { root: isAbsolute ? '/' : '', dir: '', base: '', ext: '', name: '' };\n if (path.length === 0)\n return ret;\n const start = isAbsolute ? 1 : 0;\n let startDot = -1;\n let startPart = 0;\n let end = -1;\n let matchedSlash = true;\n let i = path.length - 1;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n let preDotState = 0;\n // Get non-dir info\n for (; i >= start; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (path[i] === '.') {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1)\n startDot = i;\n else if (preDotState !== 1)\n preDotState = 1;\n }\n else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n if (end !== -1) {\n const start = startPart === 0 && isAbsolute ? 1 : startPart;\n if (startDot === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) {\n ret.base = ret.name = path.slice(start, end);\n }\n else {\n ret.name = path.slice(start, startDot);\n ret.base = path.slice(start, end);\n ret.ext = path.slice(startDot, end);\n }\n }\n if (startPart > 0)\n ret.dir = path.slice(0, startPart - 1);\n else if (isAbsolute)\n ret.dir = '/';\n return ret;\n}\n", "import { ApiError, ErrorCode } from '@zenfs/core';\n\n/**\n * Converts a DOMException into an ErrorCode\n * @see https://developer.mozilla.org/Web/API/DOMException\n */\nfunction errnoForDOMException(ex: DOMException): keyof typeof ErrorCode {\n\tswitch (ex.name) {\n\t\tcase 'IndexSizeError':\n\t\tcase 'HierarchyRequestError':\n\t\tcase 'InvalidCharacterError':\n\t\tcase 'InvalidStateError':\n\t\tcase 'SyntaxError':\n\t\tcase 'NamespaceError':\n\t\tcase 'TypeMismatchError':\n\t\tcase 'ConstraintError':\n\t\tcase 'VersionError':\n\t\tcase 'URLMismatchError':\n\t\tcase 'InvalidNodeTypeError':\n\t\t\treturn 'EINVAL';\n\t\tcase 'WrongDocumentError':\n\t\t\treturn 'EXDEV';\n\t\tcase 'NoModificationAllowedError':\n\t\tcase 'InvalidModificationError':\n\t\tcase 'InvalidAccessError':\n\t\tcase 'SecurityError':\n\t\tcase 'NotAllowedError':\n\t\t\treturn 'EACCES';\n\t\tcase 'NotFoundError':\n\t\t\treturn 'ENOENT';\n\t\tcase 'NotSupportedError':\n\t\t\treturn 'ENOTSUP';\n\t\tcase 'InUseAttributeError':\n\t\t\treturn 'EBUSY';\n\t\tcase 'NetworkError':\n\t\t\treturn 'ENETDOWN';\n\t\tcase 'AbortError':\n\t\t\treturn 'EINTR';\n\t\tcase 'QuotaExceededError':\n\t\t\treturn 'ENOSPC';\n\t\tcase 'TimeoutError':\n\t\t\treturn 'ETIMEDOUT';\n\t\tcase 'ReadOnlyError':\n\t\t\treturn 'EROFS';\n\t\tcase 'DataCloneError':\n\t\tcase 'EncodingError':\n\t\tcase 'NotReadableError':\n\t\tcase 'DataError':\n\t\tcase 'TransactionInactiveError':\n\t\tcase 'OperationError':\n\t\tcase 'UnknownError':\n\t\tdefault:\n\t\t\treturn 'EIO';\n\t}\n}\n\n/**\n * @internal\n */\nexport type ConvertException = ApiError | DOMException | Error;\n\n/**\n * Handles converting errors, then rethrowing them\n * @internal\n */\nexport function convertException(ex: ConvertException, path?: string, syscall?: string): ApiError {\n\tif (ex instanceof ApiError) {\n\t\treturn ex;\n\t}\n\n\tconst code = ex instanceof DOMException ? ErrorCode[errnoForDOMException(ex)] : ErrorCode.EIO;\n\tconst error = new ApiError(code, ex.message, path, syscall);\n\terror.stack = ex.stack!;\n\terror.cause = ex.cause;\n\treturn error;\n}\n", "import type { Backend, FileSystemMetadata } from '@zenfs/core';\nimport { ApiError, Async, ErrorCode, FileSystem, FileType, InMemory, PreloadFile, Stats } from '@zenfs/core';\nimport { basename, dirname, join } from '@zenfs/core/emulation/path.js';\nimport { convertException, type ConvertException } from './utils.js';\n\ndeclare global {\n\tinterface FileSystemDirectoryHandle {\n\t\t[Symbol.iterator](): IterableIterator<[string, FileSystemHandle]>;\n\t\tentries(): IterableIterator<[string, FileSystemHandle]>;\n\t\tkeys(): IterableIterator<string>;\n\t\tvalues(): IterableIterator<FileSystemHandle>;\n\t}\n}\n\nexport interface WebAccessOptions {\n\thandle: FileSystemDirectoryHandle;\n}\n\nexport class WebAccessFS extends Async(FileSystem) {\n\tprivate _handles: Map<string, FileSystemHandle> = new Map();\n\n\t/**\n\t * @hidden\n\t */\n\t_sync: FileSystem;\n\n\tpublic constructor({ handle }: WebAccessOptions) {\n\t\tsuper();\n\t\tthis._handles.set('/', handle);\n\t\tthis._sync = InMemory.create({ name: 'accessfs-cache' });\n\t}\n\n\tpublic metadata(): FileSystemMetadata {\n\t\treturn {\n\t\t\t...super.metadata(),\n\t\t\tname: 'WebAccess',\n\t\t};\n\t}\n\n\tpublic async sync(p: string, data: Uint8Array, stats: Stats): Promise<void> {\n\t\tconst currentStats = await this.stat(p);\n\t\tif (stats.mtime !== currentStats!.mtime) {\n\t\t\tawait this.writeFile(p, data);\n\t\t}\n\t}\n\n\tpublic async rename(oldPath: string, newPath: string): Promise<void> {\n\t\ttry {\n\t\t\tconst handle = await this.getHandle(oldPath);\n\t\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\t\tconst files = await this.readdir(oldPath);\n\n\t\t\t\tawait this.mkdir(newPath);\n\t\t\t\tif (files.length == 0) {\n\t\t\t\t\tawait this.unlink(oldPath);\n\t\t\t\t} else {\n\t\t\t\t\tfor (const file of files) {\n\t\t\t\t\t\tawait this.rename(join(oldPath, file), join(newPath, file));\n\t\t\t\t\t\tawait this.unlink(oldPath);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!(handle instanceof FileSystemFileHandle)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst oldFile = await handle.getFile(),\n\t\t\t\tdestFolder = await this.getHandle(dirname(newPath));\n\t\t\tif (!(destFolder instanceof FileSystemDirectoryHandle)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst newFile = await destFolder.getFileHandle(basename(newPath), { create: true });\n\t\t\tconst writable = await newFile.createWritable();\n\t\t\tawait writable.write(await oldFile.arrayBuffer());\n\n\t\t\twritable.close();\n\t\t\tawait this.unlink(oldPath);\n\t\t} catch (ex) {\n\t\t\tthrow convertException(ex as ConvertException, oldPath, 'rename');\n\t\t}\n\t}\n\n\tpublic async writeFile(fname: string, data: Uint8Array): Promise<void> {\n\t\tconst handle = await this.getHandle(dirname(fname));\n\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst file = await handle.getFileHandle(basename(fname), { create: true });\n\t\tconst writable = await file.createWritable();\n\t\tawait writable.write(data);\n\t\tawait writable.close();\n\t}\n\n\tpublic async createFile(path: string, flag: string): Promise<PreloadFile<this>> {\n\t\tawait this.writeFile(path, new Uint8Array());\n\t\treturn this.openFile(path, flag);\n\t}\n\n\tpublic async stat(path: string): Promise<Stats> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (!handle) {\n\t\t\tthrow ApiError.With('ENOENT', path, 'stat');\n\t\t}\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\treturn new Stats({ mode: 0o777 | FileType.DIRECTORY, size: 4096 });\n\t\t}\n\t\tif (handle instanceof FileSystemFileHandle) {\n\t\t\tconst { lastModified, size } = await handle.getFile();\n\t\t\treturn new Stats({ mode: 0o777 | FileType.FILE, size, mtimeMs: lastModified });\n\t\t}\n\t\tthrow new ApiError(ErrorCode.EBADE, 'Handle is not a directory or file', path, 'stat');\n\t}\n\n\tpublic async openFile(path: string, flag: string): Promise<PreloadFile<this>> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (!(handle instanceof FileSystemFileHandle)) {\n\t\t\tthrow ApiError.With('EISDIR', path, 'openFile');\n\t\t}\n\t\ttry {\n\t\t\tconst file = await handle.getFile();\n\t\t\tconst data = new Uint8Array(await file.arrayBuffer());\n\t\t\tconst stats = new Stats({ mode: 0o777 | FileType.FILE, size: file.size, mtimeMs: file.lastModified });\n\t\t\treturn new PreloadFile(this, path, flag, stats, data);\n\t\t} catch (ex) {\n\t\t\tthrow convertException(ex as ConvertException, path, 'openFile');\n\t\t}\n\t}\n\n\tpublic async unlink(path: string): Promise<void> {\n\t\tconst handle = await this.getHandle(dirname(path));\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\ttry {\n\t\t\t\tawait handle.removeEntry(basename(path), { recursive: true });\n\t\t\t} catch (ex) {\n\t\t\t\tthrow convertException(ex as ConvertException, path, 'unlink');\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async link(srcpath: string): Promise<void> {\n\t\tthrow ApiError.With('ENOSYS', srcpath, 'WebAccessFS.link');\n\t}\n\n\tpublic async rmdir(path: string): Promise<void> {\n\t\treturn this.unlink(path);\n\t}\n\n\tpublic async mkdir(path: string): Promise<void> {\n\t\tconst existingHandle = await this.getHandle(path);\n\t\tif (existingHandle) {\n\t\t\tthrow ApiError.With('EEXIST', path, 'mkdir');\n\t\t}\n\n\t\tconst handle = await this.getHandle(dirname(path));\n\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\tthrow ApiError.With('ENOTDIR', path, 'mkdir');\n\t\t}\n\t\tawait handle.getDirectoryHandle(basename(path), { create: true });\n\t}\n\n\tpublic async readdir(path: string): Promise<string[]> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\tthrow ApiError.With('ENOTDIR', path, 'readdir');\n\t\t}\n\t\tconst _keys: string[] = [];\n\t\tfor await (const key of handle.keys()) {\n\t\t\t_keys.push(join(path, key));\n\t\t}\n\t\treturn _keys;\n\t}\n\n\tprotected async getHandle(path: string): Promise<FileSystemHandle> {\n\t\tif (this._handles.has(path)) {\n\t\t\treturn this._handles.get(path)!;\n\t\t}\n\n\t\tlet walked = '/';\n\n\t\tfor (const part of path.split('/').slice(1)) {\n\t\t\tconst handle = this._handles.get(walked);\n\t\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\t\tthrow ApiError.With('ENOTDIR', walked, 'getHandle');\n\t\t\t}\n\t\t\twalked = join(walked, part);\n\n\t\t\ttry {\n\t\t\t\tconst dirHandle = await handle.getDirectoryHandle(part);\n\t\t\t\tthis._handles.set(walked, dirHandle);\n\t\t\t} catch (_ex) {\n\t\t\t\tconst ex = _ex as DOMException;\n\t\t\t\tif (ex.name == 'TypeMismatchError') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst fileHandle = await handle.getFileHandle(part);\n\t\t\t\t\t\tthis._handles.set(walked, fileHandle);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\tconvertException(ex as ConvertException, walked, 'getHandle');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (ex.name === 'TypeError') {\n\t\t\t\t\tthrow new ApiError(ErrorCode.ENOENT, ex.message, walked, 'getHandle');\n\t\t\t\t}\n\n\t\t\t\tconvertException(ex, walked, 'getHandle');\n\t\t\t}\n\t\t}\n\n\t\treturn this._handles.get(path)!;\n\t}\n}\n\nexport const WebAccess = {\n\tname: 'WebAccess',\n\n\toptions: {\n\t\thandle: {\n\t\t\ttype: 'object',\n\t\t\trequired: true,\n\t\t\tdescription: 'The directory handle to use for the root',\n\t\t},\n\t},\n\n\tisAvailable(): boolean {\n\t\treturn typeof FileSystemHandle == 'function';\n\t},\n\n\tcreate(options: WebAccessOptions) {\n\t\treturn new WebAccessFS(options);\n\t},\n} as const satisfies Backend;\n", "import type { AsyncStore, AsyncStoreOptions, AsyncTransaction, Backend, Ino } from '@zenfs/core';\nimport { AsyncStoreFS } from '@zenfs/core';\nimport { convertException, type ConvertException } from './utils.js';\n\nfunction wrap<T>(request: IDBRequest<T>): Promise<T> {\n\treturn new Promise((resolve, reject) => {\n\t\trequest.onsuccess = () => resolve(request.result);\n\t\trequest.onerror = e => {\n\t\t\te.preventDefault();\n\t\t\treject(convertException(request.error!));\n\t\t};\n\t});\n}\n\n/**\n * @hidden\n */\nexport class IndexedDBTransaction implements AsyncTransaction {\n\tconstructor(\n\t\tpublic tx: IDBTransaction,\n\t\tpublic store: IDBObjectStore\n\t) {}\n\n\tpublic get(key: Ino): Promise<Uint8Array> {\n\t\treturn wrap<Uint8Array>(this.store.get(key.toString()));\n\t}\n\n\t/**\n\t * @todo return false when add has a key conflict (no error)\n\t */\n\tpublic async put(key: Ino, data: Uint8Array, overwrite: boolean): Promise<boolean> {\n\t\tawait wrap(this.store[overwrite ? 'put' : 'add'](data, key.toString()));\n\t\treturn true;\n\t}\n\n\tpublic remove(key: Ino): Promise<void> {\n\t\treturn wrap(this.store.delete(key.toString()));\n\t}\n\n\tpublic async commit(): Promise<void> {\n\t\treturn;\n\t}\n\n\tpublic async abort(): Promise<void> {\n\t\ttry {\n\t\t\tthis.tx.abort();\n\t\t} catch (e) {\n\t\t\tthrow convertException(e as ConvertException);\n\t\t}\n\t}\n}\n\nexport class IndexedDBStore implements AsyncStore {\n\tpublic static async create(storeName: string, indexedDB: IDBFactory = globalThis.indexedDB): Promise<IndexedDBStore> {\n\t\tconst req: IDBOpenDBRequest = indexedDB.open(storeName, 1);\n\n\t\treq.onupgradeneeded = () => {\n\t\t\tconst db: IDBDatabase = req.result;\n\t\t\t// This should never happen; we're at version 1. Why does another database exist?\n\t\t\tif (db.objectStoreNames.contains(storeName)) {\n\t\t\t\tdb.deleteObjectStore(storeName);\n\t\t\t}\n\t\t\tdb.createObjectStore(storeName);\n\t\t};\n\n\t\tconst result = await wrap(req);\n\t\treturn new IndexedDBStore(result, storeName);\n\t}\n\n\tconstructor(\n\t\tprotected db: IDBDatabase,\n\t\tprotected storeName: string\n\t) {}\n\n\tpublic get name(): string {\n\t\treturn IndexedDB.name + ':' + this.storeName;\n\t}\n\n\tpublic clear(): Promise<void> {\n\t\treturn wrap(this.db.transaction(this.storeName, 'readwrite').objectStore(this.storeName).clear());\n\t}\n\n\tpublic beginTransaction(): IndexedDBTransaction {\n\t\tconst tx = this.db.transaction(this.storeName, 'readwrite');\n\t\treturn new IndexedDBTransaction(tx, tx.objectStore(this.storeName));\n\t}\n}\n\n/**\n * Configuration options for the IndexedDB file system.\n */\nexport interface IndexedDBOptions extends Omit<AsyncStoreOptions, 'store'> {\n\t/**\n\t * The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.\n\t */\n\tstoreName?: string;\n\n\t/**\n\t * The IDBFactory to use. Defaults to `globalThis.indexedDB`.\n\t */\n\tidbFactory?: IDBFactory;\n}\n\n/**\n * A file system that uses the IndexedDB key value file system.\n */\n\nexport const IndexedDB = {\n\tname: 'IndexedDB',\n\n\toptions: {\n\t\tstoreName: {\n\t\t\ttype: 'string',\n\t\t\trequired: false,\n\t\t\tdescription: 'The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.',\n\t\t},\n\t\tcacheSize: {\n\t\t\ttype: 'number',\n\t\t\trequired: false,\n\t\t\tdescription: 'The size of the inode cache. Defaults to 100. A size of 0 or below disables caching.',\n\t\t},\n\t\tidbFactory: {\n\t\t\ttype: 'object',\n\t\t\trequired: false,\n\t\t\tdescription: 'The IDBFactory to use. Defaults to globalThis.indexedDB.',\n\t\t},\n\t},\n\n\tasync isAvailable(idbFactory: IDBFactory = globalThis.indexedDB): Promise<boolean> {\n\t\ttry {\n\t\t\tif (!(idbFactory instanceof IDBFactory)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst req = idbFactory.open('__zenfs_test');\n\t\t\tawait wrap(req);\n\t\t\tidbFactory.deleteDatabase('__zenfs_test');\n\t\t\treturn true;\n\t\t} catch (e) {\n\t\t\tidbFactory.deleteDatabase('__zenfs_test');\n\t\t\treturn false;\n\t\t}\n\t},\n\n\tcreate(options: IndexedDBOptions) {\n\t\tconst store = IndexedDBStore.create(options.storeName || 'zenfs', options.idbFactory);\n\t\tconst fs = new AsyncStoreFS({ ...options, store });\n\t\treturn fs;\n\t},\n} as const satisfies Backend;\n", "import type { Backend, Ino, SimpleSyncStore, SyncStore } from '@zenfs/core';\nimport { ApiError, ErrorCode, SimpleSyncTransaction, SyncStoreFS, decode, encode } from '@zenfs/core';\n\n/**\n * A synchronous key-value store backed by Storage.\n */\nexport class WebStorageStore implements SyncStore, SimpleSyncStore {\n\tpublic get name(): string {\n\t\treturn WebStorage.name;\n\t}\n\n\tconstructor(protected _storage: Storage) {}\n\n\tpublic clear(): void {\n\t\tthis._storage.clear();\n\t}\n\n\tpublic beginTransaction(): SimpleSyncTransaction {\n\t\t// No need to differentiate.\n\t\treturn new SimpleSyncTransaction(this);\n\t}\n\n\tpublic get(key: Ino): Uint8Array | undefined {\n\t\tconst data = this._storage.getItem(key.toString());\n\t\tif (typeof data != 'string') {\n\t\t\treturn;\n\t\t}\n\n\t\treturn encode(data);\n\t}\n\n\tpublic put(key: Ino, data: Uint8Array, overwrite: boolean): boolean {\n\t\ttry {\n\t\t\tif (!overwrite && this._storage.getItem(key.toString()) !== null) {\n\t\t\t\t// Don't want to overwrite the key!\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis._storage.setItem(key.toString(), decode(data));\n\t\t\treturn true;\n\t\t} catch (e) {\n\t\t\tthrow new ApiError(ErrorCode.ENOSPC, 'Storage is full.');\n\t\t}\n\t}\n\n\tpublic remove(key: Ino): void {\n\t\ttry {\n\t\t\tthis._storage.removeItem(key.toString());\n\t\t} catch (e) {\n\t\t\tthrow new ApiError(ErrorCode.EIO, 'Unable to delete key ' + key + ': ' + e);\n\t\t}\n\t}\n}\n\n/**\n * Options to pass to the StorageFileSystem\n */\nexport interface WebStorageOptions {\n\t/**\n\t * The Storage to use. Defaults to globalThis.localStorage.\n\t */\n\tstorage?: Storage;\n}\n\n/**\n * A synchronous file system backed by a `Storage` (e.g. localStorage).\n */\nexport const WebStorage = {\n\tname: 'WebStorage',\n\n\toptions: {\n\t\tstorage: {\n\t\t\ttype: 'object',\n\t\t\trequired: false,\n\t\t\tdescription: 'The Storage to use. Defaults to globalThis.localStorage.',\n\t\t},\n\t},\n\n\tisAvailable(storage: Storage = globalThis.localStorage): boolean {\n\t\treturn storage instanceof globalThis.Storage;\n\t},\n\n\tcreate({ storage = globalThis.localStorage }: WebStorageOptions) {\n\t\treturn new SyncStoreFS({ store: new WebStorageStore(storage) });\n\t},\n} as const satisfies Backend;\n"],
5
- "mappings": "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",
6
- "names": ["src_exports", "__export", "IndexedDB", "IndexedDBStore", "IndexedDBTransaction", "WebAccess", "WebAccessFS", "WebStorage", "WebStorageStore", "core_default", "ActionType", "ApiError", "Async", "AsyncIndexFS", "AsyncStoreFS", "BigIntStats", "BigIntStatsFs", "Dir", "Dirent", "ErrorCode", "File", "FileIndex", "FileSystem", "FileType", "InMemory", "InMemoryStore", "IndexDirInode", "IndexFS", "IndexFileInode", "IndexInode", "Inode", "LockedFS", "Mutex", "NoSyncFile", "Overlay", "OverlayFS", "PreloadFile", "ReadStream", "Readonly", "SimpleSyncTransaction", "Stats", "StatsCommon", "StatsFs", "Sync", "SyncIndexFS", "SyncStoreFS", "UnlockedOverlayFS", "WriteStream", "_toUnixTimestamp", "access", "accessSync", "appendFile", "appendFileSync", "checkOptions", "chmod", "chmodSync", "chown", "chownSync", "close", "closeSync", "configure", "constants", "copyFile", "copyFileSync", "cp", "cpSync", "createBackend", "createReadStream", "createWriteStream", "decode", "decodeDirListing", "encode", "encodeDirListing", "errorMessages", "exists", "existsSync", "fchmod", "fchmodSync", "fchown", "fchownSync", "fdatasync", "fdatasyncSync", "flagToMode", "flagToNumber", "flagToString", "fs", "fstat", "fstatSync", "fsync", "fsyncSync", "ftruncate", "ftruncateSync", "futimes", "futimesSync", "isAppendable", "isBackend", "isBackendConfig", "isExclusive", "isReadable", "isSynchronous", "isTruncating", "isWriteable", "lchmod", "lchmodSync", "lchown", "lchownSync", "levenshtein", "link", "linkSync", "lopenSync", "lstat", "lstatSync", "lutimes", "lutimesSync", "mkdir", "mkdirSync", "mkdirpSync", "mkdtemp", "mkdtempSync", "mount", "mountMapping", "mounts", "nop", "normalizeMode", "normalizeOptions", "normalizePath", "normalizeTime", "open", "openAsBlob", "openSync", "opendir", "opendirSync", "parseFlag", "pathExistsAction", "pathNotExistsAction", "promises", "randomIno", "read", "readFile", "readFileSync", "readSync", "readdir", "readdirSync", "readlink", "readlinkSync", "readv", "readvSync", "realpath", "realpathSync", "rename", "renameSync", "resolveMountConfig", "rm", "rmSync", "rmdir", "rmdirSync", "rootCred", "rootIno", "setImmediate", "size_max", "stat", "statSync", "statfs", "statfsSync", "symlink", "symlinkSync", "truncate", "truncateSync", "umount", "unlink", "unlinkSync", "unwatchFile", "utimes", "utimesSync", "watch", "watchFile", "write", "writeFile", "writeFileSync", "writeSync", "writev", "writevSync", "validateString", "str", "name", "__name", "normalizeString", "path", "allowAboveRoot", "res", "lastSegmentLength", "lastSlash", "dots", "char", "i", "lastSlashIndex", "__name", "normalize", "path", "validateString", "isAbsolute", "trailingSeparator", "normalizeString", "__name", "join", "args", "joined", "i", "arg", "validateString", "normalize", "__name", "dirname", "path", "validateString", "hasRoot", "end", "matchedSlash", "__name", "basename", "suffix", "start", "extIdx", "firstNonSlashEnd", "i", "errnoForDOMException", "ex", "__name", "convertException", "path", "syscall", "ApiError", "code", "ErrorCode", "error", "WebAccessFS", "Async", "FileSystem", "handle", "InMemory", "p", "data", "stats", "currentStats", "oldPath", "newPath", "files", "file", "join", "oldFile", "destFolder", "dirname", "writable", "basename", "ex", "convertException", "fname", "path", "flag", "ApiError", "Stats", "FileType", "lastModified", "size", "ErrorCode", "PreloadFile", "srcpath", "_keys", "key", "walked", "part", "dirHandle", "_ex", "fileHandle", "__name", "WebAccess", "options", "wrap", "request", "resolve", "reject", "e", "convertException", "__name", "IndexedDBTransaction", "tx", "store", "key", "data", "overwrite", "IndexedDBStore", "db", "storeName", "indexedDB", "req", "result", "IndexedDB", "idbFactory", "options", "AsyncStoreFS", "WebStorageStore", "_storage", "WebStorage", "SimpleSyncTransaction", "key", "data", "encode", "overwrite", "decode", "ApiError", "ErrorCode", "e", "__name", "storage", "SyncStoreFS"]
3
+ "sources": ["../src/index.ts", "global-externals:@zenfs/core", "../node_modules/@zenfs/core/dist/emulation/path.js", "../src/utils.ts", "../src/access.ts", "../node_modules/@zenfs/core/dist/error.js", "../node_modules/@zenfs/core/dist/backends/store/store.js", "../src/IndexedDB.ts", "../src/Storage.ts"],
4
+ "sourcesContent": ["export * from './access.js';\nexport * from './IndexedDB.js';\nexport * from './Storage.js';\n", "export default ZenFS;\nconst { ActionType, Async, AsyncIndexFS, AsyncTransaction, BigIntStats, BigIntStatsFs, Dir, Dirent, Errno, ErrnoError, Fetch, FetchFS, File, FileIndex, FileSystem, FileType, InMemory, InMemoryStore, IndexDirInode, IndexFS, IndexFileInode, IndexInode, Inode, LockedFS, Mutex, NoSyncFile, Overlay, OverlayFS, Port, PortFS, PortFile, PreloadFile, ReadStream, Readonly, SimpleAsyncStore, SimpleTransaction, Stats, StatsCommon, StatsFs, StoreFS, Sync, SyncIndexFS, SyncTransaction, Transaction, UnlockedOverlayFS, WriteStream, _toUnixTimestamp, access, accessSync, appendFile, appendFileSync, attachFS, checkOptions, chmod, chmodSync, chown, chownSync, close, closeSync, configure, constants, copyFile, copyFileSync, cp, cpSync, createReadStream, createWriteStream, decode, decodeDirListing, detachFS, encode, encodeDirListing, errorMessages, exists, existsSync, fchmod, fchmodSync, fchown, fchownSync, fdatasync, fdatasyncSync, flagToMode, flagToNumber, flagToString, fs, fstat, fstatSync, fsync, fsyncSync, ftruncate, ftruncateSync, futimes, futimesSync, isAppendable, isBackend, isBackendConfig, isExclusive, isReadable, isSynchronous, isTruncating, isWriteable, lchmod, lchmodSync, lchown, lchownSync, levenshtein, link, linkSync, lopenSync, lstat, lstatSync, lutimes, lutimesSync, mkdir, mkdirSync, mkdirpSync, mkdtemp, mkdtempSync, mount, mountObject, mounts, nop, normalizeMode, normalizeOptions, normalizePath, normalizeTime, open, openAsBlob, openSync, opendir, opendirSync, parseFlag, pathExistsAction, pathNotExistsAction, promises, randomIno, read, readFile, readFileSync, readSync, readdir, readdirSync, readlink, readlinkSync, readv, readvSync, realpath, realpathSync, rename, renameSync, resolveMountConfig, rm, rmSync, rmdir, rmdirSync, rootCred, rootIno, setImmediate, size_max, stat, statSync, statfs, statfsSync, symlink, symlinkSync, truncate, truncateSync, umount, unlink, unlinkSync, unwatchFile, utimes, utimesSync, watch, watchFile, write, writeFile, writeFileSync, writeSync, writev, writevSync } = ZenFS;\nexport { ActionType, Async, AsyncIndexFS, AsyncTransaction, BigIntStats, BigIntStatsFs, Dir, Dirent, Errno, ErrnoError, Fetch, FetchFS, File, FileIndex, FileSystem, FileType, InMemory, InMemoryStore, IndexDirInode, IndexFS, IndexFileInode, IndexInode, Inode, LockedFS, Mutex, NoSyncFile, Overlay, OverlayFS, Port, PortFS, PortFile, PreloadFile, ReadStream, Readonly, SimpleAsyncStore, SimpleTransaction, Stats, StatsCommon, StatsFs, StoreFS, Sync, SyncIndexFS, SyncTransaction, Transaction, UnlockedOverlayFS, WriteStream, _toUnixTimestamp, access, accessSync, appendFile, appendFileSync, attachFS, checkOptions, chmod, chmodSync, chown, chownSync, close, closeSync, configure, constants, copyFile, copyFileSync, cp, cpSync, createReadStream, createWriteStream, decode, decodeDirListing, detachFS, encode, encodeDirListing, errorMessages, exists, existsSync, fchmod, fchmodSync, fchown, fchownSync, fdatasync, fdatasyncSync, flagToMode, flagToNumber, flagToString, fs, fstat, fstatSync, fsync, fsyncSync, ftruncate, ftruncateSync, futimes, futimesSync, isAppendable, isBackend, isBackendConfig, isExclusive, isReadable, isSynchronous, isTruncating, isWriteable, lchmod, lchmodSync, lchown, lchownSync, levenshtein, link, linkSync, lopenSync, lstat, lstatSync, lutimes, lutimesSync, mkdir, mkdirSync, mkdirpSync, mkdtemp, mkdtempSync, mount, mountObject, mounts, nop, normalizeMode, normalizeOptions, normalizePath, normalizeTime, open, openAsBlob, openSync, opendir, opendirSync, parseFlag, pathExistsAction, pathNotExistsAction, promises, randomIno, read, readFile, readFileSync, readSync, readdir, readdirSync, readlink, readlinkSync, readv, readvSync, realpath, realpathSync, rename, renameSync, resolveMountConfig, rm, rmSync, rmdir, rmdirSync, rootCred, rootIno, setImmediate, size_max, stat, statSync, statfs, statfsSync, symlink, symlinkSync, truncate, truncateSync, umount, unlink, unlinkSync, unwatchFile, utimes, utimesSync, watch, watchFile, write, writeFile, writeFileSync, writeSync, writev, writevSync };", "/*\nCopyright Joyent, Inc. and other Node contributors.\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the\nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\nNO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\nexport let cwd = '/';\nexport function cd(path) {\n cwd = resolve(cwd, path);\n}\nexport const sep = '/';\nfunction validateObject(str, name) {\n if (typeof str != 'object') {\n throw new TypeError(`\"${name}\" is not an object`);\n }\n}\n// Resolves . and .. elements in a path with directory names\nexport function normalizeString(path, allowAboveRoot) {\n let res = '';\n let lastSegmentLength = 0;\n let lastSlash = -1;\n let dots = 0;\n let char = '\\x00';\n for (let i = 0; i <= path.length; ++i) {\n if (i < path.length) {\n char = path[i];\n }\n else if (char == '/') {\n break;\n }\n else {\n char = '/';\n }\n if (char == '/') {\n if (lastSlash === i - 1 || dots === 1) {\n // NOOP\n }\n else if (dots === 2) {\n if (res.length < 2 || lastSegmentLength !== 2 || res.at(-1) !== '.' || res.at(-2) !== '.') {\n if (res.length > 2) {\n const lastSlashIndex = res.lastIndexOf('/');\n if (lastSlashIndex === -1) {\n res = '';\n lastSegmentLength = 0;\n }\n else {\n res = res.slice(0, lastSlashIndex);\n lastSegmentLength = res.length - 1 - res.lastIndexOf('/');\n }\n lastSlash = i;\n dots = 0;\n continue;\n }\n else if (res.length !== 0) {\n res = '';\n lastSegmentLength = 0;\n lastSlash = i;\n dots = 0;\n continue;\n }\n }\n if (allowAboveRoot) {\n res += res.length > 0 ? '/..' : '..';\n lastSegmentLength = 2;\n }\n }\n else {\n if (res.length > 0)\n res += '/' + path.slice(lastSlash + 1, i);\n else\n res = path.slice(lastSlash + 1, i);\n lastSegmentLength = i - lastSlash - 1;\n }\n lastSlash = i;\n dots = 0;\n }\n else if (char === '.' && dots !== -1) {\n ++dots;\n }\n else {\n dots = -1;\n }\n }\n return res;\n}\nexport function formatExt(ext) {\n return ext ? `${ext[0] === '.' ? '' : '.'}${ext}` : '';\n}\nexport function resolve(...parts) {\n let resolved = '';\n for (const part of [...parts.reverse(), cwd]) {\n if (!part.length) {\n continue;\n }\n resolved = `${part}/${resolved}`;\n if (part.startsWith('/')) {\n break;\n }\n }\n const absolute = resolved.startsWith('/');\n // At this point the path should be resolved to a full absolute path, but\n // handle relative paths to be safe (might happen when cwd fails)\n // Normalize the path\n resolved = normalizeString(resolved, !absolute);\n if (absolute) {\n return `/${resolved}`;\n }\n return resolved.length ? resolved : '/';\n}\nexport function normalize(path) {\n if (!path.length)\n return '.';\n const isAbsolute = path.startsWith('/');\n const trailingSeparator = path.endsWith('/');\n // Normalize the path\n path = normalizeString(path, !isAbsolute);\n if (!path.length) {\n if (isAbsolute)\n return '/';\n return trailingSeparator ? './' : '.';\n }\n if (trailingSeparator)\n path += '/';\n return isAbsolute ? `/${path}` : path;\n}\nexport function isAbsolute(path) {\n return path.startsWith('/');\n}\nexport function join(...parts) {\n if (!parts.length)\n return '.';\n const joined = parts.join('/');\n if (!joined?.length)\n return '.';\n return normalize(joined);\n}\nexport function relative(from, to) {\n if (from === to)\n return '';\n // Trim leading forward slashes.\n from = resolve(from);\n to = resolve(to);\n if (from === to)\n return '';\n const fromStart = 1;\n const fromEnd = from.length;\n const fromLen = fromEnd - fromStart;\n const toStart = 1;\n const toLen = to.length - toStart;\n // Compare paths to find the longest common path from root\n const length = fromLen < toLen ? fromLen : toLen;\n let lastCommonSep = -1;\n let i = 0;\n for (; i < length; i++) {\n const fromCode = from[fromStart + i];\n if (fromCode !== to[toStart + i])\n break;\n else if (fromCode === '/')\n lastCommonSep = i;\n }\n if (i === length) {\n if (toLen > length) {\n if (to[toStart + i] === '/') {\n // We get here if `from` is the exact base path for `to`.\n // For example: from='/foo/bar'; to='/foo/bar/baz'\n return to.slice(toStart + i + 1);\n }\n if (i === 0) {\n // We get here if `from` is the root\n // For example: from='/'; to='/foo'\n return to.slice(toStart + i);\n }\n }\n else if (fromLen > length) {\n if (from[fromStart + i] === '/') {\n // We get here if `to` is the exact base path for `from`.\n // For example: from='/foo/bar/baz'; to='/foo/bar'\n lastCommonSep = i;\n }\n else if (i === 0) {\n // We get here if `to` is the root.\n // For example: from='/foo/bar'; to='/'\n lastCommonSep = 0;\n }\n }\n }\n let out = '';\n // Generate the relative path based on the path difference between `to`\n // and `from`.\n for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {\n if (i === fromEnd || from[i] === '/') {\n out += out.length === 0 ? '..' : '/..';\n }\n }\n // Lastly, append the rest of the destination (`to`) path that comes after\n // the common path parts.\n return `${out}${to.slice(toStart + lastCommonSep)}`;\n}\nexport function dirname(path) {\n if (path.length === 0)\n return '.';\n const hasRoot = path[0] === '/';\n let end = -1;\n let matchedSlash = true;\n for (let i = path.length - 1; i >= 1; --i) {\n if (path[i] === '/') {\n if (!matchedSlash) {\n end = i;\n break;\n }\n }\n else {\n // We saw the first non-path separator\n matchedSlash = false;\n }\n }\n if (end === -1)\n return hasRoot ? '/' : '.';\n if (hasRoot && end === 1)\n return '//';\n return path.slice(0, end);\n}\nexport function basename(path, suffix) {\n let start = 0;\n let end = -1;\n let matchedSlash = true;\n if (suffix !== undefined && suffix.length > 0 && suffix.length <= path.length) {\n if (suffix === path)\n return '';\n let extIdx = suffix.length - 1;\n let firstNonSlashEnd = -1;\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n }\n else {\n if (firstNonSlashEnd === -1) {\n // We saw the first non-path separator, remember this index in case\n // we need it if the extension ends up not matching\n matchedSlash = false;\n firstNonSlashEnd = i + 1;\n }\n if (extIdx >= 0) {\n // Try to match the explicit extension\n if (path[i] === suffix[extIdx]) {\n if (--extIdx === -1) {\n // We matched the extension, so mark this as the end of our path\n // component\n end = i;\n }\n }\n else {\n // Extension does not match, so our result is the entire path\n // component\n extIdx = -1;\n end = firstNonSlashEnd;\n }\n }\n }\n }\n if (start === end)\n end = firstNonSlashEnd;\n else if (end === -1)\n end = path.length;\n return path.slice(start, end);\n }\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n }\n else if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // path component\n matchedSlash = false;\n end = i + 1;\n }\n }\n if (end === -1)\n return '';\n return path.slice(start, end);\n}\nexport function extname(path) {\n let startDot = -1;\n let startPart = 0;\n let end = -1;\n let matchedSlash = true;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n let preDotState = 0;\n for (let i = path.length - 1; i >= 0; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (path[i] === '.') {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1)\n startDot = i;\n else if (preDotState !== 1)\n preDotState = 1;\n }\n else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n if (startDot === -1 ||\n end === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) {\n return '';\n }\n return path.slice(startDot, end);\n}\nexport function format(pathObject) {\n validateObject(pathObject, 'pathObject');\n const dir = pathObject.dir || pathObject.root;\n const base = pathObject.base || `${pathObject.name || ''}${formatExt(pathObject.ext)}`;\n if (!dir) {\n return base;\n }\n return dir === pathObject.root ? `${dir}${base}` : `${dir}/${base}`;\n}\nexport function parse(path) {\n const isAbsolute = path.startsWith('/');\n const ret = { root: isAbsolute ? '/' : '', dir: '', base: '', ext: '', name: '' };\n if (path.length === 0)\n return ret;\n const start = isAbsolute ? 1 : 0;\n let startDot = -1;\n let startPart = 0;\n let end = -1;\n let matchedSlash = true;\n let i = path.length - 1;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n let preDotState = 0;\n // Get non-dir info\n for (; i >= start; --i) {\n if (path[i] === '/') {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (path[i] === '.') {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1)\n startDot = i;\n else if (preDotState !== 1)\n preDotState = 1;\n }\n else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n if (end !== -1) {\n const start = startPart === 0 && isAbsolute ? 1 : startPart;\n if (startDot === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) {\n ret.base = ret.name = path.slice(start, end);\n }\n else {\n ret.name = path.slice(start, startDot);\n ret.base = path.slice(start, end);\n ret.ext = path.slice(startDot, end);\n }\n }\n if (startPart > 0)\n ret.dir = path.slice(0, startPart - 1);\n else if (isAbsolute)\n ret.dir = '/';\n return ret;\n}\n", "import { ErrnoError, Errno } from '@zenfs/core';\n\n/**\n * Converts a DOMException into an Errno\n * @see https://developer.mozilla.org/Web/API/DOMException\n */\nfunction errnoForDOMException(ex: DOMException): keyof typeof Errno {\n\tswitch (ex.name) {\n\t\tcase 'IndexSizeError':\n\t\tcase 'HierarchyRequestError':\n\t\tcase 'InvalidCharacterError':\n\t\tcase 'InvalidStateError':\n\t\tcase 'SyntaxError':\n\t\tcase 'NamespaceError':\n\t\tcase 'TypeMismatchError':\n\t\tcase 'ConstraintError':\n\t\tcase 'VersionError':\n\t\tcase 'URLMismatchError':\n\t\tcase 'InvalidNodeTypeError':\n\t\t\treturn 'EINVAL';\n\t\tcase 'WrongDocumentError':\n\t\t\treturn 'EXDEV';\n\t\tcase 'NoModificationAllowedError':\n\t\tcase 'InvalidModificationError':\n\t\tcase 'InvalidAccessError':\n\t\tcase 'SecurityError':\n\t\tcase 'NotAllowedError':\n\t\t\treturn 'EACCES';\n\t\tcase 'NotFoundError':\n\t\t\treturn 'ENOENT';\n\t\tcase 'NotSupportedError':\n\t\t\treturn 'ENOTSUP';\n\t\tcase 'InUseAttributeError':\n\t\t\treturn 'EBUSY';\n\t\tcase 'NetworkError':\n\t\t\treturn 'ENETDOWN';\n\t\tcase 'AbortError':\n\t\t\treturn 'EINTR';\n\t\tcase 'QuotaExceededError':\n\t\t\treturn 'ENOSPC';\n\t\tcase 'TimeoutError':\n\t\t\treturn 'ETIMEDOUT';\n\t\tcase 'ReadOnlyError':\n\t\t\treturn 'EROFS';\n\t\tcase 'DataCloneError':\n\t\tcase 'EncodingError':\n\t\tcase 'NotReadableError':\n\t\tcase 'DataError':\n\t\tcase 'TransactionInactiveError':\n\t\tcase 'OperationError':\n\t\tcase 'UnknownError':\n\t\tdefault:\n\t\t\treturn 'EIO';\n\t}\n}\n\n/**\n * @internal\n */\nexport type ConvertException = ErrnoError | DOMException | Error;\n\n/**\n * Handles converting errors, then rethrowing them\n * @internal\n */\nexport function convertException(ex: ConvertException, path?: string, syscall?: string): ErrnoError {\n\tif (ex instanceof ErrnoError) {\n\t\treturn ex;\n\t}\n\n\tconst code = ex instanceof DOMException ? Errno[errnoForDOMException(ex)] : Errno.EIO;\n\tconst error = new ErrnoError(code, ex.message, path, syscall);\n\terror.stack = ex.stack!;\n\terror.cause = ex.cause;\n\treturn error;\n}\n", "import type { Backend, FileSystemMetadata } from '@zenfs/core';\nimport { ErrnoError, Async, Errno, FileSystem, FileType, InMemory, PreloadFile, Stats } from '@zenfs/core';\nimport { basename, dirname, join } from '@zenfs/core/emulation/path.js';\nimport { convertException, type ConvertException } from './utils.js';\n\ndeclare global {\n\tinterface FileSystemDirectoryHandle {\n\t\t[Symbol.iterator](): IterableIterator<[string, FileSystemHandle]>;\n\t\tentries(): IterableIterator<[string, FileSystemHandle]>;\n\t\tkeys(): IterableIterator<string>;\n\t\tvalues(): IterableIterator<FileSystemHandle>;\n\t}\n}\n\nexport interface WebAccessOptions {\n\thandle: FileSystemDirectoryHandle;\n}\n\nexport class WebAccessFS extends Async(FileSystem) {\n\tprivate _handles: Map<string, FileSystemHandle> = new Map();\n\n\t/**\n\t * @hidden\n\t */\n\t_sync: FileSystem;\n\n\tpublic constructor({ handle }: WebAccessOptions) {\n\t\tsuper();\n\t\tthis._handles.set('/', handle);\n\t\tthis._sync = InMemory.create({ name: 'accessfs-cache' });\n\t}\n\n\tpublic metadata(): FileSystemMetadata {\n\t\treturn {\n\t\t\t...super.metadata(),\n\t\t\tname: 'WebAccess',\n\t\t};\n\t}\n\n\tpublic async sync(path: string, data: Uint8Array, stats: Stats): Promise<void> {\n\t\tconst currentStats = await this.stat(path);\n\t\tif (stats.mtime !== currentStats!.mtime) {\n\t\t\tawait this.writeFile(path, data);\n\t\t}\n\t}\n\n\tpublic async rename(oldPath: string, newPath: string): Promise<void> {\n\t\ttry {\n\t\t\tconst handle = await this.getHandle(oldPath);\n\t\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\t\tconst files = await this.readdir(oldPath);\n\n\t\t\t\tawait this.mkdir(newPath);\n\t\t\t\tif (files.length == 0) {\n\t\t\t\t\tawait this.unlink(oldPath);\n\t\t\t\t} else {\n\t\t\t\t\tfor (const file of files) {\n\t\t\t\t\t\tawait this.rename(join(oldPath, file), join(newPath, file));\n\t\t\t\t\t\tawait this.unlink(oldPath);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!(handle instanceof FileSystemFileHandle)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst oldFile = await handle.getFile(),\n\t\t\t\tdestFolder = await this.getHandle(dirname(newPath));\n\t\t\tif (!(destFolder instanceof FileSystemDirectoryHandle)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst newFile = await destFolder.getFileHandle(basename(newPath), { create: true });\n\t\t\tconst writable = await newFile.createWritable();\n\t\t\tawait writable.write(await oldFile.arrayBuffer());\n\n\t\t\twritable.close();\n\t\t\tawait this.unlink(oldPath);\n\t\t} catch (ex) {\n\t\t\tthrow convertException(ex as ConvertException, oldPath, 'rename');\n\t\t}\n\t}\n\n\tpublic async writeFile(fname: string, data: Uint8Array): Promise<void> {\n\t\tconst handle = await this.getHandle(dirname(fname));\n\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst file = await handle.getFileHandle(basename(fname), { create: true });\n\t\tconst writable = await file.createWritable();\n\t\tawait writable.write(data);\n\t\tawait writable.close();\n\t}\n\n\tpublic async createFile(path: string, flag: string): Promise<PreloadFile<this>> {\n\t\tawait this.writeFile(path, new Uint8Array());\n\t\treturn this.openFile(path, flag);\n\t}\n\n\tpublic async stat(path: string): Promise<Stats> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (!handle) {\n\t\t\tthrow ErrnoError.With('ENOENT', path, 'stat');\n\t\t}\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\treturn new Stats({ mode: 0o777 | FileType.DIRECTORY, size: 4096 });\n\t\t}\n\t\tif (handle instanceof FileSystemFileHandle) {\n\t\t\tconst { lastModified, size } = await handle.getFile();\n\t\t\treturn new Stats({ mode: 0o777 | FileType.FILE, size, mtimeMs: lastModified });\n\t\t}\n\t\tthrow new ErrnoError(Errno.EBADE, 'Handle is not a directory or file', path, 'stat');\n\t}\n\n\tpublic async openFile(path: string, flag: string): Promise<PreloadFile<this>> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (!(handle instanceof FileSystemFileHandle)) {\n\t\t\tthrow ErrnoError.With('EISDIR', path, 'openFile');\n\t\t}\n\t\ttry {\n\t\t\tconst file = await handle.getFile();\n\t\t\tconst data = new Uint8Array(await file.arrayBuffer());\n\t\t\tconst stats = new Stats({ mode: 0o777 | FileType.FILE, size: file.size, mtimeMs: file.lastModified });\n\t\t\treturn new PreloadFile(this, path, flag, stats, data);\n\t\t} catch (ex) {\n\t\t\tthrow convertException(ex as ConvertException, path, 'openFile');\n\t\t}\n\t}\n\n\tpublic async unlink(path: string): Promise<void> {\n\t\tconst handle = await this.getHandle(dirname(path));\n\t\tif (handle instanceof FileSystemDirectoryHandle) {\n\t\t\ttry {\n\t\t\t\tawait handle.removeEntry(basename(path), { recursive: true });\n\t\t\t} catch (ex) {\n\t\t\t\tthrow convertException(ex as ConvertException, path, 'unlink');\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async link(srcpath: string): Promise<void> {\n\t\tthrow ErrnoError.With('ENOSYS', srcpath, 'WebAccessFS.link');\n\t}\n\n\tpublic async rmdir(path: string): Promise<void> {\n\t\treturn this.unlink(path);\n\t}\n\n\tpublic async mkdir(path: string): Promise<void> {\n\t\tconst existingHandle = await this.getHandle(path);\n\t\tif (existingHandle) {\n\t\t\tthrow ErrnoError.With('EEXIST', path, 'mkdir');\n\t\t}\n\n\t\tconst handle = await this.getHandle(dirname(path));\n\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\tthrow ErrnoError.With('ENOTDIR', path, 'mkdir');\n\t\t}\n\t\tawait handle.getDirectoryHandle(basename(path), { create: true });\n\t}\n\n\tpublic async readdir(path: string): Promise<string[]> {\n\t\tconst handle = await this.getHandle(path);\n\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\tthrow ErrnoError.With('ENOTDIR', path, 'readdir');\n\t\t}\n\t\tconst _keys: string[] = [];\n\t\tfor await (const key of handle.keys()) {\n\t\t\t_keys.push(join(path, key));\n\t\t}\n\t\treturn _keys;\n\t}\n\n\tprotected async getHandle(path: string): Promise<FileSystemHandle> {\n\t\tif (this._handles.has(path)) {\n\t\t\treturn this._handles.get(path)!;\n\t\t}\n\n\t\tlet walked = '/';\n\n\t\tfor (const part of path.split('/').slice(1)) {\n\t\t\tconst handle = this._handles.get(walked);\n\t\t\tif (!(handle instanceof FileSystemDirectoryHandle)) {\n\t\t\t\tthrow ErrnoError.With('ENOTDIR', walked, 'getHandle');\n\t\t\t}\n\t\t\twalked = join(walked, part);\n\n\t\t\ttry {\n\t\t\t\tconst dirHandle = await handle.getDirectoryHandle(part);\n\t\t\t\tthis._handles.set(walked, dirHandle);\n\t\t\t} catch (_ex) {\n\t\t\t\tconst ex = _ex as DOMException;\n\t\t\t\tif (ex.name == 'TypeMismatchError') {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst fileHandle = await handle.getFileHandle(part);\n\t\t\t\t\t\tthis._handles.set(walked, fileHandle);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\tconvertException(ex as ConvertException, walked, 'getHandle');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (ex.name === 'TypeError') {\n\t\t\t\t\tthrow new ErrnoError(Errno.ENOENT, ex.message, walked, 'getHandle');\n\t\t\t\t}\n\n\t\t\t\tconvertException(ex, walked, 'getHandle');\n\t\t\t}\n\t\t}\n\n\t\treturn this._handles.get(path)!;\n\t}\n}\n\nexport const WebAccess = {\n\tname: 'WebAccess',\n\n\toptions: {\n\t\thandle: {\n\t\t\ttype: 'object',\n\t\t\trequired: true,\n\t\t\tdescription: 'The directory handle to use for the root',\n\t\t},\n\t},\n\n\tisAvailable(): boolean {\n\t\treturn typeof FileSystemHandle == 'function';\n\t},\n\n\tcreate(options: WebAccessOptions) {\n\t\treturn new WebAccessFS(options);\n\t},\n} as const satisfies Backend<WebAccessFS, WebAccessOptions>;\n", "/**\n * Standard libc error codes. More will be added to this enum and error strings as they are\n * needed.\n * @url https://en.wikipedia.org/wiki/Errno.h\n */\nexport var Errno;\n(function (Errno) {\n /** Operation not permitted */\n Errno[Errno[\"EPERM\"] = 1] = \"EPERM\";\n /** No such file or directory */\n Errno[Errno[\"ENOENT\"] = 2] = \"ENOENT\";\n /** Interrupted system call */\n Errno[Errno[\"EINTR\"] = 4] = \"EINTR\";\n /** Input/output error */\n Errno[Errno[\"EIO\"] = 5] = \"EIO\";\n /** No such device or address */\n Errno[Errno[\"ENXIO\"] = 6] = \"ENXIO\";\n /** Bad file descriptor */\n Errno[Errno[\"EBADF\"] = 9] = \"EBADF\";\n /** Resource temporarily unavailable */\n Errno[Errno[\"EAGAIN\"] = 11] = \"EAGAIN\";\n /** Cannot allocate memory */\n Errno[Errno[\"ENOMEM\"] = 12] = \"ENOMEM\";\n /** Permission denied */\n Errno[Errno[\"EACCES\"] = 13] = \"EACCES\";\n /** Bad address */\n Errno[Errno[\"EFAULT\"] = 14] = \"EFAULT\";\n /** Block device required */\n Errno[Errno[\"ENOTBLK\"] = 15] = \"ENOTBLK\";\n /** Resource busy or locked */\n Errno[Errno[\"EBUSY\"] = 16] = \"EBUSY\";\n /** File exists */\n Errno[Errno[\"EEXIST\"] = 17] = \"EEXIST\";\n /** Invalid cross-device link */\n Errno[Errno[\"EXDEV\"] = 18] = \"EXDEV\";\n /** No such device */\n Errno[Errno[\"ENODEV\"] = 19] = \"ENODEV\";\n /** File is not a directory */\n Errno[Errno[\"ENOTDIR\"] = 20] = \"ENOTDIR\";\n /** File is a directory */\n Errno[Errno[\"EISDIR\"] = 21] = \"EISDIR\";\n /** Invalid argument */\n Errno[Errno[\"EINVAL\"] = 22] = \"EINVAL\";\n /** Too many open files in system */\n Errno[Errno[\"ENFILE\"] = 23] = \"ENFILE\";\n /** Too many open files */\n Errno[Errno[\"EMFILE\"] = 24] = \"EMFILE\";\n /** Text file busy */\n Errno[Errno[\"ETXTBSY\"] = 26] = \"ETXTBSY\";\n /** File is too big */\n Errno[Errno[\"EFBIG\"] = 27] = \"EFBIG\";\n /** No space left on disk */\n Errno[Errno[\"ENOSPC\"] = 28] = \"ENOSPC\";\n /** Illegal seek */\n Errno[Errno[\"ESPIPE\"] = 29] = \"ESPIPE\";\n /** Cannot modify a read-only file system */\n Errno[Errno[\"EROFS\"] = 30] = \"EROFS\";\n /** Too many links */\n Errno[Errno[\"EMLINK\"] = 31] = \"EMLINK\";\n /** Broken pipe */\n Errno[Errno[\"EPIPE\"] = 32] = \"EPIPE\";\n /** Numerical argument out of domain */\n Errno[Errno[\"EDOM\"] = 33] = \"EDOM\";\n /** Numerical result out of range */\n Errno[Errno[\"ERANGE\"] = 34] = \"ERANGE\";\n /** Resource deadlock would occur */\n Errno[Errno[\"EDEADLK\"] = 35] = \"EDEADLK\";\n /** File name too long */\n Errno[Errno[\"ENAMETOOLONG\"] = 36] = \"ENAMETOOLONG\";\n /** No locks available */\n Errno[Errno[\"ENOLCK\"] = 37] = \"ENOLCK\";\n /** Function not implemented */\n Errno[Errno[\"ENOSYS\"] = 38] = \"ENOSYS\";\n /** Directory is not empty */\n Errno[Errno[\"ENOTEMPTY\"] = 39] = \"ENOTEMPTY\";\n /** Too many levels of symbolic links */\n Errno[Errno[\"ELOOP\"] = 40] = \"ELOOP\";\n /** No message of desired type */\n Errno[Errno[\"ENOMSG\"] = 42] = \"ENOMSG\";\n /** Invalid exchange */\n Errno[Errno[\"EBADE\"] = 52] = \"EBADE\";\n /** Invalid request descriptor */\n Errno[Errno[\"EBADR\"] = 53] = \"EBADR\";\n /** Exchange full */\n Errno[Errno[\"EXFULL\"] = 54] = \"EXFULL\";\n /** No anode */\n Errno[Errno[\"ENOANO\"] = 55] = \"ENOANO\";\n /** Invalid request code */\n Errno[Errno[\"EBADRQC\"] = 56] = \"EBADRQC\";\n /** Device not a stream */\n Errno[Errno[\"ENOSTR\"] = 60] = \"ENOSTR\";\n /** No data available */\n Errno[Errno[\"ENODATA\"] = 61] = \"ENODATA\";\n /** Timer expired */\n Errno[Errno[\"ETIME\"] = 62] = \"ETIME\";\n /** Out of streams resources */\n Errno[Errno[\"ENOSR\"] = 63] = \"ENOSR\";\n /** Machine is not on the network */\n Errno[Errno[\"ENONET\"] = 64] = \"ENONET\";\n /** Object is remote */\n Errno[Errno[\"EREMOTE\"] = 66] = \"EREMOTE\";\n /** Link has been severed */\n Errno[Errno[\"ENOLINK\"] = 67] = \"ENOLINK\";\n /** Communication error on send */\n Errno[Errno[\"ECOMM\"] = 70] = \"ECOMM\";\n /** Protocol error */\n Errno[Errno[\"EPROTO\"] = 71] = \"EPROTO\";\n /** Bad message */\n Errno[Errno[\"EBADMSG\"] = 74] = \"EBADMSG\";\n /** Value too large for defined data type */\n Errno[Errno[\"EOVERFLOW\"] = 75] = \"EOVERFLOW\";\n /** File descriptor in bad state */\n Errno[Errno[\"EBADFD\"] = 77] = \"EBADFD\";\n /** Streams pipe error */\n Errno[Errno[\"ESTRPIPE\"] = 86] = \"ESTRPIPE\";\n /** Socket operation on non-socket */\n Errno[Errno[\"ENOTSOCK\"] = 88] = \"ENOTSOCK\";\n /** Destination address required */\n Errno[Errno[\"EDESTADDRREQ\"] = 89] = \"EDESTADDRREQ\";\n /** Message too long */\n Errno[Errno[\"EMSGSIZE\"] = 90] = \"EMSGSIZE\";\n /** Protocol wrong type for socket */\n Errno[Errno[\"EPROTOTYPE\"] = 91] = \"EPROTOTYPE\";\n /** Protocol not available */\n Errno[Errno[\"ENOPROTOOPT\"] = 92] = \"ENOPROTOOPT\";\n /** Protocol not supported */\n Errno[Errno[\"EPROTONOSUPPORT\"] = 93] = \"EPROTONOSUPPORT\";\n /** Socket type not supported */\n Errno[Errno[\"ESOCKTNOSUPPORT\"] = 94] = \"ESOCKTNOSUPPORT\";\n /** Operation is not supported */\n Errno[Errno[\"ENOTSUP\"] = 95] = \"ENOTSUP\";\n /** Network is down */\n Errno[Errno[\"ENETDOWN\"] = 100] = \"ENETDOWN\";\n /** Network is unreachable */\n Errno[Errno[\"ENETUNREACH\"] = 101] = \"ENETUNREACH\";\n /** Network dropped connection on reset */\n Errno[Errno[\"ENETRESET\"] = 102] = \"ENETRESET\";\n /** Connection timed out */\n Errno[Errno[\"ETIMEDOUT\"] = 110] = \"ETIMEDOUT\";\n /** Connection refused */\n Errno[Errno[\"ECONNREFUSED\"] = 111] = \"ECONNREFUSED\";\n /** Host is down */\n Errno[Errno[\"EHOSTDOWN\"] = 112] = \"EHOSTDOWN\";\n /** No route to host */\n Errno[Errno[\"EHOSTUNREACH\"] = 113] = \"EHOSTUNREACH\";\n /** Operation already in progress */\n Errno[Errno[\"EALREADY\"] = 114] = \"EALREADY\";\n /** Operation now in progress */\n Errno[Errno[\"EINPROGRESS\"] = 115] = \"EINPROGRESS\";\n /** Stale file handle */\n Errno[Errno[\"ESTALE\"] = 116] = \"ESTALE\";\n /** Remote I/O error */\n Errno[Errno[\"EREMOTEIO\"] = 121] = \"EREMOTEIO\";\n /** Disk quota exceeded */\n Errno[Errno[\"EDQUOT\"] = 122] = \"EDQUOT\";\n})(Errno || (Errno = {}));\n/**\n * Strings associated with each error code.\n * @internal\n */\nexport const errorMessages = {\n [Errno.EPERM]: 'Operation not permitted',\n [Errno.ENOENT]: 'No such file or directory',\n [Errno.EINTR]: 'Interrupted system call',\n [Errno.EIO]: 'Input/output error',\n [Errno.ENXIO]: 'No such device or address',\n [Errno.EBADF]: 'Bad file descriptor',\n [Errno.EAGAIN]: 'Resource temporarily unavailable',\n [Errno.ENOMEM]: 'Cannot allocate memory',\n [Errno.EACCES]: 'Permission denied',\n [Errno.EFAULT]: 'Bad address',\n [Errno.ENOTBLK]: 'Block device required',\n [Errno.EBUSY]: 'Resource busy or locked',\n [Errno.EEXIST]: 'File exists',\n [Errno.EXDEV]: 'Invalid cross-device link',\n [Errno.ENODEV]: 'No such device',\n [Errno.ENOTDIR]: 'File is not a directory',\n [Errno.EISDIR]: 'File is a directory',\n [Errno.EINVAL]: 'Invalid argument',\n [Errno.ENFILE]: 'Too many open files in system',\n [Errno.EMFILE]: 'Too many open files',\n [Errno.ETXTBSY]: 'Text file busy',\n [Errno.EFBIG]: 'File is too big',\n [Errno.ENOSPC]: 'No space left on disk',\n [Errno.ESPIPE]: 'Illegal seek',\n [Errno.EROFS]: 'Cannot modify a read-only file system',\n [Errno.EMLINK]: 'Too many links',\n [Errno.EPIPE]: 'Broken pipe',\n [Errno.EDOM]: 'Numerical argument out of domain',\n [Errno.ERANGE]: 'Numerical result out of range',\n [Errno.EDEADLK]: 'Resource deadlock would occur',\n [Errno.ENAMETOOLONG]: 'File name too long',\n [Errno.ENOLCK]: 'No locks available',\n [Errno.ENOSYS]: 'Function not implemented',\n [Errno.ENOTEMPTY]: 'Directory is not empty',\n [Errno.ELOOP]: 'Too many levels of symbolic links',\n [Errno.ENOMSG]: 'No message of desired type',\n [Errno.EBADE]: 'Invalid exchange',\n [Errno.EBADR]: 'Invalid request descriptor',\n [Errno.EXFULL]: 'Exchange full',\n [Errno.ENOANO]: 'No anode',\n [Errno.EBADRQC]: 'Invalid request code',\n [Errno.ENOSTR]: 'Device not a stream',\n [Errno.ENODATA]: 'No data available',\n [Errno.ETIME]: 'Timer expired',\n [Errno.ENOSR]: 'Out of streams resources',\n [Errno.ENONET]: 'Machine is not on the network',\n [Errno.EREMOTE]: 'Object is remote',\n [Errno.ENOLINK]: 'Link has been severed',\n [Errno.ECOMM]: 'Communication error on send',\n [Errno.EPROTO]: 'Protocol error',\n [Errno.EBADMSG]: 'Bad message',\n [Errno.EOVERFLOW]: 'Value too large for defined data type',\n [Errno.EBADFD]: 'File descriptor in bad state',\n [Errno.ESTRPIPE]: 'Streams pipe error',\n [Errno.ENOTSOCK]: 'Socket operation on non-socket',\n [Errno.EDESTADDRREQ]: 'Destination address required',\n [Errno.EMSGSIZE]: 'Message too long',\n [Errno.EPROTOTYPE]: 'Protocol wrong type for socket',\n [Errno.ENOPROTOOPT]: 'Protocol not available',\n [Errno.EPROTONOSUPPORT]: 'Protocol not supported',\n [Errno.ESOCKTNOSUPPORT]: 'Socket type not supported',\n [Errno.ENOTSUP]: 'Operation is not supported',\n [Errno.ENETDOWN]: 'Network is down',\n [Errno.ENETUNREACH]: 'Network is unreachable',\n [Errno.ENETRESET]: 'Network dropped connection on reset',\n [Errno.ETIMEDOUT]: 'Connection timed out',\n [Errno.ECONNREFUSED]: 'Connection refused',\n [Errno.EHOSTDOWN]: 'Host is down',\n [Errno.EHOSTUNREACH]: 'No route to host',\n [Errno.EALREADY]: 'Operation already in progress',\n [Errno.EINPROGRESS]: 'Operation now in progress',\n [Errno.ESTALE]: 'Stale file handle',\n [Errno.EREMOTEIO]: 'Remote I/O error',\n [Errno.EDQUOT]: 'Disk quota exceeded',\n};\n/**\n * Represents a ZenFS error. Passed back to applications after a failed\n * call to the ZenFS API.\n */\nexport class ErrnoError extends Error {\n static fromJSON(json) {\n const err = new ErrnoError(json.errno, json.message, json.path, json.syscall);\n err.code = json.code;\n err.stack = json.stack;\n return err;\n }\n static With(code, path, syscall) {\n return new ErrnoError(Errno[code], errorMessages[Errno[code]], path, syscall);\n }\n /**\n * Represents a ZenFS error. Passed back to applications after a failed\n * call to the ZenFS API.\n *\n * Error codes mirror those returned by regular Unix file operations, which is\n * what Node returns.\n * @param type The type of the error.\n * @param message A descriptive error message.\n */\n constructor(errno, message = errorMessages[errno], path, syscall = '') {\n super(message);\n this.errno = errno;\n this.path = path;\n this.syscall = syscall;\n this.code = Errno[errno];\n this.message = `${this.code}: ${message}${this.path ? `, '${this.path}'` : ''}`;\n }\n /**\n * @return A friendly error message.\n */\n toString() {\n return this.message;\n }\n toJSON() {\n return {\n errno: this.errno,\n code: this.code,\n path: this.path,\n stack: this.stack,\n message: this.message,\n syscall: this.syscall,\n };\n }\n /**\n * The size of the API error in buffer-form in bytes.\n */\n bufferSize() {\n // 4 bytes for string length.\n return 4 + JSON.stringify(this.toJSON()).length;\n }\n}\n", "import { ErrnoError } from '../../error.js';\n/**\n * A transaction for a synchronous store.\n */\nexport class Transaction {\n constructor() {\n this.aborted = false;\n }\n async [Symbol.asyncDispose]() {\n if (this.aborted) {\n return;\n }\n await this.commit();\n }\n [Symbol.dispose]() {\n if (this.aborted) {\n return;\n }\n this.commitSync();\n }\n}\n/**\n * Transaction that implements asynchronous operations with synchronous ones\n */\nexport class SyncTransaction extends Transaction {\n async get(ino) {\n return this.getSync(ino);\n }\n async set(ino, data) {\n return this.setSync(ino, data);\n }\n async remove(ino) {\n return this.removeSync(ino);\n }\n async commit() {\n return this.commitSync();\n }\n async abort() {\n return this.abortSync();\n }\n}\n/**\n * Transaction that only supports asynchronous operations\n * @todo Add caching\n */\nexport class AsyncTransaction extends Transaction {\n getSync(ino) {\n throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.getSync');\n }\n setSync(ino, data) {\n throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.setSync');\n }\n removeSync(ino) {\n throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.removeSync');\n }\n commitSync() {\n throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.commitSync');\n }\n abortSync() {\n throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.abortSync');\n }\n}\n", "import type { Store } from '@zenfs/core/backends/store/store.js';\nimport { AsyncTransaction } from '@zenfs/core/backends/store/store.js';\nimport type { Backend, Ino } from '@zenfs/core';\nimport { ErrnoError, StoreFS } from '@zenfs/core';\nimport { convertException, type ConvertException } from './utils.js';\n\nfunction wrap<T>(request: IDBRequest<T>): Promise<T> {\n\treturn new Promise((resolve, reject) => {\n\t\trequest.onsuccess = () => resolve(request.result);\n\t\trequest.onerror = e => {\n\t\t\te.preventDefault();\n\t\t\treject(convertException(request.error!));\n\t\t};\n\t});\n}\n\n/**\n * @hidden\n */\nexport class IndexedDBTransaction extends AsyncTransaction {\n\tconstructor(\n\t\tpublic tx: IDBTransaction,\n\t\tpublic store: IDBObjectStore\n\t) {\n\t\tsuper();\n\t}\n\n\tpublic get(key: Ino): Promise<Uint8Array> {\n\t\treturn wrap(this.store.get(key.toString()));\n\t}\n\n\tpublic async set(key: Ino, data: Uint8Array): Promise<void> {\n\t\tawait wrap(this.store.put(data, key.toString()));\n\t}\n\n\tpublic remove(key: Ino): Promise<void> {\n\t\treturn wrap(this.store.delete(key.toString()));\n\t}\n\n\tpublic async commit(): Promise<void> {\n\t\tthis.tx.commit();\n\t}\n\n\tpublic async abort(): Promise<void> {\n\t\ttry {\n\t\t\tthis.tx.abort();\n\t\t} catch (e) {\n\t\t\tthrow convertException(e as ConvertException);\n\t\t}\n\t}\n}\n\nasync function createDB(name: string, indexedDB: IDBFactory = globalThis.indexedDB): Promise<IDBDatabase> {\n\tconst req: IDBOpenDBRequest = indexedDB.open(name);\n\n\treq.onupgradeneeded = () => {\n\t\tconst db: IDBDatabase = req.result;\n\t\t// This should never happen; we're at version 1. Why does another database exist?\n\t\tif (db.objectStoreNames.contains(name)) {\n\t\t\tdb.deleteObjectStore(name);\n\t\t}\n\t\tdb.createObjectStore(name);\n\t};\n\n\tconst result = await wrap(req);\n\treturn result;\n}\n\nexport class IndexedDBStore implements Store {\n\tpublic constructor(protected db: IDBDatabase) {}\n\n\tpublic sync(): Promise<void> {\n\t\tthrow new Error('Method not implemented.');\n\t}\n\n\tpublic get name(): string {\n\t\treturn IndexedDB.name + ':' + this.db.name;\n\t}\n\n\tpublic clear(): Promise<void> {\n\t\treturn wrap(this.db.transaction(this.db.name, 'readwrite').objectStore(this.db.name).clear());\n\t}\n\n\tpublic clearSync(): void {\n\t\tthrow ErrnoError.With('ENOSYS', undefined, 'IndexedDBStore.clearSync');\n\t}\n\n\tpublic transaction(): IndexedDBTransaction {\n\t\tconst tx = this.db.transaction(this.db.name, 'readwrite');\n\t\treturn new IndexedDBTransaction(tx, tx.objectStore(this.db.name));\n\t}\n}\n\n/**\n * Configuration options for the IndexedDB file system.\n */\nexport interface IndexedDBOptions {\n\t/**\n\t * The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.\n\t */\n\tstoreName?: string;\n\n\t/**\n\t * The IDBFactory to use. Defaults to `globalThis.indexedDB`.\n\t */\n\tidbFactory?: IDBFactory;\n}\n\n/**\n * A file system that uses the IndexedDB key value file system.\n */\n\nexport const IndexedDB = {\n\tname: 'IndexedDB',\n\n\toptions: {\n\t\tstoreName: {\n\t\t\ttype: 'string',\n\t\t\trequired: false,\n\t\t\tdescription: 'The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.',\n\t\t},\n\t\tidbFactory: {\n\t\t\ttype: 'object',\n\t\t\trequired: false,\n\t\t\tdescription: 'The IDBFactory to use. Defaults to globalThis.indexedDB.',\n\t\t},\n\t},\n\n\tasync isAvailable(idbFactory: IDBFactory = globalThis.indexedDB): Promise<boolean> {\n\t\ttry {\n\t\t\tif (!(idbFactory instanceof IDBFactory)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst req = idbFactory.open('__zenfs_test');\n\t\t\tawait wrap(req);\n\t\t\tidbFactory.deleteDatabase('__zenfs_test');\n\t\t\treturn true;\n\t\t} catch (e) {\n\t\t\tidbFactory.deleteDatabase('__zenfs_test');\n\t\t\treturn false;\n\t\t}\n\t},\n\n\tasync create(options: IndexedDBOptions) {\n\t\tconst db = await createDB(options.storeName || 'zenfs', options.idbFactory);\n\t\tconst store = new IndexedDBStore(db);\n\t\tconst fs = new StoreFS(store);\n\t\treturn fs;\n\t},\n} as const satisfies Backend<StoreFS, IndexedDBOptions>;\n", "import type { Backend, Ino, SimpleSyncStore, Store } from '@zenfs/core';\nimport { ErrnoError, Errno, SimpleTransaction, StoreFS, decode, encode } from '@zenfs/core';\n\n/**\n * A synchronous key-value store backed by Storage.\n */\nexport class WebStorageStore implements Store, SimpleSyncStore {\n\tpublic get name(): string {\n\t\treturn WebStorage.name;\n\t}\n\n\tconstructor(protected _storage: Storage) {}\n\n\tpublic clear(): void {\n\t\tthis._storage.clear();\n\t}\n\n\tpublic clearSync(): void {\n\t\tthis._storage.clear();\n\t}\n\n\tpublic async sync(): Promise<void> {}\n\n\tpublic transaction(): SimpleTransaction {\n\t\t// No need to differentiate.\n\t\treturn new SimpleTransaction(this);\n\t}\n\n\tpublic get(key: Ino): Uint8Array | undefined {\n\t\tconst data = this._storage.getItem(key.toString());\n\t\tif (typeof data != 'string') {\n\t\t\treturn;\n\t\t}\n\n\t\treturn encode(data);\n\t}\n\n\tpublic set(key: Ino, data: Uint8Array): void {\n\t\ttry {\n\t\t\tthis._storage.setItem(key.toString(), decode(data));\n\t\t} catch (e) {\n\t\t\tthrow new ErrnoError(Errno.ENOSPC, 'Storage is full.');\n\t\t}\n\t}\n\n\tpublic delete(key: Ino): void {\n\t\ttry {\n\t\t\tthis._storage.removeItem(key.toString());\n\t\t} catch (e) {\n\t\t\tthrow new ErrnoError(Errno.EIO, 'Unable to delete key ' + key + ': ' + e);\n\t\t}\n\t}\n}\n\n/**\n * Options to pass to the StorageFileSystem\n */\nexport interface WebStorageOptions {\n\t/**\n\t * The Storage to use. Defaults to globalThis.localStorage.\n\t */\n\tstorage?: Storage;\n}\n\n/**\n * A synchronous file system backed by a `Storage` (e.g. localStorage).\n */\nexport const WebStorage = {\n\tname: 'WebStorage',\n\n\toptions: {\n\t\tstorage: {\n\t\t\ttype: 'object',\n\t\t\trequired: false,\n\t\t\tdescription: 'The Storage to use. Defaults to globalThis.localStorage.',\n\t\t},\n\t},\n\n\tisAvailable(storage: Storage = globalThis.localStorage): boolean {\n\t\treturn storage instanceof globalThis.Storage;\n\t},\n\n\tcreate({ storage = globalThis.localStorage }: WebStorageOptions) {\n\t\treturn new StoreFS(new WebStorageStore(storage));\n\t},\n} as const satisfies Backend<StoreFS, WebStorageOptions>;\n"],
5
+ "mappings": "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",
6
+ "names": ["src_exports", "__export", "IndexedDB", "IndexedDBStore", "IndexedDBTransaction", "WebAccess", "WebAccessFS", "WebStorage", "WebStorageStore", "core_default", "ActionType", "Async", "AsyncIndexFS", "AsyncTransaction", "BigIntStats", "BigIntStatsFs", "Dir", "Dirent", "Errno", "ErrnoError", "Fetch", "FetchFS", "File", "FileIndex", "FileSystem", "FileType", "InMemory", "InMemoryStore", "IndexDirInode", "IndexFS", "IndexFileInode", "IndexInode", "Inode", "LockedFS", "Mutex", "NoSyncFile", "Overlay", "OverlayFS", "Port", "PortFS", "PortFile", "PreloadFile", "ReadStream", "Readonly", "SimpleAsyncStore", "SimpleTransaction", "Stats", "StatsCommon", "StatsFs", "StoreFS", "Sync", "SyncIndexFS", "SyncTransaction", "Transaction", "UnlockedOverlayFS", "WriteStream", "_toUnixTimestamp", "access", "accessSync", "appendFile", "appendFileSync", "attachFS", "checkOptions", "chmod", "chmodSync", "chown", "chownSync", "close", "closeSync", "configure", "constants", "copyFile", "copyFileSync", "cp", "cpSync", "createReadStream", "createWriteStream", "decode", "decodeDirListing", "detachFS", "encode", "encodeDirListing", "errorMessages", "exists", "existsSync", "fchmod", "fchmodSync", "fchown", "fchownSync", "fdatasync", "fdatasyncSync", "flagToMode", "flagToNumber", "flagToString", "fs", "fstat", "fstatSync", "fsync", "fsyncSync", "ftruncate", "ftruncateSync", "futimes", "futimesSync", "isAppendable", "isBackend", "isBackendConfig", "isExclusive", "isReadable", "isSynchronous", "isTruncating", "isWriteable", "lchmod", "lchmodSync", "lchown", "lchownSync", "levenshtein", "link", "linkSync", "lopenSync", "lstat", "lstatSync", "lutimes", "lutimesSync", "mkdir", "mkdirSync", "mkdirpSync", "mkdtemp", "mkdtempSync", "mount", "mountObject", "mounts", "nop", "normalizeMode", "normalizeOptions", "normalizePath", "normalizeTime", "open", "openAsBlob", "openSync", "opendir", "opendirSync", "parseFlag", "pathExistsAction", "pathNotExistsAction", "promises", "randomIno", "read", "readFile", "readFileSync", "readSync", "readdir", "readdirSync", "readlink", "readlinkSync", "readv", "readvSync", "realpath", "realpathSync", "rename", "renameSync", "resolveMountConfig", "rm", "rmSync", "rmdir", "rmdirSync", "rootCred", "rootIno", "setImmediate", "size_max", "stat", "statSync", "statfs", "statfsSync", "symlink", "symlinkSync", "truncate", "truncateSync", "umount", "unlink", "unlinkSync", "unwatchFile", "utimes", "utimesSync", "watch", "watchFile", "write", "writeFile", "writeFileSync", "writeSync", "writev", "writevSync", "normalizeString", "path", "allowAboveRoot", "res", "lastSegmentLength", "lastSlash", "dots", "char", "i", "lastSlashIndex", "__name", "normalize", "path", "isAbsolute", "trailingSeparator", "normalizeString", "__name", "join", "parts", "joined", "normalize", "__name", "dirname", "path", "hasRoot", "end", "matchedSlash", "i", "__name", "basename", "suffix", "start", "extIdx", "firstNonSlashEnd", "errnoForDOMException", "ex", "__name", "convertException", "path", "syscall", "ErrnoError", "code", "Errno", "error", "WebAccessFS", "Async", "FileSystem", "handle", "InMemory", "path", "data", "stats", "currentStats", "oldPath", "newPath", "files", "file", "join", "oldFile", "destFolder", "dirname", "writable", "basename", "ex", "convertException", "fname", "flag", "ErrnoError", "Stats", "FileType", "lastModified", "size", "Errno", "PreloadFile", "srcpath", "_keys", "key", "walked", "part", "dirHandle", "_ex", "fileHandle", "__name", "WebAccess", "options", "Errno", "errorMessages", "ErrnoError", "json", "err", "code", "path", "syscall", "errno", "message", "__name", "Transaction", "__name", "AsyncTransaction", "Transaction", "ino", "ErrnoError", "data", "__name", "wrap", "request", "resolve", "reject", "e", "convertException", "__name", "IndexedDBTransaction", "AsyncTransaction", "tx", "store", "key", "data", "createDB", "name", "indexedDB", "req", "db", "IndexedDBStore", "IndexedDB", "ErrnoError", "idbFactory", "options", "StoreFS", "WebStorageStore", "_storage", "WebStorage", "SimpleTransaction", "key", "data", "encode", "decode", "ErrnoError", "Errno", "e", "__name", "storage", "StoreFS"]
7
7
  }
package/dist/utils.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { ApiError } from '@zenfs/core';
1
+ import { ErrnoError } from '@zenfs/core';
2
2
  /**
3
3
  * @internal
4
4
  */
5
- export type ConvertException = ApiError | DOMException | Error;
5
+ export type ConvertException = ErrnoError | DOMException | Error;
6
6
  /**
7
7
  * Handles converting errors, then rethrowing them
8
8
  * @internal
9
9
  */
10
- export declare function convertException(ex: ConvertException, path?: string, syscall?: string): ApiError;
10
+ export declare function convertException(ex: ConvertException, path?: string, syscall?: string): ErrnoError;
package/dist/utils.js CHANGED
@@ -1,6 +1,6 @@
1
- import { ApiError, ErrorCode } from '@zenfs/core';
1
+ import { ErrnoError, Errno } from '@zenfs/core';
2
2
  /**
3
- * Converts a DOMException into an ErrorCode
3
+ * Converts a DOMException into an Errno
4
4
  * @see https://developer.mozilla.org/Web/API/DOMException
5
5
  */
6
6
  function errnoForDOMException(ex) {
@@ -57,11 +57,11 @@ function errnoForDOMException(ex) {
57
57
  * @internal
58
58
  */
59
59
  export function convertException(ex, path, syscall) {
60
- if (ex instanceof ApiError) {
60
+ if (ex instanceof ErrnoError) {
61
61
  return ex;
62
62
  }
63
- const code = ex instanceof DOMException ? ErrorCode[errnoForDOMException(ex)] : ErrorCode.EIO;
64
- const error = new ApiError(code, ex.message, path, syscall);
63
+ const code = ex instanceof DOMException ? Errno[errnoForDOMException(ex)] : Errno.EIO;
64
+ const error = new ErrnoError(code, ex.message, path, syscall);
65
65
  error.stack = ex.stack;
66
66
  error.cause = ex.cause;
67
67
  return error;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/dom",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "DOM backends for ZenFS",
5
5
  "main": "dist/index.js",
6
6
  "types": "src/index.ts",
@@ -46,6 +46,6 @@
46
46
  "typescript": "5.2.2"
47
47
  },
48
48
  "peerDependencies": {
49
- "@zenfs/core": "^0.9.7"
49
+ "@zenfs/core": "~0.11.1"
50
50
  }
51
51
  }
package/readme.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  - `WebStorage`: Stores files in a `Storage` object, like `localStorage` and `sessionStorage`.
11
11
  - `IndexedDB`: Stores files into an `IndexedDB` object database.
12
- - `WebAccess`: Store files using the [Web File System API](https://developer.mozilla.org/Web/API/File_System_API).
12
+ - `WebAccess`: Store files using the [File System Access API](https://developer.mozilla.org/Web/API/File_System_API).
13
13
 
14
14
  For more information, see the [API documentation](https://zen-fs.github.io/dom).
15
15
 
package/src/IndexedDB.ts CHANGED
@@ -1,5 +1,7 @@
1
- import type { AsyncStore, AsyncStoreOptions, AsyncTransaction, Backend, Ino } from '@zenfs/core';
2
- import { AsyncStoreFS } from '@zenfs/core';
1
+ import type { Store } from '@zenfs/core/backends/store/store.js';
2
+ import { AsyncTransaction } from '@zenfs/core/backends/store/store.js';
3
+ import type { Backend, Ino } from '@zenfs/core';
4
+ import { ErrnoError, StoreFS } from '@zenfs/core';
3
5
  import { convertException, type ConvertException } from './utils.js';
4
6
 
5
7
  function wrap<T>(request: IDBRequest<T>): Promise<T> {
@@ -15,22 +17,20 @@ function wrap<T>(request: IDBRequest<T>): Promise<T> {
15
17
  /**
16
18
  * @hidden
17
19
  */
18
- export class IndexedDBTransaction implements AsyncTransaction {
20
+ export class IndexedDBTransaction extends AsyncTransaction {
19
21
  constructor(
20
22
  public tx: IDBTransaction,
21
23
  public store: IDBObjectStore
22
- ) {}
24
+ ) {
25
+ super();
26
+ }
23
27
 
24
28
  public get(key: Ino): Promise<Uint8Array> {
25
- return wrap<Uint8Array>(this.store.get(key.toString()));
29
+ return wrap(this.store.get(key.toString()));
26
30
  }
27
31
 
28
- /**
29
- * @todo return false when add has a key conflict (no error)
30
- */
31
- public async put(key: Ino, data: Uint8Array, overwrite: boolean): Promise<boolean> {
32
- await wrap(this.store[overwrite ? 'put' : 'add'](data, key.toString()));
33
- return true;
32
+ public async set(key: Ino, data: Uint8Array): Promise<void> {
33
+ await wrap(this.store.put(data, key.toString()));
34
34
  }
35
35
 
36
36
  public remove(key: Ino): Promise<void> {
@@ -38,7 +38,7 @@ export class IndexedDBTransaction implements AsyncTransaction {
38
38
  }
39
39
 
40
40
  public async commit(): Promise<void> {
41
- return;
41
+ this.tx.commit();
42
42
  }
43
43
 
44
44
  public async abort(): Promise<void> {
@@ -50,46 +50,51 @@ export class IndexedDBTransaction implements AsyncTransaction {
50
50
  }
51
51
  }
52
52
 
53
- export class IndexedDBStore implements AsyncStore {
54
- public static async create(storeName: string, indexedDB: IDBFactory = globalThis.indexedDB): Promise<IndexedDBStore> {
55
- const req: IDBOpenDBRequest = indexedDB.open(storeName, 1);
53
+ async function createDB(name: string, indexedDB: IDBFactory = globalThis.indexedDB): Promise<IDBDatabase> {
54
+ const req: IDBOpenDBRequest = indexedDB.open(name);
56
55
 
57
- req.onupgradeneeded = () => {
58
- const db: IDBDatabase = req.result;
59
- // This should never happen; we're at version 1. Why does another database exist?
60
- if (db.objectStoreNames.contains(storeName)) {
61
- db.deleteObjectStore(storeName);
62
- }
63
- db.createObjectStore(storeName);
64
- };
56
+ req.onupgradeneeded = () => {
57
+ const db: IDBDatabase = req.result;
58
+ // This should never happen; we're at version 1. Why does another database exist?
59
+ if (db.objectStoreNames.contains(name)) {
60
+ db.deleteObjectStore(name);
61
+ }
62
+ db.createObjectStore(name);
63
+ };
65
64
 
66
- const result = await wrap(req);
67
- return new IndexedDBStore(result, storeName);
68
- }
65
+ const result = await wrap(req);
66
+ return result;
67
+ }
69
68
 
70
- constructor(
71
- protected db: IDBDatabase,
72
- protected storeName: string
73
- ) {}
69
+ export class IndexedDBStore implements Store {
70
+ public constructor(protected db: IDBDatabase) {}
71
+
72
+ public sync(): Promise<void> {
73
+ throw new Error('Method not implemented.');
74
+ }
74
75
 
75
76
  public get name(): string {
76
- return IndexedDB.name + ':' + this.storeName;
77
+ return IndexedDB.name + ':' + this.db.name;
77
78
  }
78
79
 
79
80
  public clear(): Promise<void> {
80
- return wrap(this.db.transaction(this.storeName, 'readwrite').objectStore(this.storeName).clear());
81
+ return wrap(this.db.transaction(this.db.name, 'readwrite').objectStore(this.db.name).clear());
81
82
  }
82
83
 
83
- public beginTransaction(): IndexedDBTransaction {
84
- const tx = this.db.transaction(this.storeName, 'readwrite');
85
- return new IndexedDBTransaction(tx, tx.objectStore(this.storeName));
84
+ public clearSync(): void {
85
+ throw ErrnoError.With('ENOSYS', undefined, 'IndexedDBStore.clearSync');
86
+ }
87
+
88
+ public transaction(): IndexedDBTransaction {
89
+ const tx = this.db.transaction(this.db.name, 'readwrite');
90
+ return new IndexedDBTransaction(tx, tx.objectStore(this.db.name));
86
91
  }
87
92
  }
88
93
 
89
94
  /**
90
95
  * Configuration options for the IndexedDB file system.
91
96
  */
92
- export interface IndexedDBOptions extends Omit<AsyncStoreOptions, 'store'> {
97
+ export interface IndexedDBOptions {
93
98
  /**
94
99
  * The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.
95
100
  */
@@ -114,11 +119,6 @@ export const IndexedDB = {
114
119
  required: false,
115
120
  description: 'The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name.',
116
121
  },
117
- cacheSize: {
118
- type: 'number',
119
- required: false,
120
- description: 'The size of the inode cache. Defaults to 100. A size of 0 or below disables caching.',
121
- },
122
122
  idbFactory: {
123
123
  type: 'object',
124
124
  required: false,
@@ -141,9 +141,10 @@ export const IndexedDB = {
141
141
  }
142
142
  },
143
143
 
144
- create(options: IndexedDBOptions) {
145
- const store = IndexedDBStore.create(options.storeName || 'zenfs', options.idbFactory);
146
- const fs = new AsyncStoreFS({ ...options, store });
144
+ async create(options: IndexedDBOptions) {
145
+ const db = await createDB(options.storeName || 'zenfs', options.idbFactory);
146
+ const store = new IndexedDBStore(db);
147
+ const fs = new StoreFS(store);
147
148
  return fs;
148
149
  },
149
- } as const satisfies Backend;
150
+ } as const satisfies Backend<StoreFS, IndexedDBOptions>;
package/src/Storage.ts CHANGED
@@ -1,10 +1,10 @@
1
- import type { Backend, Ino, SimpleSyncStore, SyncStore } from '@zenfs/core';
2
- import { ApiError, ErrorCode, SimpleSyncTransaction, SyncStoreFS, decode, encode } from '@zenfs/core';
1
+ import type { Backend, Ino, SimpleSyncStore, Store } from '@zenfs/core';
2
+ import { ErrnoError, Errno, SimpleTransaction, StoreFS, decode, encode } from '@zenfs/core';
3
3
 
4
4
  /**
5
5
  * A synchronous key-value store backed by Storage.
6
6
  */
7
- export class WebStorageStore implements SyncStore, SimpleSyncStore {
7
+ export class WebStorageStore implements Store, SimpleSyncStore {
8
8
  public get name(): string {
9
9
  return WebStorage.name;
10
10
  }
@@ -15,9 +15,15 @@ export class WebStorageStore implements SyncStore, SimpleSyncStore {
15
15
  this._storage.clear();
16
16
  }
17
17
 
18
- public beginTransaction(): SimpleSyncTransaction {
18
+ public clearSync(): void {
19
+ this._storage.clear();
20
+ }
21
+
22
+ public async sync(): Promise<void> {}
23
+
24
+ public transaction(): SimpleTransaction {
19
25
  // No need to differentiate.
20
- return new SimpleSyncTransaction(this);
26
+ return new SimpleTransaction(this);
21
27
  }
22
28
 
23
29
  public get(key: Ino): Uint8Array | undefined {
@@ -29,24 +35,19 @@ export class WebStorageStore implements SyncStore, SimpleSyncStore {
29
35
  return encode(data);
30
36
  }
31
37
 
32
- public put(key: Ino, data: Uint8Array, overwrite: boolean): boolean {
38
+ public set(key: Ino, data: Uint8Array): void {
33
39
  try {
34
- if (!overwrite && this._storage.getItem(key.toString()) !== null) {
35
- // Don't want to overwrite the key!
36
- return false;
37
- }
38
40
  this._storage.setItem(key.toString(), decode(data));
39
- return true;
40
41
  } catch (e) {
41
- throw new ApiError(ErrorCode.ENOSPC, 'Storage is full.');
42
+ throw new ErrnoError(Errno.ENOSPC, 'Storage is full.');
42
43
  }
43
44
  }
44
45
 
45
- public remove(key: Ino): void {
46
+ public delete(key: Ino): void {
46
47
  try {
47
48
  this._storage.removeItem(key.toString());
48
49
  } catch (e) {
49
- throw new ApiError(ErrorCode.EIO, 'Unable to delete key ' + key + ': ' + e);
50
+ throw new ErrnoError(Errno.EIO, 'Unable to delete key ' + key + ': ' + e);
50
51
  }
51
52
  }
52
53
  }
@@ -80,6 +81,6 @@ export const WebStorage = {
80
81
  },
81
82
 
82
83
  create({ storage = globalThis.localStorage }: WebStorageOptions) {
83
- return new SyncStoreFS({ store: new WebStorageStore(storage) });
84
+ return new StoreFS(new WebStorageStore(storage));
84
85
  },
85
- } as const satisfies Backend;
86
+ } as const satisfies Backend<StoreFS, WebStorageOptions>;
package/src/access.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Backend, FileSystemMetadata } from '@zenfs/core';
2
- import { ApiError, Async, ErrorCode, FileSystem, FileType, InMemory, PreloadFile, Stats } from '@zenfs/core';
2
+ import { ErrnoError, Async, Errno, FileSystem, FileType, InMemory, PreloadFile, Stats } from '@zenfs/core';
3
3
  import { basename, dirname, join } from '@zenfs/core/emulation/path.js';
4
4
  import { convertException, type ConvertException } from './utils.js';
5
5
 
@@ -37,10 +37,10 @@ export class WebAccessFS extends Async(FileSystem) {
37
37
  };
38
38
  }
39
39
 
40
- public async sync(p: string, data: Uint8Array, stats: Stats): Promise<void> {
41
- const currentStats = await this.stat(p);
40
+ public async sync(path: string, data: Uint8Array, stats: Stats): Promise<void> {
41
+ const currentStats = await this.stat(path);
42
42
  if (stats.mtime !== currentStats!.mtime) {
43
- await this.writeFile(p, data);
43
+ await this.writeFile(path, data);
44
44
  }
45
45
  }
46
46
 
@@ -99,7 +99,7 @@ export class WebAccessFS extends Async(FileSystem) {
99
99
  public async stat(path: string): Promise<Stats> {
100
100
  const handle = await this.getHandle(path);
101
101
  if (!handle) {
102
- throw ApiError.With('ENOENT', path, 'stat');
102
+ throw ErrnoError.With('ENOENT', path, 'stat');
103
103
  }
104
104
  if (handle instanceof FileSystemDirectoryHandle) {
105
105
  return new Stats({ mode: 0o777 | FileType.DIRECTORY, size: 4096 });
@@ -108,13 +108,13 @@ export class WebAccessFS extends Async(FileSystem) {
108
108
  const { lastModified, size } = await handle.getFile();
109
109
  return new Stats({ mode: 0o777 | FileType.FILE, size, mtimeMs: lastModified });
110
110
  }
111
- throw new ApiError(ErrorCode.EBADE, 'Handle is not a directory or file', path, 'stat');
111
+ throw new ErrnoError(Errno.EBADE, 'Handle is not a directory or file', path, 'stat');
112
112
  }
113
113
 
114
114
  public async openFile(path: string, flag: string): Promise<PreloadFile<this>> {
115
115
  const handle = await this.getHandle(path);
116
116
  if (!(handle instanceof FileSystemFileHandle)) {
117
- throw ApiError.With('EISDIR', path, 'openFile');
117
+ throw ErrnoError.With('EISDIR', path, 'openFile');
118
118
  }
119
119
  try {
120
120
  const file = await handle.getFile();
@@ -138,7 +138,7 @@ export class WebAccessFS extends Async(FileSystem) {
138
138
  }
139
139
 
140
140
  public async link(srcpath: string): Promise<void> {
141
- throw ApiError.With('ENOSYS', srcpath, 'WebAccessFS.link');
141
+ throw ErrnoError.With('ENOSYS', srcpath, 'WebAccessFS.link');
142
142
  }
143
143
 
144
144
  public async rmdir(path: string): Promise<void> {
@@ -148,12 +148,12 @@ export class WebAccessFS extends Async(FileSystem) {
148
148
  public async mkdir(path: string): Promise<void> {
149
149
  const existingHandle = await this.getHandle(path);
150
150
  if (existingHandle) {
151
- throw ApiError.With('EEXIST', path, 'mkdir');
151
+ throw ErrnoError.With('EEXIST', path, 'mkdir');
152
152
  }
153
153
 
154
154
  const handle = await this.getHandle(dirname(path));
155
155
  if (!(handle instanceof FileSystemDirectoryHandle)) {
156
- throw ApiError.With('ENOTDIR', path, 'mkdir');
156
+ throw ErrnoError.With('ENOTDIR', path, 'mkdir');
157
157
  }
158
158
  await handle.getDirectoryHandle(basename(path), { create: true });
159
159
  }
@@ -161,7 +161,7 @@ export class WebAccessFS extends Async(FileSystem) {
161
161
  public async readdir(path: string): Promise<string[]> {
162
162
  const handle = await this.getHandle(path);
163
163
  if (!(handle instanceof FileSystemDirectoryHandle)) {
164
- throw ApiError.With('ENOTDIR', path, 'readdir');
164
+ throw ErrnoError.With('ENOTDIR', path, 'readdir');
165
165
  }
166
166
  const _keys: string[] = [];
167
167
  for await (const key of handle.keys()) {
@@ -180,7 +180,7 @@ export class WebAccessFS extends Async(FileSystem) {
180
180
  for (const part of path.split('/').slice(1)) {
181
181
  const handle = this._handles.get(walked);
182
182
  if (!(handle instanceof FileSystemDirectoryHandle)) {
183
- throw ApiError.With('ENOTDIR', walked, 'getHandle');
183
+ throw ErrnoError.With('ENOTDIR', walked, 'getHandle');
184
184
  }
185
185
  walked = join(walked, part);
186
186
 
@@ -199,7 +199,7 @@ export class WebAccessFS extends Async(FileSystem) {
199
199
  }
200
200
 
201
201
  if (ex.name === 'TypeError') {
202
- throw new ApiError(ErrorCode.ENOENT, ex.message, walked, 'getHandle');
202
+ throw new ErrnoError(Errno.ENOENT, ex.message, walked, 'getHandle');
203
203
  }
204
204
 
205
205
  convertException(ex, walked, 'getHandle');
@@ -228,4 +228,4 @@ export const WebAccess = {
228
228
  create(options: WebAccessOptions) {
229
229
  return new WebAccessFS(options);
230
230
  },
231
- } as const satisfies Backend;
231
+ } as const satisfies Backend<WebAccessFS, WebAccessOptions>;
package/src/utils.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { ApiError, ErrorCode } from '@zenfs/core';
1
+ import { ErrnoError, Errno } from '@zenfs/core';
2
2
 
3
3
  /**
4
- * Converts a DOMException into an ErrorCode
4
+ * Converts a DOMException into an Errno
5
5
  * @see https://developer.mozilla.org/Web/API/DOMException
6
6
  */
7
- function errnoForDOMException(ex: DOMException): keyof typeof ErrorCode {
7
+ function errnoForDOMException(ex: DOMException): keyof typeof Errno {
8
8
  switch (ex.name) {
9
9
  case 'IndexSizeError':
10
10
  case 'HierarchyRequestError':
@@ -57,19 +57,19 @@ function errnoForDOMException(ex: DOMException): keyof typeof ErrorCode {
57
57
  /**
58
58
  * @internal
59
59
  */
60
- export type ConvertException = ApiError | DOMException | Error;
60
+ export type ConvertException = ErrnoError | DOMException | Error;
61
61
 
62
62
  /**
63
63
  * Handles converting errors, then rethrowing them
64
64
  * @internal
65
65
  */
66
- export function convertException(ex: ConvertException, path?: string, syscall?: string): ApiError {
67
- if (ex instanceof ApiError) {
66
+ export function convertException(ex: ConvertException, path?: string, syscall?: string): ErrnoError {
67
+ if (ex instanceof ErrnoError) {
68
68
  return ex;
69
69
  }
70
70
 
71
- const code = ex instanceof DOMException ? ErrorCode[errnoForDOMException(ex)] : ErrorCode.EIO;
72
- const error = new ApiError(code, ex.message, path, syscall);
71
+ const code = ex instanceof DOMException ? Errno[errnoForDOMException(ex)] : Errno.EIO;
72
+ const error = new ErrnoError(code, ex.message, path, syscall);
73
73
  error.stack = ex.stack!;
74
74
  error.cause = ex.cause;
75
75
  return error;