@zenfs/core 1.4.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26,17 +26,22 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
26
26
  env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
27
  env.hasError = true;
28
28
  }
29
+ var r, s = 0;
29
30
  function next() {
30
- while (env.stack.length) {
31
- var rec = env.stack.pop();
31
+ while (r = env.stack.pop()) {
32
32
  try {
33
- var result = rec.dispose && rec.dispose.call(rec.value);
34
- if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
35
39
  }
36
40
  catch (e) {
37
41
  fail(e);
38
42
  }
39
43
  }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
40
45
  if (env.hasError) throw env.error;
41
46
  }
42
47
  return next();
@@ -26,17 +26,22 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
26
26
  env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
27
  env.hasError = true;
28
28
  }
29
+ var r, s = 0;
29
30
  function next() {
30
- while (env.stack.length) {
31
- var rec = env.stack.pop();
31
+ while (r = env.stack.pop()) {
32
32
  try {
33
- var result = rec.dispose && rec.dispose.call(rec.value);
34
- if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
35
39
  }
36
40
  catch (e) {
37
41
  fail(e);
38
42
  }
39
43
  }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
40
45
  if (env.hasError) throw env.error;
41
46
  }
42
47
  return next();
package/dist/context.d.ts CHANGED
@@ -1,8 +1,5 @@
1
- import { type ExtractProperties } from 'utilium';
2
1
  import { type CredentialInit, type Credentials } from './credentials.js';
3
2
  import * as fs from './emulation/index.js';
4
- type Fn_FS = Omit<ExtractProperties<typeof fs, (...args: any[]) => any>, 'mountObject'>;
5
- type Fn_Promises = ExtractProperties<typeof fs.promises, (...args: any[]) => any>;
6
3
  /**
7
4
  * Represents some context used for FS operations
8
5
  * @experimental
@@ -20,8 +17,8 @@ export type V_Context = void | (Partial<FSContext> & object);
20
17
  * Allows you to restrict operations to a specific root path and set of credentials.
21
18
  * @experimental
22
19
  */
23
- export interface BoundContext extends Fn_FS, FSContext {
24
- promises: Fn_Promises;
20
+ export interface BoundContext extends FSContext {
21
+ fs: typeof fs;
25
22
  }
26
23
  /**
27
24
  * Allows you to restrict operations to a specific root path and set of credentials.
@@ -29,4 +26,3 @@ export interface BoundContext extends Fn_FS, FSContext {
29
26
  * @experimental
30
27
  */
31
28
  export declare function bindContext(root: string, credentials?: CredentialInit): BoundContext;
32
- export {};
package/dist/context.js CHANGED
@@ -19,5 +19,5 @@ export function bindContext(root, credentials = structuredClone(defaultCredentia
19
19
  };
20
20
  const fn_fs = _bindFunctions(fs, ctx);
21
21
  const fn_promises = _bindFunctions(fs.promises, ctx);
22
- return { ...ctx, ...fn_fs, promises: fn_promises };
22
+ return { ...ctx, fs: { ...fs, ...fn_fs, promises: { ...fs.promises, ...fn_promises } } };
23
23
  }
package/dist/devices.js CHANGED
@@ -29,17 +29,22 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
29
29
  env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
30
30
  env.hasError = true;
31
31
  }
32
+ var r, s = 0;
32
33
  function next() {
33
- while (env.stack.length) {
34
- var rec = env.stack.pop();
34
+ while (r = env.stack.pop()) {
35
35
  try {
36
- var result = rec.dispose && rec.dispose.call(rec.value);
37
- if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
36
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
37
+ if (r.dispose) {
38
+ var result = r.dispose.call(r.value);
39
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
40
+ }
41
+ else s |= 1;
38
42
  }
39
43
  catch (e) {
40
44
  fail(e);
41
45
  }
42
46
  }
47
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
43
48
  if (env.hasError) throw env.error;
44
49
  }
45
50
  return next();
@@ -26,17 +26,22 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
26
26
  env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
27
  env.hasError = true;
28
28
  }
29
+ var r, s = 0;
29
30
  function next() {
30
- while (env.stack.length) {
31
- var rec = env.stack.pop();
31
+ while (r = env.stack.pop()) {
32
32
  try {
33
- var result = rec.dispose && rec.dispose.call(rec.value);
34
- if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
35
39
  }
36
40
  catch (e) {
37
41
  fail(e);
38
42
  }
39
43
  }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
40
45
  if (env.hasError) throw env.error;
41
46
  }
42
47
  return next();
@@ -531,9 +536,9 @@ export async function writeFile(path, data, _options) {
531
536
  try {
532
537
  const options = normalizeOptions(_options, 'utf8', 'w+', 0o644);
533
538
  const handle = __addDisposableResource(env_3, path instanceof FileHandle ? path : await open.call(this, path.toString(), options.flag, options.mode), true);
534
- const _data = typeof data == 'string' ? data : data;
539
+ const _data = typeof data == 'string' ? data : data instanceof DataView ? new Uint8Array(data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength)) : data;
535
540
  if (typeof _data != 'string' && !(_data instanceof Uint8Array)) {
536
- throw new ErrnoError(Errno.EINVAL, 'Iterables and streams not supported', handle.file.path, 'writeFile');
541
+ throw new ErrnoError(Errno.EINVAL, 'The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received ' + typeof data, handle.file.path, 'writeFile');
537
542
  }
538
543
  await handle.writeFile(_data, options);
539
544
  }
@@ -75,7 +75,7 @@ export function resolveMount(path, ctx) {
75
75
  const sortedMounts = [...mounts].sort((a, b) => (a[0].length > b[0].length ? -1 : 1)); // descending order of the string length
76
76
  for (const [mountPoint, fs] of sortedMounts) {
77
77
  // We know path is normalized, so it would be a substring of the mount point.
78
- if (mountPoint.length <= path.length && path.startsWith(mountPoint)) {
78
+ if (_isParentOf(mountPoint, path)) {
79
79
  path = path.slice(mountPoint.length > 1 ? mountPoint.length : 0); // Resolve the path relative to the mount point
80
80
  if (path === '') {
81
81
  path = root;
@@ -160,3 +160,13 @@ export function chroot(path, inPlace) {
160
160
  }
161
161
  return bindContext(join(this?.root || '/', path), creds);
162
162
  }
163
+ /**
164
+ * @internal @hidden
165
+ */
166
+ function _isParentOf(parent, child) {
167
+ if (parent === '/' || parent === child)
168
+ return true;
169
+ if (!parent.endsWith('/'))
170
+ parent += '/';
171
+ return child.startsWith(parent);
172
+ }
@@ -26,17 +26,22 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
26
26
  env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
27
  env.hasError = true;
28
28
  }
29
+ var r, s = 0;
29
30
  function next() {
30
- while (env.stack.length) {
31
- var rec = env.stack.pop();
31
+ while (r = env.stack.pop()) {
32
32
  try {
33
- var result = rec.dispose && rec.dispose.call(rec.value);
34
- if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
35
39
  }
36
40
  catch (e) {
37
41
  fail(e);
38
42
  }
39
43
  }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
40
45
  if (env.hasError) throw env.error;
41
46
  }
42
47
  return next();
package/dist/file.d.ts CHANGED
@@ -2,28 +2,6 @@ import type { FileReadResult } from 'node:fs/promises';
2
2
  import type { FileSystem } from './filesystem.js';
3
3
  import './polyfills.js';
4
4
  import { Stats } from './stats.js';
5
- /**
6
- Typescript does not include a type declaration for resizable array buffers.
7
- It has been standardized into ECMAScript though
8
- @todo Remove this if TS adds them to lib declarations
9
- */
10
- declare global {
11
- interface ArrayBuffer {
12
- readonly resizable: boolean;
13
- readonly maxByteLength?: number;
14
- resize(newLength: number): void;
15
- }
16
- interface SharedArrayBuffer {
17
- readonly resizable: boolean;
18
- readonly maxByteLength?: number;
19
- resize(newLength: number): void;
20
- }
21
- interface ArrayBufferConstructor {
22
- new (byteLength: number, options: {
23
- maxByteLength?: number;
24
- }): ArrayBuffer;
25
- }
26
- }
27
5
  export declare function parseFlag(flag: string | number): string;
28
6
  export declare function flagToString(flag: number): string;
29
7
  export declare function flagToNumber(flag: string): number;
@@ -43,14 +21,14 @@ export declare abstract class File<FS extends FileSystem = FileSystem> {
43
21
  * @internal
44
22
  * The file system that created the file
45
23
  */
46
- fs: FileSystem;
24
+ fs: FS;
47
25
  readonly path: string;
48
26
  constructor(
49
27
  /**
50
28
  * @internal
51
29
  * The file system that created the file
52
30
  */
53
- fs: FileSystem, path: string);
31
+ fs: FS, path: string);
54
32
  /**
55
33
  * Get the current file position.
56
34
  */
package/dist/file.js CHANGED
@@ -304,8 +304,12 @@ export class PreloadFile extends File {
304
304
  if (end > this.stats.size) {
305
305
  this.stats.size = end;
306
306
  if (end > this._buffer.byteLength) {
307
- if (this._buffer.buffer.resizable && this._buffer.buffer.maxByteLength <= end) {
308
- this._buffer.buffer.resize(end);
307
+ const { buffer } = this._buffer;
308
+ if ('resizable' in buffer && buffer.resizable && buffer.maxByteLength <= end) {
309
+ buffer.resize(end);
310
+ }
311
+ else if ('growable' in buffer && buffer.growable && buffer.maxByteLength <= end) {
312
+ buffer.grow(end);
309
313
  }
310
314
  else if (config.unsafeBufferReplace) {
311
315
  this._buffer = slice;
@@ -26,17 +26,22 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
26
26
  env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
27
  env.hasError = true;
28
28
  }
29
+ var r, s = 0;
29
30
  function next() {
30
- while (env.stack.length) {
31
- var rec = env.stack.pop();
31
+ while (r = env.stack.pop()) {
32
32
  try {
33
- var result = rec.dispose && rec.dispose.call(rec.value);
34
- if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
35
39
  }
36
40
  catch (e) {
37
41
  fail(e);
38
42
  }
39
43
  }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
40
45
  if (env.hasError) throw env.error;
41
46
  }
42
47
  return next();
@@ -26,17 +26,22 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
26
26
  env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
27
  env.hasError = true;
28
28
  }
29
+ var r, s = 0;
29
30
  function next() {
30
- while (env.stack.length) {
31
- var rec = env.stack.pop();
31
+ while (r = env.stack.pop()) {
32
32
  try {
33
- var result = rec.dispose && rec.dispose.call(rec.value);
34
- if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
35
39
  }
36
40
  catch (e) {
37
41
  fail(e);
38
42
  }
39
43
  }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
40
45
  if (env.hasError) throw env.error;
41
46
  }
42
47
  return next();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/core",
3
- "version": "1.4.2",
3
+ "version": "1.5.0",
4
4
  "description": "A filesystem, anywhere",
5
5
  "funding": {
6
6
  "type": "individual",
@@ -21,7 +21,6 @@
21
21
  "dist",
22
22
  "tests",
23
23
  "license.md",
24
- "tsconfig.json",
25
24
  "eslint.shared.js"
26
25
  ],
27
26
  "type": "module",
@@ -72,7 +71,7 @@
72
71
  "buffer": "^6.0.3",
73
72
  "eventemitter3": "^5.0.1",
74
73
  "readable-stream": "^4.5.2",
75
- "utilium": "^1.0.0"
74
+ "utilium": "^1.1.1"
76
75
  },
77
76
  "optionalDependencies": {
78
77
  "minimatch": "^9.0.3"
@@ -81,14 +80,13 @@
81
80
  "@eslint/js": "^9.8.0",
82
81
  "@types/eslint__js": "^8.42.3",
83
82
  "c8": "^10.1.2",
84
- "eslint": "^9.8.0",
83
+ "eslint": "^9.15.0",
85
84
  "globals": "^15.9.0",
86
85
  "lint-staged": "^15.2.7",
87
86
  "prettier": "^3.2.5",
88
87
  "tsx": "^4.19.1",
89
- "typedoc": "^0.26.10",
90
- "typedoc-plugin-remove-references": "^0.0.6",
91
- "typescript": "^5.5.0",
92
- "typescript-eslint": "^8.0.0"
88
+ "typedoc": "^0.27.1",
89
+ "typescript": "^5.7.2",
90
+ "typescript-eslint": "^8.16.0"
93
91
  }
94
92
  }
package/readme.md CHANGED
@@ -162,7 +162,7 @@ await configure({
162
162
 
163
163
  fs.writeFileSync('/dev/null', 'Some data to be discarded');
164
164
 
165
- const randomData = new Unit8Array(100);
165
+ const randomData = new Uint8Array(100);
166
166
 
167
167
  const random = fs.openSync('/dev/random', 'r');
168
168
  fs.readSync(random, randomData);
@@ -4,7 +4,7 @@ import { bindContext } from '../../dist/context.js';
4
4
  import * as fs from '../../dist/emulation/index.js';
5
5
 
6
6
  fs.mkdirSync('/new_root');
7
- const c_fs = bindContext('/new_root');
7
+ const { fs: c_fs } = bindContext('/new_root');
8
8
 
9
9
  suite('Context', () => {
10
10
  test('create a file', () => {
@@ -4,6 +4,6 @@ import { copy, data } from '../setup.js';
4
4
 
5
5
  _fs.mkdirSync('/new_root');
6
6
 
7
- export const fs = bindContext('/new_root');
7
+ export const { fs } = bindContext('/new_root');
8
8
 
9
9
  copy(data, fs);
package/tests/setup.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { join, relative } from 'node:path';
2
2
  import { statSync, readFileSync, readdirSync, existsSync, mkdirSync } from 'node:fs';
3
3
  import { fs as _fs } from '../dist/index.js';
4
- import type { BoundContext } from '../dist/context.js';
5
4
 
6
5
  export const data = join(import.meta.dirname, 'data');
7
6
 
@@ -11,7 +10,7 @@ if (!existsSync(tmp)) {
11
10
  mkdirSync(tmp);
12
11
  }
13
12
 
14
- export function copy(_path: string, fs: typeof _fs | BoundContext = _fs) {
13
+ export function copy(_path: string, fs: typeof _fs = _fs) {
15
14
  const path = relative(data, _path) || '/';
16
15
  const stats = statSync(_path);
17
16
 
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "module": "NodeNext",
4
- "target": "ES2020",
5
- "outDir": "dist",
6
- "lib": ["ESNext", "ESNext.Disposable"],
7
- "moduleResolution": "NodeNext",
8
- "declaration": true,
9
- "strict": true
10
- },
11
- "include": ["src/**/*.ts"],
12
- "exclude": ["node_modules"],
13
- "typedocOptions": {
14
- "entryPoints": ["./src/index.ts"],
15
- "out": "docs",
16
- "name": "ZenFS",
17
- "plugin": ["typedoc-plugin-remove-references"]
18
- }
19
- }