@mrjacket/ahko 0.5.0 → 0.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/CHANGELOG.md +22 -0
- package/README.md +103 -5
- package/dist/ahko.d.ts +64 -0
- package/dist/events/event-emitter.d.ts +34 -0
- package/dist/events/index.d.ts +1 -0
- package/dist/index.cjs +313 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +313 -3
- package/dist/index.js.map +1 -1
- package/dist/models/events.model.d.ts +50 -0
- package/dist/models/index.d.ts +1 -0
- package/dist/models/stats.model.d.ts +4 -0
- package/dist/scheduler/task-queue.d.ts +30 -0
- package/dist/scheduler/task-runner.d.ts +2 -0
- package/dist/version.d.ts +1 -1
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -240,7 +240,7 @@ var DebounceCoordinator = class {
|
|
|
240
240
|
* Cancels all pending debounced entries and clears the map.
|
|
241
241
|
*/
|
|
242
242
|
clear() {
|
|
243
|
-
for (const
|
|
243
|
+
for (const entry of this.entries.values()) {
|
|
244
244
|
clearTimeout(entry.timerId);
|
|
245
245
|
if (entry.options?.signal && entry.abortListener) {
|
|
246
246
|
entry.options.signal.removeEventListener("abort", entry.abortListener);
|
|
@@ -412,7 +412,7 @@ var ThrottleCoordinator = class {
|
|
|
412
412
|
* Clears all throttled entries and timers.
|
|
413
413
|
*/
|
|
414
414
|
clear() {
|
|
415
|
-
for (const
|
|
415
|
+
for (const entry of this.entries.values()) {
|
|
416
416
|
if (entry.windowTimerId !== void 0) {
|
|
417
417
|
clearTimeout(entry.windowTimerId);
|
|
418
418
|
}
|
|
@@ -424,6 +424,74 @@ var ThrottleCoordinator = class {
|
|
|
424
424
|
}
|
|
425
425
|
};
|
|
426
426
|
|
|
427
|
+
// src/events/event-emitter.ts
|
|
428
|
+
var AhkoEventEmitter = class {
|
|
429
|
+
listeners = /* @__PURE__ */ new Map();
|
|
430
|
+
/**
|
|
431
|
+
* Subscribes a listener to a specific Ahko lifecycle event.
|
|
432
|
+
*
|
|
433
|
+
* @param event - The event name to subscribe to.
|
|
434
|
+
* @param handler - The callback function to invoke when the event is emitted.
|
|
435
|
+
* @returns An unsubscribe function to remove the listener.
|
|
436
|
+
*/
|
|
437
|
+
on(event, handler) {
|
|
438
|
+
let set = this.listeners.get(event);
|
|
439
|
+
if (!set) {
|
|
440
|
+
set = /* @__PURE__ */ new Set();
|
|
441
|
+
this.listeners.set(event, set);
|
|
442
|
+
}
|
|
443
|
+
set.add(handler);
|
|
444
|
+
return () => {
|
|
445
|
+
this.off(event, handler);
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Unsubscribes a listener from a specific Ahko lifecycle event.
|
|
450
|
+
*
|
|
451
|
+
* @param event - The event name.
|
|
452
|
+
* @param handler - The callback function to remove.
|
|
453
|
+
*/
|
|
454
|
+
off(event, handler) {
|
|
455
|
+
const set = this.listeners.get(event);
|
|
456
|
+
if (set) {
|
|
457
|
+
set.delete(handler);
|
|
458
|
+
if (set.size === 0) {
|
|
459
|
+
this.listeners.delete(event);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Emits an event with the corresponding typed payload to all subscribed listeners.
|
|
465
|
+
* Listener invocations are safely isolated in try/catch to protect scheduler integrity.
|
|
466
|
+
*
|
|
467
|
+
* @param event - The event name to emit.
|
|
468
|
+
* @param payload - The event-specific payload data.
|
|
469
|
+
*/
|
|
470
|
+
emit(event, payload) {
|
|
471
|
+
const set = this.listeners.get(event);
|
|
472
|
+
if (!set || set.size === 0) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const handlers = Array.from(set);
|
|
476
|
+
for (const handler of handlers) {
|
|
477
|
+
try {
|
|
478
|
+
const result = handler(payload);
|
|
479
|
+
if (result && typeof result.catch === "function") {
|
|
480
|
+
result.catch(() => {
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
} catch {
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Removes all registered event listeners.
|
|
489
|
+
*/
|
|
490
|
+
clear() {
|
|
491
|
+
this.listeners.clear();
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
|
|
427
495
|
// src/scheduler/task-queue.ts
|
|
428
496
|
var TaskQueue = class {
|
|
429
497
|
/** Maximum concurrent active tasks */
|
|
@@ -448,6 +516,10 @@ var TaskQueue = class {
|
|
|
448
516
|
debounceCoordinator = new DebounceCoordinator();
|
|
449
517
|
/** Coordinator for throttled tasks with leading/trailing coalescing */
|
|
450
518
|
throttleCoordinator = new ThrottleCoordinator();
|
|
519
|
+
/** Lifecycle event emitter for task and scheduler events */
|
|
520
|
+
emitter = new AhkoEventEmitter();
|
|
521
|
+
/** Set of pending resolvers awaiting scheduler idle transition */
|
|
522
|
+
idleResolvers = /* @__PURE__ */ new Set();
|
|
451
523
|
/** WeakMap associating task runners with their scheduling options */
|
|
452
524
|
runnerOptions = /* @__PURE__ */ new WeakMap();
|
|
453
525
|
/** Cumulative completed tasks counter */
|
|
@@ -458,6 +530,10 @@ var TaskQueue = class {
|
|
|
458
530
|
cancelledTasks = 0;
|
|
459
531
|
/** Cumulative timed out tasks counter */
|
|
460
532
|
timedOutTasks = 0;
|
|
533
|
+
/** Cumulative count of retry attempts triggered */
|
|
534
|
+
retriedTasks = 0;
|
|
535
|
+
/** Cumulative count of tasks dispatched to concurrency slots */
|
|
536
|
+
totalDispatched = 0;
|
|
461
537
|
/**
|
|
462
538
|
* Creates a new TaskQueue.
|
|
463
539
|
*
|
|
@@ -563,6 +639,11 @@ var TaskQueue = class {
|
|
|
563
639
|
if (index !== -1) {
|
|
564
640
|
this.queue.splice(index, 1);
|
|
565
641
|
this.cancelledTasks++;
|
|
642
|
+
this.emitter.emit("task:cancel", {
|
|
643
|
+
taskId: runner.taskId,
|
|
644
|
+
reason: "Task cancelled while queued"
|
|
645
|
+
});
|
|
646
|
+
this.checkIdle();
|
|
566
647
|
}
|
|
567
648
|
};
|
|
568
649
|
this.queue.push(runner);
|
|
@@ -586,6 +667,11 @@ var TaskQueue = class {
|
|
|
586
667
|
if (index !== -1) {
|
|
587
668
|
this.queue.splice(index, 1);
|
|
588
669
|
this.cancelledTasks++;
|
|
670
|
+
this.emitter.emit("task:cancel", {
|
|
671
|
+
taskId: runner.taskId,
|
|
672
|
+
reason: "Task cancelled while queued"
|
|
673
|
+
});
|
|
674
|
+
this.checkIdle();
|
|
589
675
|
}
|
|
590
676
|
};
|
|
591
677
|
this.queue.push(runner);
|
|
@@ -598,6 +684,11 @@ var TaskQueue = class {
|
|
|
598
684
|
clearTimeout(delayedEntry.timerId);
|
|
599
685
|
this.delayedEntries.delete(delayedEntry);
|
|
600
686
|
this.cancelledTasks++;
|
|
687
|
+
this.emitter.emit("task:cancel", {
|
|
688
|
+
taskId: runner.taskId,
|
|
689
|
+
reason: "Task cancelled while waiting in delay"
|
|
690
|
+
});
|
|
691
|
+
this.checkIdle();
|
|
601
692
|
}
|
|
602
693
|
};
|
|
603
694
|
}
|
|
@@ -617,6 +708,11 @@ var TaskQueue = class {
|
|
|
617
708
|
if (index !== -1) {
|
|
618
709
|
this.queue.splice(index, 1);
|
|
619
710
|
this.cancelledTasks++;
|
|
711
|
+
this.emitter.emit("task:cancel", {
|
|
712
|
+
taskId: runner.taskId,
|
|
713
|
+
reason: "Task cancelled while queued"
|
|
714
|
+
});
|
|
715
|
+
this.checkIdle();
|
|
620
716
|
}
|
|
621
717
|
};
|
|
622
718
|
this.queue.push(runner);
|
|
@@ -629,6 +725,11 @@ var TaskQueue = class {
|
|
|
629
725
|
handle.cancel();
|
|
630
726
|
this.idleEntries.delete(idleEntry);
|
|
631
727
|
this.cancelledTasks++;
|
|
728
|
+
this.emitter.emit("task:cancel", {
|
|
729
|
+
taskId: runner.taskId,
|
|
730
|
+
reason: "Task cancelled while waiting for idle"
|
|
731
|
+
});
|
|
732
|
+
this.checkIdle();
|
|
632
733
|
}
|
|
633
734
|
};
|
|
634
735
|
}
|
|
@@ -697,36 +798,69 @@ var TaskQueue = class {
|
|
|
697
798
|
*/
|
|
698
799
|
async executeRunner(runner) {
|
|
699
800
|
const options = this.runnerOptions.get(runner);
|
|
801
|
+
this.totalDispatched++;
|
|
802
|
+
this.emitter.emit("task:start", {
|
|
803
|
+
taskId: runner.taskId,
|
|
804
|
+
attempt: runner.attempt
|
|
805
|
+
});
|
|
700
806
|
try {
|
|
701
807
|
const result = await runner.run();
|
|
702
808
|
this.completedTasks++;
|
|
703
809
|
this.activeRunners.delete(runner);
|
|
704
810
|
this.runnerOptions.delete(runner);
|
|
811
|
+
this.emitter.emit("task:complete", {
|
|
812
|
+
taskId: runner.taskId,
|
|
813
|
+
attempt: runner.attempt,
|
|
814
|
+
durationMs: runner.lastDurationMs,
|
|
815
|
+
result
|
|
816
|
+
});
|
|
705
817
|
runner.resolve(result);
|
|
706
818
|
} catch (error) {
|
|
707
819
|
if (runner.state === "cancelled" /* CANCELLED */) {
|
|
708
820
|
this.cancelledTasks++;
|
|
709
821
|
this.activeRunners.delete(runner);
|
|
710
822
|
this.runnerOptions.delete(runner);
|
|
823
|
+
this.emitter.emit("task:cancel", {
|
|
824
|
+
taskId: runner.taskId,
|
|
825
|
+
reason: error
|
|
826
|
+
});
|
|
711
827
|
runner.reject(error);
|
|
712
828
|
return;
|
|
713
829
|
}
|
|
714
830
|
const shouldRetry = await runner.canRetry(error, options?.retry);
|
|
715
831
|
if (shouldRetry) {
|
|
832
|
+
this.retriedTasks++;
|
|
716
833
|
this.activeRunners.delete(runner);
|
|
834
|
+
this.emitter.emit("task:fail", {
|
|
835
|
+
taskId: runner.taskId,
|
|
836
|
+
attempt: runner.attempt - 1,
|
|
837
|
+
error,
|
|
838
|
+
willRetry: true
|
|
839
|
+
});
|
|
717
840
|
this.scheduleRetry(runner, options);
|
|
718
841
|
return;
|
|
719
842
|
}
|
|
720
843
|
if (runner.state === "timed_out" /* TIMED_OUT */ || error instanceof AhkoTimeoutError) {
|
|
721
844
|
this.timedOutTasks++;
|
|
845
|
+
this.emitter.emit("task:timeout", {
|
|
846
|
+
taskId: runner.taskId,
|
|
847
|
+
timeoutMs: runner.timeoutMs
|
|
848
|
+
});
|
|
722
849
|
} else {
|
|
723
850
|
this.failedTasks++;
|
|
724
851
|
}
|
|
725
852
|
this.activeRunners.delete(runner);
|
|
726
853
|
this.runnerOptions.delete(runner);
|
|
854
|
+
this.emitter.emit("task:fail", {
|
|
855
|
+
taskId: runner.taskId,
|
|
856
|
+
attempt: runner.attempt,
|
|
857
|
+
error,
|
|
858
|
+
willRetry: false
|
|
859
|
+
});
|
|
727
860
|
runner.reject(error);
|
|
728
861
|
} finally {
|
|
729
862
|
this.pump();
|
|
863
|
+
this.checkIdle();
|
|
730
864
|
}
|
|
731
865
|
}
|
|
732
866
|
/**
|
|
@@ -741,6 +875,11 @@ var TaskQueue = class {
|
|
|
741
875
|
if (index !== -1) {
|
|
742
876
|
this.queue.splice(index, 1);
|
|
743
877
|
this.cancelledTasks++;
|
|
878
|
+
this.emitter.emit("task:cancel", {
|
|
879
|
+
taskId: runner.taskId,
|
|
880
|
+
reason: "Task cancelled while queued"
|
|
881
|
+
});
|
|
882
|
+
this.checkIdle();
|
|
744
883
|
}
|
|
745
884
|
};
|
|
746
885
|
this.queue.push(runner);
|
|
@@ -759,6 +898,11 @@ var TaskQueue = class {
|
|
|
759
898
|
if (index !== -1) {
|
|
760
899
|
this.queue.splice(index, 1);
|
|
761
900
|
this.cancelledTasks++;
|
|
901
|
+
this.emitter.emit("task:cancel", {
|
|
902
|
+
taskId: runner.taskId,
|
|
903
|
+
reason: "Task cancelled while queued"
|
|
904
|
+
});
|
|
905
|
+
this.checkIdle();
|
|
762
906
|
}
|
|
763
907
|
};
|
|
764
908
|
this.queue.push(runner);
|
|
@@ -771,9 +915,91 @@ var TaskQueue = class {
|
|
|
771
915
|
clearTimeout(retryEntry.timerId);
|
|
772
916
|
this.retryEntries.delete(retryEntry);
|
|
773
917
|
this.cancelledTasks++;
|
|
918
|
+
this.emitter.emit("task:cancel", {
|
|
919
|
+
taskId: runner.taskId,
|
|
920
|
+
reason: "Task cancelled during retry backoff"
|
|
921
|
+
});
|
|
922
|
+
this.checkIdle();
|
|
774
923
|
}
|
|
775
924
|
};
|
|
776
925
|
}
|
|
926
|
+
/**
|
|
927
|
+
* Checks whether the scheduler has transitioned to idle and notifies listeners/resolvers.
|
|
928
|
+
*/
|
|
929
|
+
checkIdle() {
|
|
930
|
+
if (this.isIdle()) {
|
|
931
|
+
if (this.idleResolvers.size > 0) {
|
|
932
|
+
for (const resolve of this.idleResolvers) {
|
|
933
|
+
resolve();
|
|
934
|
+
}
|
|
935
|
+
this.idleResolvers.clear();
|
|
936
|
+
}
|
|
937
|
+
this.emitter.emit("idle", { timestamp: Date.now() });
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Checks whether the scheduler is currently idle (no active runners and no pending tasks).
|
|
942
|
+
*
|
|
943
|
+
* @returns True if completely idle, false otherwise.
|
|
944
|
+
*/
|
|
945
|
+
isIdle() {
|
|
946
|
+
return this.activeRunners.size === 0 && this.queue.length === 0 && this.delayedEntries.size === 0 && this.idleEntries.size === 0 && this.retryEntries.size === 0 && this.debounceCoordinator.size === 0 && this.throttleCoordinator.size === 0;
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Returns a promise that resolves once the scheduler has processed all tasks and is idle.
|
|
950
|
+
*
|
|
951
|
+
* @returns Promise resolving when idle.
|
|
952
|
+
*/
|
|
953
|
+
onIdle() {
|
|
954
|
+
if (this.isIdle()) {
|
|
955
|
+
return Promise.resolve();
|
|
956
|
+
}
|
|
957
|
+
return new Promise((resolve) => {
|
|
958
|
+
this.idleResolvers.add(resolve);
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Clears all pending and waiting tasks from the scheduler, cancelling their runners.
|
|
963
|
+
* Active tasks currently in flight will continue to run to completion or abort via signal.
|
|
964
|
+
*/
|
|
965
|
+
clear() {
|
|
966
|
+
while (this.queue.length > 0) {
|
|
967
|
+
const runner = this.queue.shift();
|
|
968
|
+
if (runner && runner.state !== "cancelled" /* CANCELLED */) {
|
|
969
|
+
runner.cancel("Scheduler cleared");
|
|
970
|
+
this.cancelledTasks++;
|
|
971
|
+
this.emitter.emit("task:cancel", { taskId: runner.taskId, reason: "Scheduler cleared" });
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
for (const entry of this.delayedEntries.values()) {
|
|
975
|
+
clearTimeout(entry.timerId);
|
|
976
|
+
entry.runner.cancel("Scheduler cleared");
|
|
977
|
+
this.cancelledTasks++;
|
|
978
|
+
this.emitter.emit("task:cancel", { taskId: entry.runner.taskId, reason: "Scheduler cleared" });
|
|
979
|
+
}
|
|
980
|
+
this.delayedEntries.clear();
|
|
981
|
+
for (const entry of this.idleEntries.values()) {
|
|
982
|
+
entry.handle.cancel();
|
|
983
|
+
entry.runner.cancel("Scheduler cleared");
|
|
984
|
+
this.cancelledTasks++;
|
|
985
|
+
this.emitter.emit("task:cancel", { taskId: entry.runner.taskId, reason: "Scheduler cleared" });
|
|
986
|
+
}
|
|
987
|
+
this.idleEntries.clear();
|
|
988
|
+
for (const entry of this.retryEntries.values()) {
|
|
989
|
+
clearTimeout(entry.timerId);
|
|
990
|
+
entry.runner.cancel("Scheduler cleared");
|
|
991
|
+
this.cancelledTasks++;
|
|
992
|
+
this.emitter.emit("task:cancel", { taskId: entry.runner.taskId, reason: "Scheduler cleared" });
|
|
993
|
+
}
|
|
994
|
+
this.retryEntries.clear();
|
|
995
|
+
this.debounceCoordinator.clear();
|
|
996
|
+
this.throttleCoordinator.clear();
|
|
997
|
+
if (this.rateLimitTimer !== void 0) {
|
|
998
|
+
clearTimeout(this.rateLimitTimer);
|
|
999
|
+
this.rateLimitTimer = void 0;
|
|
1000
|
+
}
|
|
1001
|
+
this.checkIdle();
|
|
1002
|
+
}
|
|
777
1003
|
/**
|
|
778
1004
|
* Returns telemetry snapshot for the scheduler.
|
|
779
1005
|
*
|
|
@@ -787,6 +1013,8 @@ var TaskQueue = class {
|
|
|
787
1013
|
failedTasks: this.failedTasks,
|
|
788
1014
|
cancelledTasks: this.cancelledTasks,
|
|
789
1015
|
timedOutTasks: this.timedOutTasks,
|
|
1016
|
+
retriedTasks: this.retriedTasks,
|
|
1017
|
+
totalDispatched: this.totalDispatched,
|
|
790
1018
|
capacity: this.concurrency
|
|
791
1019
|
});
|
|
792
1020
|
}
|
|
@@ -821,6 +1049,8 @@ var TaskRunner = class {
|
|
|
821
1049
|
onCancel;
|
|
822
1050
|
/** Current execution attempt count (1-indexed) */
|
|
823
1051
|
attempt = 1;
|
|
1052
|
+
/** Duration of the most recent execution attempt in milliseconds */
|
|
1053
|
+
lastDurationMs = 0;
|
|
824
1054
|
/**
|
|
825
1055
|
* Creates a new TaskRunner instance.
|
|
826
1056
|
*
|
|
@@ -979,9 +1209,11 @@ var TaskRunner = class {
|
|
|
979
1209
|
if (timeoutPromise) {
|
|
980
1210
|
racePromises.push(timeoutPromise);
|
|
981
1211
|
}
|
|
1212
|
+
const startTime = Date.now();
|
|
982
1213
|
try {
|
|
983
1214
|
const result = await Promise.race(racePromises);
|
|
984
1215
|
this.clearTimeoutTimer();
|
|
1216
|
+
this.lastDurationMs = Math.max(0, Date.now() - startTime);
|
|
985
1217
|
if (abortListener) {
|
|
986
1218
|
this.abortController.signal.removeEventListener("abort", abortListener);
|
|
987
1219
|
}
|
|
@@ -998,6 +1230,7 @@ var TaskRunner = class {
|
|
|
998
1230
|
return result;
|
|
999
1231
|
} catch (error) {
|
|
1000
1232
|
this.clearTimeoutTimer();
|
|
1233
|
+
this.lastDurationMs = Math.max(0, Date.now() - startTime);
|
|
1001
1234
|
if (abortListener) {
|
|
1002
1235
|
this.abortController.signal.removeEventListener("abort", abortListener);
|
|
1003
1236
|
}
|
|
@@ -1239,10 +1472,87 @@ var Ahko = class {
|
|
|
1239
1472
|
stats() {
|
|
1240
1473
|
return this.queue.getStats();
|
|
1241
1474
|
}
|
|
1475
|
+
/**
|
|
1476
|
+
* Subscribes to a scheduler lifecycle event.
|
|
1477
|
+
*
|
|
1478
|
+
* @param event - Event name to listen for.
|
|
1479
|
+
* @param handler - Callback function invoked when the event is emitted.
|
|
1480
|
+
* @returns Unsubscribe function to remove the listener.
|
|
1481
|
+
*
|
|
1482
|
+
* @example
|
|
1483
|
+
* ```typescript
|
|
1484
|
+
* const unsubscribe = ahko.on("task:start", ({ taskId, attempt }) => {
|
|
1485
|
+
* console.log(`Task ${taskId} started attempt ${attempt}`);
|
|
1486
|
+
* });
|
|
1487
|
+
* ```
|
|
1488
|
+
*/
|
|
1489
|
+
on(event, handler) {
|
|
1490
|
+
return this.queue.emitter.on(event, handler);
|
|
1491
|
+
}
|
|
1492
|
+
/**
|
|
1493
|
+
* Unsubscribes an event listener from a scheduler lifecycle event.
|
|
1494
|
+
*
|
|
1495
|
+
* @param event - Event name.
|
|
1496
|
+
* @param handler - The exact listener callback to remove.
|
|
1497
|
+
*/
|
|
1498
|
+
off(event, handler) {
|
|
1499
|
+
this.queue.emitter.off(event, handler);
|
|
1500
|
+
}
|
|
1501
|
+
/**
|
|
1502
|
+
* Checks whether the scheduler is currently idle (no active runners and no pending tasks).
|
|
1503
|
+
*
|
|
1504
|
+
* @returns True if completely idle, false otherwise.
|
|
1505
|
+
*/
|
|
1506
|
+
isIdle() {
|
|
1507
|
+
return this.queue.isIdle();
|
|
1508
|
+
}
|
|
1509
|
+
/**
|
|
1510
|
+
* Returns a promise that resolves once the scheduler has completed all tasks and is idle.
|
|
1511
|
+
*
|
|
1512
|
+
* @returns Promise resolving when the scheduler is idle.
|
|
1513
|
+
*
|
|
1514
|
+
* @example
|
|
1515
|
+
* ```typescript
|
|
1516
|
+
* ahko.schedule(doWork);
|
|
1517
|
+
* await ahko.onIdle();
|
|
1518
|
+
* console.log("All work finished!");
|
|
1519
|
+
* ```
|
|
1520
|
+
*/
|
|
1521
|
+
onIdle() {
|
|
1522
|
+
return this.queue.onIdle();
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* Clears all pending, delayed, and throttled/debounced tasks from the scheduler.
|
|
1526
|
+
* In-flight active tasks will continue executing to completion or abort via signal.
|
|
1527
|
+
*/
|
|
1528
|
+
clear() {
|
|
1529
|
+
this.queue.clear();
|
|
1530
|
+
}
|
|
1531
|
+
/**
|
|
1532
|
+
* Returns the delightful Ahko mascot battery telemetry status.
|
|
1533
|
+
*
|
|
1534
|
+
* Low energy, completely chill.
|
|
1535
|
+
*/
|
|
1536
|
+
battery() {
|
|
1537
|
+
return {
|
|
1538
|
+
level: 3,
|
|
1539
|
+
chill: true,
|
|
1540
|
+
status: "low-energy",
|
|
1541
|
+
quote: "Mwee... my battery is low, but all your tasks are handled completely chill."
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
/**
|
|
1545
|
+
* Delightful alias for `onIdle()`: wait for all tasks to settle chill and relaxed.
|
|
1546
|
+
*
|
|
1547
|
+
* @returns Promise resolving when all tasks have finished.
|
|
1548
|
+
*/
|
|
1549
|
+
chill() {
|
|
1550
|
+
return this.onIdle();
|
|
1551
|
+
}
|
|
1242
1552
|
};
|
|
1243
1553
|
|
|
1244
1554
|
// src/version.ts
|
|
1245
|
-
var VERSION = "0.
|
|
1555
|
+
var VERSION = "0.6.0";
|
|
1246
1556
|
|
|
1247
1557
|
// src/errors/queue.error.ts
|
|
1248
1558
|
var AhkoQueueError = class extends AhkoError {
|