@zenfs/core 2.5.8 → 2.6.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.
- package/dist/backends/cow.d.ts +13 -0
- package/dist/backends/cow.js +48 -11
- package/dist/backends/single_buffer.d.ts +2 -2
- package/dist/backends/store/fs.d.ts +6 -6
- package/dist/backends/store/fs.js +10 -2
- package/dist/internal/devices.d.ts +6 -6
- package/dist/internal/index_fs.d.ts +4 -4
- package/dist/node/async.js +1 -1
- package/dist/node/dir.d.ts +3 -1
- package/dist/node/dir.js +23 -5
- package/dist/node/promises.d.ts +3 -1
- package/dist/node/promises.js +128 -89
- package/dist/node/streams.d.ts +4 -0
- package/dist/node/streams.js +9 -10
- package/dist/node/sync.js +71 -40
- package/dist/utils.d.ts +8 -1
- package/dist/utils.js +26 -7
- package/dist/vfs/async.js +224 -85
- package/dist/vfs/file.d.ts +13 -7
- package/dist/vfs/file.js +661 -357
- package/dist/vfs/shared.d.ts +1 -0
- package/dist/vfs/shared.js +19 -3
- package/dist/vfs/sync.js +214 -85
- package/dist/vfs/vcache.d.ts +66 -0
- package/dist/vfs/vcache.js +249 -0
- package/dist/vfs/vnode.d.ts +66 -0
- package/dist/vfs/vnode.js +200 -0
- package/dist/vfs/watchers.js +4 -2
- package/dist/vfs/xattr.js +2 -2
- package/eslint.shared.js +1 -1
- package/package.json +3 -3
- package/scripts/make-index.js +7 -1
- package/scripts/test.js +28 -21
- package/tests/backend/port.test.ts +3 -3
- package/tests/backend/store.test.ts +49 -0
- package/tests/common.ts +62 -0
- package/tests/fetch/fetch.ts +6 -0
- package/tests/fetch/run.sh +2 -2
- package/tests/fetch/server.js +3 -3
- package/tests/fs/append.test.ts +5 -5
- package/tests/fs/concurrency.test.ts +52 -0
- package/tests/fs/dir.test.ts +13 -15
- package/tests/fs/directory.test.ts +32 -31
- package/tests/fs/errors.test.ts +151 -31
- package/tests/fs/exists.test.ts +4 -4
- package/tests/fs/links.test.ts +4 -11
- package/tests/fs/open.test.ts +4 -4
- package/tests/fs/permissions.test.ts +15 -15
- package/tests/fs/read.test.ts +9 -9
- package/tests/fs/readFile.test.ts +9 -9
- package/tests/fs/rename.test.ts +8 -8
- package/tests/fs/scaling.test.ts +4 -4
- package/tests/fs/stat.test.ts +20 -20
- package/tests/fs/streams.test.ts +9 -6
- package/tests/fs/tempdir.test.ts +33 -10
- package/tests/fs/times.test.ts +11 -11
- package/tests/fs/truncate.test.ts +6 -6
- package/tests/fs/watch.test.ts +107 -53
- package/tests/fs/write.test.ts +10 -10
- package/tests/fs/xattr.test.ts +3 -3
- package/tests/native/run.sh +3 -0
- package/tests/native/setup.ts +230 -0
- package/types/readable-stream.d.ts +2 -2
package/dist/node/promises.js
CHANGED
|
@@ -55,14 +55,15 @@ import { Exception, rethrow, UV } from 'kerium';
|
|
|
55
55
|
import { encodeUTF8 } from 'utilium';
|
|
56
56
|
import * as constants from '../constants.js';
|
|
57
57
|
import { hasAccess, InodeFlags, isDirectory } from '../internal/inode.js';
|
|
58
|
-
import { join, matchesGlob } from '../path.js';
|
|
58
|
+
import { dirname, join, matchesGlob } from '../path.js';
|
|
59
59
|
import '../polyfills.js';
|
|
60
|
-
import { _tempDirName, globToRegex, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
|
|
60
|
+
import { _tempDirName, globToRegex, normalizeMode, normalizeOptions, normalizePath, normalizeTime, validateFD } from '../utils.js';
|
|
61
61
|
import * as _async from '../vfs/async.js';
|
|
62
62
|
import { checkAccess } from '../vfs/config.js';
|
|
63
63
|
import { deleteFD, fromFD, toFD } from '../vfs/file.js';
|
|
64
64
|
import * as flags from '../vfs/flags.js';
|
|
65
65
|
import { _statfs, resolveMount } from '../vfs/shared.js';
|
|
66
|
+
import { cacheOf, lockPath } from '../vfs/vcache.js';
|
|
66
67
|
import { emitChange, FSWatcher } from '../vfs/watchers.js';
|
|
67
68
|
import { Dir, Dirent } from './dir.js';
|
|
68
69
|
import { createInterface } from './readline.js';
|
|
@@ -133,11 +134,15 @@ async function* applyTransform(source, transform, signal) {
|
|
|
133
134
|
}
|
|
134
135
|
export class FileHandle {
|
|
135
136
|
context;
|
|
136
|
-
fd;
|
|
137
137
|
vfs;
|
|
138
|
+
_fd;
|
|
139
|
+
/** The file descriptor, or -1 once the handle has been closed */
|
|
140
|
+
get fd() {
|
|
141
|
+
return this._fd;
|
|
142
|
+
}
|
|
138
143
|
constructor(context, fd) {
|
|
139
144
|
this.context = context;
|
|
140
|
-
this.
|
|
145
|
+
this._fd = fd;
|
|
141
146
|
this.vfs = fromFD(context, fd);
|
|
142
147
|
}
|
|
143
148
|
_emitChange() {
|
|
@@ -250,7 +255,7 @@ export class FileHandle {
|
|
|
250
255
|
readableWebStream(options = {}) {
|
|
251
256
|
if (this.vfs.isClosed)
|
|
252
257
|
throw UV('EBADF', 'readableWebStream', this.vfs.path);
|
|
253
|
-
return this.vfs.
|
|
258
|
+
return this.vfs.streamRead(options);
|
|
254
259
|
}
|
|
255
260
|
/**
|
|
256
261
|
* Not part of the Node.js API!
|
|
@@ -264,7 +269,7 @@ export class FileHandle {
|
|
|
264
269
|
throw UV('EBADF', 'writableWebStream', this.vfs.path);
|
|
265
270
|
if (this.vfs.inode.flags & InodeFlags.Immutable)
|
|
266
271
|
throw UV('EPERM', 'writableWebStream', this.vfs.path);
|
|
267
|
-
return this.vfs.
|
|
272
|
+
return this.vfs.streamWrite(options);
|
|
268
273
|
}
|
|
269
274
|
/**
|
|
270
275
|
* Creates a readline Interface object that allows reading the file line by line
|
|
@@ -340,7 +345,9 @@ export class FileHandle {
|
|
|
340
345
|
*/
|
|
341
346
|
async close() {
|
|
342
347
|
await this.vfs.close();
|
|
343
|
-
deleteFD(this.context, this.
|
|
348
|
+
deleteFD(this.context, this._fd);
|
|
349
|
+
// Like Node, the descriptor is invalidated so later use fails validation
|
|
350
|
+
this._fd = -1;
|
|
344
351
|
}
|
|
345
352
|
/**
|
|
346
353
|
* Asynchronous `writev`. Writes from multiple buffers.
|
|
@@ -377,6 +384,7 @@ export class FileHandle {
|
|
|
377
384
|
* @param options Options for the readable stream
|
|
378
385
|
*/
|
|
379
386
|
createReadStream(options = {}) {
|
|
387
|
+
validateFD(this._fd);
|
|
380
388
|
if (this.vfs.isClosed || this.vfs.flag & constants.O_WRONLY)
|
|
381
389
|
throw UV('EBADF', 'createReadStream', this.vfs.path);
|
|
382
390
|
return new ReadStream(options, this);
|
|
@@ -386,6 +394,7 @@ export class FileHandle {
|
|
|
386
394
|
* @param options Options for the writeable stream.
|
|
387
395
|
*/
|
|
388
396
|
createWriteStream(options = {}) {
|
|
397
|
+
validateFD(this._fd);
|
|
389
398
|
if (this.vfs.isClosed)
|
|
390
399
|
throw UV('EBADF', 'createWriteStream', this.vfs.path);
|
|
391
400
|
if (this.vfs.inode.flags & InodeFlags.Immutable)
|
|
@@ -559,14 +568,26 @@ export async function truncate(path, len = 0) {
|
|
|
559
568
|
}
|
|
560
569
|
truncate;
|
|
561
570
|
export async function unlink(path) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
571
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
572
|
+
try {
|
|
573
|
+
path = normalizePath(path);
|
|
574
|
+
const { fs, path: resolved } = resolveMount(path, this);
|
|
575
|
+
const $ex = { syscall: 'unlink', path };
|
|
576
|
+
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
577
|
+
if (checkAccess && !hasAccess(this, stats, constants.W_OK))
|
|
578
|
+
throw UV('EACCES', $ex);
|
|
579
|
+
const _ = __addDisposableResource(env_2, await lockPath(fs, dirname(resolved), 'rw'), false);
|
|
580
|
+
await fs.unlink(resolved).catch(rethrow($ex));
|
|
581
|
+
cacheOf(fs).remove(resolved);
|
|
582
|
+
emitChange(this, 'rename', path.toString());
|
|
583
|
+
}
|
|
584
|
+
catch (e_2) {
|
|
585
|
+
env_2.error = e_2;
|
|
586
|
+
env_2.hasError = true;
|
|
587
|
+
}
|
|
588
|
+
finally {
|
|
589
|
+
__disposeResources(env_2);
|
|
590
|
+
}
|
|
570
591
|
}
|
|
571
592
|
unlink;
|
|
572
593
|
/**
|
|
@@ -581,18 +602,18 @@ export async function open(path, flag = 'r', mode = 0o644) {
|
|
|
581
602
|
}
|
|
582
603
|
open;
|
|
583
604
|
export async function readFile(path, _options) {
|
|
584
|
-
const
|
|
605
|
+
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
585
606
|
try {
|
|
586
607
|
const options = normalizeOptions(_options, null, 'r', 0o444);
|
|
587
|
-
const handle = __addDisposableResource(
|
|
608
|
+
const handle = __addDisposableResource(env_3, typeof path == 'object' && 'fd' in path ? path : await open.call(this, path, options.flag, options.mode), true);
|
|
588
609
|
return await handle.readFile(options);
|
|
589
610
|
}
|
|
590
|
-
catch (
|
|
591
|
-
|
|
592
|
-
|
|
611
|
+
catch (e_3) {
|
|
612
|
+
env_3.error = e_3;
|
|
613
|
+
env_3.hasError = true;
|
|
593
614
|
}
|
|
594
615
|
finally {
|
|
595
|
-
const result_2 = __disposeResources(
|
|
616
|
+
const result_2 = __disposeResources(env_3);
|
|
596
617
|
if (result_2)
|
|
597
618
|
await result_2;
|
|
598
619
|
}
|
|
@@ -607,21 +628,21 @@ readFile;
|
|
|
607
628
|
* @option flag Defaults to `'w'`.
|
|
608
629
|
*/
|
|
609
630
|
export async function writeFile(path, data, _options) {
|
|
610
|
-
const
|
|
631
|
+
const env_4 = { stack: [], error: void 0, hasError: false };
|
|
611
632
|
try {
|
|
612
633
|
const options = normalizeOptions(_options, 'utf8', 'w+', 0o644);
|
|
613
|
-
const handle = __addDisposableResource(
|
|
634
|
+
const handle = __addDisposableResource(env_4, path instanceof FileHandle ? path : await open.call(this, path.toString(), options.flag, options.mode), true);
|
|
614
635
|
const _data = typeof data == 'string' ? data : data instanceof DataView ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : data;
|
|
615
636
|
if (typeof _data != 'string' && !(_data instanceof Uint8Array))
|
|
616
637
|
throw new TypeError('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received ' + typeof data);
|
|
617
638
|
await handle.writeFile(_data, options);
|
|
618
639
|
}
|
|
619
|
-
catch (
|
|
620
|
-
|
|
621
|
-
|
|
640
|
+
catch (e_4) {
|
|
641
|
+
env_4.error = e_4;
|
|
642
|
+
env_4.hasError = true;
|
|
622
643
|
}
|
|
623
644
|
finally {
|
|
624
|
-
const result_3 = __disposeResources(
|
|
645
|
+
const result_3 = __disposeResources(env_4);
|
|
625
646
|
if (result_3)
|
|
626
647
|
await result_3;
|
|
627
648
|
}
|
|
@@ -634,7 +655,7 @@ writeFile;
|
|
|
634
655
|
* @option flag Defaults to `'a'`.
|
|
635
656
|
*/
|
|
636
657
|
export async function appendFile(path, data, _options) {
|
|
637
|
-
const
|
|
658
|
+
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
638
659
|
try {
|
|
639
660
|
const options = normalizeOptions(_options, 'utf8', 'a', 0o644);
|
|
640
661
|
const flag = flags.parse(options.flag);
|
|
@@ -644,33 +665,45 @@ export async function appendFile(path, data, _options) {
|
|
|
644
665
|
if (typeof data != 'string' && !ArrayBuffer.isView(data))
|
|
645
666
|
throw new TypeError('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received ' + typeof data);
|
|
646
667
|
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
647
|
-
const handle = __addDisposableResource(
|
|
668
|
+
const handle = __addDisposableResource(env_5, typeof path == 'object' && 'fd' in path ? path : await open.call(this, path, options.flag, options.mode), true);
|
|
648
669
|
await handle.appendFile(encodedData, options);
|
|
649
670
|
}
|
|
650
|
-
catch (
|
|
651
|
-
|
|
652
|
-
|
|
671
|
+
catch (e_5) {
|
|
672
|
+
env_5.error = e_5;
|
|
673
|
+
env_5.hasError = true;
|
|
653
674
|
}
|
|
654
675
|
finally {
|
|
655
|
-
const result_4 = __disposeResources(
|
|
676
|
+
const result_4 = __disposeResources(env_5);
|
|
656
677
|
if (result_4)
|
|
657
678
|
await result_4;
|
|
658
679
|
}
|
|
659
680
|
}
|
|
660
681
|
appendFile;
|
|
661
682
|
export async function rmdir(path) {
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
683
|
+
const env_6 = { stack: [], error: void 0, hasError: false };
|
|
684
|
+
try {
|
|
685
|
+
path = normalizePath(path);
|
|
686
|
+
const { fs, path: resolved } = await _async.resolve(this, path);
|
|
687
|
+
const $ex = { syscall: 'rmdir', path };
|
|
688
|
+
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
689
|
+
if (!stats)
|
|
690
|
+
throw UV('ENOENT', $ex);
|
|
691
|
+
if (!isDirectory(stats))
|
|
692
|
+
throw UV('ENOTDIR', $ex);
|
|
693
|
+
if (checkAccess && !hasAccess(this, stats, constants.W_OK))
|
|
694
|
+
throw UV('EACCES', $ex);
|
|
695
|
+
const _ = __addDisposableResource(env_6, await lockPath(fs, dirname(resolved), 'rw'), false);
|
|
696
|
+
await fs.rmdir(resolved).catch(rethrow($ex));
|
|
697
|
+
cacheOf(fs).remove(resolved);
|
|
698
|
+
emitChange(this, 'rename', path.toString());
|
|
699
|
+
}
|
|
700
|
+
catch (e_6) {
|
|
701
|
+
env_6.error = e_6;
|
|
702
|
+
env_6.hasError = true;
|
|
703
|
+
}
|
|
704
|
+
finally {
|
|
705
|
+
__disposeResources(env_6);
|
|
706
|
+
}
|
|
674
707
|
}
|
|
675
708
|
rmdir;
|
|
676
709
|
export async function mkdir(path, options) {
|
|
@@ -686,7 +719,7 @@ export async function readdir(path, options) {
|
|
|
686
719
|
const values = [];
|
|
687
720
|
for (const entry of rawEntries) {
|
|
688
721
|
if (opt.withFileTypes) {
|
|
689
|
-
values.push(Dirent.from(entry, opt.encoding));
|
|
722
|
+
values.push(Dirent.from(entry, opt.encoding, path));
|
|
690
723
|
}
|
|
691
724
|
else if (opt.encoding == 'buffer') {
|
|
692
725
|
values.push(Buffer.from(entry.path));
|
|
@@ -709,24 +742,24 @@ link;
|
|
|
709
742
|
* @param type can be either `'dir'` or `'file'` (default is `'file'`)
|
|
710
743
|
*/
|
|
711
744
|
export async function symlink(dest, path, type = 'file') {
|
|
712
|
-
const
|
|
745
|
+
const env_7 = { stack: [], error: void 0, hasError: false };
|
|
713
746
|
try {
|
|
714
747
|
if (!['file', 'dir', 'junction'].includes(type))
|
|
715
748
|
throw new TypeError('Invalid symlink type: ' + type);
|
|
716
749
|
path = normalizePath(path);
|
|
717
750
|
if (await exists.call(this, path))
|
|
718
751
|
throw UV('EEXIST', 'symlink', path);
|
|
719
|
-
const handle = __addDisposableResource(
|
|
752
|
+
const handle = __addDisposableResource(env_7, await _async.open(this, path, { flag: 'w+', mode: 0o644, preserveSymlinks: true }), true);
|
|
720
753
|
const encoded = encodeUTF8(normalizePath(dest, true));
|
|
721
754
|
await handle.write(encoded, 0, encoded.length, 0);
|
|
722
755
|
await handle.chmod(constants.S_IFLNK);
|
|
723
756
|
}
|
|
724
|
-
catch (
|
|
725
|
-
|
|
726
|
-
|
|
757
|
+
catch (e_7) {
|
|
758
|
+
env_7.error = e_7;
|
|
759
|
+
env_7.hasError = true;
|
|
727
760
|
}
|
|
728
761
|
finally {
|
|
729
|
-
const result_5 = __disposeResources(
|
|
762
|
+
const result_5 = __disposeResources(env_7);
|
|
730
763
|
if (result_5)
|
|
731
764
|
await result_5;
|
|
732
765
|
}
|
|
@@ -741,26 +774,26 @@ export async function readlink(path, options) {
|
|
|
741
774
|
}
|
|
742
775
|
readlink;
|
|
743
776
|
export async function chown(path, uid, gid) {
|
|
744
|
-
const
|
|
777
|
+
const env_8 = { stack: [], error: void 0, hasError: false };
|
|
745
778
|
try {
|
|
746
|
-
const handle = __addDisposableResource(
|
|
779
|
+
const handle = __addDisposableResource(env_8, await open.call(this, path, 'r+'), true);
|
|
747
780
|
await handle.chown(uid, gid);
|
|
748
781
|
}
|
|
749
|
-
catch (
|
|
750
|
-
|
|
751
|
-
|
|
782
|
+
catch (e_8) {
|
|
783
|
+
env_8.error = e_8;
|
|
784
|
+
env_8.hasError = true;
|
|
752
785
|
}
|
|
753
786
|
finally {
|
|
754
|
-
const result_6 = __disposeResources(
|
|
787
|
+
const result_6 = __disposeResources(env_8);
|
|
755
788
|
if (result_6)
|
|
756
789
|
await result_6;
|
|
757
790
|
}
|
|
758
791
|
}
|
|
759
792
|
chown;
|
|
760
793
|
export async function lchown(path, uid, gid) {
|
|
761
|
-
const
|
|
794
|
+
const env_9 = { stack: [], error: void 0, hasError: false };
|
|
762
795
|
try {
|
|
763
|
-
const handle = __addDisposableResource(
|
|
796
|
+
const handle = __addDisposableResource(env_9, await _async.open(this, path, {
|
|
764
797
|
flag: 'r+',
|
|
765
798
|
mode: 0o644,
|
|
766
799
|
preserveSymlinks: true,
|
|
@@ -768,39 +801,39 @@ export async function lchown(path, uid, gid) {
|
|
|
768
801
|
}), true);
|
|
769
802
|
await handle.chown(uid, gid);
|
|
770
803
|
}
|
|
771
|
-
catch (
|
|
772
|
-
|
|
773
|
-
|
|
804
|
+
catch (e_9) {
|
|
805
|
+
env_9.error = e_9;
|
|
806
|
+
env_9.hasError = true;
|
|
774
807
|
}
|
|
775
808
|
finally {
|
|
776
|
-
const result_7 = __disposeResources(
|
|
809
|
+
const result_7 = __disposeResources(env_9);
|
|
777
810
|
if (result_7)
|
|
778
811
|
await result_7;
|
|
779
812
|
}
|
|
780
813
|
}
|
|
781
814
|
lchown;
|
|
782
815
|
export async function chmod(path, mode) {
|
|
783
|
-
const
|
|
816
|
+
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
784
817
|
try {
|
|
785
|
-
const handle = __addDisposableResource(
|
|
818
|
+
const handle = __addDisposableResource(env_10, await open.call(this, path, 'r+').catch(rethrow({ syscall: 'chmod', path: normalizePath(path) })), true);
|
|
786
819
|
await handle.chmod(mode);
|
|
787
820
|
}
|
|
788
|
-
catch (
|
|
789
|
-
|
|
790
|
-
|
|
821
|
+
catch (e_10) {
|
|
822
|
+
env_10.error = e_10;
|
|
823
|
+
env_10.hasError = true;
|
|
791
824
|
}
|
|
792
825
|
finally {
|
|
793
|
-
const result_8 = __disposeResources(
|
|
826
|
+
const result_8 = __disposeResources(env_10);
|
|
794
827
|
if (result_8)
|
|
795
828
|
await result_8;
|
|
796
829
|
}
|
|
797
830
|
}
|
|
798
831
|
chmod;
|
|
799
832
|
export async function lchmod(path, mode) {
|
|
800
|
-
const
|
|
833
|
+
const env_11 = { stack: [], error: void 0, hasError: false };
|
|
801
834
|
try {
|
|
802
835
|
mode = normalizeMode(mode);
|
|
803
|
-
const handle = __addDisposableResource(
|
|
836
|
+
const handle = __addDisposableResource(env_11, await _async.open(this, path, {
|
|
804
837
|
flag: 'r+',
|
|
805
838
|
mode: 0o644,
|
|
806
839
|
preserveSymlinks: true,
|
|
@@ -808,12 +841,12 @@ export async function lchmod(path, mode) {
|
|
|
808
841
|
}), true);
|
|
809
842
|
await handle.chmod(mode);
|
|
810
843
|
}
|
|
811
|
-
catch (
|
|
812
|
-
|
|
813
|
-
|
|
844
|
+
catch (e_11) {
|
|
845
|
+
env_11.error = e_11;
|
|
846
|
+
env_11.hasError = true;
|
|
814
847
|
}
|
|
815
848
|
finally {
|
|
816
|
-
const result_9 = __disposeResources(
|
|
849
|
+
const result_9 = __disposeResources(env_11);
|
|
817
850
|
if (result_9)
|
|
818
851
|
await result_9;
|
|
819
852
|
}
|
|
@@ -823,20 +856,20 @@ lchmod;
|
|
|
823
856
|
* Change file timestamps of the file referenced by the supplied path.
|
|
824
857
|
*/
|
|
825
858
|
export async function utimes(path, atime, mtime) {
|
|
826
|
-
const
|
|
859
|
+
const env_12 = { stack: [], error: void 0, hasError: false };
|
|
827
860
|
try {
|
|
828
|
-
const handle = __addDisposableResource(
|
|
861
|
+
const handle = __addDisposableResource(env_12, await _async.open(this, path, {
|
|
829
862
|
flag: 'r+',
|
|
830
863
|
allowDirectory: true,
|
|
831
864
|
}), true);
|
|
832
865
|
await handle.utimes(normalizeTime(atime), normalizeTime(mtime));
|
|
833
866
|
}
|
|
834
|
-
catch (
|
|
835
|
-
|
|
836
|
-
|
|
867
|
+
catch (e_12) {
|
|
868
|
+
env_12.error = e_12;
|
|
869
|
+
env_12.hasError = true;
|
|
837
870
|
}
|
|
838
871
|
finally {
|
|
839
|
-
const result_10 = __disposeResources(
|
|
872
|
+
const result_10 = __disposeResources(env_12);
|
|
840
873
|
if (result_10)
|
|
841
874
|
await result_10;
|
|
842
875
|
}
|
|
@@ -846,9 +879,9 @@ utimes;
|
|
|
846
879
|
* Change file timestamps of the file referenced by the supplied path.
|
|
847
880
|
*/
|
|
848
881
|
export async function lutimes(path, atime, mtime) {
|
|
849
|
-
const
|
|
882
|
+
const env_13 = { stack: [], error: void 0, hasError: false };
|
|
850
883
|
try {
|
|
851
|
-
const handle = __addDisposableResource(
|
|
884
|
+
const handle = __addDisposableResource(env_13, await _async.open(this, path, {
|
|
852
885
|
flag: 'r+',
|
|
853
886
|
mode: 0o644,
|
|
854
887
|
preserveSymlinks: true,
|
|
@@ -856,12 +889,12 @@ export async function lutimes(path, atime, mtime) {
|
|
|
856
889
|
}), true);
|
|
857
890
|
await handle.utimes(normalizeTime(atime), normalizeTime(mtime));
|
|
858
891
|
}
|
|
859
|
-
catch (
|
|
860
|
-
|
|
861
|
-
|
|
892
|
+
catch (e_13) {
|
|
893
|
+
env_13.error = e_13;
|
|
894
|
+
env_13.hasError = true;
|
|
862
895
|
}
|
|
863
896
|
finally {
|
|
864
|
-
const result_11 = __disposeResources(
|
|
897
|
+
const result_11 = __disposeResources(env_13);
|
|
865
898
|
if (result_11)
|
|
866
899
|
await result_11;
|
|
867
900
|
}
|
|
@@ -880,7 +913,8 @@ export async function realpath(path, options) {
|
|
|
880
913
|
}
|
|
881
914
|
realpath;
|
|
882
915
|
export function watch(filename, options = {}) {
|
|
883
|
-
const
|
|
916
|
+
const opts = typeof options !== 'string' ? options : { encoding: options };
|
|
917
|
+
const watcher = new FSWatcher(this, filename.toString(), opts);
|
|
884
918
|
// A queue to hold change events, since we need to resolve them in the async iterator
|
|
885
919
|
const eventQueue = [];
|
|
886
920
|
let done = false;
|
|
@@ -890,12 +924,17 @@ export function watch(filename, options = {}) {
|
|
|
890
924
|
function cleanup() {
|
|
891
925
|
done = true;
|
|
892
926
|
watcher.close();
|
|
927
|
+
opts.signal?.removeEventListener('abort', cleanup);
|
|
893
928
|
for (const resolve of eventQueue) {
|
|
894
929
|
resolve({ value: null, done });
|
|
895
930
|
}
|
|
896
931
|
eventQueue.length = 0; // Clear the queue
|
|
897
932
|
return Promise.resolve({ value: undefined, done: true });
|
|
898
933
|
}
|
|
934
|
+
if (opts.signal?.aborted)
|
|
935
|
+
void cleanup();
|
|
936
|
+
else
|
|
937
|
+
opts.signal?.addEventListener('abort', cleanup, { once: true });
|
|
899
938
|
return {
|
|
900
939
|
async next() {
|
|
901
940
|
if (done)
|
package/dist/node/streams.d.ts
CHANGED
|
@@ -51,6 +51,10 @@ export declare class ReadStream extends Readable implements fs.ReadStream {
|
|
|
51
51
|
private ready;
|
|
52
52
|
constructor(opts: CreateReadStreamOptions | undefined, handleOrPromise: FileHandle | Promise<FileHandle>);
|
|
53
53
|
_read(): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Like Node, the callback is invoked once the stream is closed.
|
|
56
|
+
* Closing before the stream has finished reports `ERR_STREAM_PREMATURE_CLOSE`.
|
|
57
|
+
*/
|
|
54
58
|
close(callback?: Callback<[void]>): void;
|
|
55
59
|
get path(): string;
|
|
56
60
|
get bytesRead(): number;
|
package/dist/node/streams.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Errno, Exception, UV } from 'kerium';
|
|
2
2
|
import { warn } from 'kerium/log';
|
|
3
|
-
import { Readable, Writable } from 'readable-stream';
|
|
3
|
+
import { finished, Readable, Writable } from 'readable-stream';
|
|
4
4
|
/**
|
|
5
5
|
* A ReadStream implementation that wraps an underlying global ReadableStream.
|
|
6
6
|
*/
|
|
@@ -15,7 +15,8 @@ export class ReadStream extends Readable {
|
|
|
15
15
|
this.ready = Promise.resolve(handleOrPromise)
|
|
16
16
|
.then(handle => {
|
|
17
17
|
this._path = handle['vfs'].path;
|
|
18
|
-
|
|
18
|
+
// `end` is inclusive for streams, but the internal range is not
|
|
19
|
+
const internal = handle.readableWebStream({ start: opts.start, end: opts.end === undefined ? undefined : opts.end + 1 });
|
|
19
20
|
this.reader = internal.getReader();
|
|
20
21
|
this.pending = false;
|
|
21
22
|
})
|
|
@@ -40,15 +41,13 @@ export class ReadStream extends Readable {
|
|
|
40
41
|
this.destroy(new Exception(Errno.EIO, err.toString()));
|
|
41
42
|
}
|
|
42
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Like Node, the callback is invoked once the stream is closed.
|
|
46
|
+
* Closing before the stream has finished reports `ERR_STREAM_PREMATURE_CLOSE`.
|
|
47
|
+
*/
|
|
43
48
|
close(callback = () => null) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.emit('close');
|
|
47
|
-
callback(null);
|
|
48
|
-
}
|
|
49
|
-
catch (err) {
|
|
50
|
-
callback(new Exception(Errno.EIO, err.toString()));
|
|
51
|
-
}
|
|
49
|
+
finished(this, error => callback(error ?? null));
|
|
50
|
+
this.destroy();
|
|
52
51
|
}
|
|
53
52
|
get path() {
|
|
54
53
|
return this._path;
|