@actuallab/core 13.0.4 → 13.0.12
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 +281 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +153 -1
- package/dist/index.d.ts +153 -1
- package/dist/index.js +267 -1
- 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
|
|
|
@@ -698,6 +711,231 @@ var EventHandlerSet = class {
|
|
|
698
711
|
}
|
|
699
712
|
};
|
|
700
713
|
|
|
714
|
+
// src/withTimeout.ts
|
|
715
|
+
var TimeoutError = class extends Error {
|
|
716
|
+
name = "TimeoutError";
|
|
717
|
+
constructor(message = "Operation timed out") {
|
|
718
|
+
super(message);
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
async function withTimeout(promise, ms, message) {
|
|
722
|
+
let timer;
|
|
723
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
724
|
+
timer = setTimeout(
|
|
725
|
+
() => reject(new TimeoutError(message ?? `Operation timed out after ${ms}ms`)),
|
|
726
|
+
ms
|
|
727
|
+
);
|
|
728
|
+
});
|
|
729
|
+
timeoutPromise.catch(() => {
|
|
730
|
+
});
|
|
731
|
+
try {
|
|
732
|
+
return await Promise.race([promise, timeoutPromise]);
|
|
733
|
+
} finally {
|
|
734
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// src/promise-source-with-timeout.ts
|
|
739
|
+
var PromiseSourceWithTimeout = class extends PromiseSource {
|
|
740
|
+
_timer;
|
|
741
|
+
hasTimeout() {
|
|
742
|
+
return this._timer !== void 0;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Install (or replace) a timeout. Pass `null` to remove without setting a
|
|
746
|
+
* new one. `callback` is invoked when the timer fires — if omitted, the
|
|
747
|
+
* promise is rejected with a generic "timed out" error.
|
|
748
|
+
*/
|
|
749
|
+
setTimeout(ms, callback) {
|
|
750
|
+
this.clearTimeout();
|
|
751
|
+
if (ms === null || this.isCompleted) return;
|
|
752
|
+
this._timer = setTimeout(() => {
|
|
753
|
+
this._timer = void 0;
|
|
754
|
+
if (callback) callback();
|
|
755
|
+
else this.reject(new TimeoutError(`The promise has timed out after ${ms}ms.`));
|
|
756
|
+
}, ms);
|
|
757
|
+
}
|
|
758
|
+
clearTimeout() {
|
|
759
|
+
if (this._timer === void 0) return;
|
|
760
|
+
clearTimeout(this._timer);
|
|
761
|
+
this._timer = void 0;
|
|
762
|
+
}
|
|
763
|
+
resolve(value) {
|
|
764
|
+
const didSettle = super.resolve(value);
|
|
765
|
+
if (didSettle) this.clearTimeout();
|
|
766
|
+
return didSettle;
|
|
767
|
+
}
|
|
768
|
+
reject(reason) {
|
|
769
|
+
const didSettle = super.reject(reason);
|
|
770
|
+
if (didSettle) this.clearTimeout();
|
|
771
|
+
return didSettle;
|
|
772
|
+
}
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
// src/resolved-promise.ts
|
|
776
|
+
var ResolvedPromise = {
|
|
777
|
+
Void: Promise.resolve(),
|
|
778
|
+
True: Promise.resolve(true),
|
|
779
|
+
False: Promise.resolve(false)
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
// src/timed-out.ts
|
|
783
|
+
var TimedOut = class _TimedOut {
|
|
784
|
+
static instance = new _TimedOut();
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
// src/delay.ts
|
|
788
|
+
function delayAsync(ms) {
|
|
789
|
+
return new Promise((resolve) => {
|
|
790
|
+
setTimeout(resolve, ms);
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
function delayAsyncWith(ms, value) {
|
|
794
|
+
return new Promise((resolve) => {
|
|
795
|
+
setTimeout(() => resolve(value), ms);
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
// src/abort-promise.ts
|
|
800
|
+
var abortPromiseCache = /* @__PURE__ */ new WeakMap();
|
|
801
|
+
function abortPromise(signal) {
|
|
802
|
+
if (signal.aborted) return Promise.reject(signal.reason);
|
|
803
|
+
let cached = abortPromiseCache.get(signal);
|
|
804
|
+
if (!cached) {
|
|
805
|
+
cached = new Promise((_, reject) => {
|
|
806
|
+
signal.addEventListener("abort", () => reject(signal.reason), { once: true });
|
|
807
|
+
});
|
|
808
|
+
cached.catch(() => {
|
|
809
|
+
});
|
|
810
|
+
abortPromiseCache.set(signal, cached);
|
|
811
|
+
}
|
|
812
|
+
return cached;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// src/internal-logging.ts
|
|
816
|
+
var scopeDefaults = {
|
|
817
|
+
retry: 3 /* Warn */,
|
|
818
|
+
throttle: 3 /* Warn */
|
|
819
|
+
};
|
|
820
|
+
var getLogs = createLogProvider("core.", scopeDefaults);
|
|
821
|
+
|
|
822
|
+
// src/throttle.ts
|
|
823
|
+
var { errorLog } = getLogs("throttle");
|
|
824
|
+
var Call = class {
|
|
825
|
+
constructor(func, self, parameters) {
|
|
826
|
+
this.func = func;
|
|
827
|
+
this.self = self;
|
|
828
|
+
this.parameters = parameters;
|
|
829
|
+
}
|
|
830
|
+
invoke() {
|
|
831
|
+
return this.func.apply(this.self, this.parameters);
|
|
832
|
+
}
|
|
833
|
+
invokeSilently() {
|
|
834
|
+
try {
|
|
835
|
+
return this.invoke();
|
|
836
|
+
} catch (error) {
|
|
837
|
+
errorLog?.log("Call.invokeSilently: unhandled error:", error);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
function throttle(func, intervalMs, mode = "default") {
|
|
842
|
+
let lastCall = null;
|
|
843
|
+
let nextFireTime = 0;
|
|
844
|
+
let timeoutHandle = null;
|
|
845
|
+
const reset2 = () => {
|
|
846
|
+
if (timeoutHandle !== null) clearTimeout(timeoutHandle);
|
|
847
|
+
timeoutHandle = null;
|
|
848
|
+
lastCall = null;
|
|
849
|
+
nextFireTime = 0;
|
|
850
|
+
};
|
|
851
|
+
const fire = () => {
|
|
852
|
+
if (timeoutHandle !== null) clearTimeout(timeoutHandle);
|
|
853
|
+
if (lastCall !== null) {
|
|
854
|
+
const call = lastCall;
|
|
855
|
+
lastCall = null;
|
|
856
|
+
nextFireTime = Date.now() + intervalMs;
|
|
857
|
+
timeoutHandle = setTimeout(fire, intervalMs);
|
|
858
|
+
call.invokeSilently();
|
|
859
|
+
} else {
|
|
860
|
+
timeoutHandle = null;
|
|
861
|
+
nextFireTime = 0;
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
const wrapped = function(...args) {
|
|
865
|
+
const call = new Call(func, this, args);
|
|
866
|
+
const fireDelay = nextFireTime - Date.now();
|
|
867
|
+
if (timeoutHandle !== null && fireDelay <= 0) {
|
|
868
|
+
fire();
|
|
869
|
+
}
|
|
870
|
+
if (timeoutHandle === null) {
|
|
871
|
+
nextFireTime = Date.now() + intervalMs;
|
|
872
|
+
timeoutHandle = setTimeout(fire, intervalMs);
|
|
873
|
+
if (mode === "delayHead") {
|
|
874
|
+
lastCall = call;
|
|
875
|
+
} else {
|
|
876
|
+
call.invokeSilently();
|
|
877
|
+
}
|
|
878
|
+
} else if (mode !== "skip") {
|
|
879
|
+
lastCall = call;
|
|
880
|
+
}
|
|
881
|
+
};
|
|
882
|
+
wrapped.reset = reset2;
|
|
883
|
+
return wrapped;
|
|
884
|
+
}
|
|
885
|
+
function debounce(func, intervalMs) {
|
|
886
|
+
let lastCall = null;
|
|
887
|
+
let nextFireTime = 0;
|
|
888
|
+
let timeoutHandle = null;
|
|
889
|
+
const reset2 = () => {
|
|
890
|
+
timeoutHandle = null;
|
|
891
|
+
lastCall = null;
|
|
892
|
+
nextFireTime = 0;
|
|
893
|
+
};
|
|
894
|
+
const fire = () => {
|
|
895
|
+
if (timeoutHandle !== null) clearTimeout(timeoutHandle);
|
|
896
|
+
timeoutHandle = null;
|
|
897
|
+
const fireDelay = nextFireTime - Date.now();
|
|
898
|
+
if (fireDelay <= 0) {
|
|
899
|
+
nextFireTime = 0;
|
|
900
|
+
if (lastCall !== null) {
|
|
901
|
+
const call = lastCall;
|
|
902
|
+
lastCall = null;
|
|
903
|
+
call.invokeSilently();
|
|
904
|
+
}
|
|
905
|
+
} else {
|
|
906
|
+
timeoutHandle = setTimeout(fire, fireDelay);
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
const wrapped = function(...args) {
|
|
910
|
+
lastCall = new Call(func, this, args);
|
|
911
|
+
nextFireTime = Date.now() + intervalMs;
|
|
912
|
+
timeoutHandle ??= setTimeout(fire, intervalMs);
|
|
913
|
+
};
|
|
914
|
+
wrapped.reset = reset2;
|
|
915
|
+
return wrapped;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// src/serialize.ts
|
|
919
|
+
function serialize(func, limit = null) {
|
|
920
|
+
let lastCall = Promise.resolve(null);
|
|
921
|
+
let queueSize = 0;
|
|
922
|
+
return function(...args) {
|
|
923
|
+
if (limit !== null && queueSize >= limit) return lastCall;
|
|
924
|
+
queueSize++;
|
|
925
|
+
const prevCall = lastCall;
|
|
926
|
+
const invoke = () => func.apply(this, args);
|
|
927
|
+
return lastCall = (async () => {
|
|
928
|
+
try {
|
|
929
|
+
await prevCall.catch(() => {
|
|
930
|
+
});
|
|
931
|
+
return await invoke();
|
|
932
|
+
} finally {
|
|
933
|
+
queueSize--;
|
|
934
|
+
}
|
|
935
|
+
})();
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
|
|
701
939
|
// src/ring-buffer.ts
|
|
702
940
|
var RingBuffer = class {
|
|
703
941
|
_buffer;
|
|
@@ -888,6 +1126,34 @@ var RetryDelayer = class {
|
|
|
888
1126
|
this.cancelDelaysChanged.trigger();
|
|
889
1127
|
}
|
|
890
1128
|
};
|
|
1129
|
+
|
|
1130
|
+
// src/retry.ts
|
|
1131
|
+
var { warnLog } = getLogs("retry");
|
|
1132
|
+
var defaultRetryDelays = () => 50;
|
|
1133
|
+
async function retry(tryCount, fn, retryDelays = defaultRetryDelays) {
|
|
1134
|
+
if (tryCount <= 0)
|
|
1135
|
+
throw new Error("retry: tryCount must be positive.");
|
|
1136
|
+
let lastError;
|
|
1137
|
+
for (let tryIndex = 0; ; ) {
|
|
1138
|
+
if (tryIndex >= tryCount) throw lastError;
|
|
1139
|
+
try {
|
|
1140
|
+
return await fn(tryIndex, lastError);
|
|
1141
|
+
} catch (e) {
|
|
1142
|
+
lastError = e;
|
|
1143
|
+
}
|
|
1144
|
+
++tryIndex;
|
|
1145
|
+
if (tryIndex >= tryCount) throw lastError;
|
|
1146
|
+
warnLog?.log(`retry(${tryIndex}/${tryCount}): error:`, lastError);
|
|
1147
|
+
await delayAsync(retryDelays(tryIndex));
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
async function catchErrors(fn, onError) {
|
|
1151
|
+
try {
|
|
1152
|
+
return await fn();
|
|
1153
|
+
} catch (e) {
|
|
1154
|
+
return onError ? onError(e) : void 0;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
891
1157
|
// Annotate the CommonJS export names for ESM import in node:
|
|
892
1158
|
0 && (module.exports = {
|
|
893
1159
|
AsyncContext,
|
|
@@ -899,20 +1165,33 @@ var RetryDelayer = class {
|
|
|
899
1165
|
LogLevel,
|
|
900
1166
|
LogLevelController,
|
|
901
1167
|
PromiseSource,
|
|
1168
|
+
PromiseSourceWithTimeout,
|
|
1169
|
+
ResolvedPromise,
|
|
902
1170
|
Result,
|
|
903
1171
|
RetryDelayLimitExceeded,
|
|
904
1172
|
RetryDelayNone,
|
|
905
1173
|
RetryDelaySeq,
|
|
906
1174
|
RetryDelayer,
|
|
907
1175
|
RingBuffer,
|
|
1176
|
+
TimedOut,
|
|
1177
|
+
TimeoutError,
|
|
1178
|
+
abortPromise,
|
|
908
1179
|
abortSignalKey,
|
|
1180
|
+
catchErrors,
|
|
909
1181
|
createLogProvider,
|
|
1182
|
+
debounce,
|
|
1183
|
+
delayAsync,
|
|
1184
|
+
delayAsyncWith,
|
|
910
1185
|
errorResult,
|
|
911
1186
|
initLogging,
|
|
912
1187
|
initWorkerLogging,
|
|
913
1188
|
resolvedVoidPromise,
|
|
914
1189
|
result,
|
|
915
1190
|
resultFrom,
|
|
916
|
-
resultFromAsync
|
|
1191
|
+
resultFromAsync,
|
|
1192
|
+
retry,
|
|
1193
|
+
serialize,
|
|
1194
|
+
throttle,
|
|
1195
|
+
withTimeout
|
|
917
1196
|
});
|
|
918
1197
|
//# sourceMappingURL=index.cjs.map
|