@zenfs/core 2.7.7 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +5 -0
  2. package/dist/backends/index.d.ts +3 -1
  3. package/dist/backends/index.js +3 -1
  4. package/dist/backends/single_buffer/backend.d.ts +42 -0
  5. package/dist/backends/single_buffer/backend.js +204 -0
  6. package/dist/backends/{single_buffer.d.ts → single_buffer/v1.d.ts} +24 -34
  7. package/dist/backends/{single_buffer.js → single_buffer/v1.js} +10 -26
  8. package/dist/backends/single_buffer/v2.d.ts +257 -0
  9. package/dist/backends/single_buffer/v2.js +1283 -0
  10. package/dist/backends/store/fs.d.ts +1 -1
  11. package/dist/backends/store/fs.js +34 -15
  12. package/dist/backends/store/map.d.ts +6 -6
  13. package/dist/backends/store/map.js +6 -6
  14. package/dist/backends/store/store.d.ts +18 -14
  15. package/dist/backends/store/store.js +11 -11
  16. package/dist/internal/contexts.d.ts +5 -0
  17. package/dist/internal/contexts.js +7 -1
  18. package/dist/mixins/async.js +26 -7
  19. package/dist/node/promises.js +6 -103
  20. package/dist/node/sync.js +6 -33
  21. package/dist/node/types.d.ts +6 -1
  22. package/dist/vfs/async.d.ts +4 -1
  23. package/dist/vfs/async.js +72 -5
  24. package/dist/vfs/sync.d.ts +4 -1
  25. package/dist/vfs/sync.js +65 -4
  26. package/package.json +3 -3
  27. package/tests/backend/single-buffer-rotate.worker.js +1 -1
  28. package/tests/backend/single-buffer-v2.test.ts +342 -0
  29. package/tests/backend/single-buffer-v2.worker.js +51 -0
  30. package/tests/backend/single-buffer.test.ts +6 -6
  31. package/tests/backend/single-buffer.worker.js +1 -0
  32. package/tests/common/async.test.ts +11 -0
  33. package/tests/common/context.test.ts +30 -0
  34. package/tests/fs/permissions.test.ts +27 -6
  35. package/tests/fs/watch.test.ts +14 -0
  36. package/tests/perf/config.json +31 -1
  37. package/tests/perf/single-buffer-random.ts +38 -0
  38. package/tests/perf/single-buffer-read.ts +28 -0
  39. package/tests/perf/single-buffer-write.ts +41 -0
  40. package/tests/setup/single-buffer-v2.ts +10 -0
  41. package/tests/setup/single-buffer.ts +1 -0
@@ -123,7 +123,7 @@ export declare class StoreFS<T extends Store = Store> extends FileSystem {
123
123
  protected findInodeSync(tx: WrappedTransaction, path: string): Inode;
124
124
  private _lastID?;
125
125
  /** Allocates a new ID and adds the ID/path */
126
- protected allocNew(path: string): number;
126
+ protected allocNew(path: string): [number, number];
127
127
  /**
128
128
  * Commits a new file (well, a FILE or a DIRECTORY) to the file system with `mode`.
129
129
  * Note: This will commit the transaction.
@@ -616,13 +616,20 @@ export class StoreFS extends FileSystem {
616
616
  const tx = __addDisposableResource(env_17, this.transaction(), true);
617
617
  const inode = await this.findInode(tx, path);
618
618
  const end = offset + data.byteLength;
619
- let buffer = data;
620
619
  if (!tx.flag('partial')) {
621
- buffer = extendBuffer((await tx.get(inode.data)) ?? new Uint8Array(), end);
620
+ const buffer = extendBuffer((await tx.get(inode.data)) ?? new Uint8Array(), end);
622
621
  buffer.set(data, offset);
623
- offset = 0;
622
+ await tx.set(inode.data, buffer);
623
+ }
624
+ else if (offset <= inode.size) {
625
+ await tx.set(inode.data, data, offset);
626
+ }
627
+ else {
628
+ // Writes past the end of the file also zero the bytes before them
629
+ const extended = new Uint8Array(end - inode.size);
630
+ extended.set(data, offset - inode.size);
631
+ await tx.set(inode.data, extended, inode.size);
624
632
  }
625
- await tx.set(inode.data, buffer, offset);
626
633
  // Update the inode in the same transaction, so data and metadata can not get out of sync (#286)
627
634
  inode.update({ size: Math.max(inode.size, end), mtimeMs: Date.now() });
628
635
  await tx.set(inode.ino, inode);
@@ -645,13 +652,20 @@ export class StoreFS extends FileSystem {
645
652
  const tx = __addDisposableResource(env_18, this.transaction(), false);
646
653
  const inode = this.findInodeSync(tx, path);
647
654
  const end = offset + data.byteLength;
648
- let buffer = data;
649
655
  if (!tx.flag('partial')) {
650
- buffer = extendBuffer(tx.getSync(inode.data) ?? new Uint8Array(), end);
656
+ const buffer = extendBuffer(tx.getSync(inode.data) ?? new Uint8Array(), end);
651
657
  buffer.set(data, offset);
652
- offset = 0;
658
+ tx.setSync(inode.data, buffer);
659
+ }
660
+ else if (offset <= inode.size) {
661
+ tx.setSync(inode.data, data, offset);
662
+ }
663
+ else {
664
+ // Writes past the end of the file also zero the bytes before them
665
+ const extended = new Uint8Array(end - inode.size);
666
+ extended.set(data, offset - inode.size);
667
+ tx.setSync(inode.data, extended, inode.size);
653
668
  }
654
- tx.setSync(inode.data, buffer, offset);
655
669
  // Update the inode in the same transaction, so data and metadata can not get out of sync (#286)
656
670
  inode.update({ size: Math.max(inode.size, end), mtimeMs: Date.now() });
657
671
  tx.setSync(inode.ino, inode);
@@ -915,6 +929,11 @@ export class StoreFS extends FileSystem {
915
929
  _lastID;
916
930
  /** Allocates a new ID and adds the ID/path */
917
931
  allocNew(path) {
932
+ if (this.store.allocId) {
933
+ const ids = this.store.allocId();
934
+ this._add(ids[0], path);
935
+ return ids;
936
+ }
918
937
  // @todo use `Iterator` helper #296
919
938
  this._lastID ||= Array.from(this._paths.keys()).reduce((max, ino) => Math.max(max, ino), 0);
920
939
  this._lastID += 2;
@@ -922,7 +941,7 @@ export class StoreFS extends FileSystem {
922
941
  if (id > size_max)
923
942
  throw err(withErrno('ENOSPC', 'No IDs available'));
924
943
  this._add(id, path);
925
- return id;
944
+ return [id, id + 1];
926
945
  }
927
946
  /**
928
947
  * Commits a new file (well, a FILE or a DIRECTORY) to the file system with `mode`.
@@ -947,11 +966,11 @@ export class StoreFS extends FileSystem {
947
966
  const listing = decodeDirListing((await tx.get(parent.data)) ?? _throw(withErrno('ENOENT')));
948
967
  if (listing[fname])
949
968
  throw withErrno('EEXIST');
950
- const id = this.allocNew(path);
969
+ const [ino, dataId] = this.allocNew(path);
951
970
  const inode = new Inode({
952
971
  ...options,
953
- ino: id,
954
- data: id + 1,
972
+ ino,
973
+ data: dataId,
955
974
  size: data.byteLength,
956
975
  nlink: 1,
957
976
  });
@@ -996,11 +1015,11 @@ export class StoreFS extends FileSystem {
996
1015
  const listing = decodeDirListing(tx.getSync(parent.data) ?? _throw(withErrno('ENOENT')));
997
1016
  if (listing[fname])
998
1017
  throw withErrno('EEXIST');
999
- const id = this.allocNew(path);
1018
+ const [ino, dataId] = this.allocNew(path);
1000
1019
  const inode = new Inode({
1001
1020
  ...options,
1002
- ino: id,
1003
- data: id + 1,
1021
+ ino,
1022
+ data: dataId,
1004
1023
  size: data.byteLength,
1005
1024
  nlink: 1,
1006
1025
  });
@@ -6,9 +6,9 @@ import { AsyncTransaction, SyncTransaction } from './store.js';
6
6
  */
7
7
  export interface SyncMapStore extends Store {
8
8
  keys(): Iterable<number>;
9
- get(id: number): Uint8Array | undefined;
10
- getAsync?(id: number): Promise<Uint8Array | undefined>;
11
- set(id: number, data: Uint8Array): void;
9
+ get(id: number, offset?: number, end?: number): Uint8Array | undefined;
10
+ getAsync?(id: number, offset?: number, end?: number): Promise<Uint8Array | undefined>;
11
+ set(id: number, data: Uint8Array, offset?: number): void;
12
12
  delete(id: number): void;
13
13
  }
14
14
  /**
@@ -19,9 +19,9 @@ export interface SyncMapStore extends Store {
19
19
  export declare class SyncMapTransaction extends SyncTransaction<SyncMapStore> {
20
20
  readonly store: SyncMapStore;
21
21
  keys(): Promise<Iterable<number>>;
22
- get(id: number): Promise<Uint8Array | undefined>;
23
- getSync(id: number): Uint8Array | undefined;
24
- setSync(id: number, data: Uint8Array): void;
22
+ get(id: number, offset?: number, end?: number): Promise<Uint8Array | undefined>;
23
+ getSync(id: number, offset?: number, end?: number): Uint8Array | undefined;
24
+ setSync(id: number, data: Uint8Array, offset?: number): void;
25
25
  removeSync(id: number): void;
26
26
  }
27
27
  /**
@@ -9,14 +9,14 @@ export class SyncMapTransaction extends SyncTransaction {
9
9
  async keys() {
10
10
  return this.store.keys();
11
11
  }
12
- async get(id) {
13
- return await (this.store.getAsync?.(id) ?? this.store.get(id));
12
+ async get(id, offset, end) {
13
+ return await (this.store.getAsync?.(id, offset, end) ?? this.store.get(id, offset, end));
14
14
  }
15
- getSync(id) {
16
- return this.store.get(id);
15
+ getSync(id, offset, end) {
16
+ return this.store.get(id, offset, end);
17
17
  }
18
- setSync(id, data) {
19
- this.store.set(id, data);
18
+ setSync(id, data, offset) {
19
+ this.store.set(id, data, offset);
20
20
  }
21
21
  removeSync(id) {
22
22
  this.store.delete(id);
@@ -7,7 +7,7 @@ import type { StoreFS } from './fs.js';
7
7
  * @category Stores and Transactions
8
8
  */
9
9
  export type StoreFlag =
10
- /** The store supports partial reads and writes */
10
+ /** The store supports reading ranges and writing at offsets */
11
11
  'partial';
12
12
  /**
13
13
  * Represents a key-value store.
@@ -48,6 +48,10 @@ export interface Store {
48
48
  * Usage information for the store
49
49
  */
50
50
  usage?(): UsageInfo;
51
+ /**
52
+ * Allocate IDs for a new inode + data
53
+ */
54
+ allocId?(): [ino: number, data: number];
51
55
  /**
52
56
  * @internal @hidden
53
57
  */
@@ -77,17 +81,17 @@ export declare abstract class Transaction<T extends Store = Store> {
77
81
  */
78
82
  abstract getSync(id: number, offset: number, end?: number): Uint8Array | undefined;
79
83
  /**
80
- * Adds the data to the store under an id. Overwrites any existing data.
81
- * @param id The key to add the data under.
82
- * @param data The data to add to the store.
84
+ * Stores data under an id.
85
+ * Without `offset`, replaces any existing data.
86
+ * With `offset`, writes the data at `offset` and keeps the rest, which partial stores must support.
83
87
  */
84
- abstract set(id: number, data: Uint8Array, offset: number): Promise<void>;
88
+ abstract set(id: number, data: Uint8Array, offset?: number): Promise<void>;
85
89
  /**
86
- * Adds the data to the store under and id.
87
- * @param id The key to add the data under.
88
- * @param data The data to add to the store.
90
+ * Stores data under an id.
91
+ * Without `offset`, replaces any existing data.
92
+ * With `offset`, writes the data at `offset` and keeps the rest, which partial stores must support.
89
93
  */
90
- abstract setSync(id: number, data: Uint8Array, offset: number): void;
94
+ abstract setSync(id: number, data: Uint8Array, offset?: number): void;
91
95
  /**
92
96
  * Deletes the data at `ino`.
93
97
  * @param id The key to delete from the store.
@@ -105,7 +109,7 @@ export declare abstract class Transaction<T extends Store = Store> {
105
109
  */
106
110
  export declare abstract class SyncTransaction<T extends Store = Store> extends Transaction<T> {
107
111
  get(id: number, offset: number, end?: number): Promise<Uint8Array | undefined>;
108
- set(id: number, data: Uint8Array, offset: number): Promise<void>;
112
+ set(id: number, data: Uint8Array, offset?: number): Promise<void>;
109
113
  remove(id: number): Promise<void>;
110
114
  }
111
115
  /**
@@ -136,7 +140,7 @@ export declare abstract class AsyncTransaction<T extends AsyncStore = AsyncStore
136
140
  size: number;
137
141
  }): Resource<number> | undefined;
138
142
  getSync(id: number, offset: number, end?: number): Uint8Array | undefined;
139
- setSync(id: number, data: Uint8Array, offset: number): void;
143
+ setSync(id: number, data: Uint8Array, offset?: number): void;
140
144
  removeSync(id: number): void;
141
145
  }
142
146
  /**
@@ -160,7 +164,7 @@ export declare class WrappedTransaction<T extends Store = Store> {
160
164
  */
161
165
  protected originalData: Map<number, {
162
166
  data?: Uint8Array;
163
- offset: number;
167
+ offset?: number;
164
168
  }[]>;
165
169
  /**
166
170
  * List of keys modified in this transaction, if any.
@@ -189,9 +193,9 @@ export declare class WrappedTransaction<T extends Store = Store> {
189
193
  /**
190
194
  * Marks an id as modified, and stashes its value if it has not been stashed already.
191
195
  */
192
- protected markModified(id: number, offset: number, length?: number): Promise<void>;
196
+ protected markModified(id: number, offset?: number, length?: number): Promise<void>;
193
197
  /**
194
198
  * Marks an id as modified, and stashes its value if it has not been stashed already.
195
199
  */
196
- protected markModifiedSync(id: number, offset: number, length?: number): void;
200
+ protected markModifiedSync(id: number, offset?: number, length?: number): void;
197
201
  }
@@ -126,22 +126,22 @@ export class WrappedTransaction {
126
126
  this.stash(id);
127
127
  return data;
128
128
  }
129
- async set(id, view, offset = 0) {
129
+ async set(id, view, offset) {
130
130
  await this.markModified(id, offset, view.byteLength);
131
131
  const buffer = view instanceof Uint8Array ? view : new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
132
132
  await this.raw.set(id, buffer, offset);
133
133
  }
134
- setSync(id, view, offset = 0) {
134
+ setSync(id, view, offset) {
135
135
  this.markModifiedSync(id, offset, view.byteLength);
136
136
  const buffer = view instanceof Uint8Array ? view : new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
137
137
  this.raw.setSync(id, buffer, offset);
138
138
  }
139
139
  async remove(id) {
140
- await this.markModified(id, 0, undefined);
140
+ await this.markModified(id);
141
141
  await this.raw.remove(id);
142
142
  }
143
143
  removeSync(id) {
144
- this.markModifiedSync(id, 0, undefined);
144
+ this.markModifiedSync(id);
145
145
  this.raw.removeSync(id);
146
146
  }
147
147
  commit() {
@@ -201,7 +201,7 @@ export class WrappedTransaction {
201
201
  * prevent needless `get` requests if the program modifies the data later
202
202
  * on during the transaction.
203
203
  */
204
- stash(id, data, offset = 0) {
204
+ stash(id, data, offset) {
205
205
  this.originalData.getOrInsertComputed(id, () => []).push({ data, offset });
206
206
  }
207
207
  /**
@@ -209,9 +209,9 @@ export class WrappedTransaction {
209
209
  */
210
210
  async markModified(id, offset, length) {
211
211
  this.modifiedKeys.add(id);
212
- const end = length ? offset + length : undefined;
212
+ const end = offset !== undefined && length ? offset + length : undefined;
213
213
  try {
214
- this.stash(id, await this.raw.get(id, offset, end), offset);
214
+ this.stash(id, await this.raw.get(id, offset ?? 0, end), offset);
215
215
  }
216
216
  catch (e) {
217
217
  if (!(this.raw instanceof AsyncTransaction))
@@ -225,7 +225,7 @@ export class WrappedTransaction {
225
225
  const resource = tx._cached(id);
226
226
  if (!resource)
227
227
  throw e;
228
- for (const range of resource.cached(offset, end ?? offset)) {
228
+ for (const range of resource.cached(offset ?? 0, end ?? offset ?? 0)) {
229
229
  this.stash(id, await this.raw.get(id, range.start, range.end), range.start);
230
230
  }
231
231
  }
@@ -235,9 +235,9 @@ export class WrappedTransaction {
235
235
  */
236
236
  markModifiedSync(id, offset, length) {
237
237
  this.modifiedKeys.add(id);
238
- const end = length ? offset + length : undefined;
238
+ const end = offset !== undefined && length ? offset + length : undefined;
239
239
  try {
240
- this.stash(id, this.raw.getSync(id, offset, end), offset);
240
+ this.stash(id, this.raw.getSync(id, offset ?? 0, end), offset);
241
241
  }
242
242
  catch (e) {
243
243
  if (!(this.raw instanceof AsyncTransaction))
@@ -251,7 +251,7 @@ export class WrappedTransaction {
251
251
  const resource = tx._cached(id);
252
252
  if (!resource)
253
253
  throw e;
254
- for (const range of resource.cached(offset, end ?? offset)) {
254
+ for (const range of resource.cached(offset ?? 0, end ?? offset ?? 0)) {
255
255
  this.stash(id, this.raw.getSync(id, range.start, range.end), range.start);
256
256
  }
257
257
  }
@@ -28,6 +28,8 @@ export interface FSContext {
28
28
  pwd: string;
29
29
  /** The credentials of the context, used for access checks */
30
30
  readonly credentials: Credentials;
31
+ /** Permission bits cleared from the mode of newly created files and directories */
32
+ umask: number;
31
33
  /** A map of open file descriptors to their handles */
32
34
  readonly descriptors: Map<number, Handle>;
33
35
  /** The parent context, if any. */
@@ -66,6 +68,7 @@ export interface ContextInit {
66
68
  root?: string;
67
69
  pwd?: string;
68
70
  credentials?: CredentialsInit;
71
+ umask?: number;
69
72
  mounts?: Record<string, FileSystem>;
70
73
  }
71
74
  /**
@@ -75,6 +78,8 @@ export interface ContextInit {
75
78
  */
76
79
  export declare const defaultContext: FSContext;
77
80
  export declare function contextOf($: unknown): FSContext;
81
+ /** Clears the permission bits of `mode` that are set in the context's umask. */
82
+ export declare function applyUmask($: unknown, mode: number): number;
78
83
  /**
79
84
  * Create a blank FS Context
80
85
  * @internal
@@ -26,6 +26,7 @@ export const defaultContext = {
26
26
  root: '/',
27
27
  pwd: '/',
28
28
  credentials: createCredentials({ uid: 0, gid: 0 }),
29
+ umask: 0,
29
30
  descriptors: new Map(),
30
31
  parent: null,
31
32
  children: [],
@@ -34,6 +35,10 @@ export const defaultContext = {
34
35
  export function contextOf($) {
35
36
  return isContext($) ? $ : defaultContext;
36
37
  }
38
+ /** Clears the permission bits of `mode` that are set in the context's umask. */
39
+ export function applyUmask($, mode) {
40
+ return mode & ~(contextOf($).umask & 0o777);
41
+ }
37
42
  // 1 is reserved for the global/default context
38
43
  let _nextId = 2;
39
44
  /**
@@ -46,13 +51,14 @@ let _nextId = 2;
46
51
  */
47
52
  export function createChildContext(parent, init = {}) {
48
53
  assertContext(parent);
49
- const { root = parent.root, pwd = parent.pwd, credentials = structuredClone(parent.credentials), mounts } = init;
54
+ const { root = parent.root, pwd = parent.pwd, credentials = structuredClone(parent.credentials), umask = parent.umask, mounts } = init;
50
55
  const ctx = {
51
56
  [kIsContext]: true,
52
57
  id: _nextId++,
53
58
  root,
54
59
  pwd,
55
60
  credentials: createCredentials(credentials),
61
+ umask,
56
62
  descriptors: new Map(),
57
63
  parent: parent,
58
64
  children: [],
@@ -63,6 +63,12 @@ import { _asyncFSKeys } from './shared.js';
63
63
  function isInLoop(key, error = new Error()) {
64
64
  return new RegExp(`__patched__[^]*(__patched__|\\b${key}Sync\\b)`).test(error.stack ?? '');
65
65
  }
66
+ /**
67
+ * Whether the stack has a queued replay below the innermost patched method.
68
+ */
69
+ function isReplay() {
70
+ return /__patched__[^]*__replay__/.test(new Error().stack ?? '');
71
+ }
66
72
  /**
67
73
  * Async() implements synchronous methods on an asynchronous file system
68
74
  *
@@ -88,10 +94,21 @@ export function Async(FS) {
88
94
  return this.sync();
89
95
  }
90
96
  _promise = Promise.resolve();
97
+ /** How many queued operations have not finished */
98
+ _pending = 0;
91
99
  /** The async methods before patching, which do not update the sync cache */
92
100
  _unpatched = {};
93
101
  _async(thunk) {
94
- this._promise = this._promise.finally(() => thunk());
102
+ this._pending++;
103
+ const replay = async function __replay__() {
104
+ try {
105
+ await thunk();
106
+ }
107
+ finally {
108
+ this._pending--;
109
+ }
110
+ };
111
+ this._promise = this._promise.finally(replay.bind(this));
95
112
  }
96
113
  _isInitialized = false;
97
114
  /** Tracks how many updates to the sync. cache we skipped during initialization */
@@ -261,17 +278,19 @@ export function Async(FS) {
261
278
  }
262
279
  /**
263
280
  * @internal
264
- * Patch all async methods to also call their synchronous counterparts unless called from themselves (either sync or async)
281
+ * Patch all async methods to wait for queued operations,
282
+ * and methods that change the file system to also call their synchronous counterparts unless called from themselves (either sync or async)
265
283
  */
266
284
  _patchAsync() {
267
- const noPatch = ['read', 'readdir', 'stat', 'exists'];
268
- const toPatch = _asyncFSKeys.filter(key => !noPatch.includes(key));
269
- for (const key of toPatch) {
285
+ const reads = ['read', 'readdir', 'stat', 'exists'];
286
+ for (const key of _asyncFSKeys) {
270
287
  // TS does not narrow the union based on the key
271
288
  const originalMethod = this[key].bind(this);
272
289
  const fn = async function __patched__(...args) {
290
+ if (this._pending && !isReplay())
291
+ await this._promise.catch(() => { });
273
292
  const result = await originalMethod(...args);
274
- if (isInLoop(key))
293
+ if (reads.includes(key) || isInLoop(key))
275
294
  return result;
276
295
  if (!this._isInitialized) {
277
296
  this._skippedCacheUpdates++;
@@ -293,7 +312,7 @@ export function Async(FS) {
293
312
  this._unpatched[key] = originalMethod;
294
313
  this[key] = fn;
295
314
  }
296
- debug(`Async: patched ${toPatch.length} methods`);
315
+ debug(`Async: patched ${_asyncFSKeys.length} methods`);
297
316
  }
298
317
  }
299
318
  return AsyncFS;
@@ -780,130 +780,33 @@ export async function readlink(path, options) {
780
780
  }
781
781
  readlink;
782
782
  export async function chown(path, uid, gid) {
783
- const env_8 = { stack: [], error: void 0, hasError: false };
784
- try {
785
- const handle = __addDisposableResource(env_8, await open.call(this, path, 'r+'), true);
786
- await handle.chown(uid, gid);
787
- }
788
- catch (e_8) {
789
- env_8.error = e_8;
790
- env_8.hasError = true;
791
- }
792
- finally {
793
- const result_6 = __disposeResources(env_8);
794
- if (result_6)
795
- await result_6;
796
- }
783
+ await _async.chown.call(this, path, uid, gid, false);
797
784
  }
798
785
  chown;
799
786
  export async function lchown(path, uid, gid) {
800
- const env_9 = { stack: [], error: void 0, hasError: false };
801
- try {
802
- const handle = __addDisposableResource(env_9, await _async.open(this, path, {
803
- flag: 'r+',
804
- mode: 0o644,
805
- preserveSymlinks: true,
806
- allowDirectory: true,
807
- }), true);
808
- await handle.chown(uid, gid);
809
- }
810
- catch (e_9) {
811
- env_9.error = e_9;
812
- env_9.hasError = true;
813
- }
814
- finally {
815
- const result_7 = __disposeResources(env_9);
816
- if (result_7)
817
- await result_7;
818
- }
787
+ await _async.chown.call(this, path, uid, gid, true);
819
788
  }
820
789
  lchown;
821
790
  export async function chmod(path, mode) {
822
- const env_10 = { stack: [], error: void 0, hasError: false };
823
- try {
824
- const handle = __addDisposableResource(env_10, await open.call(this, path, 'r+').catch(rethrow({ syscall: 'chmod', path: normalizePath.call(this, path) })), true);
825
- await handle.chmod(mode);
826
- }
827
- catch (e_10) {
828
- env_10.error = e_10;
829
- env_10.hasError = true;
830
- }
831
- finally {
832
- const result_8 = __disposeResources(env_10);
833
- if (result_8)
834
- await result_8;
835
- }
791
+ await _async.chmod.call(this, path, mode, false);
836
792
  }
837
793
  chmod;
838
794
  export async function lchmod(path, mode) {
839
- const env_11 = { stack: [], error: void 0, hasError: false };
840
- try {
841
- mode = normalizeMode(mode);
842
- const handle = __addDisposableResource(env_11, await _async.open(this, path, {
843
- flag: 'r+',
844
- mode: 0o644,
845
- preserveSymlinks: true,
846
- allowDirectory: true,
847
- }), true);
848
- await handle.chmod(mode);
849
- }
850
- catch (e_11) {
851
- env_11.error = e_11;
852
- env_11.hasError = true;
853
- }
854
- finally {
855
- const result_9 = __disposeResources(env_11);
856
- if (result_9)
857
- await result_9;
858
- }
795
+ await _async.chmod.call(this, path, mode, true);
859
796
  }
860
797
  lchmod;
861
798
  /**
862
799
  * Change file timestamps of the file referenced by the supplied path.
863
800
  */
864
801
  export async function utimes(path, atime, mtime) {
865
- const env_12 = { stack: [], error: void 0, hasError: false };
866
- try {
867
- const handle = __addDisposableResource(env_12, await _async.open(this, path, {
868
- flag: 'r+',
869
- allowDirectory: true,
870
- }), true);
871
- await handle.utimes(normalizeTime(atime), normalizeTime(mtime));
872
- }
873
- catch (e_12) {
874
- env_12.error = e_12;
875
- env_12.hasError = true;
876
- }
877
- finally {
878
- const result_10 = __disposeResources(env_12);
879
- if (result_10)
880
- await result_10;
881
- }
802
+ await _async.utimes.call(this, path, atime, mtime, false);
882
803
  }
883
804
  utimes;
884
805
  /**
885
806
  * Change file timestamps of the file referenced by the supplied path.
886
807
  */
887
808
  export async function lutimes(path, atime, mtime) {
888
- const env_13 = { stack: [], error: void 0, hasError: false };
889
- try {
890
- const handle = __addDisposableResource(env_13, await _async.open(this, path, {
891
- flag: 'r+',
892
- mode: 0o644,
893
- preserveSymlinks: true,
894
- allowDirectory: true,
895
- }), true);
896
- await handle.utimes(normalizeTime(atime), normalizeTime(mtime));
897
- }
898
- catch (e_13) {
899
- env_13.error = e_13;
900
- env_13.hasError = true;
901
- }
902
- finally {
903
- const result_11 = __disposeResources(env_13);
904
- if (result_11)
905
- await result_11;
906
- }
809
+ await _async.utimes.call(this, path, atime, mtime, true);
907
810
  }
908
811
  lutimes;
909
812
  export async function realpath(path, options) {
package/dist/node/sync.js CHANGED
@@ -453,60 +453,33 @@ export function readlinkSync(path, options) {
453
453
  }
454
454
  readlinkSync;
455
455
  export function chownSync(path, uid, gid) {
456
- const env_7 = { stack: [], error: void 0, hasError: false };
457
- try {
458
- const handle = __addDisposableResource(env_7, _sync.open(this, path, { flag: 'r+', mode: constants.F_OK }), false);
459
- handle.chownSync(uid, gid);
460
- }
461
- catch (e_7) {
462
- env_7.error = e_7;
463
- env_7.hasError = true;
464
- }
465
- finally {
466
- __disposeResources(env_7);
467
- }
456
+ _sync.chown.call(this, path, uid, gid);
468
457
  }
469
458
  chownSync;
470
459
  export function lchownSync(path, uid, gid) {
471
- const fd = lopenSync.call(this, path, 'r+');
472
- fchownSync.call(this, fd, uid, gid);
473
- closeSync.call(this, fd);
460
+ _sync.chown.call(this, path, uid, gid, true);
474
461
  }
475
462
  lchownSync;
476
463
  export function chmodSync(path, mode) {
477
- let fd;
478
- try {
479
- fd = openSync.call(this, path, 'r+');
480
- }
481
- catch (e) {
482
- throw setUVMessage(Object.assign(e, { syscall: 'chmod', path: normalizePath.call(this, path) }));
483
- }
484
- fchmodSync.call(this, fd, mode);
485
- closeSync.call(this, fd);
464
+ _sync.chmod.call(this, path, mode);
486
465
  }
487
466
  chmodSync;
488
467
  export function lchmodSync(path, mode) {
489
- const fd = lopenSync.call(this, path, 'r+');
490
- fchmodSync.call(this, fd, mode);
491
- closeSync.call(this, fd);
468
+ _sync.chmod.call(this, path, mode, true);
492
469
  }
493
470
  lchmodSync;
494
471
  /**
495
472
  * Change file timestamps of the file referenced by the supplied path.
496
473
  */
497
474
  export function utimesSync(path, atime, mtime) {
498
- const fd = openSync.call(this, path, 'r+');
499
- futimesSync.call(this, fd, atime, mtime);
500
- closeSync.call(this, fd);
475
+ _sync.utimes.call(this, path, atime, mtime);
501
476
  }
502
477
  utimesSync;
503
478
  /**
504
479
  * Change file timestamps of the file referenced by the supplied path.
505
480
  */
506
481
  export function lutimesSync(path, atime, mtime) {
507
- const fd = lopenSync.call(this, path, 'r+');
508
- futimesSync.call(this, fd, atime, mtime);
509
- closeSync.call(this, fd);
482
+ _sync.utimes.call(this, path, atime, mtime, true);
510
483
  }
511
484
  lutimesSync;
512
485
  export function realpathSync(path, options) {