@zenfs/core 0.18.0 → 1.0.0-rc.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.
@@ -49,8 +49,7 @@ export class MutexLock {
49
49
  get isLocked() {
50
50
  return this._isLocked;
51
51
  }
52
- constructor(path, previous) {
53
- this.path = path;
52
+ constructor(previous) {
54
53
  this.previous = previous;
55
54
  this.current = Promise.withResolvers();
56
55
  this._isLocked = true;
@@ -68,405 +67,402 @@ export class MutexLock {
68
67
  }
69
68
  }
70
69
  /**
71
- * This serializes access to an underlying async filesystem.
72
- * For example, on an OverlayFS instance with an async lower
73
- * directory operations like rename and rmdir may involve multiple
74
- * requests involving both the upper and lower filesystems -- they
75
- * are not executed in a single atomic step. OverlayFS uses this
76
- * to avoid having to reason about the correctness of
77
- * multiple requests interleaving.
78
- *
79
- * Note: `@ts-expect-error 2513` is needed because `FS` is not properly detected as being concrete
80
- *
81
- * @todo Change `using _` to `using void` pending https://github.com/tc39/proposal-discard-binding
82
- * @internal
70
+ * @hidden
83
71
  */
84
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
- export function Mutexed(FS) {
86
- class MutexedFS extends FS {
87
- constructor() {
88
- super(...arguments);
89
- /**
90
- * The current locks
91
- */
92
- this.locks = new Map();
93
- /* eslint-enable @typescript-eslint/no-unused-vars */
94
- }
95
- /**
96
- * Adds a lock for a path
97
- */
98
- addLock(path) {
99
- const previous = this.locks.get(path);
100
- const lock = new MutexLock(path, previous?.isLocked ? previous : undefined);
101
- this.locks.set(path, lock);
102
- return lock;
103
- }
104
- /**
105
- * Locks `path` asynchronously.
106
- * If the path is currently locked, waits for it to be unlocked.
107
- * @internal
108
- */
109
- async lock(path, syscall) {
110
- const previous = this.locks.get(path);
111
- const lock = this.addLock(path);
112
- const stack = new Error().stack;
113
- setTimeout(() => {
114
- if (lock.isLocked) {
115
- const error = ErrnoError.With('EDEADLK', path, syscall);
116
- error.stack += stack?.slice('Error'.length);
117
- throw error;
118
- }
119
- }, 5000);
120
- await previous?.done();
121
- return lock;
122
- }
123
- /**
124
- * Locks `path` asynchronously.
125
- * If the path is currently locked, an error will be thrown
126
- * @internal
127
- */
128
- lockSync(path) {
129
- if (this.locks.has(path)) {
130
- // Non-null assertion: we already checked locks has path
131
- throw ErrnoError.With('EBUSY', path, 'lock');
132
- }
133
- return this.addLock(path);
134
- }
135
- /**
136
- * Whether `path` is locked
137
- * @internal
138
- */
139
- isLocked(path) {
140
- return !!this.locks.get(path)?.isLocked;
141
- }
142
- /* eslint-disable @typescript-eslint/no-unused-vars */
143
- async rename(oldPath, newPath) {
144
- const env_1 = { stack: [], error: void 0, hasError: false };
145
- try {
146
- const _ = __addDisposableResource(env_1, await this.lock(oldPath, 'rename'), false);
147
- // @ts-expect-error 2513
148
- await super.rename(oldPath, newPath);
149
- }
150
- catch (e_1) {
151
- env_1.error = e_1;
152
- env_1.hasError = true;
153
- }
154
- finally {
155
- __disposeResources(env_1);
156
- }
72
+ export class __MutexedFS {
73
+ async ready() {
74
+ return await this._fs.ready();
75
+ }
76
+ metadata() {
77
+ return this._fs.metadata();
78
+ }
79
+ /**
80
+ * Adds a lock for a path
81
+ */
82
+ addLock() {
83
+ const lock = new MutexLock(this.currentLock);
84
+ this.currentLock = lock;
85
+ return lock;
86
+ }
87
+ /**
88
+ * Locks `path` asynchronously.
89
+ * If the path is currently locked, waits for it to be unlocked.
90
+ * @internal
91
+ */
92
+ async lock(path, syscall) {
93
+ const previous = this.currentLock;
94
+ const lock = this.addLock();
95
+ const stack = new Error().stack;
96
+ setTimeout(() => {
97
+ if (lock.isLocked) {
98
+ const error = ErrnoError.With('EDEADLK', path, syscall);
99
+ error.stack += stack?.slice('Error'.length);
100
+ throw error;
101
+ }
102
+ }, 5000);
103
+ await previous?.done();
104
+ return lock;
105
+ }
106
+ /**
107
+ * Locks `path` asynchronously.
108
+ * If the path is currently locked, an error will be thrown
109
+ * @internal
110
+ */
111
+ lockSync(path, syscall) {
112
+ if (this.currentLock) {
113
+ throw ErrnoError.With('EBUSY', path, syscall);
157
114
  }
158
- renameSync(oldPath, newPath) {
159
- const env_2 = { stack: [], error: void 0, hasError: false };
160
- try {
161
- const _ = __addDisposableResource(env_2, this.lockSync(oldPath), false);
162
- // @ts-expect-error 2513
163
- return super.renameSync(oldPath, newPath);
164
- }
165
- catch (e_2) {
166
- env_2.error = e_2;
167
- env_2.hasError = true;
168
- }
169
- finally {
170
- __disposeResources(env_2);
171
- }
115
+ return this.addLock();
116
+ }
117
+ /**
118
+ * Whether `path` is locked
119
+ * @internal
120
+ */
121
+ get isLocked() {
122
+ return !!this.currentLock?.isLocked;
123
+ }
124
+ /* eslint-disable @typescript-eslint/no-unused-vars */
125
+ async rename(oldPath, newPath) {
126
+ const env_1 = { stack: [], error: void 0, hasError: false };
127
+ try {
128
+ const _ = __addDisposableResource(env_1, await this.lock(oldPath, 'rename'), false);
129
+ await this._fs.rename(oldPath, newPath);
172
130
  }
173
- async stat(path) {
174
- const env_3 = { stack: [], error: void 0, hasError: false };
175
- try {
176
- const _ = __addDisposableResource(env_3, await this.lock(path, 'stat'), false);
177
- // @ts-expect-error 2513
178
- return await super.stat(path);
179
- }
180
- catch (e_3) {
181
- env_3.error = e_3;
182
- env_3.hasError = true;
183
- }
184
- finally {
185
- __disposeResources(env_3);
186
- }
131
+ catch (e_1) {
132
+ env_1.error = e_1;
133
+ env_1.hasError = true;
187
134
  }
188
- statSync(path) {
189
- const env_4 = { stack: [], error: void 0, hasError: false };
190
- try {
191
- const _ = __addDisposableResource(env_4, this.lockSync(path), false);
192
- // @ts-expect-error 2513
193
- return super.statSync(path);
194
- }
195
- catch (e_4) {
196
- env_4.error = e_4;
197
- env_4.hasError = true;
198
- }
199
- finally {
200
- __disposeResources(env_4);
201
- }
135
+ finally {
136
+ __disposeResources(env_1);
202
137
  }
203
- async openFile(path, flag) {
204
- const env_5 = { stack: [], error: void 0, hasError: false };
205
- try {
206
- const _ = __addDisposableResource(env_5, await this.lock(path, 'openFile'), false);
207
- // @ts-expect-error 2513
208
- return await super.openFile(path, flag);
209
- }
210
- catch (e_5) {
211
- env_5.error = e_5;
212
- env_5.hasError = true;
213
- }
214
- finally {
215
- __disposeResources(env_5);
216
- }
138
+ }
139
+ renameSync(oldPath, newPath) {
140
+ const env_2 = { stack: [], error: void 0, hasError: false };
141
+ try {
142
+ const _ = __addDisposableResource(env_2, this.lockSync(oldPath, 'rename'), false);
143
+ return this._fs.renameSync(oldPath, newPath);
217
144
  }
218
- openFileSync(path, flag) {
219
- const env_6 = { stack: [], error: void 0, hasError: false };
220
- try {
221
- const _ = __addDisposableResource(env_6, this.lockSync(path), false);
222
- // @ts-expect-error 2513
223
- return super.openFileSync(path, flag);
224
- }
225
- catch (e_6) {
226
- env_6.error = e_6;
227
- env_6.hasError = true;
228
- }
229
- finally {
230
- __disposeResources(env_6);
231
- }
145
+ catch (e_2) {
146
+ env_2.error = e_2;
147
+ env_2.hasError = true;
232
148
  }
233
- async createFile(path, flag, mode) {
234
- const env_7 = { stack: [], error: void 0, hasError: false };
235
- try {
236
- const _ = __addDisposableResource(env_7, await this.lock(path, 'createFile'), false);
237
- // @ts-expect-error 2513
238
- return await super.createFile(path, flag, mode);
239
- }
240
- catch (e_7) {
241
- env_7.error = e_7;
242
- env_7.hasError = true;
243
- }
244
- finally {
245
- __disposeResources(env_7);
246
- }
149
+ finally {
150
+ __disposeResources(env_2);
247
151
  }
248
- createFileSync(path, flag, mode) {
249
- const env_8 = { stack: [], error: void 0, hasError: false };
250
- try {
251
- const _ = __addDisposableResource(env_8, this.lockSync(path), false);
252
- // @ts-expect-error 2513
253
- return super.createFileSync(path, flag, mode);
254
- }
255
- catch (e_8) {
256
- env_8.error = e_8;
257
- env_8.hasError = true;
258
- }
259
- finally {
260
- __disposeResources(env_8);
261
- }
152
+ }
153
+ async stat(path) {
154
+ const env_3 = { stack: [], error: void 0, hasError: false };
155
+ try {
156
+ const _ = __addDisposableResource(env_3, await this.lock(path, 'stat'), false);
157
+ return await this._fs.stat(path);
262
158
  }
263
- async unlink(path) {
264
- const env_9 = { stack: [], error: void 0, hasError: false };
265
- try {
266
- const _ = __addDisposableResource(env_9, await this.lock(path, 'unlink'), false);
267
- // @ts-expect-error 2513
268
- await super.unlink(path);
269
- }
270
- catch (e_9) {
271
- env_9.error = e_9;
272
- env_9.hasError = true;
273
- }
274
- finally {
275
- __disposeResources(env_9);
276
- }
159
+ catch (e_3) {
160
+ env_3.error = e_3;
161
+ env_3.hasError = true;
277
162
  }
278
- unlinkSync(path) {
279
- const env_10 = { stack: [], error: void 0, hasError: false };
280
- try {
281
- const _ = __addDisposableResource(env_10, this.lockSync(path), false);
282
- // @ts-expect-error 2513
283
- return super.unlinkSync(path);
284
- }
285
- catch (e_10) {
286
- env_10.error = e_10;
287
- env_10.hasError = true;
288
- }
289
- finally {
290
- __disposeResources(env_10);
291
- }
163
+ finally {
164
+ __disposeResources(env_3);
292
165
  }
293
- async rmdir(path) {
294
- const env_11 = { stack: [], error: void 0, hasError: false };
295
- try {
296
- const _ = __addDisposableResource(env_11, await this.lock(path, 'rmdir'), false);
297
- // @ts-expect-error 2513
298
- await super.rmdir(path);
299
- }
300
- catch (e_11) {
301
- env_11.error = e_11;
302
- env_11.hasError = true;
303
- }
304
- finally {
305
- __disposeResources(env_11);
306
- }
166
+ }
167
+ statSync(path) {
168
+ const env_4 = { stack: [], error: void 0, hasError: false };
169
+ try {
170
+ const _ = __addDisposableResource(env_4, this.lockSync(path, 'stat'), false);
171
+ return this._fs.statSync(path);
307
172
  }
308
- rmdirSync(path) {
309
- const env_12 = { stack: [], error: void 0, hasError: false };
310
- try {
311
- const _ = __addDisposableResource(env_12, this.lockSync(path), false);
312
- // @ts-expect-error 2513
313
- return super.rmdirSync(path);
314
- }
315
- catch (e_12) {
316
- env_12.error = e_12;
317
- env_12.hasError = true;
318
- }
319
- finally {
320
- __disposeResources(env_12);
321
- }
173
+ catch (e_4) {
174
+ env_4.error = e_4;
175
+ env_4.hasError = true;
322
176
  }
323
- async mkdir(path, mode) {
324
- const env_13 = { stack: [], error: void 0, hasError: false };
325
- try {
326
- const _ = __addDisposableResource(env_13, await this.lock(path, 'mkdir'), false);
327
- // @ts-expect-error 2513
328
- await super.mkdir(path, mode);
329
- }
330
- catch (e_13) {
331
- env_13.error = e_13;
332
- env_13.hasError = true;
333
- }
334
- finally {
335
- __disposeResources(env_13);
336
- }
177
+ finally {
178
+ __disposeResources(env_4);
337
179
  }
338
- mkdirSync(path, mode) {
339
- const env_14 = { stack: [], error: void 0, hasError: false };
340
- try {
341
- const _ = __addDisposableResource(env_14, this.lockSync(path), false);
342
- // @ts-expect-error 2513
343
- return super.mkdirSync(path, mode);
344
- }
345
- catch (e_14) {
346
- env_14.error = e_14;
347
- env_14.hasError = true;
348
- }
349
- finally {
350
- __disposeResources(env_14);
351
- }
180
+ }
181
+ async openFile(path, flag) {
182
+ const env_5 = { stack: [], error: void 0, hasError: false };
183
+ try {
184
+ const _ = __addDisposableResource(env_5, await this.lock(path, 'openFile'), false);
185
+ const file = await this._fs.openFile(path, flag);
186
+ file.fs = this;
187
+ return file;
352
188
  }
353
- async readdir(path) {
354
- const env_15 = { stack: [], error: void 0, hasError: false };
355
- try {
356
- const _ = __addDisposableResource(env_15, await this.lock(path, 'readdir'), false);
357
- // @ts-expect-error 2513
358
- return await super.readdir(path);
359
- }
360
- catch (e_15) {
361
- env_15.error = e_15;
362
- env_15.hasError = true;
363
- }
364
- finally {
365
- __disposeResources(env_15);
366
- }
189
+ catch (e_5) {
190
+ env_5.error = e_5;
191
+ env_5.hasError = true;
367
192
  }
368
- readdirSync(path) {
369
- const env_16 = { stack: [], error: void 0, hasError: false };
370
- try {
371
- const _ = __addDisposableResource(env_16, this.lockSync(path), false);
372
- // @ts-expect-error 2513
373
- return super.readdirSync(path);
374
- }
375
- catch (e_16) {
376
- env_16.error = e_16;
377
- env_16.hasError = true;
378
- }
379
- finally {
380
- __disposeResources(env_16);
381
- }
193
+ finally {
194
+ __disposeResources(env_5);
382
195
  }
383
- async exists(path) {
384
- const env_17 = { stack: [], error: void 0, hasError: false };
385
- try {
386
- const _ = __addDisposableResource(env_17, await this.lock(path, 'exists'), false);
387
- return await super.exists(path);
388
- }
389
- catch (e_17) {
390
- env_17.error = e_17;
391
- env_17.hasError = true;
392
- }
393
- finally {
394
- __disposeResources(env_17);
395
- }
196
+ }
197
+ openFileSync(path, flag) {
198
+ const env_6 = { stack: [], error: void 0, hasError: false };
199
+ try {
200
+ const _ = __addDisposableResource(env_6, this.lockSync(path, 'openFile'), false);
201
+ const file = this._fs.openFileSync(path, flag);
202
+ file.fs = this;
203
+ return file;
396
204
  }
397
- existsSync(path) {
398
- const env_18 = { stack: [], error: void 0, hasError: false };
399
- try {
400
- const _ = __addDisposableResource(env_18, this.lockSync(path), false);
401
- return super.existsSync(path);
402
- }
403
- catch (e_18) {
404
- env_18.error = e_18;
405
- env_18.hasError = true;
406
- }
407
- finally {
408
- __disposeResources(env_18);
409
- }
205
+ catch (e_6) {
206
+ env_6.error = e_6;
207
+ env_6.hasError = true;
410
208
  }
411
- async link(srcpath, dstpath) {
412
- const env_19 = { stack: [], error: void 0, hasError: false };
413
- try {
414
- const _ = __addDisposableResource(env_19, await this.lock(srcpath, 'link'), false);
415
- // @ts-expect-error 2513
416
- await super.link(srcpath, dstpath);
417
- }
418
- catch (e_19) {
419
- env_19.error = e_19;
420
- env_19.hasError = true;
421
- }
422
- finally {
423
- __disposeResources(env_19);
424
- }
209
+ finally {
210
+ __disposeResources(env_6);
425
211
  }
426
- linkSync(srcpath, dstpath) {
427
- const env_20 = { stack: [], error: void 0, hasError: false };
428
- try {
429
- const _ = __addDisposableResource(env_20, this.lockSync(srcpath), false);
430
- // @ts-expect-error 2513
431
- return super.linkSync(srcpath, dstpath);
432
- }
433
- catch (e_20) {
434
- env_20.error = e_20;
435
- env_20.hasError = true;
436
- }
437
- finally {
438
- __disposeResources(env_20);
439
- }
212
+ }
213
+ async createFile(path, flag, mode) {
214
+ const env_7 = { stack: [], error: void 0, hasError: false };
215
+ try {
216
+ const _ = __addDisposableResource(env_7, await this.lock(path, 'createFile'), false);
217
+ const file = await this._fs.createFile(path, flag, mode);
218
+ file.fs = this;
219
+ return file;
440
220
  }
441
- async sync(path, data, stats) {
442
- const env_21 = { stack: [], error: void 0, hasError: false };
443
- try {
444
- const _ = __addDisposableResource(env_21, await this.lock(path, 'sync'), false);
445
- // @ts-expect-error 2513
446
- await super.sync(path, data, stats);
447
- }
448
- catch (e_21) {
449
- env_21.error = e_21;
450
- env_21.hasError = true;
451
- }
452
- finally {
453
- __disposeResources(env_21);
454
- }
221
+ catch (e_7) {
222
+ env_7.error = e_7;
223
+ env_7.hasError = true;
455
224
  }
456
- syncSync(path, data, stats) {
457
- const env_22 = { stack: [], error: void 0, hasError: false };
458
- try {
459
- const _ = __addDisposableResource(env_22, this.lockSync(path), false);
460
- // @ts-expect-error 2513
461
- return super.syncSync(path, data, stats);
462
- }
463
- catch (e_22) {
464
- env_22.error = e_22;
465
- env_22.hasError = true;
466
- }
467
- finally {
468
- __disposeResources(env_22);
469
- }
225
+ finally {
226
+ __disposeResources(env_7);
227
+ }
228
+ }
229
+ createFileSync(path, flag, mode) {
230
+ const env_8 = { stack: [], error: void 0, hasError: false };
231
+ try {
232
+ const _ = __addDisposableResource(env_8, this.lockSync(path, 'createFile'), false);
233
+ const file = this._fs.createFileSync(path, flag, mode);
234
+ file.fs = this;
235
+ return file;
236
+ }
237
+ catch (e_8) {
238
+ env_8.error = e_8;
239
+ env_8.hasError = true;
240
+ }
241
+ finally {
242
+ __disposeResources(env_8);
243
+ }
244
+ }
245
+ async unlink(path) {
246
+ const env_9 = { stack: [], error: void 0, hasError: false };
247
+ try {
248
+ const _ = __addDisposableResource(env_9, await this.lock(path, 'unlink'), false);
249
+ await this._fs.unlink(path);
250
+ }
251
+ catch (e_9) {
252
+ env_9.error = e_9;
253
+ env_9.hasError = true;
254
+ }
255
+ finally {
256
+ __disposeResources(env_9);
257
+ }
258
+ }
259
+ unlinkSync(path) {
260
+ const env_10 = { stack: [], error: void 0, hasError: false };
261
+ try {
262
+ const _ = __addDisposableResource(env_10, this.lockSync(path, 'unlink'), false);
263
+ return this._fs.unlinkSync(path);
264
+ }
265
+ catch (e_10) {
266
+ env_10.error = e_10;
267
+ env_10.hasError = true;
268
+ }
269
+ finally {
270
+ __disposeResources(env_10);
271
+ }
272
+ }
273
+ async rmdir(path) {
274
+ const env_11 = { stack: [], error: void 0, hasError: false };
275
+ try {
276
+ const _ = __addDisposableResource(env_11, await this.lock(path, 'rmdir'), false);
277
+ await this._fs.rmdir(path);
278
+ }
279
+ catch (e_11) {
280
+ env_11.error = e_11;
281
+ env_11.hasError = true;
282
+ }
283
+ finally {
284
+ __disposeResources(env_11);
285
+ }
286
+ }
287
+ rmdirSync(path) {
288
+ const env_12 = { stack: [], error: void 0, hasError: false };
289
+ try {
290
+ const _ = __addDisposableResource(env_12, this.lockSync(path, 'rmdir'), false);
291
+ return this._fs.rmdirSync(path);
292
+ }
293
+ catch (e_12) {
294
+ env_12.error = e_12;
295
+ env_12.hasError = true;
296
+ }
297
+ finally {
298
+ __disposeResources(env_12);
299
+ }
300
+ }
301
+ async mkdir(path, mode) {
302
+ const env_13 = { stack: [], error: void 0, hasError: false };
303
+ try {
304
+ const _ = __addDisposableResource(env_13, await this.lock(path, 'mkdir'), false);
305
+ await this._fs.mkdir(path, mode);
306
+ }
307
+ catch (e_13) {
308
+ env_13.error = e_13;
309
+ env_13.hasError = true;
310
+ }
311
+ finally {
312
+ __disposeResources(env_13);
313
+ }
314
+ }
315
+ mkdirSync(path, mode) {
316
+ const env_14 = { stack: [], error: void 0, hasError: false };
317
+ try {
318
+ const _ = __addDisposableResource(env_14, this.lockSync(path, 'mkdir'), false);
319
+ return this._fs.mkdirSync(path, mode);
320
+ }
321
+ catch (e_14) {
322
+ env_14.error = e_14;
323
+ env_14.hasError = true;
324
+ }
325
+ finally {
326
+ __disposeResources(env_14);
327
+ }
328
+ }
329
+ async readdir(path) {
330
+ const env_15 = { stack: [], error: void 0, hasError: false };
331
+ try {
332
+ const _ = __addDisposableResource(env_15, await this.lock(path, 'readdir'), false);
333
+ return await this._fs.readdir(path);
334
+ }
335
+ catch (e_15) {
336
+ env_15.error = e_15;
337
+ env_15.hasError = true;
338
+ }
339
+ finally {
340
+ __disposeResources(env_15);
341
+ }
342
+ }
343
+ readdirSync(path) {
344
+ const env_16 = { stack: [], error: void 0, hasError: false };
345
+ try {
346
+ const _ = __addDisposableResource(env_16, this.lockSync(path, 'readdir'), false);
347
+ return this._fs.readdirSync(path);
348
+ }
349
+ catch (e_16) {
350
+ env_16.error = e_16;
351
+ env_16.hasError = true;
352
+ }
353
+ finally {
354
+ __disposeResources(env_16);
355
+ }
356
+ }
357
+ async exists(path) {
358
+ const env_17 = { stack: [], error: void 0, hasError: false };
359
+ try {
360
+ const _ = __addDisposableResource(env_17, await this.lock(path, 'exists'), false);
361
+ return await this._fs.exists(path);
362
+ }
363
+ catch (e_17) {
364
+ env_17.error = e_17;
365
+ env_17.hasError = true;
366
+ }
367
+ finally {
368
+ __disposeResources(env_17);
369
+ }
370
+ }
371
+ existsSync(path) {
372
+ const env_18 = { stack: [], error: void 0, hasError: false };
373
+ try {
374
+ const _ = __addDisposableResource(env_18, this.lockSync(path, 'exists'), false);
375
+ return this._fs.existsSync(path);
376
+ }
377
+ catch (e_18) {
378
+ env_18.error = e_18;
379
+ env_18.hasError = true;
380
+ }
381
+ finally {
382
+ __disposeResources(env_18);
383
+ }
384
+ }
385
+ async link(srcpath, dstpath) {
386
+ const env_19 = { stack: [], error: void 0, hasError: false };
387
+ try {
388
+ const _ = __addDisposableResource(env_19, await this.lock(srcpath, 'link'), false);
389
+ await this._fs.link(srcpath, dstpath);
390
+ }
391
+ catch (e_19) {
392
+ env_19.error = e_19;
393
+ env_19.hasError = true;
394
+ }
395
+ finally {
396
+ __disposeResources(env_19);
397
+ }
398
+ }
399
+ linkSync(srcpath, dstpath) {
400
+ const env_20 = { stack: [], error: void 0, hasError: false };
401
+ try {
402
+ const _ = __addDisposableResource(env_20, this.lockSync(srcpath, 'link'), false);
403
+ return this._fs.linkSync(srcpath, dstpath);
404
+ }
405
+ catch (e_20) {
406
+ env_20.error = e_20;
407
+ env_20.hasError = true;
408
+ }
409
+ finally {
410
+ __disposeResources(env_20);
411
+ }
412
+ }
413
+ async sync(path, data, stats) {
414
+ const env_21 = { stack: [], error: void 0, hasError: false };
415
+ try {
416
+ const _ = __addDisposableResource(env_21, await this.lock(path, 'sync'), false);
417
+ await this._fs.sync(path, data, stats);
418
+ }
419
+ catch (e_21) {
420
+ env_21.error = e_21;
421
+ env_21.hasError = true;
422
+ }
423
+ finally {
424
+ __disposeResources(env_21);
425
+ }
426
+ }
427
+ syncSync(path, data, stats) {
428
+ const env_22 = { stack: [], error: void 0, hasError: false };
429
+ try {
430
+ const _ = __addDisposableResource(env_22, this.lockSync(path, 'sync'), false);
431
+ return this._fs.syncSync(path, data, stats);
432
+ }
433
+ catch (e_22) {
434
+ env_22.error = e_22;
435
+ env_22.hasError = true;
436
+ }
437
+ finally {
438
+ __disposeResources(env_22);
439
+ }
440
+ }
441
+ }
442
+ /**
443
+ * This serializes access to an underlying async filesystem.
444
+ * For example, on an OverlayFS instance with an async lower
445
+ * directory operations like rename and rmdir may involve multiple
446
+ * requests involving both the upper and lower filesystems -- they
447
+ * are not executed in a single atomic step. OverlayFS uses this
448
+ * to avoid having to reason about the correctness of
449
+ * multiple requests interleaving.
450
+ *
451
+ * Note:
452
+ * Instead of extending the passed class, `MutexedFS` stores it internally.
453
+ * This is to avoid a deadlock caused when a mathod calls another one
454
+ * The problem is discussed extensivly in [#78](https://github.com/zen-fs/core/issues/78)
455
+ * Instead of extending `FileSystem`,
456
+ * `MutexedFS` implements it in order to make sure all of the methods are passed through
457
+ *
458
+ * @todo Change `using _` to `using void` pending https://github.com/tc39/proposal-discard-binding
459
+ * @internal
460
+ */
461
+ export function Mutexed(FS) {
462
+ class MutexedFS extends __MutexedFS {
463
+ constructor(...args) {
464
+ super();
465
+ this._fs = new FS(...args);
470
466
  }
471
467
  }
472
468
  return MutexedFS;