@zk-tech/bedrock 0.0.1
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/README.md +24 -0
- package/dist/array/index.cjs +22 -0
- package/dist/array/index.cjs.map +1 -0
- package/dist/array/index.d.cts +13 -0
- package/dist/array/index.d.ts +13 -0
- package/dist/array/index.js +19 -0
- package/dist/array/index.js.map +1 -0
- package/dist/assert/index.cjs +29 -0
- package/dist/assert/index.cjs.map +1 -0
- package/dist/assert/index.d.cts +25 -0
- package/dist/assert/index.d.ts +25 -0
- package/dist/assert/index.js +24 -0
- package/dist/assert/index.js.map +1 -0
- package/dist/async/index.cjs +746 -0
- package/dist/async/index.cjs.map +1 -0
- package/dist/async/index.d.cts +47 -0
- package/dist/async/index.d.ts +47 -0
- package/dist/async/index.js +738 -0
- package/dist/async/index.js.map +1 -0
- package/dist/barrier-316Xonfd.d.cts +18 -0
- package/dist/barrier-316Xonfd.d.ts +18 -0
- package/dist/byte/index.cjs +59 -0
- package/dist/byte/index.cjs.map +1 -0
- package/dist/byte/index.d.cts +12 -0
- package/dist/byte/index.d.ts +12 -0
- package/dist/byte/index.js +49 -0
- package/dist/byte/index.js.map +1 -0
- package/dist/cache/index.cjs +418 -0
- package/dist/cache/index.cjs.map +1 -0
- package/dist/cache/index.d.cts +40 -0
- package/dist/cache/index.d.ts +40 -0
- package/dist/cache/index.js +415 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cancellation-BIIv2UJm.d.cts +25 -0
- package/dist/cancellation-ClqPPsV1.d.ts +25 -0
- package/dist/context/index.cjs +59 -0
- package/dist/context/index.cjs.map +1 -0
- package/dist/context/index.d.cts +33 -0
- package/dist/context/index.d.ts +33 -0
- package/dist/context/index.js +51 -0
- package/dist/context/index.js.map +1 -0
- package/dist/di/index.cjs +1965 -0
- package/dist/di/index.cjs.map +1 -0
- package/dist/di/index.d.cts +140 -0
- package/dist/di/index.d.ts +140 -0
- package/dist/di/index.js +1949 -0
- package/dist/di/index.js.map +1 -0
- package/dist/disposable-t-B15Nu57y.d.ts +93 -0
- package/dist/disposable-t-CVsiyHPL.d.cts +93 -0
- package/dist/dispose/index.cjs +356 -0
- package/dist/dispose/index.cjs.map +1 -0
- package/dist/dispose/index.d.cts +26 -0
- package/dist/dispose/index.d.ts +26 -0
- package/dist/dispose/index.js +340 -0
- package/dist/dispose/index.js.map +1 -0
- package/dist/dispose-base-CAeXDpjg.d.cts +6 -0
- package/dist/dispose-base-CAeXDpjg.d.ts +6 -0
- package/dist/emitter-CAfCtSTg.d.cts +35 -0
- package/dist/emitter-DeM5mlEm.d.ts +35 -0
- package/dist/error/index.cjs +145 -0
- package/dist/error/index.cjs.map +1 -0
- package/dist/error/index.d.cts +45 -0
- package/dist/error/index.d.ts +45 -0
- package/dist/error/index.js +126 -0
- package/dist/error/index.js.map +1 -0
- package/dist/error-base-B4zaiJ5m.d.cts +32 -0
- package/dist/error-base-B4zaiJ5m.d.ts +32 -0
- package/dist/event/index.cjs +550 -0
- package/dist/event/index.cjs.map +1 -0
- package/dist/event/index.d.cts +139 -0
- package/dist/event/index.d.ts +139 -0
- package/dist/event/index.js +538 -0
- package/dist/event/index.js.map +1 -0
- package/dist/function/index.cjs +132 -0
- package/dist/function/index.cjs.map +1 -0
- package/dist/function/index.d.cts +26 -0
- package/dist/function/index.d.ts +26 -0
- package/dist/function/index.js +129 -0
- package/dist/function/index.js.map +1 -0
- package/dist/graph-BGbNOniY.d.cts +23 -0
- package/dist/graph-BGbNOniY.d.ts +23 -0
- package/dist/hash/index.cjs +54 -0
- package/dist/hash/index.cjs.map +1 -0
- package/dist/hash/index.d.cts +5 -0
- package/dist/hash/index.d.ts +5 -0
- package/dist/hash/index.js +50 -0
- package/dist/hash/index.js.map +1 -0
- package/dist/instantiation-service.interface-CVFMBUUD.d.cts +78 -0
- package/dist/instantiation-service.interface-CVFMBUUD.d.ts +78 -0
- package/dist/json/index.cjs +28 -0
- package/dist/json/index.cjs.map +1 -0
- package/dist/json/index.d.cts +8 -0
- package/dist/json/index.d.ts +8 -0
- package/dist/json/index.js +26 -0
- package/dist/json/index.js.map +1 -0
- package/dist/launch/index.cjs +213 -0
- package/dist/launch/index.cjs.map +1 -0
- package/dist/launch/index.d.cts +46 -0
- package/dist/launch/index.d.ts +46 -0
- package/dist/launch/index.js +211 -0
- package/dist/launch/index.js.map +1 -0
- package/dist/linked-list-CUkue5DZ.d.cts +24 -0
- package/dist/linked-list-CUkue5DZ.d.ts +24 -0
- package/dist/lock/index.cjs +662 -0
- package/dist/lock/index.cjs.map +1 -0
- package/dist/lock/index.d.cts +145 -0
- package/dist/lock/index.d.ts +145 -0
- package/dist/lock/index.js +656 -0
- package/dist/lock/index.js.map +1 -0
- package/dist/lodash-es/index.cjs +14 -0
- package/dist/lodash-es/index.cjs.map +1 -0
- package/dist/lodash-es/index.d.cts +1 -0
- package/dist/lodash-es/index.d.ts +1 -0
- package/dist/lodash-es/index.js +3 -0
- package/dist/lodash-es/index.js.map +1 -0
- package/dist/math/index.cjs +161 -0
- package/dist/math/index.cjs.map +1 -0
- package/dist/math/index.d.cts +76 -0
- package/dist/math/index.d.ts +76 -0
- package/dist/math/index.js +156 -0
- package/dist/math/index.js.map +1 -0
- package/dist/network/index.cjs +91 -0
- package/dist/network/index.cjs.map +1 -0
- package/dist/network/index.d.cts +62 -0
- package/dist/network/index.d.ts +62 -0
- package/dist/network/index.js +82 -0
- package/dist/network/index.js.map +1 -0
- package/dist/objects/index.cjs +80 -0
- package/dist/objects/index.cjs.map +1 -0
- package/dist/objects/index.d.cts +11 -0
- package/dist/objects/index.d.ts +11 -0
- package/dist/objects/index.js +77 -0
- package/dist/objects/index.js.map +1 -0
- package/dist/platform/index.cjs +62 -0
- package/dist/platform/index.cjs.map +1 -0
- package/dist/platform/index.d.cts +21 -0
- package/dist/platform/index.d.ts +21 -0
- package/dist/platform/index.js +48 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/promise/index.cjs +639 -0
- package/dist/promise/index.cjs.map +1 -0
- package/dist/promise/index.d.cts +63 -0
- package/dist/promise/index.d.ts +63 -0
- package/dist/promise/index.js +633 -0
- package/dist/promise/index.js.map +1 -0
- package/dist/scheduler/index.cjs +599 -0
- package/dist/scheduler/index.cjs.map +1 -0
- package/dist/scheduler/index.d.cts +57 -0
- package/dist/scheduler/index.d.ts +57 -0
- package/dist/scheduler/index.js +594 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/sprintf/index.cjs +101 -0
- package/dist/sprintf/index.cjs.map +1 -0
- package/dist/sprintf/index.d.cts +3 -0
- package/dist/sprintf/index.d.ts +3 -0
- package/dist/sprintf/index.js +99 -0
- package/dist/sprintf/index.js.map +1 -0
- package/dist/structure/index.cjs +300 -0
- package/dist/structure/index.cjs.map +1 -0
- package/dist/structure/index.d.cts +21 -0
- package/dist/structure/index.d.ts +21 -0
- package/dist/structure/index.js +296 -0
- package/dist/structure/index.js.map +1 -0
- package/dist/type/index.cjs +4 -0
- package/dist/type/index.cjs.map +1 -0
- package/dist/type/index.d.cts +20 -0
- package/dist/type/index.d.ts +20 -0
- package/dist/type/index.js +3 -0
- package/dist/type/index.js.map +1 -0
- package/dist/undo-redo-stack/index.cjs +545 -0
- package/dist/undo-redo-stack/index.cjs.map +1 -0
- package/dist/undo-redo-stack/index.d.cts +130 -0
- package/dist/undo-redo-stack/index.d.ts +130 -0
- package/dist/undo-redo-stack/index.js +542 -0
- package/dist/undo-redo-stack/index.js.map +1 -0
- package/dist/uuid/index.cjs +67 -0
- package/dist/uuid/index.cjs.map +1 -0
- package/dist/uuid/index.d.cts +17 -0
- package/dist/uuid/index.d.ts +17 -0
- package/dist/uuid/index.js +61 -0
- package/dist/uuid/index.js.map +1 -0
- package/dist/worker/index.cjs +271 -0
- package/dist/worker/index.cjs.map +1 -0
- package/dist/worker/index.d.cts +66 -0
- package/dist/worker/index.d.ts +66 -0
- package/dist/worker/index.js +267 -0
- package/dist/worker/index.js.map +1 -0
- package/package.json +285 -0
- package/src/_internal/logger.ts +59 -0
- package/src/array/array.test.ts +35 -0
- package/src/array/array.ts +25 -0
- package/src/array/index.ts +1 -0
- package/src/assert/assert.test.ts +86 -0
- package/src/assert/assert.ts +42 -0
- package/src/assert/index.ts +2 -0
- package/src/async/barrier.test.ts +90 -0
- package/src/async/barrier.ts +58 -0
- package/src/async/cancellation.test.ts +85 -0
- package/src/async/cancellation.ts +193 -0
- package/src/async/index.ts +18 -0
- package/src/async/queue/queue.test.ts +70 -0
- package/src/async/queue/queue.ts +56 -0
- package/src/async/queue/task.test.ts +155 -0
- package/src/async/queue/task.ts +67 -0
- package/src/async/utils.test.ts +28 -0
- package/src/async/utils.ts +8 -0
- package/src/async/wait.ts +9 -0
- package/src/byte/format.test.ts +64 -0
- package/src/byte/format.ts +44 -0
- package/src/byte/index.ts +2 -0
- package/src/byte/node_modules/.vitest/results.json +1 -0
- package/src/byte/var.ts +11 -0
- package/src/cache/index.ts +2 -0
- package/src/cache/lru-with-timeout.test.ts +88 -0
- package/src/cache/lru-with-timeout.ts +85 -0
- package/src/cache/lru.test.ts +56 -0
- package/src/cache/lru.ts +59 -0
- package/src/context/context.test.ts +17 -0
- package/src/context/context.ts +60 -0
- package/src/context/index.ts +8 -0
- package/src/di/base.ts +73 -0
- package/src/di/container-service.test.ts +179 -0
- package/src/di/context.web.tsx +41 -0
- package/src/di/descriptor.ts +31 -0
- package/src/di/idle-value.test.ts +73 -0
- package/src/di/idle-value.ts +63 -0
- package/src/di/index.common.ts +32 -0
- package/src/di/index.ts +2 -0
- package/src/di/instantiation-service.interface.ts +46 -0
- package/src/di/instantiation-service.test.ts +337 -0
- package/src/di/instantiation-service.ts +468 -0
- package/src/di/lazy/foo.mock.ts +28 -0
- package/src/di/lazy/idle-load.ts +39 -0
- package/src/di/lazy/index.ts +4 -0
- package/src/di/lazy/lazy-service.test.ts +65 -0
- package/src/di/lazy/lazy-service.ts +71 -0
- package/src/di/lazy/type.ts +5 -0
- package/src/di/node_modules/.vitest/results.json +1 -0
- package/src/di/proxy-builder.test.ts +45 -0
- package/src/di/proxy-builder.ts +38 -0
- package/src/di/service-collection.test.ts +27 -0
- package/src/di/service-collection.ts +46 -0
- package/src/di/service-ownership-collection.test.ts +39 -0
- package/src/di/service-ownership-collection.ts +38 -0
- package/src/di/service-registry.test.ts +66 -0
- package/src/di/service-registry.ts +99 -0
- package/src/di/trace.ts +85 -0
- package/src/dispose/disposable-store.test.ts +57 -0
- package/src/dispose/disposable-store.ts +80 -0
- package/src/dispose/disposable-t.test.ts +123 -0
- package/src/dispose/disposable-t.ts +238 -0
- package/src/dispose/disposable-utils.test.ts +15 -0
- package/src/dispose/disposable-utils.ts +28 -0
- package/src/dispose/dispose-base.ts +9 -0
- package/src/dispose/index.ts +34 -0
- package/src/dispose/logger.test.ts +65 -0
- package/src/dispose/logger.ts +39 -0
- package/src/dispose/timer.test.ts +30 -0
- package/src/dispose/timer.ts +16 -0
- package/src/dispose/tracker.test.ts +51 -0
- package/src/dispose/tracker.ts +105 -0
- package/src/error/error-base.ts +45 -0
- package/src/error/error-code.ts +39 -0
- package/src/error/error-const.test.ts +30 -0
- package/src/error/error-const.ts +16 -0
- package/src/error/error-or.test.ts +44 -0
- package/src/error/error-or.ts +2 -0
- package/src/error/error-t.test.ts +116 -0
- package/src/error/error-t.ts +100 -0
- package/src/error/index.ts +24 -0
- package/src/error/node_modules/.vitest/results.json +1 -0
- package/src/event/disposable-linked-list.ts +29 -0
- package/src/event/emitter.test.ts +191 -0
- package/src/event/emitter.ts +162 -0
- package/src/event/error-handler.ts +22 -0
- package/src/event/index.ts +34 -0
- package/src/event/once.ts +29 -0
- package/src/event/phase-emitter.test.ts +212 -0
- package/src/event/phase-emitter.ts +209 -0
- package/src/event/shortcut-event-utils.ts +33 -0
- package/src/event/utils.ts +6 -0
- package/src/event/when.ts +40 -0
- package/src/function/debounce.test.ts +274 -0
- package/src/function/debounce.ts +168 -0
- package/src/function/index.ts +2 -0
- package/src/function/node_modules/.vitest/results.json +1 -0
- package/src/function/throttle.test.ts +179 -0
- package/src/function/throttle.ts +26 -0
- package/src/hash/hash-t.test.ts +100 -0
- package/src/hash/hash-t.ts +51 -0
- package/src/hash/index.ts +3 -0
- package/src/json/index.ts +1 -0
- package/src/json/node_modules/.vitest/results.json +1 -0
- package/src/json/parse.ts +19 -0
- package/src/launch/abstract-job.ts +45 -0
- package/src/launch/cost-recorder.ts +22 -0
- package/src/launch/index.ts +2 -0
- package/src/launch/job-scheduler.test.ts +122 -0
- package/src/launch/job-scheduler.ts +118 -0
- package/src/launch/node_modules/.vitest/deps/_metadata.json +8 -0
- package/src/launch/node_modules/.vitest/deps/package.json +3 -0
- package/src/launch/node_modules/.vitest/results.json +1 -0
- package/src/lock/README.md +11 -0
- package/src/lock/capability.test.ts +110 -0
- package/src/lock/capability.ts +89 -0
- package/src/lock/index.ts +15 -0
- package/src/lock/node_modules/.vitest/results.json +1 -0
- package/src/lock/semaphore.ts +21 -0
- package/src/lock/shared-mutex.test.ts +537 -0
- package/src/lock/shared-mutex.ts +242 -0
- package/src/lock/utils.test.ts +165 -0
- package/src/lock/utils.ts +135 -0
- package/src/lodash-es/index.ts +1 -0
- package/src/math/degree.ts +16 -0
- package/src/math/index.ts +7 -0
- package/src/math/math.test.ts +40 -0
- package/src/math/math.ts +64 -0
- package/src/math/node_modules/.vitest/results.json +1 -0
- package/src/math/vector.test.ts +73 -0
- package/src/math/vector.ts +114 -0
- package/src/network/client.interface.ts +104 -0
- package/src/network/client.web.ts +24 -0
- package/src/network/index.common.ts +10 -0
- package/src/network/index.ts +2 -0
- package/src/network/plugins/retry.ts +98 -0
- package/src/objects/deep-clone.test.ts +40 -0
- package/src/objects/deep-clone.ts +13 -0
- package/src/objects/deep-equal.test.ts +86 -0
- package/src/objects/deep-equal.ts +60 -0
- package/src/objects/index.ts +4 -0
- package/src/platform/index.ts +64 -0
- package/src/promise/index.ts +16 -0
- package/src/promise/promise.test.ts +254 -0
- package/src/promise/promise.ts +212 -0
- package/src/scheduler/callback-token.ts +31 -0
- package/src/scheduler/core/actuator-args.test.ts +47 -0
- package/src/scheduler/core/actuator.test.ts +82 -0
- package/src/scheduler/core/actuator.ts +58 -0
- package/src/scheduler/core/chunk-scheduler.test.ts +54 -0
- package/src/scheduler/core/chunk-scheduler.ts +28 -0
- package/src/scheduler/core/node_modules/.vitest/results.json +1 -0
- package/src/scheduler/core/scheduler.test.ts +328 -0
- package/src/scheduler/core/scheduler.ts +172 -0
- package/src/scheduler/core/task-queue.test.ts +78 -0
- package/src/scheduler/core/task-queue.ts +44 -0
- package/src/scheduler/core/task.test.ts +34 -0
- package/src/scheduler/core/task.ts +52 -0
- package/src/scheduler/core/utils.ts +48 -0
- package/src/scheduler/executor/abstract-executor.test.ts +44 -0
- package/src/scheduler/executor/abstract-executor.ts +38 -0
- package/src/scheduler/executor/executor.interface.ts +39 -0
- package/src/scheduler/executor/idle-callback-executor.test.ts +70 -0
- package/src/scheduler/executor/idle-callback-executor.ts +98 -0
- package/src/scheduler/executor/make-executor.ts +18 -0
- package/src/scheduler/executor/post-message-executor.test.ts +66 -0
- package/src/scheduler/executor/post-message-executor.ts +52 -0
- package/src/scheduler/index.ts +15 -0
- package/src/scheduler/lv-scheduler-callback.ts +19 -0
- package/src/scheduler/lv-scheduler-config.ts +17 -0
- package/src/scheduler/type.ts +48 -0
- package/src/sprintf/index.ts +2 -0
- package/src/sprintf/sprintf.test.ts +95 -0
- package/src/sprintf/sprintf.ts +97 -0
- package/src/structure/graph.test.ts +181 -0
- package/src/structure/graph.ts +105 -0
- package/src/structure/index.ts +8 -0
- package/src/structure/linked-list.test.ts +74 -0
- package/src/structure/linked-list.ts +145 -0
- package/src/structure/min-heap.test.ts +71 -0
- package/src/structure/min-heap.ts +91 -0
- package/src/type/REAME.md +2 -0
- package/src/type/distributive-omit.interface.ts +4 -0
- package/src/type/index.ts +3 -0
- package/src/type/object-key-paths.interface.ts +40 -0
- package/src/undo-redo-stack/README.md +61 -0
- package/src/undo-redo-stack/action-stack.test.ts +330 -0
- package/src/undo-redo-stack/action-stack.ts +150 -0
- package/src/undo-redo-stack/element.ts +4 -0
- package/src/undo-redo-stack/index.ts +7 -0
- package/src/undo-redo-stack/state-stack.test.ts +118 -0
- package/src/undo-redo-stack/state-stack.ts +133 -0
- package/src/uuid/index.ts +7 -0
- package/src/uuid/uuid.ts +86 -0
- package/src/worker/cors-worker.ts +38 -0
- package/src/worker/index.ts +4 -0
- package/src/worker/node_modules/.vitest/results.json +1 -0
- package/src/worker/promise-worker-main-thread.test.ts +91 -0
- package/src/worker/promise-worker-main-thread.ts +76 -0
- package/src/worker/promise-worker-worker-thread.ts +64 -0
- package/src/worker/promise-worker.interface.ts +15 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
interface DebounceSettings {
|
|
2
|
+
leading?: boolean | undefined;
|
|
3
|
+
maxWait?: number | undefined;
|
|
4
|
+
trailing?: boolean | undefined;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface DebounceSettingsLeading extends DebounceSettings {
|
|
8
|
+
leading: true;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface InvokeContext {
|
|
12
|
+
func: (...args: any[]) => any;
|
|
13
|
+
lastThis?: any;
|
|
14
|
+
lastArgs?: any[];
|
|
15
|
+
lastCallTime: number;
|
|
16
|
+
lastInvokeTime: number;
|
|
17
|
+
wait: number;
|
|
18
|
+
|
|
19
|
+
maxing: boolean;
|
|
20
|
+
maxWait: number;
|
|
21
|
+
|
|
22
|
+
leading: boolean;
|
|
23
|
+
trailing: boolean;
|
|
24
|
+
timerId?: any;
|
|
25
|
+
result: any;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function invokeFunc(context: InvokeContext, time: number) {
|
|
29
|
+
const args = context.lastArgs ?? [];
|
|
30
|
+
const thisArg = context.lastThis;
|
|
31
|
+
context.lastArgs = undefined;
|
|
32
|
+
context.lastThis = undefined;
|
|
33
|
+
context.lastInvokeTime = time;
|
|
34
|
+
context.result = context.func.apply(thisArg, args);
|
|
35
|
+
return context.result;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function leadingEdge(context: InvokeContext) {
|
|
39
|
+
// Reset any `maxWait` timer.
|
|
40
|
+
context.lastInvokeTime = context.lastCallTime;
|
|
41
|
+
// Start the timer for the trailing edge.
|
|
42
|
+
context.timerId = setTimeout(() => {
|
|
43
|
+
timerExpired(context);
|
|
44
|
+
}, context.wait);
|
|
45
|
+
// Invoke the leading edge.
|
|
46
|
+
return context.leading ? invokeFunc(context, context.lastCallTime) : context.result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function remainingWait(context: InvokeContext, time: number) {
|
|
50
|
+
const timeSinceLastCall = time - context.lastCallTime;
|
|
51
|
+
const timeSinceLastInvoke = time - context.lastInvokeTime;
|
|
52
|
+
const timeWaiting = context.wait - timeSinceLastCall;
|
|
53
|
+
|
|
54
|
+
return context.maxing ? Math.min(timeWaiting, context.maxWait - timeSinceLastInvoke) : timeWaiting;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function shouldInvoke(context: InvokeContext, time: number): boolean {
|
|
58
|
+
const timeSinceLastCall = time - context.lastCallTime;
|
|
59
|
+
const timeSinceLastInvoke = time - context.lastInvokeTime;
|
|
60
|
+
|
|
61
|
+
return Boolean(
|
|
62
|
+
context.lastCallTime === 0 ||
|
|
63
|
+
timeSinceLastCall >= context.wait ||
|
|
64
|
+
timeSinceLastCall < 0 ||
|
|
65
|
+
(context.maxWait && timeSinceLastInvoke >= context.maxWait),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function timerExpired(context: InvokeContext) {
|
|
70
|
+
const time = Date.now();
|
|
71
|
+
if (shouldInvoke(context, time)) {
|
|
72
|
+
return trailingEdge(context, time);
|
|
73
|
+
}
|
|
74
|
+
// Restart the timer.
|
|
75
|
+
context.timerId = setTimeout(
|
|
76
|
+
() => {
|
|
77
|
+
timerExpired(context);
|
|
78
|
+
},
|
|
79
|
+
remainingWait(context, time),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function trailingEdge(context: InvokeContext, time: number) {
|
|
84
|
+
context.timerId = undefined;
|
|
85
|
+
|
|
86
|
+
if (context.trailing && context.lastArgs) {
|
|
87
|
+
return invokeFunc(context, time);
|
|
88
|
+
}
|
|
89
|
+
context.lastArgs = context.lastThis = undefined;
|
|
90
|
+
return context.result;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function cancel(context: InvokeContext) {
|
|
94
|
+
if (context.timerId !== undefined) {
|
|
95
|
+
clearTimeout(context.timerId);
|
|
96
|
+
}
|
|
97
|
+
context.lastInvokeTime = 0;
|
|
98
|
+
context.lastCallTime = 0;
|
|
99
|
+
context.lastArgs = undefined;
|
|
100
|
+
context.lastThis = undefined;
|
|
101
|
+
context.timerId = undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function flush(context: InvokeContext) {
|
|
105
|
+
return context.timerId === undefined ? context.result : trailingEdge(context, Date.now());
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function debounce<T extends (...args: any[]) => any>(
|
|
109
|
+
func: T,
|
|
110
|
+
_wait?: number,
|
|
111
|
+
_options?: DebounceSettings | DebounceSettingsLeading,
|
|
112
|
+
): {
|
|
113
|
+
(...args: Parameters<T>): ReturnType<T> | undefined;
|
|
114
|
+
cancel: () => void;
|
|
115
|
+
flush: () => ReturnType<T> | undefined;
|
|
116
|
+
} {
|
|
117
|
+
const wait = _wait ?? 0;
|
|
118
|
+
const maxing = _options?.maxWait !== undefined;
|
|
119
|
+
|
|
120
|
+
const context: InvokeContext = {
|
|
121
|
+
func,
|
|
122
|
+
wait,
|
|
123
|
+
maxing,
|
|
124
|
+
maxWait: maxing ? Math.max(_options.maxWait ?? 0, wait) : wait,
|
|
125
|
+
leading: _options?.leading ?? false,
|
|
126
|
+
trailing: _options?.trailing ?? true,
|
|
127
|
+
lastInvokeTime: 0,
|
|
128
|
+
lastCallTime: 0,
|
|
129
|
+
result: undefined,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
function debounced(...args: any[]) {
|
|
133
|
+
const time = Date.now();
|
|
134
|
+
const isInvoking = shouldInvoke(context, time);
|
|
135
|
+
|
|
136
|
+
context.lastThis = this;
|
|
137
|
+
context.lastArgs = args;
|
|
138
|
+
context.lastCallTime = time;
|
|
139
|
+
|
|
140
|
+
if (isInvoking) {
|
|
141
|
+
if (context.timerId === undefined) {
|
|
142
|
+
return leadingEdge(context);
|
|
143
|
+
}
|
|
144
|
+
if (_options?.maxWait !== undefined) {
|
|
145
|
+
// Handle invocations in a tight loop.
|
|
146
|
+
clearTimeout(context.timerId);
|
|
147
|
+
context.timerId = setTimeout(() => {
|
|
148
|
+
timerExpired(context);
|
|
149
|
+
}, wait);
|
|
150
|
+
return invokeFunc(context, context.lastCallTime);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (context.timerId === undefined) {
|
|
154
|
+
context.timerId = setTimeout(() => {
|
|
155
|
+
timerExpired(context);
|
|
156
|
+
}, wait);
|
|
157
|
+
}
|
|
158
|
+
return context.result;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
debounced.cancel = () => {
|
|
162
|
+
cancel(context);
|
|
163
|
+
};
|
|
164
|
+
debounced.flush = () => {
|
|
165
|
+
return flush(context);
|
|
166
|
+
};
|
|
167
|
+
return debounced;
|
|
168
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"1.0.1","results":[[":throttle.test.ts",{"duration":67,"failed":false}],[":debounce.test.ts",{"duration":0,"failed":false}]]}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/* eslint-disable max-lines-per-function */
|
|
2
|
+
import { sleep } from '../async';
|
|
3
|
+
import { throttle } from './throttle';
|
|
4
|
+
|
|
5
|
+
describe('Throttle', () => {
|
|
6
|
+
test('should throttle a function', async () => {
|
|
7
|
+
let callCount = 0;
|
|
8
|
+
const throttled = throttle(() => {
|
|
9
|
+
callCount++;
|
|
10
|
+
}, 32);
|
|
11
|
+
|
|
12
|
+
throttled();
|
|
13
|
+
throttled();
|
|
14
|
+
throttled();
|
|
15
|
+
|
|
16
|
+
const lastCount = callCount;
|
|
17
|
+
expect(callCount).toBeGreaterThan(0);
|
|
18
|
+
|
|
19
|
+
await sleep(64);
|
|
20
|
+
expect(callCount).toBeGreaterThan(lastCount);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('subsequent calls should return the result of the first call', async () => {
|
|
24
|
+
const identity = (x: string) => x;
|
|
25
|
+
const throttled = throttle(identity, 32);
|
|
26
|
+
const results = [throttled('a'), throttled('b')];
|
|
27
|
+
|
|
28
|
+
expect(results).toEqual(['a', 'a']);
|
|
29
|
+
|
|
30
|
+
await sleep(64);
|
|
31
|
+
|
|
32
|
+
const newResults = [throttled('c'), throttled('d')];
|
|
33
|
+
expect(newResults[0]).not.toBe('a');
|
|
34
|
+
expect(newResults[0]).not.toBeUndefined();
|
|
35
|
+
|
|
36
|
+
expect(newResults[1]).not.toBe('d');
|
|
37
|
+
expect(newResults[1]).not.toBeUndefined();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('should clear timeout when func is called', async () => {
|
|
41
|
+
let callCount = 0;
|
|
42
|
+
|
|
43
|
+
const throttled = throttle(() => {
|
|
44
|
+
callCount++;
|
|
45
|
+
}, 32);
|
|
46
|
+
|
|
47
|
+
throttled();
|
|
48
|
+
throttled();
|
|
49
|
+
|
|
50
|
+
await sleep(64);
|
|
51
|
+
|
|
52
|
+
expect(callCount).toBe(2);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('should not trigger a trailing call when invoked once', async () => {
|
|
56
|
+
let callCount = 0;
|
|
57
|
+
const throttled = throttle(() => {
|
|
58
|
+
callCount++;
|
|
59
|
+
}, 32);
|
|
60
|
+
|
|
61
|
+
throttled();
|
|
62
|
+
expect(callCount).toBe(1);
|
|
63
|
+
|
|
64
|
+
await sleep(64);
|
|
65
|
+
|
|
66
|
+
expect(callCount).toBe(1);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('should trigger a second throttled call as soon as possible', async () => {
|
|
70
|
+
expect.assertions(3);
|
|
71
|
+
|
|
72
|
+
let callCount = 0;
|
|
73
|
+
const throttled = throttle(() => {
|
|
74
|
+
callCount++;
|
|
75
|
+
}, 128, { leading: false });
|
|
76
|
+
|
|
77
|
+
throttled();
|
|
78
|
+
|
|
79
|
+
await sleep(192);
|
|
80
|
+
expect(callCount).toBe(1);
|
|
81
|
+
throttled();
|
|
82
|
+
|
|
83
|
+
await sleep(254 - 192);
|
|
84
|
+
expect(callCount).toBe(1);
|
|
85
|
+
|
|
86
|
+
await sleep(384 - 254);
|
|
87
|
+
expect(callCount).toBe(2);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('should apply default options', async () => {
|
|
91
|
+
let callCount = 0;
|
|
92
|
+
const throttled = throttle(() => {
|
|
93
|
+
callCount++;
|
|
94
|
+
}, 32, {});
|
|
95
|
+
|
|
96
|
+
throttled();
|
|
97
|
+
throttled();
|
|
98
|
+
expect(callCount).toBe(1);
|
|
99
|
+
|
|
100
|
+
await sleep(128);
|
|
101
|
+
expect(callCount).toBe(2);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('should support a leading option', () => {
|
|
105
|
+
const identity = (x: string) => x; // 确保identity函数定义已存在
|
|
106
|
+
|
|
107
|
+
// 含leading选项的throttle
|
|
108
|
+
const withLeading = throttle(identity, 32, { leading: true });
|
|
109
|
+
expect(withLeading('a')).toBe('a');
|
|
110
|
+
|
|
111
|
+
// 不含leading选项的throttle
|
|
112
|
+
const withoutLeading = throttle(identity, 32, { leading: false });
|
|
113
|
+
expect(withoutLeading('a')).toBeUndefined();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('should support a trailing option', async () => {
|
|
117
|
+
const withCount = vi.fn();
|
|
118
|
+
const withoutCount = vi.fn();
|
|
119
|
+
|
|
120
|
+
const withTrailing = throttle((value) => {
|
|
121
|
+
withCount();
|
|
122
|
+
return value;
|
|
123
|
+
}, 64, { trailing: true });
|
|
124
|
+
|
|
125
|
+
const withoutTrailing = throttle((value) => {
|
|
126
|
+
withoutCount();
|
|
127
|
+
return value;
|
|
128
|
+
}, 64, { trailing: false });
|
|
129
|
+
|
|
130
|
+
expect(withTrailing('a')).toBe('a');
|
|
131
|
+
expect(withTrailing('b')).toBe('a');
|
|
132
|
+
|
|
133
|
+
expect(withoutTrailing('a')).toBe('a');
|
|
134
|
+
expect(withoutTrailing('b')).toBe('a');
|
|
135
|
+
|
|
136
|
+
await sleep(256);
|
|
137
|
+
|
|
138
|
+
expect(withCount.mock.calls.length).toBe(2);
|
|
139
|
+
expect(withoutCount.mock.calls.length).toBe(1);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('should not update lastCalled, at the end of the timeout, when trailing is false', async () => {
|
|
143
|
+
expect.assertions(1);
|
|
144
|
+
|
|
145
|
+
let callCount = 0;
|
|
146
|
+
|
|
147
|
+
const throttled = throttle(() => {
|
|
148
|
+
callCount++;
|
|
149
|
+
}, 64, { trailing: false });
|
|
150
|
+
|
|
151
|
+
throttled();
|
|
152
|
+
throttled();
|
|
153
|
+
|
|
154
|
+
setTimeout(() => {
|
|
155
|
+
throttled();
|
|
156
|
+
throttled();
|
|
157
|
+
}, 96);
|
|
158
|
+
|
|
159
|
+
await sleep(192);
|
|
160
|
+
|
|
161
|
+
expect(callCount).toBeGreaterThan(1);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('should work with a system time of 0', async () => {
|
|
165
|
+
let callCount = 0;
|
|
166
|
+
const throttled = throttle((value) => {
|
|
167
|
+
callCount++;
|
|
168
|
+
return value;
|
|
169
|
+
}, 32);
|
|
170
|
+
|
|
171
|
+
const results = [throttled('a'), throttled('b'), throttled('c')];
|
|
172
|
+
expect(results).toEqual(['a', 'a', 'a']);
|
|
173
|
+
expect(callCount).toBe(1);
|
|
174
|
+
|
|
175
|
+
await sleep(64);
|
|
176
|
+
|
|
177
|
+
expect(callCount).toBe(2);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { debounce } from './debounce';
|
|
2
|
+
|
|
3
|
+
interface ThrottleSettings {
|
|
4
|
+
leading?: boolean | undefined;
|
|
5
|
+
maxWait?: number | undefined;
|
|
6
|
+
trailing?: boolean | undefined;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function throttle<T extends (...args: any[]) => any>(
|
|
10
|
+
func: T,
|
|
11
|
+
_wait?: number,
|
|
12
|
+
_options?: ThrottleSettings,
|
|
13
|
+
) {
|
|
14
|
+
let leading = true;
|
|
15
|
+
let trailing = true;
|
|
16
|
+
if (_options) {
|
|
17
|
+
leading = _options.leading ?? leading;
|
|
18
|
+
trailing = _options.trailing ?? trailing;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return debounce(func, _wait, {
|
|
22
|
+
leading,
|
|
23
|
+
maxWait: _options?.maxWait,
|
|
24
|
+
trailing,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { numberHash, objectHash, stringHash } from './hash-t';
|
|
2
|
+
|
|
3
|
+
describe('hash', () => {
|
|
4
|
+
it('numberHash', () => {
|
|
5
|
+
expect(numberHash(100)).toEqual(100);
|
|
6
|
+
|
|
7
|
+
expect(numberHash(-100)).toEqual(-100);
|
|
8
|
+
|
|
9
|
+
expect(numberHash(Number.MAX_SAFE_INTEGER)).toEqual(-1);
|
|
10
|
+
|
|
11
|
+
expect(numberHash(Number.MIN_SAFE_INTEGER)).toEqual(1);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('stringHash', () => {
|
|
15
|
+
expect(stringHash('lvweb')).toEqual(-2198655);
|
|
16
|
+
|
|
17
|
+
expect(stringHash('lvweb yyds!')).toEqual(1937556723);
|
|
18
|
+
|
|
19
|
+
expect(stringHash('😀😀')).toEqual(-2038654673);
|
|
20
|
+
|
|
21
|
+
expect(stringHash('👩👩👧👧👩👩👧👧👩👩👧👧')).toEqual(-1143343164);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('objectHash', () => {
|
|
25
|
+
it('should return the correct hash for a given object', () => {
|
|
26
|
+
const inputObject = { key1: 'value1', key2: 42, key3: [1, 2, 3] };
|
|
27
|
+
const expectedHash = objectHash(inputObject); // 预期的哈希值
|
|
28
|
+
|
|
29
|
+
expect(objectHash(inputObject)).toEqual(expectedHash);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should return the same hash for objects with the same content', () => {
|
|
33
|
+
const inputObject1 = { key1: 'value1', key2: 42, key3: [1, 2, 3] };
|
|
34
|
+
const inputObject2 = { key3: [1, 2, 3], key1: 'value1', key2: 42 }; // 属性顺序不同
|
|
35
|
+
const expectedHash = objectHash(inputObject1);
|
|
36
|
+
|
|
37
|
+
expect(objectHash(inputObject1)).toEqual(expectedHash);
|
|
38
|
+
expect(objectHash(inputObject2)).toEqual(expectedHash);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should return different hashes for objects with different content', () => {
|
|
42
|
+
const inputObject1 = { key1: 'value1', key2: 42, key3: [1, 2, 3] };
|
|
43
|
+
const inputObject2 = { key1: 'value2', key2: 42, key3: [1, 2, 3] }; // 不同的内容
|
|
44
|
+
const expectedHash1 = objectHash(inputObject1);
|
|
45
|
+
const expectedHash2 = objectHash(inputObject2);
|
|
46
|
+
|
|
47
|
+
expect(objectHash(inputObject1)).toEqual(expectedHash1);
|
|
48
|
+
expect(objectHash(inputObject2)).toEqual(expectedHash2);
|
|
49
|
+
expect(expectedHash1).not.toEqual(expectedHash2);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should return the same hash for deeply nested arrays with the same content', () => {
|
|
53
|
+
const inputObject1 = {
|
|
54
|
+
key1: 'value1',
|
|
55
|
+
key2: 42,
|
|
56
|
+
key3: [
|
|
57
|
+
[1, 2, 3],
|
|
58
|
+
[4, 5, 6],
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
const inputObject2 = {
|
|
62
|
+
key3: [
|
|
63
|
+
[1, 2, 3],
|
|
64
|
+
[4, 5, 6],
|
|
65
|
+
],
|
|
66
|
+
key1: 'value1',
|
|
67
|
+
key2: 42,
|
|
68
|
+
}; // 属性顺序不同
|
|
69
|
+
const expectedHash = objectHash(inputObject1);
|
|
70
|
+
|
|
71
|
+
expect(objectHash(inputObject1)).toEqual(expectedHash);
|
|
72
|
+
expect(objectHash(inputObject2)).toEqual(expectedHash);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should return different hashes for objects with different nested arrays', () => {
|
|
76
|
+
const inputObject1 = {
|
|
77
|
+
key1: 'value1',
|
|
78
|
+
key2: 42,
|
|
79
|
+
key3: [
|
|
80
|
+
[1, 2, 3],
|
|
81
|
+
[4, 5, 6],
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
const inputObject2 = {
|
|
85
|
+
key1: 'value1',
|
|
86
|
+
key2: 42,
|
|
87
|
+
key3: [
|
|
88
|
+
[1, 2, 3],
|
|
89
|
+
[4, 5, 7],
|
|
90
|
+
],
|
|
91
|
+
}; // 不同的内容
|
|
92
|
+
const expectedHash1 = objectHash(inputObject1);
|
|
93
|
+
const expectedHash2 = objectHash(inputObject2);
|
|
94
|
+
|
|
95
|
+
expect(objectHash(inputObject1)).toEqual(expectedHash1);
|
|
96
|
+
expect(objectHash(inputObject2)).toEqual(expectedHash2);
|
|
97
|
+
expect(expectedHash1).not.toEqual(expectedHash2);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
function doHash(obj: any, hashVal: number): number {
|
|
2
|
+
switch (typeof obj) {
|
|
3
|
+
case 'object':
|
|
4
|
+
if (obj === null) {
|
|
5
|
+
return numberHash(349, hashVal);
|
|
6
|
+
} else if (Array.isArray(obj)) {
|
|
7
|
+
return arrayHash(obj, hashVal);
|
|
8
|
+
}
|
|
9
|
+
return objectHash(obj, hashVal);
|
|
10
|
+
case 'string':
|
|
11
|
+
return stringHash(obj, hashVal);
|
|
12
|
+
case 'boolean':
|
|
13
|
+
return booleanHash(obj, hashVal);
|
|
14
|
+
case 'number':
|
|
15
|
+
return numberHash(obj, hashVal);
|
|
16
|
+
case 'undefined':
|
|
17
|
+
return numberHash(937, hashVal);
|
|
18
|
+
default:
|
|
19
|
+
return numberHash(617, hashVal);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function numberHash(val: number, initialHashVal = 0): number {
|
|
24
|
+
// 将原始的hash值扩大范围,结果强制为int32整数
|
|
25
|
+
return ((initialHashVal << 5) - initialHashVal + val) | 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function arrayHash(arr: any[], initialHashVal: number): number {
|
|
29
|
+
initialHashVal = numberHash(104579, initialHashVal);
|
|
30
|
+
return arr.reduce((hashVal, item) => doHash(item, hashVal), initialHashVal);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function stringHash(s: string, hashVal = 0): number {
|
|
34
|
+
hashVal = numberHash(149417, hashVal);
|
|
35
|
+
for (let i = 0, {length} = s; i < length; i++) {
|
|
36
|
+
hashVal = numberHash(s.charCodeAt(i), hashVal);
|
|
37
|
+
}
|
|
38
|
+
return hashVal;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function objectHash(obj: any, initialHashVal = 0): number {
|
|
42
|
+
initialHashVal = numberHash(181387, initialHashVal);
|
|
43
|
+
return Object.keys(obj).sort().reduce((hashVal, key) => {
|
|
44
|
+
hashVal = stringHash(key, hashVal);
|
|
45
|
+
return doHash(obj[key], hashVal);
|
|
46
|
+
}, initialHashVal);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function booleanHash(b: boolean, initialHashVal: number): number {
|
|
50
|
+
return numberHash(b ? 433 : 863, initialHashVal);
|
|
51
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { safeJsonParse } from './parse';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"1.0.1","results":[[":parse.test.ts",{"duration":3,"failed":false}]]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { lvAssert } from '@/assert';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 解析 json 字符串,如果解析失败,返回空对象。
|
|
5
|
+
* @param value 序列化后的 json 字符串,注意,一定是json字符串
|
|
6
|
+
* @returns 反序列化的 json 字符串对应的对象,如果解析异常,返回空对象
|
|
7
|
+
*/
|
|
8
|
+
export function safeJsonParse(value: string, fallback: Record<string, any> = {}): Record<string, any> {
|
|
9
|
+
if (!value) {
|
|
10
|
+
return fallback;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
lvAssert(typeof value === 'string');
|
|
15
|
+
return JSON.parse(value);
|
|
16
|
+
} catch (e) {
|
|
17
|
+
return fallback;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Barrier } from '@/async';
|
|
2
|
+
|
|
3
|
+
export abstract class AbstractJob<T, K extends T = T> {
|
|
4
|
+
protected abstract _name: string;
|
|
5
|
+
protected _store: Map<K, Barrier[]> = new Map();
|
|
6
|
+
|
|
7
|
+
get name() {
|
|
8
|
+
return this._name;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
shouldWait(phase: K) {
|
|
12
|
+
const barriers = this._store.get(phase);
|
|
13
|
+
if (!barriers?.length) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
wait(phase: K): Promise<void> {
|
|
20
|
+
try {
|
|
21
|
+
const barriers = this._store.get(phase);
|
|
22
|
+
if (!barriers?.length) {
|
|
23
|
+
return Promise.resolve();
|
|
24
|
+
}
|
|
25
|
+
return Promise.all(barriers.map((barrier) => barrier.wait())) as unknown as Promise<void>;
|
|
26
|
+
} finally {
|
|
27
|
+
// 执行之后就清空,确保失败或cancel态时可以重复 prepare.
|
|
28
|
+
this._store.delete(phase);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
prepare(phase: K) {
|
|
33
|
+
this._executePhase(phase);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
protected _setBarrier(phase: K, barrier: Barrier) {
|
|
37
|
+
if (!this._store.has(phase)) {
|
|
38
|
+
this._store.set(phase, []);
|
|
39
|
+
}
|
|
40
|
+
const barriers = this._store.get(phase)!;
|
|
41
|
+
barriers.push(barrier);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
protected abstract _executePhase(phase: K): void;
|
|
45
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// lifecycle -> cost
|
|
2
|
+
// 启动流程lifecycle某个阶段对应的耗时
|
|
3
|
+
type Trace = Record<string | number, number>;
|
|
4
|
+
|
|
5
|
+
export class CostRecorder {
|
|
6
|
+
// 每个job在不同阶段的耗时
|
|
7
|
+
private _jobCost: Record<string, Trace> = {};
|
|
8
|
+
|
|
9
|
+
record(jobName: string, lifecycle: string | number, cost: number) {
|
|
10
|
+
if (!this._jobCost[jobName]) {
|
|
11
|
+
this._jobCost[jobName] = {};
|
|
12
|
+
}
|
|
13
|
+
if (!this._jobCost[jobName][lifecycle]) {
|
|
14
|
+
this._jobCost[jobName][lifecycle] = 0;
|
|
15
|
+
}
|
|
16
|
+
this._jobCost[jobName][lifecycle] += cost;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
toString() {
|
|
20
|
+
return JSON.stringify(this._jobCost);
|
|
21
|
+
}
|
|
22
|
+
}
|