@zenfs/core 1.11.4 → 2.0.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 (116) hide show
  1. package/dist/backends/backend.d.ts +19 -15
  2. package/dist/backends/backend.js +31 -15
  3. package/dist/backends/cow.d.ts +20 -30
  4. package/dist/backends/cow.js +52 -142
  5. package/dist/backends/fetch.d.ts +1 -0
  6. package/dist/backends/fetch.js +3 -1
  7. package/dist/backends/index.d.ts +1 -1
  8. package/dist/backends/index.js +1 -1
  9. package/dist/backends/memory.d.ts +5 -7
  10. package/dist/backends/memory.js +2 -3
  11. package/dist/backends/passthrough.d.ts +19 -22
  12. package/dist/backends/passthrough.js +85 -160
  13. package/dist/backends/port.d.ts +207 -0
  14. package/dist/backends/port.js +297 -0
  15. package/dist/backends/single_buffer.d.ts +11 -5
  16. package/dist/backends/single_buffer.js +18 -12
  17. package/dist/backends/store/fs.d.ts +11 -27
  18. package/dist/backends/store/fs.js +67 -91
  19. package/dist/backends/store/store.d.ts +7 -12
  20. package/dist/config.d.ts +1 -10
  21. package/dist/config.js +7 -8
  22. package/dist/context.d.ts +8 -21
  23. package/dist/context.js +33 -10
  24. package/dist/index.d.ts +2 -1
  25. package/dist/index.js +2 -1
  26. package/dist/internal/contexts.d.ts +63 -0
  27. package/dist/internal/contexts.js +15 -0
  28. package/dist/internal/credentials.d.ts +2 -11
  29. package/dist/internal/credentials.js +0 -19
  30. package/dist/internal/devices.d.ts +18 -80
  31. package/dist/internal/devices.js +76 -279
  32. package/dist/internal/file_index.js +3 -3
  33. package/dist/internal/filesystem.d.ts +31 -89
  34. package/dist/internal/filesystem.js +21 -20
  35. package/dist/internal/index.d.ts +0 -1
  36. package/dist/internal/index.js +0 -1
  37. package/dist/internal/index_fs.d.ts +12 -30
  38. package/dist/internal/index_fs.js +23 -55
  39. package/dist/internal/inode.d.ts +147 -9
  40. package/dist/internal/inode.js +333 -25
  41. package/dist/internal/log.d.ts +19 -13
  42. package/dist/internal/log.js +81 -80
  43. package/dist/mixins/async.js +26 -90
  44. package/dist/mixins/mutexed.d.ts +17 -16
  45. package/dist/mixins/mutexed.js +29 -31
  46. package/dist/mixins/readonly.d.ts +7 -6
  47. package/dist/mixins/readonly.js +6 -0
  48. package/dist/mixins/sync.js +8 -8
  49. package/dist/{vfs/path.d.ts → path.d.ts} +3 -4
  50. package/dist/{vfs/path.js → path.js} +6 -9
  51. package/dist/readline.d.ts +134 -0
  52. package/dist/readline.js +623 -0
  53. package/dist/utils.d.ts +4 -35
  54. package/dist/utils.js +8 -73
  55. package/dist/vfs/acl.d.ts +42 -0
  56. package/dist/vfs/acl.js +249 -0
  57. package/dist/vfs/async.d.ts +7 -21
  58. package/dist/vfs/async.js +19 -19
  59. package/dist/vfs/config.d.ts +6 -18
  60. package/dist/vfs/config.js +8 -18
  61. package/dist/vfs/dir.d.ts +3 -3
  62. package/dist/vfs/dir.js +9 -8
  63. package/dist/vfs/file.d.ts +106 -0
  64. package/dist/vfs/file.js +235 -0
  65. package/dist/vfs/flags.d.ts +19 -0
  66. package/dist/vfs/flags.js +62 -0
  67. package/dist/vfs/index.d.ts +4 -10
  68. package/dist/vfs/index.js +4 -13
  69. package/dist/vfs/ioctl.d.ts +87 -0
  70. package/dist/vfs/ioctl.js +304 -0
  71. package/dist/vfs/promises.d.ts +78 -16
  72. package/dist/vfs/promises.js +273 -122
  73. package/dist/vfs/shared.d.ts +7 -26
  74. package/dist/vfs/shared.js +25 -53
  75. package/dist/{stats.d.ts → vfs/stats.d.ts} +14 -28
  76. package/dist/{stats.js → vfs/stats.js} +11 -66
  77. package/dist/vfs/streams.d.ts +1 -0
  78. package/dist/vfs/streams.js +24 -19
  79. package/dist/vfs/sync.d.ts +4 -3
  80. package/dist/vfs/sync.js +143 -128
  81. package/dist/vfs/watchers.d.ts +2 -2
  82. package/dist/vfs/watchers.js +6 -6
  83. package/dist/vfs/xattr.d.ts +116 -0
  84. package/dist/vfs/xattr.js +218 -0
  85. package/package.json +3 -3
  86. package/readme.md +1 -1
  87. package/tests/backend/config.worker.js +4 -1
  88. package/tests/backend/fetch.test.ts +3 -0
  89. package/tests/backend/port.test.ts +21 -35
  90. package/tests/backend/remote.worker.js +4 -1
  91. package/tests/backend/single-buffer.test.ts +24 -0
  92. package/tests/common/context.test.ts +1 -1
  93. package/tests/common/handle.test.ts +17 -12
  94. package/tests/common/path.test.ts +1 -1
  95. package/tests/common/readline.test.ts +104 -0
  96. package/tests/common.ts +4 -19
  97. package/tests/fetch/fetch.ts +1 -1
  98. package/tests/fs/links.test.ts +1 -1
  99. package/tests/fs/permissions.test.ts +7 -6
  100. package/tests/fs/readFile.test.ts +3 -3
  101. package/tests/fs/stat.test.ts +6 -6
  102. package/tests/fs/streams.test.ts +2 -11
  103. package/tests/fs/times.test.ts +1 -1
  104. package/tests/fs/xattr.test.ts +85 -0
  105. package/tests/logs.js +22 -0
  106. package/tests/setup/context.ts +1 -1
  107. package/tests/setup/index.ts +3 -3
  108. package/tests/setup/port.ts +1 -1
  109. package/dist/backends/port/fs.d.ts +0 -84
  110. package/dist/backends/port/fs.js +0 -151
  111. package/dist/backends/port/rpc.d.ts +0 -77
  112. package/dist/backends/port/rpc.js +0 -100
  113. package/dist/backends/store/simple.d.ts +0 -20
  114. package/dist/backends/store/simple.js +0 -13
  115. package/dist/internal/file.d.ts +0 -359
  116. package/dist/internal/file.js +0 -751
@@ -0,0 +1,304 @@
1
+ /*
2
+ ioctl stuff. The majority of the code here is ported from Linux
3
+ See:
4
+ - include/uapi/asm-generic/ioctl.h
5
+ - include/uapi/linux/fs.h (`FS_IOC_*`)
6
+ */
7
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
8
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
9
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
10
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
11
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
12
+ var _, done = false;
13
+ for (var i = decorators.length - 1; i >= 0; i--) {
14
+ var context = {};
15
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
16
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
17
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
18
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
19
+ if (kind === "accessor") {
20
+ if (result === void 0) continue;
21
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
22
+ if (_ = accept(result.get)) descriptor.get = _;
23
+ if (_ = accept(result.set)) descriptor.set = _;
24
+ if (_ = accept(result.init)) initializers.unshift(_);
25
+ }
26
+ else if (_ = accept(result)) {
27
+ if (kind === "field") initializers.unshift(_);
28
+ else descriptor[key] = _;
29
+ }
30
+ }
31
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
32
+ done = true;
33
+ };
34
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
35
+ var useValue = arguments.length > 2;
36
+ for (var i = 0; i < initializers.length; i++) {
37
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
38
+ }
39
+ return useValue ? value : void 0;
40
+ };
41
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
42
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
43
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
44
+ };
45
+ import { _throw, struct, types as t } from 'utilium';
46
+ import { Errno, ErrnoError } from '../internal/error.js';
47
+ import { Inode, InodeFlags } from '../internal/inode.js';
48
+ import { normalizePath } from '../utils.js';
49
+ import { fixError, resolveMount } from './shared.js';
50
+ /*
51
+ * Flags for the fsxattr.xflags field
52
+ */
53
+ var XFlag;
54
+ (function (XFlag) {
55
+ /** data in realtime volume */
56
+ XFlag[XFlag["RealTime"] = 1] = "RealTime";
57
+ /** preallocated file extents */
58
+ XFlag[XFlag["PreAlloc"] = 2] = "PreAlloc";
59
+ /** file cannot be modified */
60
+ XFlag[XFlag["Immutable"] = 8] = "Immutable";
61
+ /** all writes append */
62
+ XFlag[XFlag["Append"] = 16] = "Append";
63
+ /** all writes synchronous */
64
+ XFlag[XFlag["Sync"] = 32] = "Sync";
65
+ /** do not update access time */
66
+ XFlag[XFlag["NoAtime"] = 64] = "NoAtime";
67
+ /** do not include in backups */
68
+ XFlag[XFlag["NoDump"] = 128] = "NoDump";
69
+ /** create with rt bit set */
70
+ XFlag[XFlag["RtInherit"] = 256] = "RtInherit";
71
+ /** create with parents projid */
72
+ XFlag[XFlag["ProjInherit"] = 512] = "ProjInherit";
73
+ /** disallow symlink creation */
74
+ XFlag[XFlag["NoSymlinks"] = 1024] = "NoSymlinks";
75
+ /** extent size allocator hint */
76
+ XFlag[XFlag["ExtSize"] = 2048] = "ExtSize";
77
+ /** inherit inode extent size */
78
+ XFlag[XFlag["ExtSzInherit"] = 4096] = "ExtSzInherit";
79
+ /** do not defragment */
80
+ XFlag[XFlag["NoDefrag"] = 8192] = "NoDefrag";
81
+ /** use filestream allocator */
82
+ XFlag[XFlag["FileStream"] = 16384] = "FileStream";
83
+ /** use DAX for IO */
84
+ XFlag[XFlag["Dax"] = 32768] = "Dax";
85
+ /** CoW extent size allocator hint */
86
+ XFlag[XFlag["CowExtSize"] = 65536] = "CowExtSize";
87
+ /** no DIFLAG for this */
88
+ XFlag[XFlag["HasAttr"] = 2147483648] = "HasAttr";
89
+ })(XFlag || (XFlag = {}));
90
+ let fsxattr = (() => {
91
+ var _a, _b, _c, _d, _e;
92
+ let _classDecorators = [struct()];
93
+ let _classDescriptor;
94
+ let _classExtraInitializers = [];
95
+ let _classThis;
96
+ let _xflags_decorators;
97
+ let _xflags_initializers = [];
98
+ let _xflags_extraInitializers = [];
99
+ let _extsize_decorators;
100
+ let _extsize_initializers = [];
101
+ let _extsize_extraInitializers = [];
102
+ let _nextents_decorators;
103
+ let _nextents_initializers = [];
104
+ let _nextents_extraInitializers = [];
105
+ let _projid_decorators;
106
+ let _projid_initializers = [];
107
+ let _projid_extraInitializers = [];
108
+ let _cowextsize_decorators;
109
+ let _cowextsize_initializers = [];
110
+ let _cowextsize_extraInitializers = [];
111
+ let _pad_decorators;
112
+ let _pad_initializers = [];
113
+ let _pad_extraInitializers = [];
114
+ var fsxattr = _classThis = class {
115
+ constructor(inode = _throw(new ErrnoError(Errno.EINVAL, 'fsxattr must be initialized with an inode'))) {
116
+ /** xflags field value */
117
+ this.xflags = __runInitializers(this, _xflags_initializers, 0);
118
+ /** extsize field value */
119
+ this.extsize = (__runInitializers(this, _xflags_extraInitializers), __runInitializers(this, _extsize_initializers, 0));
120
+ /** nextents field value */
121
+ this.nextents = (__runInitializers(this, _extsize_extraInitializers), __runInitializers(this, _nextents_initializers, 0));
122
+ /** project identifier */
123
+ this.projid = (__runInitializers(this, _nextents_extraInitializers), __runInitializers(this, _projid_initializers, 0));
124
+ /** CoW extsize field value */
125
+ this.cowextsize = (__runInitializers(this, _projid_extraInitializers), __runInitializers(this, _cowextsize_initializers, 0));
126
+ this.pad = (__runInitializers(this, _cowextsize_extraInitializers), __runInitializers(this, _pad_initializers, []));
127
+ __runInitializers(this, _pad_extraInitializers);
128
+ this.extsize = inode.size;
129
+ this.nextents = 1;
130
+ this.projid = inode.uid;
131
+ this.cowextsize = inode.size;
132
+ for (const name of Object.keys(InodeFlags)) {
133
+ if (!(inode.flags & InodeFlags[name]))
134
+ continue;
135
+ if (name in XFlag)
136
+ this.xflags |= XFlag[name];
137
+ }
138
+ }
139
+ };
140
+ __setFunctionName(_classThis, "fsxattr");
141
+ (() => {
142
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
143
+ _xflags_decorators = [(_a = t).uint32.bind(_a)];
144
+ _extsize_decorators = [(_b = t).uint32.bind(_b)];
145
+ _nextents_decorators = [(_c = t).uint32.bind(_c)];
146
+ _projid_decorators = [(_d = t).uint32.bind(_d)];
147
+ _cowextsize_decorators = [(_e = t).uint32.bind(_e)];
148
+ _pad_decorators = [t.char(8)];
149
+ __esDecorate(null, null, _xflags_decorators, { kind: "field", name: "xflags", static: false, private: false, access: { has: obj => "xflags" in obj, get: obj => obj.xflags, set: (obj, value) => { obj.xflags = value; } }, metadata: _metadata }, _xflags_initializers, _xflags_extraInitializers);
150
+ __esDecorate(null, null, _extsize_decorators, { kind: "field", name: "extsize", static: false, private: false, access: { has: obj => "extsize" in obj, get: obj => obj.extsize, set: (obj, value) => { obj.extsize = value; } }, metadata: _metadata }, _extsize_initializers, _extsize_extraInitializers);
151
+ __esDecorate(null, null, _nextents_decorators, { kind: "field", name: "nextents", static: false, private: false, access: { has: obj => "nextents" in obj, get: obj => obj.nextents, set: (obj, value) => { obj.nextents = value; } }, metadata: _metadata }, _nextents_initializers, _nextents_extraInitializers);
152
+ __esDecorate(null, null, _projid_decorators, { kind: "field", name: "projid", static: false, private: false, access: { has: obj => "projid" in obj, get: obj => obj.projid, set: (obj, value) => { obj.projid = value; } }, metadata: _metadata }, _projid_initializers, _projid_extraInitializers);
153
+ __esDecorate(null, null, _cowextsize_decorators, { kind: "field", name: "cowextsize", static: false, private: false, access: { has: obj => "cowextsize" in obj, get: obj => obj.cowextsize, set: (obj, value) => { obj.cowextsize = value; } }, metadata: _metadata }, _cowextsize_initializers, _cowextsize_extraInitializers);
154
+ __esDecorate(null, null, _pad_decorators, { kind: "field", name: "pad", static: false, private: false, access: { has: obj => "pad" in obj, get: obj => obj.pad, set: (obj, value) => { obj.pad = value; } }, metadata: _metadata }, _pad_initializers, _pad_extraInitializers);
155
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
156
+ fsxattr = _classThis = _classDescriptor.value;
157
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
158
+ __runInitializers(_classThis, _classExtraInitializers);
159
+ })();
160
+ return fsxattr = _classThis;
161
+ })();
162
+ /**
163
+ * `FS_IOC_*` commands for {@link ioctl | `ioctl`}
164
+ * @remarks
165
+ * These are computed from a script since constant values are needed for enum member types
166
+ */
167
+ export var IOC;
168
+ (function (IOC) {
169
+ IOC[IOC["GetFlags"] = 2148034049] = "GetFlags";
170
+ IOC[IOC["SetFlags"] = 1074292226] = "SetFlags";
171
+ IOC[IOC["GetVersion"] = 2148038145] = "GetVersion";
172
+ IOC[IOC["SetVersion"] = 1074296322] = "SetVersion";
173
+ IOC[IOC["Fiemap"] = 3223348747] = "Fiemap";
174
+ IOC[IOC["GetXattr"] = 2149341215] = "GetXattr";
175
+ IOC[IOC["SetXattr"] = 1075599392] = "SetXattr";
176
+ IOC[IOC["GetLabel"] = 2164298801] = "GetLabel";
177
+ IOC[IOC["SetLabel"] = 1090556978] = "SetLabel";
178
+ IOC[IOC["GetUUID"] = 2148603136] = "GetUUID";
179
+ IOC[IOC["GetSysfsPath"] = 2155943169] = "GetSysfsPath";
180
+ })(IOC || (IOC = {}));
181
+ /**
182
+ * `FS_IOC32_*` commands for {@link ioctl | `ioctl`}
183
+ * @remarks
184
+ * These are computed from a script since constant values are needed for enum member types
185
+ */
186
+ export var IOC32;
187
+ (function (IOC32) {
188
+ IOC32[IOC32["GetFlags"] = 2147771905] = "GetFlags";
189
+ IOC32[IOC32["SetFlags"] = 1074030082] = "SetFlags";
190
+ IOC32[IOC32["GetVersion"] = 2147776001] = "GetVersion";
191
+ IOC32[IOC32["SetVersion"] = 1074034178] = "SetVersion";
192
+ })(IOC32 || (IOC32 = {}));
193
+ /** Perform an `ioctl` on a file or file system. */
194
+ export async function ioctl(
195
+ /** The path to the file or file system to perform the `ioctl` on */
196
+ path,
197
+ /** The command to perform (uint32) */
198
+ command,
199
+ /** The arguments to pass to the command */
200
+ ...args) {
201
+ path = normalizePath(path);
202
+ const { fs, path: resolved } = resolveMount(path, this);
203
+ try {
204
+ const inode = new Inode(await fs.stat(resolved));
205
+ switch (command) {
206
+ case IOC.GetFlags:
207
+ case IOC32.GetFlags:
208
+ return inode.flags;
209
+ case IOC.SetFlags:
210
+ case IOC32.SetFlags:
211
+ inode.flags = args[0];
212
+ await fs.touch(resolved, inode);
213
+ return undefined;
214
+ case IOC.GetVersion:
215
+ case IOC32.GetVersion:
216
+ return inode.version;
217
+ case IOC.SetVersion:
218
+ case IOC32.SetVersion:
219
+ inode.version = args[0];
220
+ await fs.touch(resolved, inode);
221
+ return undefined;
222
+ case IOC.Fiemap:
223
+ break;
224
+ case IOC.GetXattr:
225
+ return new fsxattr(inode);
226
+ case IOC.SetXattr:
227
+ break;
228
+ case IOC.GetLabel:
229
+ return fs.label;
230
+ case IOC.SetLabel:
231
+ fs.label = args[0];
232
+ return undefined;
233
+ case IOC.GetUUID:
234
+ return fs.uuid;
235
+ case IOC.GetSysfsPath:
236
+ /**
237
+ * Returns the path component under /sys/fs/ that refers to this filesystem;
238
+ * also /sys/kernel/debug/ for filesystems with debugfs exports
239
+ * @todo Implement sysfs and have each FS implement the /sys/fs/<name> tree
240
+ */
241
+ return `/sys/fs/${fs.name}/${fs.uuid}`;
242
+ }
243
+ }
244
+ catch (e) {
245
+ throw fixError(e, { [resolved]: path });
246
+ }
247
+ throw new ErrnoError(Errno.ENOTSUP, 'Unsupported command: ' + command, path, 'ioctl');
248
+ }
249
+ /** Perform an `ioctl` on a file or file system */
250
+ export function ioctlSync(
251
+ /** The path to the file or file system to perform the `ioctl` on */
252
+ path,
253
+ /** The command to perform (uint32) */
254
+ command,
255
+ /** The arguments to pass to the command */
256
+ ...args) {
257
+ path = normalizePath(path);
258
+ const { fs, path: resolved } = resolveMount(path, this);
259
+ try {
260
+ const inode = new Inode(fs.statSync(resolved));
261
+ switch (command) {
262
+ case IOC.GetFlags:
263
+ case IOC32.GetFlags:
264
+ return inode.flags;
265
+ case IOC.SetFlags:
266
+ case IOC32.SetFlags:
267
+ inode.flags = args[0];
268
+ fs.touchSync(resolved, inode);
269
+ return undefined;
270
+ case IOC.GetVersion:
271
+ case IOC32.GetVersion:
272
+ return inode.version;
273
+ case IOC.SetVersion:
274
+ case IOC32.SetVersion:
275
+ inode.version = args[0];
276
+ fs.touchSync(resolved, inode);
277
+ return undefined;
278
+ case IOC.Fiemap:
279
+ break;
280
+ case IOC.GetXattr:
281
+ return new fsxattr(inode);
282
+ case IOC.SetXattr:
283
+ break;
284
+ case IOC.GetLabel:
285
+ return fs.label;
286
+ case IOC.SetLabel:
287
+ fs.label = args[0];
288
+ return undefined;
289
+ case IOC.GetUUID:
290
+ return fs.uuid;
291
+ case IOC.GetSysfsPath:
292
+ /**
293
+ * Returns the path component under /sys/fs/ that refers to this filesystem;
294
+ * also /sys/kernel/debug/ for filesystems with debugfs exports
295
+ * @todo Implement sysfs and have each FS implement the /sys/fs/<name> tree
296
+ */
297
+ return `/sys/fs/${fs.name}/${fs.uuid}`;
298
+ }
299
+ }
300
+ catch (e) {
301
+ throw fixError(e, { [resolved]: path });
302
+ }
303
+ throw new ErrnoError(Errno.ENOTSUP, 'Unsupported command: ' + command, path, 'ioctl');
304
+ }
@@ -1,30 +1,57 @@
1
1
  import type * as fs from 'node:fs';
2
2
  import type * as promises from 'node:fs/promises';
3
- import type { Interface as ReadlineInterface } from 'node:readline';
4
3
  import type { Stream } from 'node:stream';
5
4
  import type { ReadableStream as NodeReadableStream } from 'node:stream/web';
6
5
  import type { V_Context } from '../context.js';
7
- import type { File } from '../internal/file.js';
8
- import type { Stats } from '../stats.js';
6
+ import type { FileSystem, StreamOptions } from '../internal/filesystem.js';
7
+ import type { InodeLike } from '../internal/inode.js';
8
+ import type { Interface as ReadlineInterface } from '../readline.js';
9
9
  import type { FileContents, NullEnc, ReaddirOptions, ReaddirOptsI, ReaddirOptsU } from './types.js';
10
10
  import { Buffer } from 'buffer';
11
11
  import '../polyfills.js';
12
- import { BigIntStats } from '../stats.js';
13
12
  import { Dir, Dirent } from './dir.js';
13
+ import { BigIntStats, Stats } from './stats.js';
14
14
  import { ReadStream, WriteStream } from './streams.js';
15
15
  export * as constants from './constants.js';
16
16
  export declare class FileHandle implements promises.FileHandle {
17
- protected context?: V_Context | undefined;
17
+ protected context: V_Context;
18
+ readonly fd: number;
19
+ protected _buffer?: Uint8Array;
18
20
  /**
19
- * The file descriptor for this file handle.
21
+ * Current position
20
22
  */
21
- readonly fd: number;
23
+ protected _position: number;
22
24
  /**
23
- * @internal
24
- * The file for this file handle
25
+ * Get the current file position.
26
+ *
27
+ * We emulate the following bug mentioned in the Node documentation:
28
+ *
29
+ * On Linux, positional writes don't work when the file is opened in append mode.
30
+ * The kernel ignores the position argument and always appends the data to the end of the file.
31
+ * @returns The current file position.
32
+ */
33
+ get position(): number;
34
+ set position(value: number);
35
+ /**
36
+ * Whether the file has changes which have not been written to the FS
25
37
  */
26
- readonly file: File;
27
- constructor(fdOrFile: number | File, context?: V_Context | undefined);
38
+ protected dirty: boolean;
39
+ /**
40
+ * Whether the file is open or closed
41
+ */
42
+ protected closed: boolean;
43
+ /** The path relative to the context's root */
44
+ readonly path: string;
45
+ /** The internal FS associated with the handle */
46
+ protected readonly fs: FileSystem;
47
+ /** The path relative to the `FileSystem`'s root */
48
+ readonly internalPath: string;
49
+ /** The flag the handle was opened with */
50
+ readonly flag: number;
51
+ /** Stats for the handle */
52
+ readonly inode: InodeLike;
53
+ constructor(context: V_Context, fd: number);
54
+ private get _isSync();
28
55
  private _emitChange;
29
56
  /**
30
57
  * Asynchronous fchown(2) - Change ownership of a file.
@@ -47,7 +74,7 @@ export declare class FileHandle implements promises.FileHandle {
47
74
  * Asynchronous ftruncate(2) - Truncate a file to a specified length.
48
75
  * @param length If not specified, defaults to `0`.
49
76
  */
50
- truncate(length?: number | null): Promise<void>;
77
+ truncate(length?: number): Promise<void>;
51
78
  /**
52
79
  * Asynchronously change file timestamps of the file.
53
80
  * @param atime The last access time. If a string is provided, it will be coerced to number.
@@ -64,6 +91,18 @@ export declare class FileHandle implements promises.FileHandle {
64
91
  * - `flag` defaults to `'a'`.
65
92
  */
66
93
  appendFile(data: string | Uint8Array, _options?: (fs.ObjectEncodingOptions & promises.FlagAndOpenMode) | BufferEncoding): Promise<void>;
94
+ /**
95
+ * Read data from the file.
96
+ * @param buffer The buffer that the data will be written to.
97
+ * @param offset The offset within the buffer where writing will start.
98
+ * @param length An integer specifying the number of bytes to read.
99
+ * @param position An integer specifying where to begin reading from in the file.
100
+ * If position is unset, data will be read from the current file position.
101
+ */
102
+ protected _read<TBuffer extends ArrayBufferView>(buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<{
103
+ bytesRead: number;
104
+ buffer: TBuffer;
105
+ }>;
67
106
  /**
68
107
  * Asynchronously reads data from the file.
69
108
  * The `FileHandle` must have been opened for reading.
@@ -89,9 +128,19 @@ export declare class FileHandle implements promises.FileHandle {
89
128
  * Read file data using a `ReadableStream`.
90
129
  * The handle will not be closed automatically.
91
130
  */
92
- readableWebStream(options?: promises.ReadableWebStreamOptions): NodeReadableStream<Uint8Array>;
131
+ readableWebStream(options?: promises.ReadableWebStreamOptions & StreamOptions): NodeReadableStream<Uint8Array>;
132
+ /**
133
+ * Not part of the Node.js API!
134
+ *
135
+ * Write file data using a `WritableStream`.
136
+ * The handle will not be closed automatically.
137
+ * @internal
138
+ */
139
+ writableWebStream(options?: promises.ReadableWebStreamOptions & StreamOptions): WritableStream;
93
140
  /**
94
- * @todo Implement
141
+ * Creates a readline Interface object that allows reading the file line by line
142
+ * @param options Options for creating a read stream
143
+ * @returns A readline interface for reading the file line by line
95
144
  */
96
145
  readLines(options?: promises.CreateReadStreamOptions): ReadlineInterface;
97
146
  [Symbol.asyncDispose](): Promise<void>;
@@ -102,6 +151,15 @@ export declare class FileHandle implements promises.FileHandle {
102
151
  stat(opts?: fs.StatOptions & {
103
152
  bigint?: false;
104
153
  }): Promise<Stats>;
154
+ /**
155
+ * Write buffer to the file.
156
+ * @param buffer Uint8Array containing the data to write to the file.
157
+ * @param offset Offset in the buffer to start reading data from.
158
+ * @param length The amount of bytes to write to the file.
159
+ * @param position Offset from the beginning of the file where this data should be written.
160
+ * If position is null, the data will be written at the current position.
161
+ */
162
+ protected _write(buffer: Uint8Array, offset?: number, length?: number, position?: number): Promise<number>;
105
163
  /**
106
164
  * Asynchronously writes `string` to the file.
107
165
  * The `FileHandle` must have been opened for writing.
@@ -131,6 +189,10 @@ export declare class FileHandle implements promises.FileHandle {
131
189
  * Asynchronous close(2) - close a `FileHandle`.
132
190
  */
133
191
  close(): Promise<void>;
192
+ /**
193
+ * Cleans up. This will *not* sync the file data to the FS
194
+ */
195
+ protected dispose(force?: boolean): void;
134
196
  /**
135
197
  * Asynchronous `writev`. Writes from multiple buffers.
136
198
  * @param buffers An array of Uint8Array buffers.
@@ -181,8 +243,8 @@ export declare function truncate(this: V_Context, path: fs.PathLike, len?: numbe
181
243
  export declare function unlink(this: V_Context, path: fs.PathLike): Promise<void>;
182
244
  /**
183
245
  * Asynchronous file open.
184
- * @see http://www.manpagez.com/man/2/open/
185
- * @param flag Handles the complexity of the various file modes. See its API for more details.
246
+ * @see https://nodejs.org/api/fs.html#fspromisesopenpath-flags-mode
247
+ * @param flag {@link https://nodejs.org/api/fs.html#file-system-flags}
186
248
  * @param mode Mode to use to open the file. Can be ignored if the filesystem doesn't support permissions.
187
249
  */
188
250
  export declare function open(this: V_Context, path: fs.PathLike, flag?: fs.OpenMode, mode?: fs.Mode): Promise<FileHandle>;