@isdk/util 0.3.1 → 0.3.3

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 (55) hide show
  1. package/dist/index.d.mts +491 -1
  2. package/dist/index.d.ts +491 -1
  3. package/dist/index.js +1 -1
  4. package/dist/index.mjs +1 -1
  5. package/docs/classes/BinarySemaphore.md +418 -0
  6. package/docs/classes/ConfigFile.md +54 -5
  7. package/docs/classes/Deque.md +1912 -0
  8. package/docs/classes/IntSet.md +216 -0
  9. package/docs/classes/Semaphore.md +538 -0
  10. package/docs/classes/SignalGate.md +184 -0
  11. package/docs/functions/RateLimit.md +37 -0
  12. package/docs/functions/arrayHasAll.md +1 -1
  13. package/docs/functions/extNameLevel.md +1 -1
  14. package/docs/functions/filenameReservedRegex.md +1 -1
  15. package/docs/functions/findPort.md +25 -0
  16. package/docs/functions/getMultiLevelExtname.md +1 -1
  17. package/docs/functions/glob.md +1 -1
  18. package/docs/functions/isStringIn.md +1 -1
  19. package/docs/functions/isValidFilename.md +1 -1
  20. package/docs/functions/isValidFilepath.md +1 -1
  21. package/docs/functions/normalizeIncludeFiles.md +1 -1
  22. package/docs/functions/parseFrontMatter.md +1 -1
  23. package/docs/functions/parseYaml.md +1 -1
  24. package/docs/functions/reControlCharsRegex.md +1 -1
  25. package/docs/functions/registerYamlTag.md +2 -2
  26. package/docs/functions/removeLeadingEmptyLines.md +1 -1
  27. package/docs/functions/sanitizeFilename.md +1 -1
  28. package/docs/functions/sanitizeFilepath.md +1 -1
  29. package/docs/functions/sleep.md +36 -0
  30. package/docs/functions/stringifyYaml.md +1 -1
  31. package/docs/functions/toCamelCase.md +1 -1
  32. package/docs/functions/toCapitalCase.md +1 -1
  33. package/docs/functions/toPascalCase.md +1 -1
  34. package/docs/functions/traverseFolder.md +1 -1
  35. package/docs/functions/traverseFolderSync.md +1 -1
  36. package/docs/functions/yieldExec.md +27 -0
  37. package/docs/globals.md +17 -0
  38. package/docs/interfaces/BinarySemaphoreAcquireOptions.md +25 -0
  39. package/docs/interfaces/BinarySemaphoreOptions.md +57 -0
  40. package/docs/interfaces/BinarySemaphoreReleaseOptions.md +25 -0
  41. package/docs/interfaces/BinarySemaphoreReleaserFunc.md +37 -0
  42. package/docs/interfaces/IncludeFiles.md +3 -3
  43. package/docs/interfaces/LoadConfigFileOptions.md +3 -3
  44. package/docs/interfaces/SanitizeFilenameOptions.md +3 -3
  45. package/docs/interfaces/SemaphoreOptions.md +89 -0
  46. package/docs/interfaces/SemaphoreTaskItem.md +73 -0
  47. package/docs/type-aliases/SemaphoreIsReadyFuncType.md +15 -0
  48. package/docs/type-aliases/StringifyFunc.md +1 -1
  49. package/docs/type-aliases/TraverseFolderHandler.md +1 -1
  50. package/docs/type-aliases/TraverseFolderSyncHandler.md +1 -1
  51. package/docs/variables/DefaultAllTextFiles.md +1 -1
  52. package/docs/variables/DefaultAsyncSemaphoreCapacity.md +11 -0
  53. package/docs/variables/FilenameReservedRegex.md +1 -1
  54. package/docs/variables/WindowsReservedNameRegex.md +1 -1
  55. package/package.json +4 -2
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Dirent } from 'fs';
2
2
  import { ScalarTag, CollectionTag, TagId, Tags, ParseOptions, DocumentOptions, SchemaOptions, ToJSOptions, CreateNodeOptions, ToStringOptions } from 'yaml';
3
+ import { EventEmitter } from 'events-ex';
3
4
 
4
5
  type StringifyFunc = (content: any) => string;
5
6
  interface LoadConfigFileOptions {
@@ -73,6 +74,33 @@ declare class ConfigFile {
73
74
  * ```
74
75
  */
75
76
  static saveSync(filename: string, config: any, options?: LoadConfigFileOptions): string;
77
+ /**
78
+ * Checks if a configuration file exists at the specified path.
79
+ *
80
+ * This method normalizes the filename by removing the extension (if present) and then delegates
81
+ * to the underlying LoadConfigFile utility to perform the existence check. The normalization
82
+ * ensures consistent handling of files regardless of whether they include extensions in the
83
+ * provided filename.
84
+ *
85
+ * @param filename - The path to the configuration file to check for existence.
86
+ * This can include or omit the file extension.
87
+ * @param options - Optional configuration options that may affect how the file existence
88
+ * is checked, including extension level handling.
89
+ *
90
+ * @returns `true` if the configuration file exists, `false` otherwise.
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * // Check if a YAML config file exists
95
+ * const exists = ConfigFile.existsSync('config.yaml');
96
+ * console.log(exists); // true or false
97
+ *
98
+ * // Check with options
99
+ * const existsWithExt = ConfigFile.existsSync('config', { extLevel: 2 });
100
+ * console.log(existsWithExt); // true or false
101
+ * ```
102
+ */
103
+ static existsSync(filename: string, options?: LoadConfigFileOptions): boolean;
76
104
  }
77
105
 
78
106
  /**
@@ -437,4 +465,466 @@ declare function extNameLevel(extName: string): number;
437
465
  */
438
466
  declare function arrayHasAll<T = any>(array: T[], elements: T[]): boolean;
439
467
 
440
- export { ConfigFile, DefaultAllTextFiles, FilenameReservedRegex, type IncludeFiles, type LoadConfigFileOptions, type SanitizeFilenameOptions, type StringifyFunc, type TraverseFolderHandler, type TraverseFolderSyncHandler, WindowsReservedNameRegex, arrayHasAll, extNameLevel, filenameReservedRegex, getMultiLevelExtname, glob, isStringIn, isValidFilename, isValidFilepath, normalizeIncludeFiles, parseFrontMatter, parseYaml, reControlCharsRegex, registerYamlTag, removeLeadingEmptyLines, sanitizeFilename, sanitizeFilepath, stringifyYaml, toCamelCase, toCapitalCase, toPascalCase, traverseFolder, traverseFolderSync };
468
+ declare class Deque<T = any> extends Array<T> {
469
+ private _capacity;
470
+ private _length;
471
+ private _front;
472
+ private _disableAutoResize?;
473
+ constructor(capacity?: number | T[], disableAutoResize?: boolean);
474
+ push(item: T): number;
475
+ unshift(item: T): number;
476
+ /**
477
+ * Removes and returns the element at the back of the deque.
478
+ *
479
+ * @param skipNull When `true`, skips trailing `null`/`undefined` values until a valid element is found or all elements are processed.
480
+ * @returns The removed element, or `undefined` if the deque is empty or all elements are skipped.
481
+ *
482
+ * @example
483
+ * // Normal pop without skipping
484
+ * const deque = new Deque([1, 2, 3]);
485
+ * deque.pop(); // 3
486
+ *
487
+ * @example
488
+ * // Skipping null values
489
+ * const nullDeque = new Deque([null, 4, null]);
490
+ * nullDeque.pop(true); // 4
491
+ * nullDeque.pop(true); // undefined (skipped remaining nulls)
492
+ *
493
+ * @example
494
+ * // Mixed elements with skip
495
+ * const mixedDeque = new Deque([5, null, 6, null]);
496
+ * mixedDeque.pop(true); // 6
497
+ * mixedDeque.pop(false); // null (explicitly not skipping)
498
+ */
499
+ pop(skipNull?: boolean): T | undefined;
500
+ /**
501
+ * Removes and returns the element at the front of the deque.
502
+ *
503
+ * @param skipNull When `true`, skips leading `null`/`undefined` values until a valid element is found or all elements are processed.
504
+ * @returns The removed element, or `undefined` if the deque is empty or all elements are skipped.
505
+ *
506
+ * @example
507
+ * // Normal shift without skipping
508
+ * const deque = new Deque([1, 2, 3]);
509
+ * deque.shift(); // 1
510
+ *
511
+ * @example
512
+ * // Skipping null values
513
+ * const nullDeque = new Deque([null, 4, null]);
514
+ * nullDeque.shift(true); // 4
515
+ * nullDeque.shift(true); // undefined (skipped remaining nulls)
516
+ *
517
+ * @example
518
+ * // Mixed elements with skip
519
+ * const mixedDeque = new Deque([null, 5, null, 6]);
520
+ * mixedDeque.shift(true); // 5
521
+ * mixedDeque.shift(false); // null (explicitly not skipping)
522
+ */
523
+ shift(skipNull?: boolean): T | undefined;
524
+ /**
525
+ * Gets the number of elements in the deque.
526
+ *
527
+ * @returns The current count of elements in the deque.
528
+ *
529
+ * @example
530
+ * const deque = new Deque([1, 2, 3]);
531
+ * console.log(deque.size); // 3
532
+ *
533
+ * @important
534
+ * Do NOT use the native `Array.length` property. The Deque implementation uses a circular buffer with capacity management, so the native `length` reflects the underlying array capacity, not the actual element count. Always use `size` to get the correct element count.
535
+ */
536
+ get size(): number;
537
+ get(index: number): T | undefined;
538
+ peekBack(): T | undefined;
539
+ peekFront(): T | undefined;
540
+ clear(): void;
541
+ isEmpty(): boolean;
542
+ /**
543
+ * Removes the element at the specified index.
544
+ * @param index Logical index position (0 represents the front, length-1 represents the back)
545
+ * @returns The removed element
546
+ */
547
+ removeAt(index: number): T | undefined;
548
+ private checkCapacity;
549
+ private resizeTo;
550
+ }
551
+
552
+ /**
553
+ * Represents a set of integers using a bit field.
554
+ * Each bit in the bit field represents an integer starting from 0,
555
+ * where the flag value 0 represents the 0th bit, 1 represents the 1st bit, and so on.
556
+ */
557
+ declare class IntSet {
558
+ private bitField;
559
+ static has(bitField: number, flag: number): boolean;
560
+ static add(bitField: number, flag: number): number;
561
+ static delete(bitField: number, flag: number): number;
562
+ constructor(bitField?: number);
563
+ /**
564
+ * Adds an element to the set.
565
+ *
566
+ * @param flag - The flag value representing the bit position to set.
567
+ * Note: the flag value 0 represents the 0th bit, and so on.
568
+ */
569
+ add(flag: number): this;
570
+ /**
571
+ * Removes an element from the set.
572
+ *
573
+ * @param flag - The flag value representing the bit position to set. 0 represents the 0th bit
574
+ */
575
+ delete(flag: number): this;
576
+ /**
577
+ * Determines whether an element is in the set.
578
+ *
579
+ * @param flag - The flag value representing the bit position to set. 0 represents the 0th bit
580
+ * @returns true if the element is in the set; otherwise, false.
581
+ */
582
+ has(flag: number): boolean;
583
+ /**
584
+ * Clears all elements from the set.
585
+ */
586
+ clear(): this;
587
+ valueOf(): number;
588
+ toString(): string;
589
+ toJSON(): number;
590
+ }
591
+
592
+ /**
593
+ * Suspends execution for a specified number of milliseconds
594
+ * @param ms - The number of milliseconds to pause execution
595
+ * @example
596
+ * ```ts
597
+ * await sleep(500); // Pause for half a second
598
+ * ```
599
+ * @remarks
600
+ * This implementation uses `setTimeout` under the hood and is more precise
601
+ * for longer durations than `setImmediate`-based approaches
602
+ */
603
+ declare function sleep(ms: number): Promise<void>;
604
+ /**
605
+ * Yields execution control to the event loop, allowing pending I/O operations
606
+ * and scheduled tasks to run before continuing.
607
+ *
608
+ * @remarks
609
+ * This method creates a microtask checkpoint using `setImmediate`, which helps:
610
+ * - Interleave CPU-intensive work with I/O events
611
+ * - Prevent event loop blocking
612
+ * - Maintain application responsiveness
613
+ *
614
+ * Particularly useful for breaking up long synchronous operations in Node.js.
615
+ */
616
+ declare function yieldExec(): Promise<void>;
617
+
618
+ declare const DefaultAsyncSemaphoreCapacity = 32;
619
+ type SemaphoreIsReadyFuncType = () => Promise<boolean> | boolean;
620
+ interface BinarySemaphoreOptions {
621
+ initFn?: () => any;
622
+ pauseFn?: () => void;
623
+ resumeFn?: () => void;
624
+ capacity?: number;
625
+ }
626
+ interface BinarySemaphoreAcquireOptions {
627
+ signal?: AbortSignal;
628
+ [n: string]: any;
629
+ }
630
+ interface BinarySemaphoreReleaseOptions {
631
+ token?: any;
632
+ [n: string]: any;
633
+ }
634
+ interface BinarySemaphoreReleaserFunc extends BinarySemaphoreReleaseOptions {
635
+ (): void;
636
+ }
637
+ interface SemaphoreOptions extends BinarySemaphoreOptions {
638
+ maxConcurrency?: number;
639
+ isReadyFn?: SemaphoreIsReadyFuncType;
640
+ }
641
+ interface SemaphoreTaskItem extends BinarySemaphoreAcquireOptions {
642
+ resolve: (value: any) => void;
643
+ reject: (reason?: any) => void;
644
+ token?: any;
645
+ }
646
+ /**
647
+ * A binary semaphore implementation for managing concurrency in asynchronous operations.
648
+ * Unlike a general semaphore, a binary semaphore allows only one caller to acquire the semaphore at a time.
649
+ * It provides methods to acquire, release, and manage waiting tasks efficiently.
650
+ *
651
+ * Example usage:
652
+ *
653
+ * ```typescript
654
+ * const semaphore = new Semaphore(5); // Allows 5 concurrent operations.
655
+ *
656
+ * const semaphore = new Semaphore(
657
+ * 4, // Allow 4 concurrent async calls
658
+ * {
659
+ * capacity: 100 // Prealloc space for 100 tokens
660
+ * }
661
+ * );
662
+ *
663
+ * async function fetchData(x) {
664
+ * await semaphore.acquire()
665
+ * try {
666
+ * console.log(semaphore.pendingCount + ' calls to fetch are waiting')
667
+ * // ... do some async stuff with x
668
+ * } finally {
669
+ * semaphore.release();
670
+ * }
671
+ * }
672
+ *
673
+ * const data = await Promise.all(array.map(fetchData));
674
+ * ```
675
+ */
676
+ declare class BinarySemaphore {
677
+ readonly waiting: Deque<SemaphoreTaskItem | undefined>;
678
+ protected free: any;
679
+ protected emitter: EventEmitter;
680
+ protected useDefaultTokens: boolean;
681
+ protected pauseFn?: () => void;
682
+ protected resumeFn?: () => void;
683
+ protected initTokenFn: (token?: any) => void;
684
+ protected paused: boolean;
685
+ protected _activeCount: number;
686
+ /**
687
+ * Creates a binary semaphore object for managing concurrency in asynchronous operations.
688
+ *
689
+ * @param options.initFn Function that is used to initialize the tokens used to manage the semaphore. The default is () => '1'.
690
+ * @param options.pauseFn An optional fuction that is called to opportunistically request pausing the the incoming stream of data,
691
+ * instead of piling up waiting promises and possibly running out of memory. See examples/pausing.js.
692
+ * @param options.resumeFn An optional function that is called when there is room again to accept new waiters on the semaphore.
693
+ * This function must be declared if a pauseFn is declared.
694
+ * @param options.capacity Sets the size of the preallocated waiting list inside the semaphore.
695
+ * This is typically used by high performance where the developer can make a rough estimate of the number of concurrent users of a semaphore.
696
+ *
697
+ * ```ts
698
+ * const readline = require('readline');
699
+ *
700
+ * const rl = readline.createInterface({
701
+ * input: process.stdin,
702
+ * output: process.stdout,
703
+ * terminal: false
704
+ * });
705
+ *
706
+ * function pause() {
707
+ * console.log('Pausing the stream');
708
+ * rl.pause();
709
+ * }
710
+ *
711
+ * function resume() {
712
+ * console.log('Resuming the stream');
713
+ * rl.resume();
714
+ * }
715
+ *
716
+ * const s = new BinarySemaphore({ pauseFn: pause, resumeFn: resume });
717
+ *
718
+ * async function parse(line) {
719
+ * await s.acquire();
720
+ *
721
+ * console.log(line);
722
+ *
723
+ * s.release();
724
+ * }
725
+ *
726
+ * rl.on('line', line => {
727
+ * parse(line).catch(console.error);
728
+ * });
729
+ * ```
730
+ *
731
+ */
732
+ constructor(options?: BinarySemaphoreOptions);
733
+ initFree(options?: BinarySemaphoreOptions): void;
734
+ onReleased(options?: BinarySemaphoreReleaseOptions): void;
735
+ init(options: BinarySemaphoreOptions): void;
736
+ _newReleaser(options?: BinarySemaphoreReleaseOptions): BinarySemaphoreReleaserFunc;
737
+ _dispatchTask(task: SemaphoreTaskItem, options?: BinarySemaphoreReleaseOptions): void;
738
+ lock(options?: BinarySemaphoreAcquireOptions): any;
739
+ unlock(token?: any): void;
740
+ /**
741
+ * Attempt to acquire a token from the semaphore, if one is available immediately. Otherwise, return undefined.
742
+ *
743
+ * @return Returns a token if the semaphore is not full; otherwise, returns `undefined`.
744
+ */
745
+ tryAcquire(options?: BinarySemaphoreAcquireOptions): any | undefined;
746
+ /**
747
+ * Acquire a token from the semaphore, thus decrement the number of available execution slots. If initFn is not used then the return value of the function can be discarded.
748
+ * @param options.signal An optional AbortSignal to abort the acquisition process. If aborted, the promise will reject with an AbortError.
749
+ * @return A promise that resolves to a release function when a token is acquired. If the semaphore is full, the caller will be added to a waiting queue.
750
+ */
751
+ acquire(options?: BinarySemaphoreAcquireOptions): Promise<BinarySemaphoreReleaserFunc>;
752
+ /**
753
+ * Releases the semaphore, incrementing the number of free execution slots. If there are tasks in the waiting queue, the next task will be dispatched.
754
+ * @param options.token Optional token returned by `acquire()` when using a custom `initFn`. If provided, it will be used to unlock the semaphore.
755
+ */
756
+ release(options?: BinarySemaphoreReleaseOptions): void;
757
+ /**
758
+ * Drains the semaphore and returns all the initialized tokens in an array. Draining is an ideal way to ensure there are no pending async tasks, for example before a process will terminate.
759
+ */
760
+ drain(): Promise<any[]>;
761
+ abort(reason?: any): void;
762
+ /**
763
+ * Get the total count of all active operations.
764
+ *
765
+ * This method returns the number of operations that are either:
766
+ * - Waiting in the queue to acquire the semaphore (`pendingCount`).
767
+ * - Already acquired the semaphore but have not yet released it.
768
+ *
769
+ * @returns {number} The total count of active operations, including both waiting and ongoing tasks.
770
+ */
771
+ get activeCount(): number;
772
+ /**
773
+ * Get the number of callers waiting on the semaphore, i.e. the number of pending promises.
774
+ *
775
+ * @returns The number of waiters in the waiting list.
776
+ */
777
+ get pendingCount(): number;
778
+ }
779
+ /**
780
+ * A Semaphore implementation for managing concurrency in asynchronous operations.
781
+ * Semaphores allow a fixed number of resources to be accessed concurrently.
782
+ * This class extends BinarySemaphore and adds support for a maximum concurrency limit and an optional readiness check.
783
+ *
784
+ * Example usage:
785
+ *
786
+ * ```typescript
787
+ * const semaphore = new Semaphore(5); // Allows 5 concurrent operations.
788
+ *
789
+ * const semaphore = new Semaphore(
790
+ * 4, // Allow 4 concurrent async calls
791
+ * {
792
+ * capacity: 100, // Prealloc space for 100 tokens
793
+ * isReadyFn: async () => {
794
+ * // Check if the system is ready to handle more requests
795
+ * return true;
796
+ * },
797
+ * pauseFn: () => {
798
+ * console.log('Pausing the stream');
799
+ * },
800
+ * resumeFn: () => {
801
+ * console.log('Resuming the stream');
802
+ * }
803
+ * }
804
+ * );
805
+ *
806
+ * async function fetchData(x) {
807
+ * await semaphore.acquire()
808
+ * try {
809
+ * console.log(semaphore.pendingCount() + ' calls to fetch are waiting')
810
+ * // ... do some async stuff with x
811
+ * } finally {
812
+ * semaphore.release();
813
+ * }
814
+ * }
815
+ *
816
+ * const data = await Promise.all(array.map(fetchData));
817
+ * ```
818
+ */
819
+ declare class Semaphore extends BinarySemaphore {
820
+ readonly maxConcurrency: number;
821
+ protected free: Deque<any>;
822
+ private isReady?;
823
+ /**
824
+ * Creates a semaphore object. The first argument is the maximum concurrently number and the second argument is optional.
825
+ *
826
+ * @param maxConcurrency The maximum number of callers allowed to acquire the semaphore concurrently.
827
+ * @param options.initFn Function that is used to initialize the tokens used to manage the semaphore. The default is () => '1'.
828
+ * @param options.pauseFn An optional function that is called to opportunistically request pausing the incoming stream of data,
829
+ * instead of piling up waiting promises and possibly running out of memory. See examples/pausing.js.
830
+ * @param options.resumeFn An optional function that is called when there is room again to accept new waiters on the semaphore.
831
+ * This function must be declared if a pauseFn is declared.
832
+ * @param options.capacity Sets the size of the preallocated waiting list inside the semaphore.
833
+ * This is typically used by high performance where the developer can make a rough estimate of the number of concurrent users of a semaphore.
834
+ * @param options.isReadyFn An optional function that returns a boolean or a promise that resolves to a boolean indicating whether the semaphore is ready to accept new requests.
835
+ */
836
+ constructor(maxConcurrency: number | SemaphoreOptions, options?: SemaphoreOptions);
837
+ initFree(options: SemaphoreOptions): void;
838
+ tryAcquire(options?: BinarySemaphoreAcquireOptions): Promise<any | undefined> | any | undefined;
839
+ unlock(token?: any): void;
840
+ lock(options?: BinarySemaphoreAcquireOptions): any;
841
+ drain(): Promise<any[]>;
842
+ }
843
+ /**
844
+ * Creates a rate limiter function that blocks with a promise whenever the rate limit is hit and resolves the promise once the call rate is within the limit set by rps. The second argument is optional.
845
+ *
846
+ * @param rps
847
+ * @param options.timeUnit The `timeUnit` is an optional argument setting the width of the rate limiting window in milliseconds.
848
+ * The default `timeUnit` is 1000 ms, therefore making the rps argument act as requests per second limit.
849
+ * @param options.uniformDistribution The `uniformDistribution` argument enforces a discrete uniform distribution over time,
850
+ * instead of the default that allows hitting the function rps time and then pausing for timeWindow milliseconds. Setting
851
+ * the `uniformDistribution` option is mainly useful in a situation where the flow of rate limit function calls is continuous
852
+ * and and occuring faster than timeUnit (e.g. reading a file) and not enabling it would cause the maximum number of calls to
853
+ * resolve immediately (thus exhaust the limit immediately) and therefore the next bunch calls would need to wait for timeWindow
854
+ * milliseconds. However if the flow is sparse then this option may make the code run slower with no advantages.
855
+ *
856
+ * Examples:
857
+ *
858
+ * ```ts
859
+ * async function f() {
860
+ * const lim = RateLimit(5); // rps
861
+ *
862
+ * for (let i = 0; i < n; i++) {
863
+ * await lim();
864
+ * // ... do something async
865
+ * }
866
+ * }
867
+ * ```
868
+ *
869
+ *
870
+ */
871
+ declare function RateLimit(rps: number, { timeUnit, uniformDistribution, }?: {
872
+ timeUnit?: number;
873
+ uniformDistribution?: boolean;
874
+ }): () => Promise<void>;
875
+
876
+ /**
877
+ * An asynchronous signal gate that blocks operations until a signal is emitted.
878
+ * This class allows multiple awaiters to wait for a signal and resolves all pending promises with the emitted value.
879
+ * The gate can be reset to reuse for subsequent signals.
880
+ *
881
+ * @example
882
+ *
883
+ * ```typescript
884
+ * // Default type is void, can call signal() without parameters
885
+ * const gate = new SignalGate();
886
+ * gate.signal(); // No parameters required
887
+ *
888
+ * // Example with explicit type
889
+ * const valueGate = new SignalGate<number>();
890
+ * valueGate.signal(42); // Must provide a number value
891
+ * ```
892
+ */
893
+ declare class SignalGate<T = void> {
894
+ protected _isSignaled: boolean;
895
+ protected _signalValue: T | undefined;
896
+ protected waitQueue: Array<{
897
+ resolve: (value: T) => void;
898
+ reject: (error: any) => void;
899
+ }>;
900
+ get signaled(): boolean;
901
+ /**
902
+ * Emits the signal with an optional value, resolving all pending {@link wait} promises.
903
+ * Subsequent calls have no effect until {@link reset} is called.
904
+ *
905
+ * @param value The value to emit with the signal (only required if T is not void).
906
+ */
907
+ signal(value?: T): void;
908
+ /**
909
+ * Resets the gate to its initial state, allowing a new signal to be emitted.
910
+ */
911
+ reset(): void;
912
+ /**
913
+ * Aborts all pending waits, rejecting their promises with an error.
914
+ * This does **not** reset the signal state (the gate remains signaled or unsignaled).
915
+ *
916
+ * @param reason The reason for aborting the waits.
917
+ */
918
+ abort(reason?: any): void;
919
+ /**
920
+ * Returns a promise that resolves with the emitted signal value.
921
+ * If called after the signal has been emitted, resolves immediately with the stored value.
922
+ *
923
+ * @returns A promise resolving to the signal value (type T).
924
+ */
925
+ wait(): Promise<T>;
926
+ }
927
+
928
+ declare function findPort(port: string | number, portRetryCount?: number): Promise<number>;
929
+
930
+ export { BinarySemaphore, type BinarySemaphoreAcquireOptions, type BinarySemaphoreOptions, type BinarySemaphoreReleaseOptions, type BinarySemaphoreReleaserFunc, ConfigFile, DefaultAllTextFiles, DefaultAsyncSemaphoreCapacity, Deque, FilenameReservedRegex, type IncludeFiles, IntSet, type LoadConfigFileOptions, RateLimit, type SanitizeFilenameOptions, Semaphore, type SemaphoreIsReadyFuncType, type SemaphoreOptions, type SemaphoreTaskItem, SignalGate, type StringifyFunc, type TraverseFolderHandler, type TraverseFolderSyncHandler, WindowsReservedNameRegex, arrayHasAll, extNameLevel, filenameReservedRegex, findPort, getMultiLevelExtname, glob, isStringIn, isValidFilename, isValidFilepath, normalizeIncludeFiles, parseFrontMatter, parseYaml, reControlCharsRegex, registerYamlTag, removeLeadingEmptyLines, sanitizeFilename, sanitizeFilepath, sleep, stringifyYaml, toCamelCase, toCapitalCase, toPascalCase, traverseFolder, traverseFolderSync, yieldExec };