@zenfs/core 1.11.3 → 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 -351
  116. package/dist/internal/file.js +0 -739
@@ -1,22 +1,9 @@
1
1
  import type * as fs from 'node:fs';
2
- import type { File } from '../internal/file.js';
3
2
  import type { FileSystem } from '../internal/filesystem.js';
4
- import type { Stats } from '../stats.js';
5
- import { type BoundContext, type V_Context } from '../context.js';
3
+ import type { V_Context } from '../context.js';
6
4
  import { ErrnoError } from '../internal/error.js';
7
- import { type AbsolutePath } from './path.js';
8
- /**
9
- * @internal @hidden
10
- */
11
- export declare const fdMap: Map<number, File>;
12
- /**
13
- * @internal @hidden
14
- */
15
- export declare function file2fd(file: File): number;
16
- /**
17
- * @internal @hidden
18
- */
19
- export declare function fd2file(fd: number): File;
5
+ import type { InodeLike } from '../internal/inode.js';
6
+ import { type AbsolutePath } from '../path.js';
20
7
  /**
21
8
  * @internal @hidden
22
9
  */
@@ -32,12 +19,12 @@ export declare const mounts: Map<string, FileSystem>;
32
19
  * @category Backends and Configuration
33
20
  * @internal
34
21
  */
35
- export declare function mount(mountPoint: string, fs: FileSystem): void;
22
+ export declare function mount(this: V_Context, mountPoint: string, fs: FileSystem): void;
36
23
  /**
37
24
  * Unmounts the file system at `mountPoint`.
38
25
  * @category Backends and Configuration
39
26
  */
40
- export declare function umount(mountPoint: string): void;
27
+ export declare function umount(this: V_Context, mountPoint: string): void;
41
28
  /**
42
29
  * @internal @hidden
43
30
  */
@@ -54,7 +41,7 @@ export interface ResolvedPath extends ResolvedMount {
54
41
  /** The real, absolute path */
55
42
  fullPath: string;
56
43
  /** Stats */
57
- stats?: Stats;
44
+ stats?: InodeLike;
58
45
  }
59
46
  /**
60
47
  * Gets the internal `FileSystem` for the path, then returns it along with the path relative to the FS' root
@@ -71,18 +58,12 @@ export declare function fixPaths(text: string, paths: Record<string, string>): s
71
58
  * @internal @hidden
72
59
  */
73
60
  export declare function fixError<E extends ErrnoError>(e: E, paths: Record<string, string>): E;
74
- /**
75
- * @internal @deprecated
76
- */
77
- export declare function mountObject(mounts: MountObject): void;
78
61
  /**
79
62
  * @internal @hidden
80
63
  */
81
64
  export declare function _statfs<const T extends boolean>(fs: FileSystem, bigint?: T): T extends true ? fs.BigIntStatsFs : fs.StatsFs;
82
65
  /**
83
66
  * Change the root path
84
- * @param inPlace if true, this changes the root for the current context instead of creating a new one (if associated with a context).
85
67
  * @category Backends and Configuration
86
68
  */
87
- export declare function chroot(this: V_Context, path: string, inPlace?: false): BoundContext;
88
- export declare function chroot<T extends V_Context>(this: T, path: string, inPlace: true): T;
69
+ export declare function chroot(this: V_Context, path: string): void;
@@ -1,34 +1,11 @@
1
1
  // Utilities and shared data
2
2
  import { InMemory } from '../backends/memory.js';
3
- import { bindContext } from '../context.js';
3
+ import { defaultContext } from '../internal/contexts.js';
4
4
  import { Errno, ErrnoError } from '../internal/error.js';
5
- import { alert, debug, err, info, log_deprecated, notice, warn } from '../internal/log.js';
5
+ import { alert, debug, err, info, notice, warn } from '../internal/log.js';
6
+ import { join, resolve } from '../path.js';
6
7
  import { normalizePath } from '../utils.js';
7
8
  import { size_max } from './constants.js';
8
- import { join, resolve } from './path.js';
9
- // descriptors
10
- /**
11
- * @internal @hidden
12
- */
13
- export const fdMap = new Map();
14
- let nextFd = 100;
15
- /**
16
- * @internal @hidden
17
- */
18
- export function file2fd(file) {
19
- const fd = nextFd++;
20
- fdMap.set(fd, file);
21
- return fd;
22
- }
23
- /**
24
- * @internal @hidden
25
- */
26
- export function fd2file(fd) {
27
- if (!fdMap.has(fd)) {
28
- throw new ErrnoError(Errno.EBADF);
29
- }
30
- return fdMap.get(fd);
31
- }
32
9
  /**
33
10
  * The map of mount points
34
11
  * @category Backends and Configuration
@@ -36,7 +13,7 @@ export function fd2file(fd) {
36
13
  */
37
14
  export const mounts = new Map();
38
15
  // Set a default root.
39
- mount('/', InMemory.create({ name: 'root' }));
16
+ mount('/', InMemory.create({ label: 'root' }));
40
17
  /**
41
18
  * Mounts the file system at `mountPoint`.
42
19
  * @category Backends and Configuration
@@ -45,7 +22,7 @@ mount('/', InMemory.create({ name: 'root' }));
45
22
  export function mount(mountPoint, fs) {
46
23
  if (mountPoint[0] != '/')
47
24
  mountPoint = '/' + mountPoint;
48
- mountPoint = resolve(mountPoint);
25
+ mountPoint = resolve.call(this, mountPoint);
49
26
  if (mounts.has(mountPoint))
50
27
  throw err(new ErrnoError(Errno.EINVAL, 'Mount point is already in use: ' + mountPoint));
51
28
  fs._mountPoint = mountPoint;
@@ -60,7 +37,7 @@ export function mount(mountPoint, fs) {
60
37
  export function umount(mountPoint) {
61
38
  if (mountPoint[0] != '/')
62
39
  mountPoint = '/' + mountPoint;
63
- mountPoint = resolve(mountPoint);
40
+ mountPoint = resolve.call(this, mountPoint);
64
41
  if (!mounts.has(mountPoint)) {
65
42
  warn(mountPoint + ' is already unmounted');
66
43
  return;
@@ -73,7 +50,7 @@ export function umount(mountPoint) {
73
50
  * @internal @hidden
74
51
  */
75
52
  export function resolveMount(path, ctx) {
76
- const root = (ctx === null || ctx === void 0 ? void 0 : ctx.root) || '/';
53
+ const root = (ctx === null || ctx === void 0 ? void 0 : ctx.root) || defaultContext.root;
77
54
  path = normalizePath(join(root, path));
78
55
  const sortedMounts = [...mounts].sort((a, b) => (a[0].length > b[0].length ? -1 : 1)); // descending order of the string length
79
56
  for (const [mountPoint, fs] of sortedMounts) {
@@ -115,20 +92,6 @@ export function fixError(e, paths) {
115
92
  e.path = fixPaths(e.path, paths);
116
93
  return e;
117
94
  }
118
- /* node:coverage disable */
119
- /**
120
- * @internal @deprecated
121
- */
122
- export function mountObject(mounts) {
123
- log_deprecated('mountObject');
124
- if ('/' in mounts) {
125
- umount('/');
126
- }
127
- for (const [point, fs] of Object.entries(mounts)) {
128
- mount(point, fs);
129
- }
130
- }
131
- /* node:coverage enable */
132
95
  /**
133
96
  * @internal @hidden
134
97
  */
@@ -136,7 +99,7 @@ export function _statfs(fs, bigint) {
136
99
  const md = fs.usage();
137
100
  const bs = md.blockSize || 4096;
138
101
  return {
139
- type: (bigint ? BigInt : Number)(fs.id),
102
+ type: (bigint ? BigInt : Number)(fs.type),
140
103
  bsize: (bigint ? BigInt : Number)(bs),
141
104
  ffree: (bigint ? BigInt : Number)(md.freeNodes || size_max),
142
105
  files: (bigint ? BigInt : Number)(md.totalNodes || size_max),
@@ -145,16 +108,25 @@ export function _statfs(fs, bigint) {
145
108
  blocks: (bigint ? BigInt : Number)(md.totalSpace / bs),
146
109
  };
147
110
  }
148
- export function chroot(path, inPlace) {
149
- const creds = this === null || this === void 0 ? void 0 : this.credentials;
150
- if ((creds === null || creds === void 0 ? void 0 : creds.uid) && (creds === null || creds === void 0 ? void 0 : creds.gid) && (creds === null || creds === void 0 ? void 0 : creds.euid) && (creds === null || creds === void 0 ? void 0 : creds.egid)) {
111
+ /**
112
+ * Change the root path
113
+ * @category Backends and Configuration
114
+ */
115
+ export function chroot(path) {
116
+ var _a, _b, _c, _d, _e, _f, _g;
117
+ const $ = this !== null && this !== void 0 ? this : defaultContext;
118
+ if (((_a = $.credentials) === null || _a === void 0 ? void 0 : _a.uid) !== 0 && ((_b = $.credentials) === null || _b === void 0 ? void 0 : _b.gid) !== 0 && ((_c = $.credentials) === null || _c === void 0 ? void 0 : _c.euid) !== 0 && ((_d = $.credentials) === null || _d === void 0 ? void 0 : _d.egid) !== 0)
151
119
  throw new ErrnoError(Errno.EPERM, 'Can not chroot() as non-root user');
120
+ (_e = $.root) !== null && _e !== void 0 ? _e : ($.root = '/');
121
+ const newRoot = join($.root, path);
122
+ for (const handle of (_g = (_f = $.descriptors) === null || _f === void 0 ? void 0 : _f.values()) !== null && _g !== void 0 ? _g : []) {
123
+ if (!handle.path.startsWith($.root))
124
+ throw ErrnoError.With('EBUSY', handle.path, 'chroot');
125
+ handle.path = handle.path.slice($.root.length);
152
126
  }
153
- if (inPlace && this) {
154
- this.root += path;
155
- return this;
156
- }
157
- return bindContext(join((this === null || this === void 0 ? void 0 : this.root) || '/', path), creds);
127
+ if (newRoot.length > $.root.length)
128
+ throw new ErrnoError(Errno.EPERM, 'Can not chroot() outside of current root');
129
+ $.root = newRoot;
158
130
  }
159
131
  /**
160
132
  * @internal @hidden
@@ -1,12 +1,6 @@
1
1
  import type * as Node from 'node:fs';
2
- import type { V_Context } from './context.js';
3
- import type { InodeFields, InodeLike } from './internal/inode.js';
4
- import * as c from './vfs/constants.js';
5
- /**
6
- * Indicates the type of a file. Applied to 'mode'.
7
- * @deprecated
8
- */
9
- export type FileType = typeof c.S_IFREG | typeof c.S_IFDIR | typeof c.S_IFLNK;
2
+ import type { V_Context } from '../context.js';
3
+ import type { InodeFields } from '../internal/inode.js';
10
4
  export interface StatsLike<T extends number | bigint = number | bigint> {
11
5
  /**
12
6
  * Size of the item in bytes.
@@ -91,12 +85,6 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
91
85
  * Group ID of owner
92
86
  */
93
87
  gid: T;
94
- /**
95
- * Some file systems stash data on stats objects.
96
- * @todo [BREAKING] Remove this
97
- * @deprecated @hidden
98
- */
99
- fileData?: unknown;
100
88
  /**
101
89
  * Time of last access, since epoch
102
90
  */
@@ -126,12 +114,22 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
126
114
  * For directories/symlinks, this is normally the size of the struct that represents the item.
127
115
  */
128
116
  size: T;
117
+ /**
118
+ * @internal Used by inodes
119
+ */
129
120
  data?: number;
121
+ /**
122
+ * @internal Used by inodes
123
+ */
130
124
  flags?: number;
125
+ /**
126
+ * @internal Used by inodes
127
+ */
128
+ version?: number;
131
129
  /**
132
130
  * Creates a new stats instance from a stats-like object. Can be used to copy stats (note)
133
131
  */
134
- constructor({ atimeMs, mtimeMs, ctimeMs, birthtimeMs, uid, gid, size, mode, ino, ...rest }?: Partial<InodeLike>);
132
+ constructor({ atimeMs, mtimeMs, ctimeMs, birthtimeMs, uid, gid, size, mode, ino, ...rest }?: Partial<StatsLike & InodeFields>);
135
133
  isFile(): boolean;
136
134
  isDirectory(): boolean;
137
135
  isSymbolicLink(): boolean;
@@ -147,18 +145,6 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
147
145
  * @internal
148
146
  */
149
147
  hasAccess(mode: number, context?: V_Context): boolean;
150
- /**
151
- * Change the mode of the file.
152
- * We use this helper function to prevent messing up the type of the file.
153
- * @internal @deprecated
154
- */
155
- chmod(mode: number): void;
156
- /**
157
- * Change the owner user/group of the file.
158
- * This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)
159
- * @internal @deprecated
160
- */
161
- chown(uid: number, gid: number): void;
162
148
  get atimeNs(): bigint;
163
149
  get mtimeNs(): bigint;
164
150
  get ctimeNs(): bigint;
@@ -167,7 +153,7 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
167
153
  /**
168
154
  * @hidden @internal
169
155
  */
170
- export declare function _chown(stats: Partial<StatsLike<number>>, uid: number, gid: number): void;
156
+ export declare function _chown(stats: Partial<StatsLike<number>>, uid: number, gid: number): boolean;
171
157
  /**
172
158
  * Implementation of Node's `Stats`.
173
159
  *
@@ -1,8 +1,6 @@
1
1
  import { pick } from 'utilium';
2
- import { credentials } from './internal/credentials.js';
3
- import { _inode_fields } from './internal/inode.js';
4
- import { log_deprecated } from './internal/log.js';
5
- import * as c from './vfs/constants.js';
2
+ import { _inode_fields, hasAccess } from '../internal/inode.js';
3
+ import * as c from './constants.js';
6
4
  const n1000 = BigInt(1000);
7
5
  /**
8
6
  * Provides information about a particular entry in the file system.
@@ -118,65 +116,8 @@ export class StatsCommon {
118
116
  * @internal
119
117
  */
120
118
  hasAccess(mode, context) {
121
- const creds = (context === null || context === void 0 ? void 0 : context.credentials) || credentials;
122
- if (this.isSymbolicLink() || creds.euid === 0 || creds.egid === 0)
123
- return true;
124
- let perm = 0;
125
- // Owner permissions
126
- if (creds.uid === this.uid) {
127
- if (this.mode & c.S_IRUSR)
128
- perm |= c.R_OK;
129
- if (this.mode & c.S_IWUSR)
130
- perm |= c.W_OK;
131
- if (this.mode & c.S_IXUSR)
132
- perm |= c.X_OK;
133
- }
134
- // Group permissions
135
- if (creds.gid === this.gid || creds.groups.includes(Number(this.gid))) {
136
- if (this.mode & c.S_IRGRP)
137
- perm |= c.R_OK;
138
- if (this.mode & c.S_IWGRP)
139
- perm |= c.W_OK;
140
- if (this.mode & c.S_IXGRP)
141
- perm |= c.X_OK;
142
- }
143
- // Others permissions
144
- if (this.mode & c.S_IROTH)
145
- perm |= c.R_OK;
146
- if (this.mode & c.S_IWOTH)
147
- perm |= c.W_OK;
148
- if (this.mode & c.S_IXOTH)
149
- perm |= c.X_OK;
150
- // Perform the access check
151
- return (perm & mode) === mode;
152
- }
153
- /* node:coverage disable */
154
- /**
155
- * Change the mode of the file.
156
- * We use this helper function to prevent messing up the type of the file.
157
- * @internal @deprecated
158
- */
159
- chmod(mode) {
160
- log_deprecated('StatsCommon#chmod');
161
- this.mode = this._convert((this.mode & c.S_IFMT) | mode);
162
- }
163
- /**
164
- * Change the owner user/group of the file.
165
- * This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)
166
- * @internal @deprecated
167
- */
168
- chown(uid, gid) {
169
- log_deprecated('StatsCommon#chown');
170
- uid = Number(uid);
171
- gid = Number(gid);
172
- if (!isNaN(uid) && 0 <= uid && uid < 2 ** 32) {
173
- this.uid = this._convert(uid);
174
- }
175
- if (!isNaN(gid) && 0 <= gid && gid < 2 ** 32) {
176
- this.gid = this._convert(gid);
177
- }
119
+ return hasAccess(context, this._isBigint ? new Stats(this) : this, mode);
178
120
  }
179
- /* node:coverage enable */
180
121
  get atimeNs() {
181
122
  return BigInt(this.atimeMs) * n1000;
182
123
  }
@@ -194,12 +135,16 @@ export class StatsCommon {
194
135
  * @hidden @internal
195
136
  */
196
137
  export function _chown(stats, uid, gid) {
197
- if (!isNaN(uid) && 0 <= uid && uid < c.size_max) {
138
+ let valid = true;
139
+ if (!isNaN(uid) && uid >= 0 && uid < c.size_max)
198
140
  stats.uid = uid;
199
- }
200
- if (!isNaN(gid) && 0 <= gid && gid < 2 ** 32) {
141
+ else
142
+ valid = false;
143
+ if (!isNaN(gid) && gid >= 0 && gid < c.size_max)
201
144
  stats.gid = gid;
202
- }
145
+ else
146
+ valid = false;
147
+ return valid;
203
148
  }
204
149
  /**
205
150
  * Implementation of Node's `Stats`.
@@ -48,6 +48,7 @@ export declare class ReadStream extends Readable implements fs.ReadStream {
48
48
  private _path;
49
49
  private _bytesRead;
50
50
  private reader?;
51
+ private ready;
51
52
  constructor(opts: CreateReadStreamOptions | undefined, handleOrPromise: FileHandle | Promise<FileHandle>);
52
53
  _read(): Promise<void>;
53
54
  close(callback?: Callback<[void], null>): void;
@@ -11,28 +11,33 @@ export class ReadStream extends Readable {
11
11
  this.pending = true;
12
12
  this._path = '<unknown>';
13
13
  this._bytesRead = 0;
14
- Promise.resolve(handleOrPromise)
15
- .then(({ file }) => {
16
- this._path = file.path;
17
- const internal = file.fs.streamRead(file.path, { start: opts.start, end: opts.end });
14
+ this.ready = Promise.resolve(handleOrPromise)
15
+ .then(handle => {
16
+ this._path = handle.path;
17
+ const internal = handle.readableWebStream({ start: opts.start, end: opts.end });
18
18
  this.reader = internal.getReader();
19
19
  this.pending = false;
20
- return this._read();
21
20
  })
22
- .catch(err => this.destroy(err));
21
+ .catch(err => {
22
+ this.destroy(err);
23
+ });
23
24
  }
24
25
  async _read() {
25
- if (!this.reader)
26
- return;
27
- const { done, value } = await this.reader.read();
28
- if (done) {
29
- this.push(null);
30
- return;
26
+ try {
27
+ await this.ready;
28
+ if (!this.reader)
29
+ return;
30
+ const { done, value } = await this.reader.read();
31
+ if (done) {
32
+ this.push(null);
33
+ return;
34
+ }
35
+ this._bytesRead += value.byteLength;
36
+ this.push(value);
37
+ }
38
+ catch (err) {
39
+ this.destroy(new ErrnoError(Errno.EIO, err.toString()));
31
40
  }
32
- this._bytesRead += value.byteLength;
33
- if (!this.push(value))
34
- return;
35
- await this._read();
36
41
  }
37
42
  close(callback = () => null) {
38
43
  try {
@@ -65,9 +70,9 @@ export class WriteStream extends Writable {
65
70
  this._path = '<unknown>';
66
71
  this._bytesWritten = 0;
67
72
  this.ready = Promise.resolve(handleOrPromise)
68
- .then(({ file }) => {
69
- this._path = file.path;
70
- const internal = file.fs.streamWrite(file.path, { start: opts.start });
73
+ .then(handle => {
74
+ this._path = handle.path;
75
+ const internal = handle.writableWebStream({ start: opts.start });
71
76
  this.writer = internal.getWriter();
72
77
  this.pending = false;
73
78
  })
@@ -1,10 +1,10 @@
1
1
  import type * as fs from 'node:fs';
2
2
  import type { V_Context } from '../context.js';
3
- import type { Stats } from '../stats.js';
3
+ import { Stats } from './stats.js';
4
4
  import type { FileContents, NullEnc, ReaddirOptions, ReaddirOptsI, ReaddirOptsU } from './types.js';
5
5
  import { Buffer } from 'buffer';
6
- import { BigIntStats } from '../stats.js';
7
6
  import { Dir, Dirent } from './dir.js';
7
+ import { BigIntStats } from './stats.js';
8
8
  export declare function renameSync(this: V_Context, oldPath: fs.PathLike, newPath: fs.PathLike): void;
9
9
  /**
10
10
  * Test whether or not `path` exists by checking with the file system.
@@ -31,7 +31,8 @@ export declare function truncateSync(this: V_Context, path: fs.PathLike, len?: n
31
31
  export declare function unlinkSync(this: V_Context, path: fs.PathLike): void;
32
32
  /**
33
33
  * Synchronous file open.
34
- * @see http://www.manpagez.com/man/2/open/
34
+ * @see https://nodejs.org/api/fs.html#fsopensyncpath-flags-mode
35
+ * @param flag {@link https://nodejs.org/api/fs.html#file-system-flags}
35
36
  */
36
37
  export declare function openSync(this: V_Context, path: fs.PathLike, flag: fs.OpenMode, mode?: fs.Mode | null): number;
37
38
  /**