@actuallab/core 13.0.4 → 13.0.14
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/index.cjs +292 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +158 -2
- package/dist/index.d.ts +158 -2
- package/dist/index.js +278 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -29,21 +29,34 @@ __export(index_exports, {
|
|
|
29
29
|
LogLevel: () => LogLevel,
|
|
30
30
|
LogLevelController: () => LogLevelController,
|
|
31
31
|
PromiseSource: () => PromiseSource,
|
|
32
|
+
PromiseSourceWithTimeout: () => PromiseSourceWithTimeout,
|
|
33
|
+
ResolvedPromise: () => ResolvedPromise,
|
|
32
34
|
Result: () => Result,
|
|
33
35
|
RetryDelayLimitExceeded: () => RetryDelayLimitExceeded,
|
|
34
36
|
RetryDelayNone: () => RetryDelayNone,
|
|
35
37
|
RetryDelaySeq: () => RetryDelaySeq,
|
|
36
38
|
RetryDelayer: () => RetryDelayer,
|
|
37
39
|
RingBuffer: () => RingBuffer,
|
|
40
|
+
TimedOut: () => TimedOut,
|
|
41
|
+
TimeoutError: () => TimeoutError,
|
|
42
|
+
abortPromise: () => abortPromise,
|
|
38
43
|
abortSignalKey: () => abortSignalKey,
|
|
44
|
+
catchErrors: () => catchErrors,
|
|
39
45
|
createLogProvider: () => createLogProvider,
|
|
46
|
+
debounce: () => debounce,
|
|
47
|
+
delayAsync: () => delayAsync,
|
|
48
|
+
delayAsyncWith: () => delayAsyncWith,
|
|
40
49
|
errorResult: () => errorResult,
|
|
41
50
|
initLogging: () => initLogging,
|
|
42
51
|
initWorkerLogging: () => initWorkerLogging,
|
|
43
52
|
resolvedVoidPromise: () => resolvedVoidPromise,
|
|
44
53
|
result: () => result,
|
|
45
54
|
resultFrom: () => resultFrom,
|
|
46
|
-
resultFromAsync: () => resultFromAsync
|
|
55
|
+
resultFromAsync: () => resultFromAsync,
|
|
56
|
+
retry: () => retry,
|
|
57
|
+
serialize: () => serialize,
|
|
58
|
+
throttle: () => throttle,
|
|
59
|
+
withTimeout: () => withTimeout
|
|
47
60
|
});
|
|
48
61
|
module.exports = __toCommonJS(index_exports);
|
|
49
62
|
|
|
@@ -642,6 +655,7 @@ var AsyncLock = class {
|
|
|
642
655
|
// src/promise-source.ts
|
|
643
656
|
var PromiseSource = class {
|
|
644
657
|
promise;
|
|
658
|
+
[Symbol.toStringTag] = "Promise";
|
|
645
659
|
_resolve;
|
|
646
660
|
_reject;
|
|
647
661
|
_isCompleted = false;
|
|
@@ -666,6 +680,15 @@ var PromiseSource = class {
|
|
|
666
680
|
this._reject(reason);
|
|
667
681
|
return true;
|
|
668
682
|
}
|
|
683
|
+
then(onfulfilled, onrejected) {
|
|
684
|
+
return this.promise.then(onfulfilled, onrejected);
|
|
685
|
+
}
|
|
686
|
+
catch(onrejected) {
|
|
687
|
+
return this.promise.catch(onrejected);
|
|
688
|
+
}
|
|
689
|
+
finally(onfinally) {
|
|
690
|
+
return this.promise.finally(onfinally);
|
|
691
|
+
}
|
|
669
692
|
};
|
|
670
693
|
var resolvedVoidPromise = Promise.resolve();
|
|
671
694
|
|
|
@@ -694,10 +717,235 @@ var EventHandlerSet = class {
|
|
|
694
717
|
ps.resolve(arg);
|
|
695
718
|
};
|
|
696
719
|
this._handlers.add(handler);
|
|
697
|
-
return ps
|
|
720
|
+
return ps;
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
// src/withTimeout.ts
|
|
725
|
+
var TimeoutError = class extends Error {
|
|
726
|
+
name = "TimeoutError";
|
|
727
|
+
constructor(message = "Operation timed out") {
|
|
728
|
+
super(message);
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
async function withTimeout(promise, ms, message) {
|
|
732
|
+
let timer;
|
|
733
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
734
|
+
timer = setTimeout(
|
|
735
|
+
() => reject(new TimeoutError(message ?? `Operation timed out after ${ms}ms`)),
|
|
736
|
+
ms
|
|
737
|
+
);
|
|
738
|
+
});
|
|
739
|
+
timeoutPromise.catch(() => {
|
|
740
|
+
});
|
|
741
|
+
try {
|
|
742
|
+
return await Promise.race([promise, timeoutPromise]);
|
|
743
|
+
} finally {
|
|
744
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// src/promise-source-with-timeout.ts
|
|
749
|
+
var PromiseSourceWithTimeout = class extends PromiseSource {
|
|
750
|
+
_timer;
|
|
751
|
+
hasTimeout() {
|
|
752
|
+
return this._timer !== void 0;
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Install (or replace) a timeout. Pass `null` to remove without setting a
|
|
756
|
+
* new one. `callback` is invoked when the timer fires — if omitted, the
|
|
757
|
+
* promise is rejected with a generic "timed out" error.
|
|
758
|
+
*/
|
|
759
|
+
setTimeout(ms, callback) {
|
|
760
|
+
this.clearTimeout();
|
|
761
|
+
if (ms === null || this.isCompleted) return;
|
|
762
|
+
this._timer = setTimeout(() => {
|
|
763
|
+
this._timer = void 0;
|
|
764
|
+
if (callback) callback();
|
|
765
|
+
else this.reject(new TimeoutError(`The promise has timed out after ${ms}ms.`));
|
|
766
|
+
}, ms);
|
|
767
|
+
}
|
|
768
|
+
clearTimeout() {
|
|
769
|
+
if (this._timer === void 0) return;
|
|
770
|
+
clearTimeout(this._timer);
|
|
771
|
+
this._timer = void 0;
|
|
772
|
+
}
|
|
773
|
+
resolve(value) {
|
|
774
|
+
const didSettle = super.resolve(value);
|
|
775
|
+
if (didSettle) this.clearTimeout();
|
|
776
|
+
return didSettle;
|
|
777
|
+
}
|
|
778
|
+
reject(reason) {
|
|
779
|
+
const didSettle = super.reject(reason);
|
|
780
|
+
if (didSettle) this.clearTimeout();
|
|
781
|
+
return didSettle;
|
|
698
782
|
}
|
|
699
783
|
};
|
|
700
784
|
|
|
785
|
+
// src/resolved-promise.ts
|
|
786
|
+
var ResolvedPromise = {
|
|
787
|
+
Void: Promise.resolve(),
|
|
788
|
+
True: Promise.resolve(true),
|
|
789
|
+
False: Promise.resolve(false)
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
// src/timed-out.ts
|
|
793
|
+
var TimedOut = class _TimedOut {
|
|
794
|
+
static instance = new _TimedOut();
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
// src/delay.ts
|
|
798
|
+
function delayAsync(ms) {
|
|
799
|
+
return new Promise((resolve) => {
|
|
800
|
+
setTimeout(resolve, ms);
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
function delayAsyncWith(ms, value) {
|
|
804
|
+
return new Promise((resolve) => {
|
|
805
|
+
setTimeout(() => resolve(value), ms);
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
// src/abort-promise.ts
|
|
810
|
+
var abortPromiseCache = /* @__PURE__ */ new WeakMap();
|
|
811
|
+
function abortPromise(signal) {
|
|
812
|
+
if (signal.aborted) return Promise.reject(signal.reason);
|
|
813
|
+
let cached = abortPromiseCache.get(signal);
|
|
814
|
+
if (!cached) {
|
|
815
|
+
cached = new Promise((_, reject) => {
|
|
816
|
+
signal.addEventListener("abort", () => reject(signal.reason), { once: true });
|
|
817
|
+
});
|
|
818
|
+
cached.catch(() => {
|
|
819
|
+
});
|
|
820
|
+
abortPromiseCache.set(signal, cached);
|
|
821
|
+
}
|
|
822
|
+
return cached;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// src/internal-logging.ts
|
|
826
|
+
var scopeDefaults = {
|
|
827
|
+
retry: 3 /* Warn */,
|
|
828
|
+
throttle: 3 /* Warn */
|
|
829
|
+
};
|
|
830
|
+
var getLogs = createLogProvider("core.", scopeDefaults);
|
|
831
|
+
|
|
832
|
+
// src/throttle.ts
|
|
833
|
+
var { errorLog } = getLogs("throttle");
|
|
834
|
+
var Call = class {
|
|
835
|
+
constructor(func, self, parameters) {
|
|
836
|
+
this.func = func;
|
|
837
|
+
this.self = self;
|
|
838
|
+
this.parameters = parameters;
|
|
839
|
+
}
|
|
840
|
+
invoke() {
|
|
841
|
+
return this.func.apply(this.self, this.parameters);
|
|
842
|
+
}
|
|
843
|
+
invokeSilently() {
|
|
844
|
+
try {
|
|
845
|
+
return this.invoke();
|
|
846
|
+
} catch (error) {
|
|
847
|
+
errorLog?.log("Call.invokeSilently: unhandled error:", error);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
function throttle(func, intervalMs, mode = "default") {
|
|
852
|
+
let lastCall = null;
|
|
853
|
+
let nextFireTime = 0;
|
|
854
|
+
let timeoutHandle = null;
|
|
855
|
+
const reset2 = () => {
|
|
856
|
+
if (timeoutHandle !== null) clearTimeout(timeoutHandle);
|
|
857
|
+
timeoutHandle = null;
|
|
858
|
+
lastCall = null;
|
|
859
|
+
nextFireTime = 0;
|
|
860
|
+
};
|
|
861
|
+
const fire = () => {
|
|
862
|
+
if (timeoutHandle !== null) clearTimeout(timeoutHandle);
|
|
863
|
+
if (lastCall !== null) {
|
|
864
|
+
const call = lastCall;
|
|
865
|
+
lastCall = null;
|
|
866
|
+
nextFireTime = Date.now() + intervalMs;
|
|
867
|
+
timeoutHandle = setTimeout(fire, intervalMs);
|
|
868
|
+
call.invokeSilently();
|
|
869
|
+
} else {
|
|
870
|
+
timeoutHandle = null;
|
|
871
|
+
nextFireTime = 0;
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
const wrapped = function(...args) {
|
|
875
|
+
const call = new Call(func, this, args);
|
|
876
|
+
const fireDelay = nextFireTime - Date.now();
|
|
877
|
+
if (timeoutHandle !== null && fireDelay <= 0) {
|
|
878
|
+
fire();
|
|
879
|
+
}
|
|
880
|
+
if (timeoutHandle === null) {
|
|
881
|
+
nextFireTime = Date.now() + intervalMs;
|
|
882
|
+
timeoutHandle = setTimeout(fire, intervalMs);
|
|
883
|
+
if (mode === "delayHead") {
|
|
884
|
+
lastCall = call;
|
|
885
|
+
} else {
|
|
886
|
+
call.invokeSilently();
|
|
887
|
+
}
|
|
888
|
+
} else if (mode !== "skip") {
|
|
889
|
+
lastCall = call;
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
wrapped.reset = reset2;
|
|
893
|
+
return wrapped;
|
|
894
|
+
}
|
|
895
|
+
function debounce(func, intervalMs) {
|
|
896
|
+
let lastCall = null;
|
|
897
|
+
let nextFireTime = 0;
|
|
898
|
+
let timeoutHandle = null;
|
|
899
|
+
const reset2 = () => {
|
|
900
|
+
timeoutHandle = null;
|
|
901
|
+
lastCall = null;
|
|
902
|
+
nextFireTime = 0;
|
|
903
|
+
};
|
|
904
|
+
const fire = () => {
|
|
905
|
+
if (timeoutHandle !== null) clearTimeout(timeoutHandle);
|
|
906
|
+
timeoutHandle = null;
|
|
907
|
+
const fireDelay = nextFireTime - Date.now();
|
|
908
|
+
if (fireDelay <= 0) {
|
|
909
|
+
nextFireTime = 0;
|
|
910
|
+
if (lastCall !== null) {
|
|
911
|
+
const call = lastCall;
|
|
912
|
+
lastCall = null;
|
|
913
|
+
call.invokeSilently();
|
|
914
|
+
}
|
|
915
|
+
} else {
|
|
916
|
+
timeoutHandle = setTimeout(fire, fireDelay);
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
const wrapped = function(...args) {
|
|
920
|
+
lastCall = new Call(func, this, args);
|
|
921
|
+
nextFireTime = Date.now() + intervalMs;
|
|
922
|
+
timeoutHandle ??= setTimeout(fire, intervalMs);
|
|
923
|
+
};
|
|
924
|
+
wrapped.reset = reset2;
|
|
925
|
+
return wrapped;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// src/serialize.ts
|
|
929
|
+
function serialize(func, limit = null) {
|
|
930
|
+
let lastCall = Promise.resolve(null);
|
|
931
|
+
let queueSize = 0;
|
|
932
|
+
return function(...args) {
|
|
933
|
+
if (limit !== null && queueSize >= limit) return lastCall;
|
|
934
|
+
queueSize++;
|
|
935
|
+
const prevCall = lastCall;
|
|
936
|
+
const invoke = () => func.apply(this, args);
|
|
937
|
+
return lastCall = (async () => {
|
|
938
|
+
try {
|
|
939
|
+
await prevCall.catch(() => {
|
|
940
|
+
});
|
|
941
|
+
return await invoke();
|
|
942
|
+
} finally {
|
|
943
|
+
queueSize--;
|
|
944
|
+
}
|
|
945
|
+
})();
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
|
|
701
949
|
// src/ring-buffer.ts
|
|
702
950
|
var RingBuffer = class {
|
|
703
951
|
_buffer;
|
|
@@ -888,6 +1136,34 @@ var RetryDelayer = class {
|
|
|
888
1136
|
this.cancelDelaysChanged.trigger();
|
|
889
1137
|
}
|
|
890
1138
|
};
|
|
1139
|
+
|
|
1140
|
+
// src/retry.ts
|
|
1141
|
+
var { warnLog } = getLogs("retry");
|
|
1142
|
+
var defaultRetryDelays = () => 50;
|
|
1143
|
+
async function retry(tryCount, fn, retryDelays = defaultRetryDelays) {
|
|
1144
|
+
if (tryCount <= 0)
|
|
1145
|
+
throw new Error("retry: tryCount must be positive.");
|
|
1146
|
+
let lastError;
|
|
1147
|
+
for (let tryIndex = 0; ; ) {
|
|
1148
|
+
if (tryIndex >= tryCount) throw lastError;
|
|
1149
|
+
try {
|
|
1150
|
+
return await fn(tryIndex, lastError);
|
|
1151
|
+
} catch (e) {
|
|
1152
|
+
lastError = e;
|
|
1153
|
+
}
|
|
1154
|
+
++tryIndex;
|
|
1155
|
+
if (tryIndex >= tryCount) throw lastError;
|
|
1156
|
+
warnLog?.log(`retry(${tryIndex}/${tryCount}): error:`, lastError);
|
|
1157
|
+
await delayAsync(retryDelays(tryIndex));
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
async function catchErrors(fn, onError) {
|
|
1161
|
+
try {
|
|
1162
|
+
return await fn();
|
|
1163
|
+
} catch (e) {
|
|
1164
|
+
return onError ? onError(e) : void 0;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
891
1167
|
// Annotate the CommonJS export names for ESM import in node:
|
|
892
1168
|
0 && (module.exports = {
|
|
893
1169
|
AsyncContext,
|
|
@@ -899,20 +1175,33 @@ var RetryDelayer = class {
|
|
|
899
1175
|
LogLevel,
|
|
900
1176
|
LogLevelController,
|
|
901
1177
|
PromiseSource,
|
|
1178
|
+
PromiseSourceWithTimeout,
|
|
1179
|
+
ResolvedPromise,
|
|
902
1180
|
Result,
|
|
903
1181
|
RetryDelayLimitExceeded,
|
|
904
1182
|
RetryDelayNone,
|
|
905
1183
|
RetryDelaySeq,
|
|
906
1184
|
RetryDelayer,
|
|
907
1185
|
RingBuffer,
|
|
1186
|
+
TimedOut,
|
|
1187
|
+
TimeoutError,
|
|
1188
|
+
abortPromise,
|
|
908
1189
|
abortSignalKey,
|
|
1190
|
+
catchErrors,
|
|
909
1191
|
createLogProvider,
|
|
1192
|
+
debounce,
|
|
1193
|
+
delayAsync,
|
|
1194
|
+
delayAsyncWith,
|
|
910
1195
|
errorResult,
|
|
911
1196
|
initLogging,
|
|
912
1197
|
initWorkerLogging,
|
|
913
1198
|
resolvedVoidPromise,
|
|
914
1199
|
result,
|
|
915
1200
|
resultFrom,
|
|
916
|
-
resultFromAsync
|
|
1201
|
+
resultFromAsync,
|
|
1202
|
+
retry,
|
|
1203
|
+
serialize,
|
|
1204
|
+
throttle,
|
|
1205
|
+
withTimeout
|
|
917
1206
|
});
|
|
918
1207
|
//# sourceMappingURL=index.cjs.map
|