@zenfs/core 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/backends/backend.js +6 -5
  2. package/dist/backends/cow.d.ts +2 -2
  3. package/dist/backends/cow.js +39 -58
  4. package/dist/backends/fetch.js +27 -29
  5. package/dist/backends/passthrough.d.ts +2 -3
  6. package/dist/backends/passthrough.js +84 -199
  7. package/dist/backends/port.d.ts +16 -3
  8. package/dist/backends/port.js +61 -30
  9. package/dist/backends/single_buffer.d.ts +52 -46
  10. package/dist/backends/single_buffer.js +462 -219
  11. package/dist/backends/store/fs.d.ts +16 -10
  12. package/dist/backends/store/fs.js +227 -242
  13. package/dist/backends/store/store.d.ts +3 -3
  14. package/dist/backends/store/store.js +11 -10
  15. package/dist/config.d.ts +2 -2
  16. package/dist/config.js +10 -11
  17. package/dist/internal/devices.d.ts +2 -2
  18. package/dist/internal/devices.js +39 -49
  19. package/dist/internal/error.d.ts +9 -204
  20. package/dist/internal/error.js +19 -288
  21. package/dist/internal/file_index.d.ts +1 -1
  22. package/dist/internal/file_index.js +9 -9
  23. package/dist/internal/filesystem.d.ts +23 -8
  24. package/dist/internal/index.d.ts +1 -1
  25. package/dist/internal/index.js +1 -1
  26. package/dist/internal/index_fs.d.ts +2 -2
  27. package/dist/internal/index_fs.js +19 -19
  28. package/dist/internal/inode.d.ts +81 -103
  29. package/dist/internal/inode.js +336 -195
  30. package/dist/mixins/async.js +32 -28
  31. package/dist/mixins/mutexed.d.ts +4 -4
  32. package/dist/mixins/mutexed.js +39 -39
  33. package/dist/mixins/readonly.d.ts +2 -2
  34. package/dist/mixins/readonly.js +20 -20
  35. package/dist/mixins/sync.js +2 -2
  36. package/dist/polyfills.js +1 -1
  37. package/dist/readline.js +1 -1
  38. package/dist/utils.d.ts +8 -5
  39. package/dist/utils.js +14 -17
  40. package/dist/vfs/acl.d.ts +8 -8
  41. package/dist/vfs/acl.js +66 -47
  42. package/dist/vfs/async.d.ts +2 -2
  43. package/dist/vfs/async.js +6 -8
  44. package/dist/vfs/dir.d.ts +1 -1
  45. package/dist/vfs/dir.js +3 -4
  46. package/dist/vfs/file.js +33 -24
  47. package/dist/vfs/flags.js +3 -3
  48. package/dist/vfs/ioctl.d.ts +8 -7
  49. package/dist/vfs/ioctl.js +132 -27
  50. package/dist/vfs/promises.d.ts +3 -3
  51. package/dist/vfs/promises.js +200 -235
  52. package/dist/vfs/shared.d.ts +1 -12
  53. package/dist/vfs/shared.js +7 -35
  54. package/dist/vfs/streams.js +9 -9
  55. package/dist/vfs/sync.d.ts +1 -2
  56. package/dist/vfs/sync.js +158 -170
  57. package/dist/vfs/watchers.js +8 -8
  58. package/dist/vfs/xattr.js +89 -106
  59. package/package.json +4 -2
  60. package/scripts/test.js +2 -2
  61. package/tests/assignment.ts +1 -1
  62. package/tests/backend/port.test.ts +4 -4
  63. package/tests/backend/single-buffer.test.ts +39 -10
  64. package/tests/backend/single-buffer.worker.js +30 -0
  65. package/tests/common/context.test.ts +2 -2
  66. package/tests/common/mutex.test.ts +9 -9
  67. package/tests/fetch/fetch.ts +1 -1
  68. package/tests/fs/append.test.ts +4 -4
  69. package/tests/fs/directory.test.ts +25 -25
  70. package/tests/fs/errors.test.ts +15 -19
  71. package/tests/fs/links.test.ts +3 -2
  72. package/tests/fs/open.test.ts +4 -21
  73. package/tests/fs/permissions.test.ts +8 -13
  74. package/tests/fs/read.test.ts +10 -9
  75. package/tests/fs/readFile.test.ts +8 -24
  76. package/tests/fs/rename.test.ts +4 -9
  77. package/tests/fs/stat.test.ts +2 -2
  78. package/tests/fs/times.test.ts +6 -6
  79. package/tests/fs/truncate.test.ts +8 -36
  80. package/tests/fs/watch.test.ts +10 -10
  81. package/tests/fs/write.test.ts +77 -13
  82. package/tests/fs/xattr.test.ts +7 -7
  83. package/tests/logs.js +2 -2
  84. package/tests/setup/port.ts +6 -0
  85. package/dist/internal/log.d.ts +0 -139
  86. package/dist/internal/log.js +0 -219
  87. package/tests/fs/writeFile.test.ts +0 -70
package/dist/utils.js CHANGED
@@ -1,5 +1,5 @@
1
+ import { withErrno } from 'kerium';
1
2
  import { decodeUTF8, encodeUTF8 } from 'utilium';
2
- import { Errno, ErrnoError } from './internal/error.js';
3
3
  import { resolve } from './path.js';
4
4
  /**
5
5
  * Decodes a directory listing
@@ -31,7 +31,7 @@ export function normalizeMode(mode, def) {
31
31
  }
32
32
  if (typeof def == 'number')
33
33
  return def;
34
- throw new ErrnoError(Errno.EINVAL, 'Invalid mode: ' + (mode === null || mode === void 0 ? void 0 : mode.toString()));
34
+ throw withErrno('EINVAL', 'Invalid mode: ' + (mode === null || mode === void 0 ? void 0 : mode.toString()));
35
35
  }
36
36
  /**
37
37
  * Normalizes a time
@@ -44,9 +44,15 @@ export function normalizeTime(time) {
44
44
  return Number(time);
45
45
  }
46
46
  catch {
47
- throw new ErrnoError(Errno.EINVAL, 'Invalid time.');
47
+ throw withErrno('EINVAL', 'Invalid time.');
48
48
  }
49
49
  }
50
+ /**
51
+ * TypeScript is dumb, so we need to assert the type of a value sometimes.
52
+ * For example, after calling `normalizePath`, TS still thinks the type is `PathLike` and not `string`.
53
+ * @internal @hidden
54
+ */
55
+ export function __assertType(value) { }
50
56
  /**
51
57
  * Normalizes a path
52
58
  * @internal
@@ -54,18 +60,16 @@ export function normalizeTime(time) {
54
60
  export function normalizePath(p, noResolve = false) {
55
61
  if (p instanceof URL) {
56
62
  if (p.protocol != 'file:')
57
- throw new ErrnoError(Errno.EINVAL, 'URLs must use the file: protocol');
63
+ throw withErrno('EINVAL', 'URLs must use the file: protocol');
58
64
  p = p.pathname;
59
65
  }
60
66
  p = p.toString();
61
67
  if (p.startsWith('file://'))
62
68
  p = p.slice('file://'.length);
63
- if (p.includes('\x00')) {
64
- throw new ErrnoError(Errno.EINVAL, 'Path can not contain null character');
65
- }
66
- if (p.length == 0) {
67
- throw new ErrnoError(Errno.EINVAL, 'Path can not be empty');
68
- }
69
+ if (p.includes('\x00'))
70
+ throw withErrno('EINVAL', 'Path can not contain null character');
71
+ if (p.length == 0)
72
+ throw withErrno('EINVAL', 'Path can not be empty');
69
73
  p = p.replaceAll(/[/\\]+/g, '/');
70
74
  // Note: PWD is not resolved here, it is resolved later.
71
75
  return noResolve ? p : resolve(p);
@@ -92,10 +96,3 @@ export function normalizeOptions(options, encoding = 'utf8', flag, mode = 0) {
92
96
  mode: normalizeMode('mode' in options ? options === null || options === void 0 ? void 0 : options.mode : null, mode),
93
97
  };
94
98
  }
95
- export function stringifyUUID(uuid) {
96
- const hex = uuid.toString(16).padStart(32, '0');
97
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
98
- }
99
- export function parseUUID(uuid) {
100
- return BigInt(`0x${uuid.replace(/-/g, '')}`);
101
- }
package/dist/vfs/acl.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { BufferView } from 'utilium/buffer.js';
1
2
  import { type V_Context } from '../internal/contexts.js';
2
3
  import { type InodeLike } from '../internal/inode.js';
3
4
  export declare const enum Type {
@@ -16,16 +17,15 @@ export declare const enum Tag {
16
17
  */
17
18
  _None = 0
18
19
  }
19
- export declare class Entry {
20
- tag: Tag;
21
- perm: number;
22
- id: number;
23
- constructor(data?: Partial<Entry> | Uint8Array);
20
+ export declare class Entry extends BufferView {
21
+ accessor tag: Tag;
22
+ accessor perm: number;
23
+ accessor id: number;
24
24
  }
25
- export declare class ACL {
26
- version: number;
25
+ export declare class ACL extends BufferView {
26
+ accessor version: number;
27
27
  entries: Entry[];
28
- constructor(data?: Uint8Array | Entry[]);
28
+ constructor(...args: ConstructorParameters<typeof BufferView>);
29
29
  }
30
30
  export declare function fromMode(mode: number): ACL;
31
31
  export declare function toMode(acl: ACL): number;
package/dist/vfs/acl.js CHANGED
@@ -36,18 +36,30 @@ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, p
36
36
  if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
37
37
  return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
38
38
  };
39
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
40
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
41
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
42
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
43
+ };
44
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
45
+ if (kind === "m") throw new TypeError("Private method is not writable");
46
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
47
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
48
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
49
+ };
39
50
  /*
40
51
  Access Control Lists.
41
52
  At the moment, they are only intended for internal use.
42
53
  They also are not checked for permissions yet.
43
54
  Please use a namespace import for the best experience.
44
55
  */
45
- import { assignWithDefaults, deserialize, serialize, sizeof, struct, types as t } from 'utilium';
56
+ import { withErrno } from 'kerium';
57
+ import { err } from 'kerium/log';
58
+ import { packed, sizeof, struct, types as t } from 'memium';
59
+ import { BufferView } from 'utilium/buffer.js';
46
60
  import { defaultContext } from '../internal/contexts.js';
47
- import { Errno, ErrnoError } from '../internal/error.js';
48
61
  import { Attributes } from '../internal/inode.js';
49
- import { err } from '../internal/log.js';
50
- import { S_IRWXG, S_IRWXO, S_IRWXU, W_OK, X_OK, R_OK } from './constants.js';
62
+ import { R_OK, S_IRWXG, S_IRWXO, S_IRWXU, W_OK, X_OK } from './constants.js';
51
63
  import * as xattr from './xattr.js';
52
64
  const version = 2;
53
65
  export var Type;
@@ -69,11 +81,13 @@ export var Tag;
69
81
  Tag[Tag["_None"] = 0] = "_None";
70
82
  })(Tag || (Tag = {}));
71
83
  let Entry = (() => {
84
+ var _Entry_tag_accessor_storage, _Entry_perm_accessor_storage, _Entry_id_accessor_storage;
72
85
  var _a, _b, _c;
73
- let _classDecorators = [struct()];
86
+ let _classDecorators = [struct(packed)];
74
87
  let _classDescriptor;
75
88
  let _classExtraInitializers = [];
76
89
  let _classThis;
90
+ let _classSuper = BufferView;
77
91
  let _tag_decorators;
78
92
  let _tag_initializers = [];
79
93
  let _tag_extraInitializers = [];
@@ -83,27 +97,34 @@ let Entry = (() => {
83
97
  let _id_decorators;
84
98
  let _id_initializers = [];
85
99
  let _id_extraInitializers = [];
86
- var Entry = _classThis = class {
87
- constructor(data) {
88
- this.tag = __runInitializers(this, _tag_initializers, 0);
89
- this.perm = (__runInitializers(this, _tag_extraInitializers), __runInitializers(this, _perm_initializers, 0));
90
- this.id = (__runInitializers(this, _perm_extraInitializers), __runInitializers(this, _id_initializers, 0));
100
+ var Entry = _classThis = class extends _classSuper {
101
+ get tag() { return __classPrivateFieldGet(this, _Entry_tag_accessor_storage, "f"); }
102
+ set tag(value) { __classPrivateFieldSet(this, _Entry_tag_accessor_storage, value, "f"); }
103
+ get perm() { return __classPrivateFieldGet(this, _Entry_perm_accessor_storage, "f"); }
104
+ set perm(value) { __classPrivateFieldSet(this, _Entry_perm_accessor_storage, value, "f"); }
105
+ get id() { return __classPrivateFieldGet(this, _Entry_id_accessor_storage, "f"); }
106
+ set id(value) { __classPrivateFieldSet(this, _Entry_id_accessor_storage, value, "f"); }
107
+ constructor() {
108
+ super(...arguments);
109
+ _Entry_tag_accessor_storage.set(this, __runInitializers(this, _tag_initializers, void 0));
110
+ _Entry_perm_accessor_storage.set(this, (__runInitializers(this, _tag_extraInitializers), __runInitializers(this, _perm_initializers, void 0)));
111
+ _Entry_id_accessor_storage.set(this, (__runInitializers(this, _perm_extraInitializers), __runInitializers(this, _id_initializers, void 0)));
91
112
  __runInitializers(this, _id_extraInitializers);
92
- if (data instanceof Uint8Array)
93
- deserialize(this, data);
94
- else if (typeof data == 'object')
95
- assignWithDefaults(this, data);
96
113
  }
97
114
  };
115
+ _Entry_tag_accessor_storage = new WeakMap();
116
+ _Entry_perm_accessor_storage = new WeakMap();
117
+ _Entry_id_accessor_storage = new WeakMap();
98
118
  __setFunctionName(_classThis, "Entry");
99
119
  (() => {
100
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
120
+ var _a;
121
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
101
122
  _tag_decorators = [(_a = t).uint16.bind(_a)];
102
123
  _perm_decorators = [(_b = t).uint16.bind(_b)];
103
124
  _id_decorators = [(_c = t).uint32.bind(_c)];
104
- __esDecorate(null, null, _tag_decorators, { kind: "field", name: "tag", static: false, private: false, access: { has: obj => "tag" in obj, get: obj => obj.tag, set: (obj, value) => { obj.tag = value; } }, metadata: _metadata }, _tag_initializers, _tag_extraInitializers);
105
- __esDecorate(null, null, _perm_decorators, { kind: "field", name: "perm", static: false, private: false, access: { has: obj => "perm" in obj, get: obj => obj.perm, set: (obj, value) => { obj.perm = value; } }, metadata: _metadata }, _perm_initializers, _perm_extraInitializers);
106
- __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
125
+ __esDecorate(_classThis, null, _tag_decorators, { kind: "accessor", name: "tag", static: false, private: false, access: { has: obj => "tag" in obj, get: obj => obj.tag, set: (obj, value) => { obj.tag = value; } }, metadata: _metadata }, _tag_initializers, _tag_extraInitializers);
126
+ __esDecorate(_classThis, null, _perm_decorators, { kind: "accessor", name: "perm", static: false, private: false, access: { has: obj => "perm" in obj, get: obj => obj.perm, set: (obj, value) => { obj.perm = value; } }, metadata: _metadata }, _perm_initializers, _perm_extraInitializers);
127
+ __esDecorate(_classThis, null, _id_decorators, { kind: "accessor", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
107
128
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
108
129
  Entry = _classThis = _classDescriptor.value;
109
130
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -113,40 +134,40 @@ let Entry = (() => {
113
134
  })();
114
135
  export { Entry };
115
136
  let ACL = (() => {
137
+ var _ACL_version_accessor_storage;
116
138
  var _a;
117
- let _classDecorators = [struct()];
139
+ let _classDecorators = [struct(packed)];
118
140
  let _classDescriptor;
119
141
  let _classExtraInitializers = [];
120
142
  let _classThis;
143
+ let _classSuper = BufferView;
121
144
  let _version_decorators;
122
145
  let _version_initializers = [];
123
146
  let _version_extraInitializers = [];
124
- var ACL = _classThis = class {
125
- constructor(data) {
126
- this.version = __runInitializers(this, _version_initializers, version);
147
+ var ACL = _classThis = class extends _classSuper {
148
+ get version() { return __classPrivateFieldGet(this, _ACL_version_accessor_storage, "f"); }
149
+ set version(value) { __classPrivateFieldSet(this, _ACL_version_accessor_storage, value, "f"); }
150
+ constructor(...args) {
151
+ super(...args);
152
+ _ACL_version_accessor_storage.set(this, __runInitializers(this, _version_initializers, void 0));
127
153
  this.entries = (__runInitializers(this, _version_extraInitializers), []);
128
- if (!data)
129
- return;
130
- if (!(data instanceof Uint8Array)) {
131
- this.entries.push(...data);
132
- return;
133
- }
134
- deserialize(this, data);
154
+ this.version || (this.version = version);
135
155
  if (this.version != version)
136
- throw err(new ErrnoError(Errno.EINVAL, 'Invalid ACL version'));
137
- for (let offset = sizeof(ACL); offset < data.length; offset += sizeof(Entry)) {
138
- if (offset + sizeof(Entry) > data.length)
139
- throw err(new ErrnoError(Errno.EIO, 'Invalid ACL data'));
140
- const slice = data.subarray(offset, offset + sizeof(Entry));
141
- this.entries.push(new Entry(slice));
156
+ throw err(withErrno('EINVAL', 'Invalid ACL version'));
157
+ for (let offset = sizeof(ACL); offset < this.byteLength; offset += sizeof(Entry)) {
158
+ if (offset + sizeof(Entry) > this.byteLength)
159
+ throw err(withErrno('EIO', 'Invalid ACL data'));
160
+ this.entries.push(new Entry(this.buffer, offset));
142
161
  }
143
162
  }
144
163
  };
164
+ _ACL_version_accessor_storage = new WeakMap();
145
165
  __setFunctionName(_classThis, "ACL");
146
166
  (() => {
147
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
167
+ var _a;
168
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
148
169
  _version_decorators = [(_a = t).uint32.bind(_a)];
149
- __esDecorate(null, null, _version_decorators, { kind: "field", name: "version", static: false, private: false, access: { has: obj => "version" in obj, get: obj => obj.version, set: (obj, value) => { obj.version = value; } }, metadata: _metadata }, _version_initializers, _version_extraInitializers);
170
+ __esDecorate(_classThis, null, _version_decorators, { kind: "accessor", name: "version", static: false, private: false, access: { has: obj => "version" in obj, get: obj => obj.version, set: (obj, value) => { obj.version = value; } }, metadata: _metadata }, _version_initializers, _version_extraInitializers);
150
171
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
151
172
  ACL = _classThis = _classDescriptor.value;
152
173
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -156,11 +177,9 @@ let ACL = (() => {
156
177
  })();
157
178
  export { ACL };
158
179
  export function fromMode(mode) {
159
- return new ACL([
160
- new Entry({ tag: Tag.UserObj, perm: (mode & S_IRWXU) >> 6 }),
161
- new Entry({ tag: Tag.GroupObj, perm: (mode & S_IRWXG) >> 3 }),
162
- new Entry({ tag: Tag.Other, perm: mode & S_IRWXO }),
163
- ]);
180
+ const acl = new ACL();
181
+ acl.entries.push(Object.assign(new Entry(), { tag: Tag.UserObj, perm: (mode & S_IRWXU) >> 6 }), Object.assign(new Entry(), { tag: Tag.GroupObj, perm: (mode & S_IRWXG) >> 3 }), Object.assign(new Entry(), { tag: Tag.Other, perm: mode & S_IRWXO }));
182
+ return acl;
164
183
  }
165
184
  export function toMode(acl) {
166
185
  let mode = 0;
@@ -191,10 +210,10 @@ export function getSync($, path) {
191
210
  return new ACL(xattr.getSync.call($, path, 'system.posix_acl_access'));
192
211
  }
193
212
  export async function set($, path, acl) {
194
- await xattr.set.call($, path, 'system.posix_acl_access', serialize(acl));
213
+ await xattr.set.call($, path, 'system.posix_acl_access', new Uint8Array(acl.buffer, acl.byteOffset, acl.byteLength));
195
214
  }
196
215
  export function setSync($, path, acl) {
197
- xattr.setSync.call($, path, 'system.posix_acl_access', serialize(acl));
216
+ xattr.setSync.call($, path, 'system.posix_acl_access', new Uint8Array(acl.buffer, acl.byteOffset, acl.byteLength));
198
217
  }
199
218
  export let shouldCheck = true;
200
219
  export function setChecks(enabled) {
@@ -210,10 +229,10 @@ export function check($, inode, access) {
210
229
  return true;
211
230
  (_a = inode.attributes) !== null && _a !== void 0 ? _a : (inode.attributes = new Attributes());
212
231
  const { euid, egid } = (_b = $ === null || $ === void 0 ? void 0 : $.credentials) !== null && _b !== void 0 ? _b : defaultContext.credentials;
213
- const attr = inode.attributes.get('system.posix_acl_access');
214
- if (!attr)
232
+ const data = inode.attributes.get('system.posix_acl_access');
233
+ if (!data)
215
234
  return true;
216
- const acl = new ACL(attr.value);
235
+ const acl = new ACL(data);
217
236
  let mask = R_OK | W_OK | X_OK;
218
237
  let result = false;
219
238
  for (const entry of acl.entries) {
@@ -5,7 +5,7 @@ import type { Dir, Dirent } from './dir.js';
5
5
  import type { Stats } from './stats.js';
6
6
  import type { FileContents } from './types.js';
7
7
  import { Buffer } from 'buffer';
8
- import { ErrnoError } from '../internal/error.js';
8
+ import { type Exception } from 'kerium';
9
9
  import { BigIntStats } from './stats.js';
10
10
  import { ReadStream, WriteStream, type ReadStreamOptions, type WriteStreamOptions } from './streams.js';
11
11
  import { FSWatcher } from './watchers.js';
@@ -267,7 +267,7 @@ export declare function statfs(this: V_Context, path: fs.PathLike, options: fs.S
267
267
  bigint: true;
268
268
  }, callback: Callback<[fs.BigIntStatsFs]>): void;
269
269
  export declare function openAsBlob(this: V_Context, path: fs.PathLike, options?: fs.OpenAsBlobOptions): Promise<Blob>;
270
- type GlobCallback<Args extends unknown[]> = (e: ErrnoError | null, ...args: Args) => unknown;
270
+ type GlobCallback<Args extends unknown[]> = (e: Exception | null, ...args: Args) => unknown;
271
271
  /**
272
272
  * Retrieves the files matching the specified pattern.
273
273
  */
package/dist/vfs/async.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Buffer } from 'buffer';
2
- import { Errno, ErrnoError } from '../internal/error.js';
2
+ import { UV, withErrno } from 'kerium';
3
3
  import { normalizeMode, normalizePath } from '../utils.js';
4
4
  import { R_OK } from './constants.js';
5
5
  import * as promises from './promises.js';
@@ -124,9 +124,8 @@ export function ftruncate(fd, lenOrCB, cb = nop) {
124
124
  const length = typeof lenOrCB === 'number' ? lenOrCB : 0;
125
125
  cb = typeof lenOrCB === 'function' ? lenOrCB : cb;
126
126
  const file = new promises.FileHandle(this, fd);
127
- if (length < 0) {
128
- throw new ErrnoError(Errno.EINVAL);
129
- }
127
+ if (length < 0)
128
+ throw withErrno('EINVAL');
130
129
  file.truncate(length)
131
130
  .then(() => cb())
132
131
  .catch(cb);
@@ -166,7 +165,7 @@ export function write(fd, data, cbPosOff, cbLenEnc, cbPosEnc, cb = nop) {
166
165
  default:
167
166
  // ...try to find the callback and get out of here!
168
167
  cb = (typeof cbLenEnc === 'function' ? cbLenEnc : typeof cbPosEnc === 'function' ? cbPosEnc : cb);
169
- cb(new ErrnoError(Errno.EINVAL, 'Invalid arguments'));
168
+ cb(withErrno('EINVAL'));
170
169
  return;
171
170
  }
172
171
  buffer = Buffer.from(data);
@@ -355,9 +354,8 @@ export function watchFile(path, options, listener) {
355
354
  if (typeof options == 'function') {
356
355
  listener = options;
357
356
  }
358
- if (!listener) {
359
- throw new ErrnoError(Errno.EINVAL, 'No listener specified', path.toString(), 'watchFile');
360
- }
357
+ if (!listener)
358
+ throw UV('EINVAL', 'watch', path.toString());
361
359
  if (statWatchers.has(normalizedPath)) {
362
360
  const entry = statWatchers.get(normalizedPath);
363
361
  if (entry) {
package/dist/vfs/dir.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Dir as _Dir, Dirent as _Dirent } from 'node:fs';
2
2
  import type { V_Context } from '../context.js';
3
- import { type InodeLike } from '../internal/inode.js';
3
+ import type { InodeLike } from '../internal/inode.js';
4
4
  import type { Callback } from '../utils.js';
5
5
  export declare class Dirent implements _Dirent {
6
6
  path: string;
package/dist/vfs/dir.js CHANGED
@@ -1,5 +1,5 @@
1
+ import { withErrno } from 'kerium';
1
2
  import { isBlockDevice, isCharacterDevice, isDirectory, isFIFO, isFile, isSocket, isSymbolicLink } from '../internal/inode.js';
2
- import { Errno, ErrnoError } from '../internal/error.js';
3
3
  import { basename } from '../path.js';
4
4
  import { readdir } from './promises.js';
5
5
  import { readdirSync } from './sync.js';
@@ -41,9 +41,8 @@ export class Dirent {
41
41
  */
42
42
  export class Dir {
43
43
  checkClosed() {
44
- if (this.closed) {
45
- throw new ErrnoError(Errno.EBADF, 'Can not use closed Dir');
46
- }
44
+ if (this.closed)
45
+ throw withErrno('EBADF', 'Can not use closed Dir');
47
46
  }
48
47
  constructor(path, context) {
49
48
  this.path = path;
package/dist/vfs/file.js CHANGED
@@ -1,5 +1,5 @@
1
+ import { UV, withErrno } from 'kerium';
1
2
  import { defaultContext } from '../internal/contexts.js';
2
- import { Errno, ErrnoError } from '../internal/error.js';
3
3
  import { InodeFlags, isBlockDevice, isCharacterDevice } from '../internal/inode.js';
4
4
  import '../polyfills.js';
5
5
  import * as c from './constants.js';
@@ -51,11 +51,11 @@ export class SyncHandle {
51
51
  this.close();
52
52
  }
53
53
  get _isSync() {
54
- return !!(this.flag & c.O_SYNC || this.inode.flags & InodeFlags.Sync);
54
+ return !!(this.flag & c.O_SYNC || this.inode.flags & InodeFlags.Sync || this.fs.attributes.has('sync'));
55
55
  }
56
56
  sync() {
57
57
  if (this.closed)
58
- throw ErrnoError.With('EBADF', this.path, 'sync');
58
+ throw UV('EBADF', 'sync', this.path);
59
59
  if (!this.dirty)
60
60
  return;
61
61
  if (!this.fs.attributes.has('no_write'))
@@ -70,7 +70,7 @@ export class SyncHandle {
70
70
  }
71
71
  close() {
72
72
  if (this.closed)
73
- throw ErrnoError.With('EBADF', this.path, 'close');
73
+ throw UV('EBADF', 'close', this.path);
74
74
  this.sync();
75
75
  this.dispose();
76
76
  }
@@ -79,23 +79,28 @@ export class SyncHandle {
79
79
  */
80
80
  dispose(force) {
81
81
  if (this.closed)
82
- throw ErrnoError.With('EBADF', this.path, 'dispose');
82
+ throw UV('EBADF', 'close', this.path);
83
83
  if (this.dirty && !force)
84
- throw ErrnoError.With('EBUSY', this.path, 'dispose');
84
+ throw UV('EBUSY', 'close', this.path);
85
85
  this.closed = true;
86
86
  }
87
87
  stat() {
88
88
  if (this.closed)
89
- throw ErrnoError.With('EBADF', this.path, 'stat');
89
+ throw UV('EBADF', 'stat', this.path);
90
90
  return this.inode;
91
91
  }
92
92
  truncate(length) {
93
+ if (length < 0)
94
+ throw UV('EINVAL', 'truncate', this.path);
93
95
  if (this.closed)
94
- throw ErrnoError.With('EBADF', this.path, 'truncate');
96
+ throw UV('EBADF', 'truncate', this.path);
97
+ if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR))
98
+ throw UV('EBADF', 'truncate', this.path);
99
+ if (this.fs.attributes.has('readonly'))
100
+ throw UV('EROFS', 'truncate', this.path);
101
+ if (this.inode.flags & InodeFlags.Immutable)
102
+ throw UV('EPERM', 'truncate', this.path);
95
103
  this.dirty = true;
96
- if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR)) {
97
- throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode', this.path, 'truncate');
98
- }
99
104
  this.inode.mtimeMs = Date.now();
100
105
  this.inode.size = length;
101
106
  this.inode.ctimeMs = Date.now();
@@ -113,11 +118,13 @@ export class SyncHandle {
113
118
  */
114
119
  write(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
115
120
  if (this.closed)
116
- throw ErrnoError.With('EBADF', this.path, 'write');
121
+ throw UV('EBADF', 'write', this.path);
117
122
  if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR))
118
- throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode');
123
+ throw UV('EBADF', 'write', this.path);
124
+ if (this.fs.attributes.has('readonly'))
125
+ throw UV('EROFS', 'write', this.path);
119
126
  if (this.inode.flags & InodeFlags.Immutable)
120
- throw new ErrnoError(Errno.EPERM, 'File is immutable', this.path, 'write');
127
+ throw UV('EPERM', 'write', this.path);
121
128
  this.dirty = true;
122
129
  const end = position + length;
123
130
  const slice = buffer.subarray(offset, offset + length);
@@ -142,10 +149,10 @@ export class SyncHandle {
142
149
  */
143
150
  read(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
144
151
  if (this.closed)
145
- throw ErrnoError.With('EBADF', this.path, 'read');
152
+ throw UV('EBADF', 'read', this.path);
146
153
  if (this.flag & c.O_WRONLY)
147
- throw new ErrnoError(Errno.EPERM, 'File not opened with a readable mode');
148
- if (!(this.inode.flags & InodeFlags.NoAtime)) {
154
+ throw UV('EBADF', 'read', this.path);
155
+ if (!(this.inode.flags & InodeFlags.NoAtime) && !this.fs.attributes.has('no_atime')) {
149
156
  this.dirty = true;
150
157
  this.inode.atimeMs = Date.now();
151
158
  }
@@ -162,7 +169,7 @@ export class SyncHandle {
162
169
  }
163
170
  chmod(mode) {
164
171
  if (this.closed)
165
- throw ErrnoError.With('EBADF', this.path, 'chmod');
172
+ throw UV('EBADF', 'chmod', this.path);
166
173
  this.dirty = true;
167
174
  this.inode.mode = (this.inode.mode & (mode > c.S_IFMT ? ~c.S_IFMT : c.S_IFMT)) | mode;
168
175
  if (this._isSync || mode > c.S_IFMT)
@@ -170,7 +177,7 @@ export class SyncHandle {
170
177
  }
171
178
  chown(uid, gid) {
172
179
  if (this.closed)
173
- throw ErrnoError.With('EBADF', this.path, 'chown');
180
+ throw UV('EBADF', 'chmod', this.path);
174
181
  this.dirty = true;
175
182
  _chown(this.inode, uid, gid);
176
183
  if (this._isSync)
@@ -181,7 +188,7 @@ export class SyncHandle {
181
188
  */
182
189
  utimes(atime, mtime) {
183
190
  if (this.closed)
184
- throw ErrnoError.With('EBADF', this.path, 'utimes');
191
+ throw UV('EBADF', 'utimes', this.path);
185
192
  this.dirty = true;
186
193
  this.inode.atimeMs = atime;
187
194
  this.inode.mtimeMs = mtime;
@@ -193,7 +200,7 @@ export class SyncHandle {
193
200
  */
194
201
  streamRead(options) {
195
202
  if (this.closed)
196
- throw ErrnoError.With('EBADF', this.path, 'streamRead');
203
+ throw UV('EBADF', 'streamRead', this.path);
197
204
  return this.fs.streamRead(this.internalPath, options);
198
205
  }
199
206
  /**
@@ -201,9 +208,11 @@ export class SyncHandle {
201
208
  */
202
209
  streamWrite(options) {
203
210
  if (this.closed)
204
- throw ErrnoError.With('EBADF', this.path, 'streamWrite');
211
+ throw UV('EBADF', 'write', this.path);
205
212
  if (this.inode.flags & InodeFlags.Immutable)
206
- throw new ErrnoError(Errno.EPERM, 'File is immutable', this.path, 'streamWrite');
213
+ throw UV('EPERM', 'write', this.path);
214
+ if (this.fs.attributes.has('readonly'))
215
+ throw UV('EROFS', 'write', this.path);
207
216
  return this.fs.streamWrite(this.internalPath, options);
208
217
  }
209
218
  }
@@ -226,7 +235,7 @@ export function fromFD($, fd) {
226
235
  const map = (_a = $ === null || $ === void 0 ? void 0 : $.descriptors) !== null && _a !== void 0 ? _a : defaultContext.descriptors;
227
236
  const value = map.get(fd);
228
237
  if (!value)
229
- throw new ErrnoError(Errno.EBADF);
238
+ throw withErrno('EBADF');
230
239
  return value;
231
240
  }
232
241
  export function deleteFD($, fd) {
package/dist/vfs/flags.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Errno, ErrnoError } from '../internal/error.js';
1
+ import { withErrno } from 'kerium';
2
2
  import * as c from './constants.js';
3
3
  export const pattern = /[rwasx]{1,2}\+?/;
4
4
  /**
@@ -8,7 +8,7 @@ export function parse(flag) {
8
8
  if (typeof flag == 'number')
9
9
  return flag;
10
10
  if (!pattern.test(flag)) {
11
- throw new ErrnoError(Errno.EINVAL, 'Invalid flag string: ' + flag);
11
+ throw withErrno('EINVAL', 'Invalid flag string: ' + flag);
12
12
  }
13
13
  return toNumber(flag);
14
14
  }
@@ -30,7 +30,7 @@ export function toString(flag) {
30
30
  */
31
31
  export function toNumber(flag) {
32
32
  if (!flag.includes('r') && !flag.includes('w') && !flag.includes('a')) {
33
- throw new ErrnoError(Errno.EINVAL, 'Invalid flag string: ' + flag);
33
+ throw withErrno('EINVAL', 'Invalid flag string: ' + flag);
34
34
  }
35
35
  let n = flag.includes('r') ? c.O_RDONLY : c.O_CREAT;
36
36
  if (flag.includes('w'))
@@ -1,17 +1,18 @@
1
+ import { BufferView } from 'utilium/buffer.js';
1
2
  import type { V_Context } from '../context.js';
2
3
  import { Inode } from '../internal/inode.js';
3
- declare class fsxattr {
4
+ declare class fsxattr extends BufferView {
4
5
  /** xflags field value */
5
- xflags: number;
6
+ accessor xflags: number;
6
7
  /** extsize field value */
7
- extsize: number;
8
+ accessor extsize: number;
8
9
  /** nextents field value */
9
- nextents: number;
10
+ accessor nextents: number;
10
11
  /** project identifier */
11
- projid: number;
12
+ accessor projid: number;
12
13
  /** CoW extsize field value */
13
- cowextsize: number;
14
- protected pad: never[];
14
+ accessor cowextsize: number;
15
+ protected accessor pad: number[];
15
16
  constructor(inode?: Inode);
16
17
  }
17
18
  /**