instrumentality 0.0.13 → 0.0.15

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/road.js CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import * as cr from "node:crypto";
2
3
  import * as fs from "node:fs";
3
4
  import { constants as fsc } from "node:fs";
@@ -57,22 +58,6 @@ export function resolveDirent(dirent) {
57
58
  throw new Err(`Unknown dirent type for ${dirent.name}`);
58
59
  }
59
60
  export { resolveDirent as resDirent };
60
- /**
61
- * Creates the appropriate subclass of {@link Road} based on the file mode of the specified path.
62
- *
63
- * @param path_ The path to follow.
64
- * @returns A new instance of {@link Road}.
65
- * @throws If {@link fp.lstat}/{@link fs.lstatSync} fails to retrieved the status of {@link path_}.
66
- */
67
- export async function factory(path_) {
68
- return new (resolveStat((await fp.lstat(path_)).mode))(path_, false);
69
- }
70
- export { factory as fac, factory as mk };
71
- /** Sync version of {@link factory}. */
72
- export function factorySync(path_) {
73
- return new (resolveStat(fs.lstatSync(path_).mode))(path_, false);
74
- }
75
- export { factorySync as facSync, factorySync as mkSync };
76
61
  /**
77
62
  * A map that keeps track of locked roads to prevent concurrent modifications.
78
63
  *
@@ -91,18 +76,32 @@ export let lockedRoads = null;
91
76
  * It is more like a memory representation, similar to a pointer in low-level programming languages; other processes might mess with the underlying entry. There are methods to check for consistency, but they are not guaranteed to be foolproof.
92
77
  */
93
78
  export class Road {
94
- /** The absolute path to the file or directory that this Road instance represents.
79
+ /** The absolute path to the entry that this Road instance represents.
95
80
  * @remarks Intentionally made protected to prevent external modification, as changing this value could lead to inconsistencies and unexpected behavior. */
96
81
  pointsTo;
97
- /** Indicates whether the file or directory represented by this Road instance can be modified.
82
+ /** Indicates which operations are allowed on the entry represented by this Road instance.
98
83
  * Changing this value does not affect the actual file system permissions, but rather serves as a safeguard within the application to prevent accidental modifications. */
99
- mutable = true;
84
+ writable = true;
85
+ moveable = true;
86
+ deletable = true;
87
+ copyable = true;
88
+ renameable = true;
89
+ assertWrite() { if (!this.writable)
90
+ throw new Err(`Road to '${this.isAt}' isn't writable.`); }
91
+ assertMove() { if (!this.moveable)
92
+ throw new Err(`Road to '${this.isAt}' isn't moveable.`); }
93
+ assertDelete() { if (!this.deletable)
94
+ throw new Err(`Road to '${this.isAt}' isn't deletable.`); }
95
+ assertCopy() { if (!this.copyable)
96
+ throw new Err(`Road to '${this.isAt}' isn't copyable.`); }
97
+ assertRename() { if (!this.renameable)
98
+ throw new Err(`Road to '${this.isAt}' isn't renameable.`); }
100
99
  // Quick accessors
101
100
  /** Copy of the absolute path. */
102
101
  get isAt() { return this.pointsTo; }
103
102
  /** Name of the road without the path (including extensions). */
104
103
  get name() { return this.isAt.slice(this.isAt.lastIndexOf(ph.sep) + 1); }
105
- /** The amount of path segments in the absolute path to the file or directory represented by this Road instance, minus one (i.e., the depth of the path in the file system hierarchy). */
104
+ /** The amount of path segments in the absolute path to the entry represented by this Road instance, minus one (i.e., the depth of the path in the file system hierarchy). */
106
105
  get depth() { return this.isAt.split(ph.sep).length - 1; }
107
106
  /** Same as {@link isAt} but for compatibility with external APIs. */
108
107
  toString() { return this.isAt; }
@@ -116,7 +115,7 @@ export class Road {
116
115
  */
117
116
  constructor(path_, typeCheck_) {
118
117
  this.pointsTo = ph.resolve(path_);
119
- if (typeCheck_ && !this.checkSync())
118
+ if (typeCheck_ && !this.checkSync(true))
120
119
  throw new Err(`Type mismatch: '${this.isAt}'`);
121
120
  }
122
121
  /** @returns An instance of {@link Folder} representing the parent directory of the current road. */
@@ -138,8 +137,6 @@ export class Road {
138
137
  /** @returns An array of {@link Folder} instances representing the ancestors of the current road. */
139
138
  ancestors() { return [...this.ancestorsIt()]; }
140
139
  reserveLock(allowConcurrent) {
141
- if (!this.mutable)
142
- throw new Err(`Road to '${this.isAt}' is immutable.`);
143
140
  lockedRoads ??= new Map();
144
141
  const { promise, resolve } = Promise.withResolvers();
145
142
  const isAt = this.isAt;
@@ -161,7 +158,9 @@ export class Road {
161
158
  try {
162
159
  await l.previous;
163
160
  }
164
- catch { }
161
+ catch {
162
+ null;
163
+ }
165
164
  return l;
166
165
  }
167
166
  lockSync() {
@@ -180,7 +179,7 @@ export class Road {
180
179
  async untilAccessible(abs, expectMode = fsc.F_OK, cb_) {
181
180
  const watcher = fs.watch(this.isAt);
182
181
  try {
183
- for await (let _ of on(watcher, 'change', { signal: abs })) {
182
+ for await (const _ of on(watcher, 'change', { signal: abs })) {
184
183
  try {
185
184
  await fp.access(this.isAt, expectMode);
186
185
  return;
@@ -207,7 +206,7 @@ export class Road {
207
206
  async onChange(abs_, cb_) {
208
207
  const watcher = fs.watch(this.isAt);
209
208
  try {
210
- for await (let _ of on(watcher, 'change', { signal: abs_ }))
209
+ for await (const _ of on(watcher, 'change', { signal: abs_ }))
211
210
  return await cb_?.() ?? null;
212
211
  return null;
213
212
  }
@@ -224,43 +223,51 @@ export class Road {
224
223
  lstatSync() { return fs.lstatSync(this.isAt); }
225
224
  /** Wrapper around {@link fp.rm} with locking. */
226
225
  async delete() {
226
+ this.assertDelete();
227
227
  using _ = await this.lock();
228
228
  await fp.rm(this.isAt, { recursive: true, force: true });
229
229
  }
230
230
  /** Wrapper around {@link fs.rmSync} with locking. */
231
231
  deleteSync() {
232
+ this.assertDelete();
232
233
  using _ = this.lockSync();
233
234
  fs.rmSync(this.isAt, { recursive: true, force: true });
234
235
  }
235
236
  async copy(into_) {
237
+ this.assertCopy();
236
238
  const newPath = into_.join(this.name);
237
239
  await fp.cp(this.isAt, newPath, { recursive: true, force: true });
238
240
  return new this.constructor(newPath, false);
239
241
  }
240
242
  copySync(into_) {
243
+ this.assertCopy();
241
244
  const newPath = into_.join(this.name);
242
245
  fs.cpSync(this.isAt, newPath, { recursive: true, force: true });
243
246
  return new this.constructor(newPath, false);
244
247
  }
245
248
  async move(into_) {
249
+ this.assertMove();
246
250
  using _ = await this.lock();
247
251
  const newPath = into_.join(this.name);
248
252
  await fp.rename(this.isAt, newPath);
249
253
  this.pointsTo = newPath;
250
254
  }
251
255
  moveSync(into_) {
256
+ this.assertMove();
252
257
  using _ = this.lockSync();
253
258
  const newPath = into_.join(this.name);
254
259
  fs.renameSync(this.isAt, newPath);
255
260
  this.pointsTo = newPath;
256
261
  }
257
262
  async rename(newName_) {
263
+ this.assertRename();
258
264
  using _ = await this.lock();
259
265
  const newPath = this.parent().join(newName_);
260
266
  await fp.rename(this.isAt, newPath);
261
267
  this.pointsTo = newPath;
262
268
  }
263
269
  renameSync(newName_) {
270
+ this.assertRename();
264
271
  using _ = this.lockSync();
265
272
  const newPath = this.parent().join(newName_);
266
273
  fs.renameSync(this.isAt, newPath);
@@ -289,6 +296,18 @@ export class Road {
289
296
  /** Type narrowing for {@link Socket} (similar to `instanceof` without unnecessary runtime checks). */
290
297
  isSocket() { return false; }
291
298
  }
299
+ /**
300
+ * Creates the appropriate subclass of {@link Road} based on the file mode of the specified path.
301
+ *
302
+ * @param path_ The path to follow.
303
+ * @returns A new instance of {@link Road}.
304
+ * @throws If {@link fp.lstat}/{@link fs.lstatSync} fails to retrieved the status of {@link path_}.
305
+ */
306
+ export async function road(path_) { return new (resolveStat((await fp.lstat(path_)).mode))(path_, false); }
307
+ export { road as fac, road as mk, road as factory };
308
+ /** Sync version of {@link road}. */
309
+ export function roadSync(path_) { return new (resolveStat((fs.lstatSync(path_).mode)))(path_, false); }
310
+ export { roadSync as facSync, roadSync as mkSync, roadSync as factorySync };
292
311
  /** Subclass of {@link Road} that represents a file. */
293
312
  export class File extends Road {
294
313
  /**
@@ -326,7 +345,7 @@ export class File extends Road {
326
345
  /** The file name without its extension. */
327
346
  get noExt() { return ph.basename(this.isAt, this.ext); }
328
347
  async read(options_) {
329
- return fp.readFile(this.isAt, options_);
348
+ return await fp.readFile(this.isAt, options_);
330
349
  }
331
350
  readSync(options_) {
332
351
  return fs.readFileSync(this.isAt, options_);
@@ -408,11 +427,15 @@ export class File extends Road {
408
427
  try {
409
428
  iter1.return?.(undefined);
410
429
  }
411
- catch { }
430
+ catch {
431
+ null;
432
+ }
412
433
  try {
413
434
  iter2.return?.(undefined);
414
435
  }
415
- catch { }
436
+ catch {
437
+ null;
438
+ }
416
439
  }
417
440
  }
418
441
  async hash(algorithm_ = "sha256", options_, encoding_) {
@@ -430,30 +453,37 @@ export class File extends Road {
430
453
  async size() { return (await this.lstat()).size; }
431
454
  sizeSync() { return this.lstatSync().size; }
432
455
  async writeAtomic(data_, options_) {
456
+ this.assertWrite();
433
457
  using _ = await this.lock();
434
458
  await this.parent().borrow(File, async (tmp) => {
459
+ tmp.assertWrite();
435
460
  using _ = await tmp.lock();
436
461
  await fp.writeFile(tmp.isAt, data_, options_);
437
462
  await fp.rename(tmp.isAt, this.isAt);
438
463
  });
439
464
  }
440
465
  writeAtomicSync(data_, options_) {
466
+ this.assertWrite();
441
467
  using _ = this.lockSync();
442
468
  this.parent().borrowSync(File, tmp => {
469
+ tmp.assertWrite();
443
470
  using _ = tmp.lockSync();
444
471
  fs.writeFileSync(tmp.isAt, data_, options_);
445
472
  fs.renameSync(tmp.isAt, this.isAt);
446
473
  });
447
474
  }
448
475
  async write(data_, options_) {
476
+ this.assertWrite();
449
477
  using _ = await this.lock();
450
478
  await fp.writeFile(this.isAt, data_, options_);
451
479
  }
452
480
  writeSync(data_, options_) {
481
+ this.assertWrite();
453
482
  using _ = this.lockSync();
454
483
  fs.writeFileSync(this.isAt, data_, options_);
455
484
  }
456
485
  async writePast(offset_, data_) {
486
+ this.assertWrite();
457
487
  using _ = await this.lock();
458
488
  const fd = await fp.open(this.isAt, 'r+');
459
489
  try {
@@ -465,6 +495,7 @@ export class File extends Road {
465
495
  }
466
496
  }
467
497
  writePastSync(offset_, data_) {
498
+ this.assertWrite();
468
499
  using _ = this.lockSync();
469
500
  const fd = fs.openSync(this.isAt, 'r+');
470
501
  try {
@@ -476,6 +507,7 @@ export class File extends Road {
476
507
  }
477
508
  }
478
509
  async truncWritePast(offset_, data_) {
510
+ this.assertWrite();
479
511
  using _ = await this.lock();
480
512
  const fd = await fp.open(this.isAt, 'r+');
481
513
  try {
@@ -488,6 +520,7 @@ export class File extends Road {
488
520
  }
489
521
  }
490
522
  truncWritePastSync(offset_, data_) {
523
+ this.assertWrite();
491
524
  using _ = this.lockSync();
492
525
  const fd = fs.openSync(this.isAt, 'r+');
493
526
  try {
@@ -500,23 +533,29 @@ export class File extends Road {
500
533
  }
501
534
  }
502
535
  async append(data_, options_) {
536
+ this.assertWrite();
503
537
  using _ = await this.lock();
504
538
  await fp.appendFile(this.isAt, data_, options_);
505
539
  }
506
540
  appendSync(data_, options_) {
541
+ this.assertWrite();
507
542
  using _ = this.lockSync();
508
543
  fs.appendFileSync(this.isAt, data_, options_);
509
544
  }
510
- async check() { try {
545
+ async check(throwOnError_) { try {
511
546
  return (await fp.lstat(this.isAt)).isFile();
512
547
  }
513
- catch {
548
+ catch (e) {
549
+ if (throwOnError_)
550
+ throw e;
514
551
  return false;
515
552
  } }
516
- checkSync() { try {
553
+ checkSync(throwOnError_) { try {
517
554
  return fs.lstatSync(this.isAt).isFile();
518
555
  }
519
- catch {
556
+ catch (e) {
557
+ if (throwOnError_)
558
+ throw e;
520
559
  return false;
521
560
  } }
522
561
  isFile() { return true; }
@@ -584,12 +623,10 @@ export class Folder extends Road {
584
623
  yield* entry.walkSync(filter_);
585
624
  }
586
625
  }
587
- async find(name_, expect_) {
626
+ async find(name_, filter_) {
588
627
  try {
589
- const found = await factory(this.join(name_));
590
- if (!expect_)
591
- return found;
592
- if (found instanceof expect_)
628
+ const found = await road(this.join(name_));
629
+ if (!filter_ || filter_(found))
593
630
  return found;
594
631
  return null;
595
632
  }
@@ -597,45 +634,45 @@ export class Folder extends Road {
597
634
  return null;
598
635
  }
599
636
  }
600
- findSync(name_, expect_) {
637
+ findSync(name_, filter_) {
601
638
  try {
602
- const found = factorySync(this.join(name_));
603
- if (!expect_)
604
- return found;
605
- if (found instanceof expect_)
639
+ const found = roadSync(this.join(name_));
640
+ if (!filter_ || filter_(found))
606
641
  return found;
607
642
  return null;
608
643
  }
609
- catch (e) {
644
+ catch {
610
645
  return null;
611
646
  }
612
647
  }
613
648
  async add(name_, createable_) {
649
+ this.assertWrite();
614
650
  const newPath = this.join(name_);
615
651
  await createable_.mk(newPath);
616
- return (await factory(newPath));
652
+ return (await road(newPath));
617
653
  }
618
654
  addSync(name_, createable_) {
655
+ this.assertWrite();
619
656
  const newPath = this.join(name_);
620
657
  createable_.mkSync(newPath);
621
- return factorySync(newPath);
658
+ return roadSync(newPath);
622
659
  }
623
660
  async borrow(createable_, cb_) {
624
- const path = this.join(`instrumentality@${crypto.randomUUID()}`);
661
+ const created = await createable_.mk(this.join(`instrumentality@${crypto.randomUUID()}`));
625
662
  try {
626
- await cb_(await createable_.mk(path));
663
+ await cb_(created);
627
664
  }
628
665
  finally {
629
- await fp.rm(path, { recursive: true, force: true });
666
+ await fp.rm(created.isAt, { recursive: true, force: true });
630
667
  }
631
668
  }
632
669
  borrowSync(createable_, cb_) {
633
- const path = this.join(`instrumentality@${crypto.randomUUID()}`);
670
+ const created = createable_.mkSync(this.join(`instrumentality@${crypto.randomUUID()}`));
634
671
  try {
635
- cb_(createable_.mkSync(path));
672
+ cb_(created);
636
673
  }
637
674
  finally {
638
- fs.rmSync(path, { recursive: true, force: true });
675
+ fs.rmSync(created.isAt, { recursive: true, force: true });
639
676
  }
640
677
  }
641
678
  async size() {
@@ -650,16 +687,20 @@ export class Folder extends Road {
650
687
  size += entry.sizeSync();
651
688
  return size;
652
689
  }
653
- async check() { try {
690
+ async check(throwOnError_) { try {
654
691
  return (await fp.lstat(this.isAt)).isDirectory();
655
692
  }
656
- catch {
693
+ catch (e) {
694
+ if (throwOnError_)
695
+ throw e;
657
696
  return false;
658
697
  } }
659
- checkSync() { try {
698
+ checkSync(throwOnError_) { try {
660
699
  return fs.lstatSync(this.isAt).isDirectory();
661
700
  }
662
- catch {
701
+ catch (e) {
702
+ if (throwOnError_)
703
+ throw e;
663
704
  return false;
664
705
  } }
665
706
  isFolder() { return true; }
@@ -668,11 +709,12 @@ export class Folder extends Road {
668
709
  }
669
710
  export function folder(...args) { return new Folder(...args); }
670
711
  export function dir(...args) { return new Folder(...args); }
712
+ export function directory(...args) { return new Folder(...args); }
671
713
  export function sysRoot() { return new Folder(ph.parse(process.cwd()).root, false); }
672
714
  export function home() { return new Folder(os.homedir(), false); }
673
715
  export function tmp() { return new Folder(os.tmpdir(), false); }
674
716
  export function here() { return new Folder(process.cwd(), false); }
675
- export { Folder as Dir, Folder as Directory, Folder as Dict, Folder as Dictionary };
717
+ export { Folder as Dir, Folder as Directory };
676
718
  export class SymbolicLink extends Road {
677
719
  static async create(at_, target_) {
678
720
  try {
@@ -695,17 +737,21 @@ export class SymbolicLink extends Road {
695
737
  }
696
738
  static mkSync = SymbolicLink.createSync;
697
739
  async target() {
698
- return factory(ph.resolve(ph.dirname(this.isAt), await fp.readlink(this.isAt)));
740
+ return await road(ph.resolve(ph.dirname(this.isAt), await fp.readlink(this.isAt)));
699
741
  }
700
742
  targetSync() {
701
- return factorySync(ph.resolve(ph.dirname(this.isAt), fs.readlinkSync(this.isAt)));
743
+ return roadSync(ph.resolve(ph.dirname(this.isAt), fs.readlinkSync(this.isAt)));
702
744
  }
703
745
  async retarget(to_) {
746
+ this.assertDelete();
747
+ this.assertWrite();
704
748
  using _ = await this.lock();
705
749
  await fp.unlink(this.isAt);
706
750
  await fp.symlink(to_.isAt, this.isAt);
707
751
  }
708
752
  retargetSync(to_) {
753
+ this.assertDelete();
754
+ this.assertWrite();
709
755
  using _ = this.lockSync();
710
756
  fs.unlinkSync(this.isAt);
711
757
  fs.symlinkSync(to_.isAt, this.isAt);
@@ -713,23 +759,29 @@ export class SymbolicLink extends Road {
713
759
  async size() { return (await this.lstat()).size; }
714
760
  sizeSync() { return this.lstatSync().size; }
715
761
  async delete() {
762
+ this.assertDelete();
716
763
  using _ = await this.lock();
717
764
  await fp.unlink(this.isAt);
718
765
  }
719
766
  deleteSync() {
767
+ this.assertDelete();
720
768
  using _ = this.lockSync();
721
769
  fs.unlinkSync(this.isAt);
722
770
  }
723
- async check() { try {
771
+ async check(throwOnError_) { try {
724
772
  return (await fp.lstat(this.isAt)).isSymbolicLink();
725
773
  }
726
- catch {
774
+ catch (e) {
775
+ if (throwOnError_)
776
+ throw e;
727
777
  return false;
728
778
  } }
729
- checkSync() { try {
779
+ checkSync(throwOnError_) { try {
730
780
  return fs.lstatSync(this.isAt).isSymbolicLink();
731
781
  }
732
- catch {
782
+ catch (e) {
783
+ if (throwOnError_)
784
+ throw e;
733
785
  return false;
734
786
  } }
735
787
  isSymlink() { return true; }
@@ -737,92 +789,118 @@ export class SymbolicLink extends Road {
737
789
  }
738
790
  export { SymbolicLink as Symlink };
739
791
  export function symlink(...args) { return new SymbolicLink(...args); }
792
+ /**
793
+ * Represents a system-level resource that is not subject to modification.
794
+ * All modification operations will throw an error.
795
+ *
796
+ * One could say 'this road truly is *unusable*.' hehe
797
+ */
740
798
  export class UnusableRoad extends Road {
741
- mutable = false; // Modification will cause system issues (e.g. deleting a device file)
742
- async size() { return 0; }
799
+ // Modification will cause system issues (e.g. deleting a device file)
800
+ writable = false;
801
+ moveable = false;
802
+ deletable = false;
803
+ copyable = false;
804
+ size() { return Promise.resolve(0); }
743
805
  sizeSync() { return 0; }
744
806
  error() { throw new Err(`${this.constructor.name} at '${this.isAt}' is a system-level resource thus not subject to modification.`); }
745
- /** @deprecated System-level resources (UnusableRoad) can't/shouldn't be locked */
807
+ /** @deprecated System-level resources ({@link UnusableRoad}) can't/shouldn't be locked */
746
808
  lock() { return this.error(); }
747
- /** @deprecated System-level resources (UnusableRoad) can't/shouldn't be locked */
809
+ /** @deprecated System-level resources ({@link UnusableRoad}) can't/shouldn't be locked */
748
810
  lockSync() { return this.error(); }
749
- /** @deprecated System-level resources (UnusableRoad) can't/shouldn't be deleted */
811
+ /** @deprecated System-level resources ({@link UnusableRoad}) can't/shouldn't be deleted */
750
812
  delete() { return this.error(); }
751
- /** @deprecated System-level resources (UnusableRoad) can't/shouldn't be deleted */
813
+ /** @deprecated System-level resources ({@link UnusableRoad}) can't/shouldn't be deleted */
752
814
  deleteSync() { return this.error(); }
753
- /** @deprecated System-level resources (UnusableRoad) can't/shouldn't be moved */
815
+ /** @deprecated System-level resources ({@link UnusableRoad}) can't/shouldn't be moved */
754
816
  move() { return this.error(); }
755
- /** @deprecated System-level resources (UnusableRoad) can't/shouldn't be moved */
817
+ /** @deprecated System-level resources ({@link UnusableRoad}) can't/shouldn't be moved */
756
818
  moveSync() { return this.error(); }
757
- /** @deprecated System-level resources (UnusableRoad) can't/shouldn't be copied */
819
+ /** @deprecated System-level resources ({@link UnusableRoad}) can't/shouldn't be copied */
758
820
  copy() { return this.error(); }
759
- /** @deprecated System-level resources (UnusableRoad) can't/shouldn't be copied */
821
+ /** @deprecated System-level resources ({@link UnusableRoad}) can't/shouldn't be copied */
760
822
  copySync() { return this.error(); }
761
- /** @deprecated System-level resources (UnusableRoad) can't/shouldn't be renamed */
823
+ /** @deprecated System-level resources ({@link UnusableRoad}) can't/shouldn't be renamed */
762
824
  rename() { return this.error(); }
763
- /** @deprecated System-level resources (UnusableRoad) can't/shouldn't be renamed */
825
+ /** @deprecated System-level resources ({@link UnusableRoad}) can't/shouldn't be renamed */
764
826
  renameSync() { return this.error(); }
765
827
  isUnusable() { return true; }
766
828
  }
767
829
  export class BlockDevice extends UnusableRoad {
768
- async check() { try {
830
+ async check(throwOnError_) { try {
769
831
  return (await fp.lstat(this.isAt)).isBlockDevice();
770
832
  }
771
- catch {
833
+ catch (e) {
834
+ if (throwOnError_)
835
+ throw e;
772
836
  return false;
773
837
  } }
774
- checkSync() { try {
838
+ checkSync(throwOnError_) { try {
775
839
  return fs.lstatSync(this.isAt).isBlockDevice();
776
840
  }
777
- catch {
841
+ catch (e) {
842
+ if (throwOnError_)
843
+ throw e;
778
844
  return false;
779
845
  } }
780
846
  isBlockDevice() { return true; }
781
847
  }
782
848
  export function blockDevice(...args) { return new BlockDevice(...args); }
783
849
  export class CharacterDevice extends UnusableRoad {
784
- async check() { try {
850
+ async check(throwOnError_) { try {
785
851
  return (await fp.lstat(this.isAt)).isCharacterDevice();
786
852
  }
787
- catch {
853
+ catch (e) {
854
+ if (throwOnError_)
855
+ throw e;
788
856
  return false;
789
857
  } }
790
- checkSync() { try {
858
+ checkSync(throwOnError_) { try {
791
859
  return fs.lstatSync(this.isAt).isCharacterDevice();
792
860
  }
793
- catch {
861
+ catch (e) {
862
+ if (throwOnError_)
863
+ throw e;
794
864
  return false;
795
865
  } }
796
866
  isCharacterDevice() { return true; }
797
867
  }
798
868
  export function characterDevice(...args) { return new CharacterDevice(...args); }
799
869
  export class Fifo extends UnusableRoad {
800
- async check() { try {
870
+ async check(throwOnError_) { try {
801
871
  return (await fp.lstat(this.isAt)).isFIFO();
802
872
  }
803
- catch {
873
+ catch (e) {
874
+ if (throwOnError_)
875
+ throw e;
804
876
  return false;
805
877
  } }
806
- checkSync() { try {
878
+ checkSync(throwOnError_) { try {
807
879
  return fs.lstatSync(this.isAt).isFIFO();
808
880
  }
809
- catch {
881
+ catch (e) {
882
+ if (throwOnError_)
883
+ throw e;
810
884
  return false;
811
885
  } }
812
886
  isFifo() { return true; }
813
887
  }
814
888
  export function fifo(...args) { return new Fifo(...args); }
815
889
  export class Socket extends UnusableRoad {
816
- async check() { try {
890
+ async check(throwOnError_) { try {
817
891
  return (await fp.lstat(this.isAt)).isSocket();
818
892
  }
819
- catch {
893
+ catch (e) {
894
+ if (throwOnError_)
895
+ throw e;
820
896
  return false;
821
897
  } }
822
- checkSync() { try {
898
+ checkSync(throwOnError_) { try {
823
899
  return fs.lstatSync(this.isAt).isSocket();
824
900
  }
825
- catch {
901
+ catch (e) {
902
+ if (throwOnError_)
903
+ throw e;
826
904
  return false;
827
905
  } }
828
906
  isSocket() { return true; }
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/clerkburk/instrumentality.git"
6
6
  },
7
7
  "type": "module",
8
- "version": "0.0.13",
8
+ "version": "0.0.15",
9
9
  "main": "./dist/base.js",
10
10
  "types": "./dist/base.d.ts",
11
11
  "devDependencies": {
package/src/dom.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Resolves on `DOMContentLoaded` or immediately if the document is already ready.
3
3
  */
4
- export async function onceReady(): Promise<void> {
4
+ export function onceReady(): Promise<void> {
5
5
  if (document.readyState === "complete" || document.readyState === "interactive")
6
- return
6
+ return Promise.resolve()
7
7
  return new Promise(r => document.addEventListener("DOMContentLoaded", () => r(), { once: true }))
8
8
  }
9
9