@zk-tech/bedrock 0.0.1 → 0.1.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.
Files changed (221) hide show
  1. package/dist/async/index.cjs.map +1 -1
  2. package/dist/async/index.d.cts +2 -2
  3. package/dist/async/index.d.ts +2 -2
  4. package/dist/async/index.js.map +1 -1
  5. package/dist/error/index.cjs.map +1 -1
  6. package/dist/error/index.d.cts +19 -19
  7. package/dist/error/index.d.ts +19 -19
  8. package/dist/error/index.js.map +1 -1
  9. package/dist/{error-base-B4zaiJ5m.d.cts → error-base-DOFtBFla.d.cts} +8 -8
  10. package/dist/{error-base-B4zaiJ5m.d.ts → error-base-DOFtBFla.d.ts} +8 -8
  11. package/dist/promise/index.cjs.map +1 -1
  12. package/dist/promise/index.d.cts +4 -4
  13. package/dist/promise/index.d.ts +4 -4
  14. package/dist/promise/index.js.map +1 -1
  15. package/dist/worker/index.cjs.map +1 -1
  16. package/dist/worker/index.d.cts +2 -2
  17. package/dist/worker/index.d.ts +2 -2
  18. package/dist/worker/index.js.map +1 -1
  19. package/package.json +1 -2
  20. package/src/_internal/logger.ts +0 -59
  21. package/src/array/array.test.ts +0 -35
  22. package/src/array/array.ts +0 -25
  23. package/src/array/index.ts +0 -1
  24. package/src/assert/assert.test.ts +0 -86
  25. package/src/assert/assert.ts +0 -42
  26. package/src/assert/index.ts +0 -2
  27. package/src/async/barrier.test.ts +0 -90
  28. package/src/async/barrier.ts +0 -58
  29. package/src/async/cancellation.test.ts +0 -85
  30. package/src/async/cancellation.ts +0 -193
  31. package/src/async/index.ts +0 -18
  32. package/src/async/queue/queue.test.ts +0 -70
  33. package/src/async/queue/queue.ts +0 -56
  34. package/src/async/queue/task.test.ts +0 -155
  35. package/src/async/queue/task.ts +0 -67
  36. package/src/async/utils.test.ts +0 -28
  37. package/src/async/utils.ts +0 -8
  38. package/src/async/wait.ts +0 -9
  39. package/src/byte/format.test.ts +0 -64
  40. package/src/byte/format.ts +0 -44
  41. package/src/byte/index.ts +0 -2
  42. package/src/byte/node_modules/.vitest/results.json +0 -1
  43. package/src/byte/var.ts +0 -11
  44. package/src/cache/index.ts +0 -2
  45. package/src/cache/lru-with-timeout.test.ts +0 -88
  46. package/src/cache/lru-with-timeout.ts +0 -85
  47. package/src/cache/lru.test.ts +0 -56
  48. package/src/cache/lru.ts +0 -59
  49. package/src/context/context.test.ts +0 -17
  50. package/src/context/context.ts +0 -60
  51. package/src/context/index.ts +0 -8
  52. package/src/di/base.ts +0 -73
  53. package/src/di/container-service.test.ts +0 -179
  54. package/src/di/context.web.tsx +0 -41
  55. package/src/di/descriptor.ts +0 -31
  56. package/src/di/idle-value.test.ts +0 -73
  57. package/src/di/idle-value.ts +0 -63
  58. package/src/di/index.common.ts +0 -32
  59. package/src/di/index.ts +0 -2
  60. package/src/di/instantiation-service.interface.ts +0 -46
  61. package/src/di/instantiation-service.test.ts +0 -337
  62. package/src/di/instantiation-service.ts +0 -468
  63. package/src/di/lazy/foo.mock.ts +0 -28
  64. package/src/di/lazy/idle-load.ts +0 -39
  65. package/src/di/lazy/index.ts +0 -4
  66. package/src/di/lazy/lazy-service.test.ts +0 -65
  67. package/src/di/lazy/lazy-service.ts +0 -71
  68. package/src/di/lazy/type.ts +0 -5
  69. package/src/di/node_modules/.vitest/results.json +0 -1
  70. package/src/di/proxy-builder.test.ts +0 -45
  71. package/src/di/proxy-builder.ts +0 -38
  72. package/src/di/service-collection.test.ts +0 -27
  73. package/src/di/service-collection.ts +0 -46
  74. package/src/di/service-ownership-collection.test.ts +0 -39
  75. package/src/di/service-ownership-collection.ts +0 -38
  76. package/src/di/service-registry.test.ts +0 -66
  77. package/src/di/service-registry.ts +0 -99
  78. package/src/di/trace.ts +0 -85
  79. package/src/dispose/disposable-store.test.ts +0 -57
  80. package/src/dispose/disposable-store.ts +0 -80
  81. package/src/dispose/disposable-t.test.ts +0 -123
  82. package/src/dispose/disposable-t.ts +0 -238
  83. package/src/dispose/disposable-utils.test.ts +0 -15
  84. package/src/dispose/disposable-utils.ts +0 -28
  85. package/src/dispose/dispose-base.ts +0 -9
  86. package/src/dispose/index.ts +0 -34
  87. package/src/dispose/logger.test.ts +0 -65
  88. package/src/dispose/logger.ts +0 -39
  89. package/src/dispose/timer.test.ts +0 -30
  90. package/src/dispose/timer.ts +0 -16
  91. package/src/dispose/tracker.test.ts +0 -51
  92. package/src/dispose/tracker.ts +0 -105
  93. package/src/error/error-base.ts +0 -45
  94. package/src/error/error-code.ts +0 -39
  95. package/src/error/error-const.test.ts +0 -30
  96. package/src/error/error-const.ts +0 -16
  97. package/src/error/error-or.test.ts +0 -44
  98. package/src/error/error-or.ts +0 -2
  99. package/src/error/error-t.test.ts +0 -116
  100. package/src/error/error-t.ts +0 -100
  101. package/src/error/index.ts +0 -24
  102. package/src/error/node_modules/.vitest/results.json +0 -1
  103. package/src/event/disposable-linked-list.ts +0 -29
  104. package/src/event/emitter.test.ts +0 -191
  105. package/src/event/emitter.ts +0 -162
  106. package/src/event/error-handler.ts +0 -22
  107. package/src/event/index.ts +0 -34
  108. package/src/event/once.ts +0 -29
  109. package/src/event/phase-emitter.test.ts +0 -212
  110. package/src/event/phase-emitter.ts +0 -209
  111. package/src/event/shortcut-event-utils.ts +0 -33
  112. package/src/event/utils.ts +0 -6
  113. package/src/event/when.ts +0 -40
  114. package/src/function/debounce.test.ts +0 -274
  115. package/src/function/debounce.ts +0 -168
  116. package/src/function/index.ts +0 -2
  117. package/src/function/node_modules/.vitest/results.json +0 -1
  118. package/src/function/throttle.test.ts +0 -179
  119. package/src/function/throttle.ts +0 -26
  120. package/src/hash/hash-t.test.ts +0 -100
  121. package/src/hash/hash-t.ts +0 -51
  122. package/src/hash/index.ts +0 -3
  123. package/src/json/index.ts +0 -1
  124. package/src/json/node_modules/.vitest/results.json +0 -1
  125. package/src/json/parse.ts +0 -19
  126. package/src/launch/abstract-job.ts +0 -45
  127. package/src/launch/cost-recorder.ts +0 -22
  128. package/src/launch/index.ts +0 -2
  129. package/src/launch/job-scheduler.test.ts +0 -122
  130. package/src/launch/job-scheduler.ts +0 -118
  131. package/src/launch/node_modules/.vitest/deps/_metadata.json +0 -8
  132. package/src/launch/node_modules/.vitest/deps/package.json +0 -3
  133. package/src/launch/node_modules/.vitest/results.json +0 -1
  134. package/src/lock/README.md +0 -11
  135. package/src/lock/capability.test.ts +0 -110
  136. package/src/lock/capability.ts +0 -89
  137. package/src/lock/index.ts +0 -15
  138. package/src/lock/node_modules/.vitest/results.json +0 -1
  139. package/src/lock/semaphore.ts +0 -21
  140. package/src/lock/shared-mutex.test.ts +0 -537
  141. package/src/lock/shared-mutex.ts +0 -242
  142. package/src/lock/utils.test.ts +0 -165
  143. package/src/lock/utils.ts +0 -135
  144. package/src/lodash-es/index.ts +0 -1
  145. package/src/math/degree.ts +0 -16
  146. package/src/math/index.ts +0 -7
  147. package/src/math/math.test.ts +0 -40
  148. package/src/math/math.ts +0 -64
  149. package/src/math/node_modules/.vitest/results.json +0 -1
  150. package/src/math/vector.test.ts +0 -73
  151. package/src/math/vector.ts +0 -114
  152. package/src/network/client.interface.ts +0 -104
  153. package/src/network/client.web.ts +0 -24
  154. package/src/network/index.common.ts +0 -10
  155. package/src/network/index.ts +0 -2
  156. package/src/network/plugins/retry.ts +0 -98
  157. package/src/objects/deep-clone.test.ts +0 -40
  158. package/src/objects/deep-clone.ts +0 -13
  159. package/src/objects/deep-equal.test.ts +0 -86
  160. package/src/objects/deep-equal.ts +0 -60
  161. package/src/objects/index.ts +0 -4
  162. package/src/platform/index.ts +0 -64
  163. package/src/promise/index.ts +0 -16
  164. package/src/promise/promise.test.ts +0 -254
  165. package/src/promise/promise.ts +0 -212
  166. package/src/scheduler/callback-token.ts +0 -31
  167. package/src/scheduler/core/actuator-args.test.ts +0 -47
  168. package/src/scheduler/core/actuator.test.ts +0 -82
  169. package/src/scheduler/core/actuator.ts +0 -58
  170. package/src/scheduler/core/chunk-scheduler.test.ts +0 -54
  171. package/src/scheduler/core/chunk-scheduler.ts +0 -28
  172. package/src/scheduler/core/node_modules/.vitest/results.json +0 -1
  173. package/src/scheduler/core/scheduler.test.ts +0 -328
  174. package/src/scheduler/core/scheduler.ts +0 -172
  175. package/src/scheduler/core/task-queue.test.ts +0 -78
  176. package/src/scheduler/core/task-queue.ts +0 -44
  177. package/src/scheduler/core/task.test.ts +0 -34
  178. package/src/scheduler/core/task.ts +0 -52
  179. package/src/scheduler/core/utils.ts +0 -48
  180. package/src/scheduler/executor/abstract-executor.test.ts +0 -44
  181. package/src/scheduler/executor/abstract-executor.ts +0 -38
  182. package/src/scheduler/executor/executor.interface.ts +0 -39
  183. package/src/scheduler/executor/idle-callback-executor.test.ts +0 -70
  184. package/src/scheduler/executor/idle-callback-executor.ts +0 -98
  185. package/src/scheduler/executor/make-executor.ts +0 -18
  186. package/src/scheduler/executor/post-message-executor.test.ts +0 -66
  187. package/src/scheduler/executor/post-message-executor.ts +0 -52
  188. package/src/scheduler/index.ts +0 -15
  189. package/src/scheduler/lv-scheduler-callback.ts +0 -19
  190. package/src/scheduler/lv-scheduler-config.ts +0 -17
  191. package/src/scheduler/type.ts +0 -48
  192. package/src/sprintf/index.ts +0 -2
  193. package/src/sprintf/sprintf.test.ts +0 -95
  194. package/src/sprintf/sprintf.ts +0 -97
  195. package/src/structure/graph.test.ts +0 -181
  196. package/src/structure/graph.ts +0 -105
  197. package/src/structure/index.ts +0 -8
  198. package/src/structure/linked-list.test.ts +0 -74
  199. package/src/structure/linked-list.ts +0 -145
  200. package/src/structure/min-heap.test.ts +0 -71
  201. package/src/structure/min-heap.ts +0 -91
  202. package/src/type/REAME.md +0 -2
  203. package/src/type/distributive-omit.interface.ts +0 -4
  204. package/src/type/index.ts +0 -3
  205. package/src/type/object-key-paths.interface.ts +0 -40
  206. package/src/undo-redo-stack/README.md +0 -61
  207. package/src/undo-redo-stack/action-stack.test.ts +0 -330
  208. package/src/undo-redo-stack/action-stack.ts +0 -150
  209. package/src/undo-redo-stack/element.ts +0 -4
  210. package/src/undo-redo-stack/index.ts +0 -7
  211. package/src/undo-redo-stack/state-stack.test.ts +0 -118
  212. package/src/undo-redo-stack/state-stack.ts +0 -133
  213. package/src/uuid/index.ts +0 -7
  214. package/src/uuid/uuid.ts +0 -86
  215. package/src/worker/cors-worker.ts +0 -38
  216. package/src/worker/index.ts +0 -4
  217. package/src/worker/node_modules/.vitest/results.json +0 -1
  218. package/src/worker/promise-worker-main-thread.test.ts +0 -91
  219. package/src/worker/promise-worker-main-thread.ts +0 -76
  220. package/src/worker/promise-worker-worker-thread.ts +0 -64
  221. package/src/worker/promise-worker.interface.ts +0 -15
@@ -1,90 +0,0 @@
1
- import { Barrier, makeBarrierByPromise } from './barrier';
2
-
3
- describe('barrier', () => {
4
- it('barriers promise', async () => {
5
- vi.useFakeTimers();
6
- const before = Date.now();
7
- const barrier = new Barrier();
8
- expect(barrier.isOpen()).toBe(false);
9
- setTimeout(() => {
10
- barrier.open();
11
- }, 300);
12
- vi.advanceTimersByTime(300);
13
- await barrier.wait();
14
- expect(barrier.isOpen()).toBe(true);
15
- expect(Date.now() - before).toBe(300);
16
- });
17
-
18
- // resolve成功
19
- it('makeBarrierByPromise1', async () => {
20
- vi.useFakeTimers();
21
- const barrier = makeBarrierByPromise(
22
- new Promise<void>((resolve) => {
23
- setTimeout(() => {
24
- resolve();
25
- }, 300);
26
- }),
27
- );
28
- vi.advanceTimersByTime(400);
29
- // 涉及到promise,等待一次tick
30
- await Promise.resolve();
31
- expect(barrier.isOpen()).toBe(true);
32
- });
33
-
34
- // 一直在pending中
35
- it('makeBarrierByPromise2', async () => {
36
- vi.useFakeTimers();
37
- const barrier = makeBarrierByPromise(
38
- new Promise<void>((resolve) => {
39
- setTimeout(() => {
40
- resolve();
41
- }, 500);
42
- }),
43
- );
44
- vi.advanceTimersByTime(300);
45
- // 涉及到promise,等待一次tick
46
- await Promise.resolve();
47
- expect(barrier.isOpen()).toBe(false);
48
- });
49
-
50
- // reject,没有扭转
51
- it('makeBarrierByPromise3', async () => {
52
- try {
53
- vi.useFakeTimers();
54
- const barrier = makeBarrierByPromise(
55
- expect(
56
- new Promise<void>((resolve, reject) => {
57
- setTimeout(() => {
58
- reject(new Error('123'));
59
- }, 300);
60
- }),
61
- ).rejects.toThrow(new Error('123')),
62
- );
63
- vi.advanceTimersByTime(400);
64
- // 涉及到promise,等待一次tick
65
- await Promise.resolve();
66
- expect(barrier.isOpen()).toBe(false);
67
- } catch (error) {}
68
- });
69
-
70
- // reject,进行扭转
71
- it('makeBarrierByPromise4', async () => {
72
- try {
73
- vi.useFakeTimers();
74
- const barrier = makeBarrierByPromise(
75
- expect(
76
- new Promise<void>((resolve, reject) => {
77
- setTimeout(() => {
78
- reject(new Error('123'));
79
- }, 300);
80
- }),
81
- ).rejects.toThrow(new Error('123')),
82
- true,
83
- );
84
- vi.advanceTimersByTime(400);
85
- // 涉及到promise,等待一次tick
86
- await Promise.resolve();
87
- expect(barrier.isOpen()).toBe(true);
88
- } catch (error) {}
89
- });
90
- });
@@ -1,58 +0,0 @@
1
- export interface IBarrier {
2
- isOpen: () => boolean;
3
- open: () => void;
4
- wait: () => Promise<boolean>;
5
- }
6
-
7
- /**
8
- * A barrier that is initially closed and then becomes opened permanently after a certain period of
9
- * time or when open is called explicitly
10
- */
11
- export class Barrier {
12
- private _isOpen: boolean;
13
- private readonly _promise: Promise<boolean>;
14
- private _completePromise!: (v: boolean) => void;
15
- private _rejectPromise!: (e: unknown) => void;
16
-
17
- constructor() {
18
- this._isOpen = false;
19
- this._promise = new Promise<boolean>((c, e) => {
20
- this._completePromise = c;
21
- this._rejectPromise = e;
22
- });
23
- }
24
-
25
- isOpen(): boolean {
26
- return this._isOpen;
27
- }
28
-
29
- open(): void {
30
- this._isOpen = true;
31
- this._completePromise(true);
32
- }
33
-
34
- reject(e: unknown): void {
35
- this._rejectPromise(e);
36
- }
37
-
38
- wait(): Promise<boolean> {
39
- return this._promise;
40
- }
41
- }
42
-
43
- export function makeBarrierByPromise(promise: Promise<any>, openWhenReject: boolean = false) {
44
- const barrier = new Barrier();
45
-
46
- promise
47
- .then(() => barrier.open())
48
- .catch((err) => {
49
- if (openWhenReject) {
50
- barrier.open();
51
- throw err;
52
- } else {
53
- barrier.reject(err);
54
- }
55
- });
56
-
57
- return barrier;
58
- }
@@ -1,85 +0,0 @@
1
- import type { ICancellationToken } from './cancellation';
2
- import { CancellationTokenSource } from './cancellation';
3
-
4
- vi.useFakeTimers();
5
- vi.spyOn(global, 'setTimeout');
6
- vi.spyOn(global, 'clearTimeout');
7
-
8
- function mockFetchData(token: ICancellationToken, mockTime: number) {
9
- return new Promise((resolve, reject) => {
10
- setTimeout(() => {
11
- resolve(true);
12
- }, 4000);
13
- token.onCancellationRequested(() => {
14
- resolve(false);
15
- });
16
- vi.advanceTimersByTime(mockTime);
17
- });
18
- }
19
-
20
- describe('CancellationToken', () => {
21
- it('token cancelled', async () => {
22
- const tokenSource = new CancellationTokenSource();
23
- const { token } = tokenSource;
24
- tokenSource.cancel();
25
- const result = await mockFetchData(token, 0);
26
- expect(result).toBe(false);
27
- });
28
-
29
- it('token cancel when waiting', async () => {
30
- const tokenSource = new CancellationTokenSource();
31
- const { token } = tokenSource;
32
- setTimeout(() => {
33
- tokenSource.cancel();
34
- }, 1000);
35
- const result = await mockFetchData(token, 1000);
36
- expect(result).toBe(false);
37
- });
38
-
39
- it('fetch success', async () => {
40
- const tokenSource = new CancellationTokenSource();
41
- const { token } = tokenSource;
42
- setTimeout(() => {
43
- tokenSource.cancel();
44
- }, 5000);
45
- const result = await mockFetchData(token, 4000);
46
- expect(result).toBe(true);
47
- });
48
-
49
- /**
50
- * 取消前先获取signal
51
- */
52
- it('signal change1', async () => {
53
- const tokenSource = new CancellationTokenSource();
54
- const { signal, token } = tokenSource;
55
- expect(signal.aborted).toBe(false);
56
- setTimeout(() => {
57
- tokenSource.cancel();
58
- }, 1000);
59
- await mockFetchData(token, 4000);
60
- expect(signal.aborted).toBe(true);
61
- });
62
-
63
- /**
64
- * 取消后再获取signal
65
- */
66
- it('signal change2', async () => {
67
- const tokenSource = new CancellationTokenSource();
68
- const { token } = tokenSource;
69
- setTimeout(() => {
70
- tokenSource.cancel();
71
- }, 1000);
72
- await mockFetchData(token, 4000);
73
- expect(tokenSource.signal.aborted).toBe(true);
74
- });
75
-
76
- it('reason', async () => {
77
- const tokenSource = new CancellationTokenSource();
78
- const { token } = tokenSource;
79
- setTimeout(() => {
80
- tokenSource.cancel('unknown');
81
- }, 1000);
82
- await mockFetchData(token, 4000);
83
- expect(token.reason).toBe('unknown');
84
- });
85
- });
@@ -1,193 +0,0 @@
1
- import { EmptyDispose, type IDisposable } from '@/dispose';
2
- import type { Event } from '@/event';
3
- import { Emitter } from '@/event';
4
-
5
- //
6
- // 任何可取消的异步调用 的令牌接口
7
- // 因为异步调用无法真正意义上取消,但是可以在异步任务的回调中增加该令牌作为参数
8
- // 以便在操作被取消时停止执行
9
- //
10
- export interface ICancellationToken {
11
- // 标记是否进行过了cancel
12
- readonly isCancellationRequested: boolean;
13
-
14
- // 取消的原因
15
- readonly reason?: string;
16
-
17
- // 令牌调用cancel后触发的回调
18
- // 有如下特点
19
- // 1. 只会触发一次
20
- // 2. 当监听的时候token已经cancelled,仍然会触发一次
21
- readonly onCancellationRequested: (
22
- listener: () => any,
23
- thisArgs?: any,
24
- disposables?: IDisposable[],
25
- ) => IDisposable;
26
- }
27
-
28
- //
29
- // 编译时常量,一个快捷的事件响应
30
- // 用于当外界监听令牌取消时,直接触发回调
31
- //
32
- const shortcutEvent: Event<[]> = Object.freeze(function (callback, context?): IDisposable {
33
- const handle = setTimeout(callback.bind(context), 0);
34
-
35
- return {
36
- dispose() {
37
- clearTimeout(handle);
38
- },
39
- };
40
- });
41
-
42
- //
43
- // 可取消异步调用的令牌实现
44
- // 默认是未取消状态,可以调用cancel进行取消
45
- //
46
- class MutableToken implements ICancellationToken, IDisposable {
47
- // 是否已经取消该异步调用
48
- private _isCancelled = false;
49
- private _emitter: Emitter<[]> | null = null;
50
- private _reason?: string;
51
-
52
- public get reason(): undefined | string {
53
- return this._reason;
54
- }
55
-
56
- // 获取当前是否已经取消该异步调用
57
- public get isCancellationRequested(): boolean {
58
- return this._isCancelled;
59
- }
60
-
61
- // 外界可以监听异步取消发起
62
- public get onCancellationRequested(): Event<[]> {
63
- if (this._isCancelled) {
64
- return shortcutEvent;
65
- }
66
- if (!this._emitter) {
67
- this._emitter = new Emitter<[]>();
68
- }
69
- return this._emitter.event;
70
- }
71
-
72
- public cancel(reason?: string) {
73
- if (!this._isCancelled) {
74
- this._reason = reason;
75
- this._isCancelled = true;
76
- if (this._emitter) {
77
- this._emitter.fire();
78
- this.dispose();
79
- }
80
- }
81
- }
82
-
83
- public dispose(): void {
84
- if (this._emitter) {
85
- this._emitter.dispose();
86
- this._emitter = null;
87
- }
88
- }
89
- }
90
-
91
- //
92
- // 编译期提供的一些常量Token
93
- // 不可修改
94
- //
95
- // eslint-disable-next-line unicorn/no-static-only-class, @typescript-eslint/no-extraneous-class
96
- export class CancellationToken {
97
- static None = Object.freeze<ICancellationToken>({
98
- isCancellationRequested: false,
99
- onCancellationRequested: () => EmptyDispose,
100
- });
101
-
102
- static Cancelled = Object.freeze<ICancellationToken>({
103
- isCancellationRequested: true,
104
- onCancellationRequested: shortcutEvent,
105
- });
106
-
107
- static Make = (reason: string) => {
108
- return Object.freeze<ICancellationToken>({
109
- isCancellationRequested: true,
110
- onCancellationRequested: shortcutEvent,
111
- reason,
112
- });
113
- };
114
- }
115
-
116
- //
117
- // 任何可取消的异步调用 的控制类
118
- // 参考ICancellationToken,我们通过在异步调用的回调中添加token参数来判断异步调用的状态
119
- // token来源于CancellationTokenSource
120
- // CancellationTokenSource也会暴露cancel的接口
121
- //
122
- // 使用方式
123
- // const tokenSource = new CancellationTokenSource();
124
- //
125
- // asyncCall(() => {
126
- // if (token.isCancellationRequested) { return; } // 如果cancelled
127
- // doSomething();
128
- // });
129
- //
130
- // tokenSource.cancel(); // 因为某些情况,可能会cancel
131
- // tokenSource.dispose(); // dispose时一定会cancel
132
- //
133
- export class CancellationTokenSource implements IDisposable {
134
- // 真正的token
135
- private _token?: ICancellationToken = undefined;
136
- // 可能存在父级CancellationTokenSource
137
- private readonly _parentListener?: IDisposable = undefined;
138
- // 为了支持signal场景,所以在需要时会初始化浏览器提供的abortController原生结构
139
- private _abortController?: AbortController = undefined;
140
-
141
- constructor(parent?: ICancellationToken) {
142
- // 如果存在父级,当父对象cancel时,子对象也必须cancel
143
- this._parentListener = parent?.onCancellationRequested(this.cancel, this);
144
- }
145
-
146
- /**
147
- * 传统的cancellation用法
148
- */
149
- public get token(): ICancellationToken {
150
- if (!this._token) {
151
- this._token = new MutableToken();
152
- }
153
- return this._token;
154
- }
155
-
156
- /**
157
- * 对齐浏览器提供的abortSignal,支持给fetch、axios等传参使用
158
- */
159
- public get signal(): AbortSignal {
160
- if (this._abortController) {
161
- return this._abortController.signal;
162
- }
163
- this._abortController = new AbortController();
164
- if (this._token?.isCancellationRequested) {
165
- this._abortController.abort();
166
- }
167
- return this._abortController.signal;
168
- }
169
-
170
- public cancel(reason?: string): void {
171
- if (!this._token) {
172
- // 如果没有使用过token就直接cancel,那么就返回一个常量即可
173
- this._token = reason === undefined ? CancellationToken.Cancelled : CancellationToken.Make(reason);
174
- } else if (this._token instanceof MutableToken) {
175
- this._token.cancel(reason);
176
- }
177
- if (this._abortController) {
178
- this._abortController.abort(reason);
179
- }
180
- }
181
-
182
- public dispose(cancel = false): void {
183
- if (cancel) {
184
- this.cancel();
185
- }
186
- this._parentListener?.dispose();
187
- if (!this._token) {
188
- this._token = CancellationToken.None;
189
- } else if (this._token instanceof MutableToken) {
190
- this._token.dispose();
191
- }
192
- }
193
- }
@@ -1,18 +0,0 @@
1
- // 异步任务可取消的token
2
- export type { ICancellationToken } from './cancellation';
3
- // 异步任务可取消的源
4
- export { CancellationTokenSource } from './cancellation';
5
-
6
- // 通用的wait函数,提供异步等待能力
7
- export { wait, sleep } from './wait';
8
-
9
- // 提供调用 open 后 resolve promise 的能力
10
- export { Barrier } from './barrier';
11
- export { makeBarrierByPromise } from './barrier';
12
-
13
- // 提供异步队列控制器
14
- export { AsyncQueue } from './queue/queue';
15
- export type { IAsyncTask } from './queue/task';
16
-
17
- // 下一次eventloop再执行方法
18
- export { invokeNextLoop } from './utils';
@@ -1,70 +0,0 @@
1
- import { type Mock } from 'vitest';
2
- import { defer, type Deferred } from '@/promise';
3
- import { AsyncQueue } from './queue';
4
-
5
- const nextTick = () => {
6
- return new Promise<void>((res) => {
7
- setTimeout(() => {
8
- res();
9
- }, 0);
10
- });
11
- };
12
-
13
- const getTask = (): [() => Promise<void>, Deferred<void>, () => Mock<any, any>] => {
14
- const defer1 = defer();
15
- const mockFn1 = vi.fn();
16
-
17
- return [
18
- async () => {
19
- mockFn1();
20
- await defer1.promise;
21
- },
22
- defer1,
23
- mockFn1,
24
- ];
25
- };
26
-
27
- describe('AsyncQueue', () => {
28
- test('base', async () => {
29
- const queue = new AsyncQueue({
30
- concurrent: 1,
31
- });
32
-
33
- const [fn1, defer1, mockFn1] = getTask();
34
- queue.addTask(fn1);
35
-
36
- const [fn2, defer2, mockFn2] = getTask();
37
- queue.addTask(fn2);
38
-
39
- expect(mockFn1).toBeCalled();
40
- expect(mockFn2).not.toBeCalled();
41
-
42
- defer1.resolve();
43
- await nextTick();
44
-
45
- expect(mockFn2).toBeCalled();
46
- });
47
-
48
- test('base 2', async () => {
49
- const queue = new AsyncQueue({
50
- concurrent: 2,
51
- });
52
-
53
- const [fn1, defer1, mockFn1] = getTask();
54
- queue.addTask(fn1);
55
-
56
- const [fn2, defer2, mockFn2] = getTask();
57
- queue.addTask(fn2);
58
-
59
- const [fn3, defer3, mockFn3] = getTask();
60
- queue.addTask(fn3);
61
-
62
- expect(mockFn1).toBeCalled();
63
- expect(mockFn2).toBeCalled();
64
- expect(mockFn3).not.toBeCalled();
65
-
66
- defer1.resolve();
67
- await nextTick();
68
- expect(mockFn3).toBeCalled();
69
- });
70
- });
@@ -1,56 +0,0 @@
1
- /**
2
- * 异步任务队列
3
- */
4
- import { Disposable } from '@/dispose';
5
- import { AsyncTask, type IAsyncTask } from './task';
6
- import type { ICancellationToken } from '../cancellation';
7
-
8
- type IAsyncQueue = {
9
- /** 队列的任务并发数 */
10
- concurrent: number;
11
- };
12
-
13
- export class AsyncQueue extends Disposable {
14
- private readonly _queue: AsyncTask[] = [];
15
- private readonly _maxConcurrent: number = 1;
16
- private _execCounter: number = 0;
17
-
18
- constructor(options: IAsyncQueue) {
19
- super();
20
- // 初始化最大并发数
21
- this._maxConcurrent = options.concurrent;
22
- }
23
-
24
- /** 添加一个异步任务到队列 */
25
- addTask(
26
- callback: (cancellation: ICancellationToken) => Promise<void>,
27
- cancellationToken?: ICancellationToken,
28
- ): IAsyncTask {
29
- if (cancellationToken?.isCancellationRequested) {
30
- return new AsyncTask(null);
31
- }
32
- const task = new AsyncTask(callback);
33
- // 将任务函数加入队列
34
- this._queue.push(this._store.add(task));
35
- // 尝试执行下一个任务
36
- this._next();
37
-
38
- return task;
39
- }
40
-
41
- // 执行下一个任务,如果当前并发数小于最大并发数,并且队列不为空,则从队列中取出一个任务并执行,否则什么都不做
42
- private _next() {
43
- if (this._queue.length && this._execCounter < this._maxConcurrent && this._queue.length > 0) {
44
- // 取出队列中的第一个任务函数,并从队列中移除它
45
- const task = this._queue.shift()!;
46
- // 增加当前并发数
47
- this._execCounter++;
48
- // 执行任务函数,并处理其返回的promise对象
49
- task.safeExec().finally(() => {
50
- // 不管成功还是失败,都要减少当前并发数,并执行下一个任务(递归调用)
51
- this._execCounter--;
52
- this._next();
53
- });
54
- }
55
- }
56
- }