@zenfs/dom 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/access.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { CreationOptions, FileSystem, InodeLike } from '@zenfs/core';
2
- import { IndexFS } from '@zenfs/core';
2
+ import { IndexFS, Inode } from '@zenfs/core';
3
3
  export interface WebAccessOptions {
4
4
  handle: FileSystemDirectoryHandle;
5
5
  metadata?: string;
@@ -39,6 +39,7 @@ export declare class WebAccessFS extends WebAccessFS_base {
39
39
  */
40
40
  _sync: FileSystem;
41
41
  constructor(root: FileSystemDirectoryHandle, disableHandleCache?: boolean);
42
+ stat(path: string): Promise<Inode>;
42
43
  protected remove(path: string): Promise<void>;
43
44
  protected removeSync(): void;
44
45
  read(path: string, buffer: Uint8Array, offset: number, end: number): Promise<void>;
package/dist/access.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Async, constants, IndexFS, InMemory, Inode } from '@zenfs/core';
2
2
  import { basename, dirname, join } from '@zenfs/core/path.js';
3
- import { S_IFDIR, S_IFMT } from '@zenfs/core/vfs/constants.js';
4
3
  import { log, withErrno } from 'kerium';
5
4
  import { alert } from 'kerium/log';
6
5
  import { _throw } from 'utilium';
@@ -79,6 +78,35 @@ export class WebAccessFS extends Async(IndexFS) {
79
78
  if (disableHandleCache)
80
79
  this.attributes.set('no_handle_cache', true);
81
80
  }
81
+ async stat(path) {
82
+ try {
83
+ return await super.stat(path);
84
+ }
85
+ catch (ex) {
86
+ if (ex.code != 'ENOENT')
87
+ throw ex;
88
+ // This handle must have been created after initialization
89
+ // Try to add a new inode for the handle to the index
90
+ const handle = await this.get(null, path);
91
+ const inode = new Inode();
92
+ if (isKind(handle, 'file')) {
93
+ const file = await handle.getFile();
94
+ inode.update({
95
+ mode: 0o644 | constants.S_IFREG,
96
+ size: file.size,
97
+ mtimeMs: file.lastModified,
98
+ });
99
+ }
100
+ else {
101
+ inode.update({
102
+ mode: constants.S_IFDIR | 0o777,
103
+ size: 0,
104
+ });
105
+ }
106
+ this.index.set(path, inode);
107
+ return inode;
108
+ }
109
+ }
82
110
  async remove(path) {
83
111
  const handle = await this.get('directory', dirname(path));
84
112
  await handle.removeEntry(basename(path), { recursive: true }).catch(ex => _throw(convertException(ex, path)));
@@ -93,7 +121,11 @@ export class WebAccessFS extends Async(IndexFS) {
93
121
  const file = await handle.getFile();
94
122
  const data = await file.arrayBuffer();
95
123
  if (data.byteLength < end - offset)
96
- throw alert(withErrno('EIO', `Unexpected mismatch in file data size. This should not happen.\n\t\tTried to read ${end - offset} bytes but the file is ${data.byteLength} bytes.`));
124
+ throw alert(withErrno('EIO', [
125
+ 'Unexpected mismatch in file data size. This should not happen.',
126
+ `tried to read ${end - offset} bytes but the file is ${data.byteLength} bytes.`,
127
+ `path: ${path}`,
128
+ ].join('\n' + ' '.repeat(24))));
97
129
  buffer.set(new Uint8Array(data, offset, end - offset));
98
130
  }
99
131
  async write(path, buffer, offset) {
@@ -105,7 +137,7 @@ export class WebAccessFS extends Async(IndexFS) {
105
137
  const inode = this.index.get(path);
106
138
  if (!inode)
107
139
  throw withErrno('ENOENT');
108
- const isDir = (inode.mode & S_IFMT) == S_IFDIR;
140
+ const isDir = (inode.mode & constants.S_IFMT) == constants.S_IFDIR;
109
141
  let handle;
110
142
  try {
111
143
  handle = await this.get(isDir ? 'directory' : 'file', path);
@@ -151,13 +183,12 @@ export class WebAccessFS extends Async(IndexFS) {
151
183
  return inode;
152
184
  }
153
185
  async get(kind = null, path) {
154
- if (!this.disableHandleCache) {
155
- const handle = this._handles.get(path);
156
- if (!handle)
157
- throw withErrno('ENOENT');
158
- if (kind && !isKind(handle, kind))
186
+ const maybeHandle = this._handles.get(path);
187
+ if (!this.disableHandleCache && maybeHandle) {
188
+ if (kind && !isKind(maybeHandle, kind))
159
189
  throw withErrno(kind == 'directory' ? 'ENOTDIR' : 'EISDIR');
160
- return handle;
190
+ return maybeHandle;
191
+ // Otherwise, fall through to the slow path
161
192
  }
162
193
  if (path == '/')
163
194
  return this.root;
@@ -168,6 +199,8 @@ export class WebAccessFS extends Async(IndexFS) {
168
199
  }
169
200
  try {
170
201
  const handle = await dir[kind == 'file' ? 'getFileHandle' : 'getDirectoryHandle'](parts.at(-1));
202
+ if (!this.disableHandleCache)
203
+ this._handles.set(path, handle);
171
204
  return handle;
172
205
  }
173
206
  catch (ex) {
@@ -186,7 +219,7 @@ const _WebAccess = {
186
219
  disableHandleCache: { type: 'boolean', required: false },
187
220
  },
188
221
  async create(options) {
189
- const fs = new WebAccessFS(options.handle);
222
+ const fs = new WebAccessFS(options.handle, options.disableHandleCache);
190
223
  await fs._loadMetadata(options.metadata);
191
224
  return fs;
192
225
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/dom",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "DOM backends for ZenFS",
5
5
  "funding": {
6
6
  "type": "individual",