@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,64 +0,0 @@
1
- /* eslint-disable @typescript-eslint/naming-convention */
2
- let _isWindows = false;
3
- let _isMac = false;
4
- let _isLinux = false;
5
- let _isWeb = false;
6
- let _isIOS = false;
7
- let _isAndroid = false;
8
- let _isMobile = false;
9
- let _isIPad = false;
10
- let _isFirefox = false;
11
- let _isChrome = false;
12
- let _isSafari = false;
13
- let _userAgent: string | undefined;
14
-
15
- // Web environment
16
- if (typeof navigator === 'object') {
17
- _userAgent = navigator.userAgent;
18
- _isWindows = _userAgent.indexOf('Windows') >= 0;
19
- _isIOS =
20
- (_userAgent.indexOf('Macintosh') >= 0 ||
21
- _userAgent.indexOf('iPad') >= 0 ||
22
- _userAgent.indexOf('iPhone') >= 0) &&
23
- Boolean(navigator.maxTouchPoints) &&
24
- navigator.maxTouchPoints > 0;
25
- _isAndroid = _userAgent.indexOf('Android') >= 0;
26
- _isLinux = _userAgent.indexOf('Linux') >= 0;
27
- _isMobile = _userAgent.indexOf('Mobi') >= 0;
28
- _isIPad = _userAgent.indexOf('iPad') >= 0;
29
- _isMac = !_isMobile && _userAgent.indexOf('Macintosh') >= 0;
30
- _isFirefox = /firefox/i.test(_userAgent);
31
- _isChrome = /chrome/i.test(_userAgent);
32
- _isSafari = /^((?!chrome|android).)*safari/i.test(_userAgent);
33
- _isWeb = true;
34
- }
35
-
36
- export const isWindows = _isWindows;
37
- export const isMac = _isMac;
38
- export const isLinux = _isLinux;
39
- export const isWeb = _isWeb;
40
- export const isIOS = _isIOS;
41
- export const isAndroid = _isAndroid;
42
- export const isIPad = _isIPad;
43
- export const isMobile = _isMobile;
44
- export const isChrome = _isChrome;
45
- export const isFirefox = _isFirefox;
46
- export const isSafari = _isSafari;
47
-
48
- /**
49
- * 判断是否为 Arc 浏览器
50
- * arc 浏览器判定方式比较奇特,无法通过 UA 判断
51
- * https://stackoverflow.com/questions/76123232/can-javascript-detect-the-arc-browser
52
- */
53
- export function isArcBrowser(): boolean {
54
- return getComputedStyle(document.documentElement).getPropertyValue('--arc-palette-title') ? true : false;
55
- };
56
-
57
- /** ace2.0 不再提供这个方法 用于判断是否为浏览器环境*/
58
- export function isBrowser(): boolean {
59
- return (
60
- typeof window !== 'undefined' &&
61
- typeof window.document !== 'undefined' &&
62
- typeof window.document.createElement !== 'undefined'
63
- );
64
- }
@@ -1,16 +0,0 @@
1
- // defer相关
2
- export type { Deferred } from './promise';
3
- export { defer } from './promise';
4
-
5
- // 包装后可dispose的promise能力
6
- export type { CancelablePromise } from './promise';
7
- export { makeCancelablePromise } from './promise';
8
-
9
- // 并发执行一组promise
10
- export { parallelPromise } from './promise';
11
-
12
- // 让一个promise设置超时时间
13
- export { makePromiseWithTimeout } from './promise';
14
-
15
- // 生成一个等待AbortSignal的promise
16
- export { waitForAbortSignal } from './promise';
@@ -1,254 +0,0 @@
1
- /* eslint-disable max-nested-callbacks */
2
- import type { ILvErrorOr, ILvErrorRef } from '../error';
3
- import { GenericError, makeError } from '../error';
4
- import type { ICancellationToken } from '../async';
5
- import { makeCancelablePromise, makePromiseWithTimeout, parallelPromise } from './promise';
6
-
7
- describe('cancel promise', () => {
8
- beforeEach(() => {
9
- vi.useFakeTimers();
10
- });
11
-
12
- // promise可以正常resolve
13
- it('promise resolve', async () => {
14
- let res: ILvErrorOr<boolean> | undefined;
15
- makeCancelablePromise(
16
- (_token: ICancellationToken) =>
17
- new Promise<boolean>((resolve) => {
18
- setTimeout(() => resolve(true), 400);
19
- }),
20
- ).then((result) => {
21
- res = result;
22
- });
23
- vi.advanceTimersByTime(500);
24
- await Promise.resolve();
25
- await Promise.resolve();
26
- expect(res).not.toBeUndefined();
27
- expect(res!.ok).toBeTruthy();
28
- });
29
-
30
- // promise可以正常reject
31
- it('promise reject', async () => {
32
- let res: ILvErrorOr<boolean> | undefined;
33
- makeCancelablePromise(
34
- (_token: ICancellationToken) =>
35
- new Promise<boolean>((resolve, reject) => {
36
- setTimeout(() => reject(), 400);
37
- }),
38
- )
39
- .then((result) => {
40
- res = result;
41
- })
42
- .catch(() => {
43
- res = makeError(-1, '');
44
- });
45
- vi.advanceTimersByTime(500);
46
- await Promise.resolve();
47
- await Promise.resolve();
48
- await Promise.resolve();
49
- expect(res).not.toBeUndefined();
50
- expect(res!.ok).toBeFalsy();
51
- expect(res!.code).toBe(-1);
52
- });
53
-
54
- // promise可以取消
55
- it('cancel success', async () => {
56
- let res: ILvErrorOr<boolean> | undefined;
57
- const p = makeCancelablePromise(
58
- (_token: ICancellationToken) =>
59
- new Promise<boolean>((resolve) => {
60
- setTimeout(() => resolve(true), 400);
61
- }),
62
- );
63
- p.then((result) => {
64
- res = result;
65
- });
66
- vi.advanceTimersByTime(200);
67
- await Promise.resolve();
68
- expect(res).toBeUndefined();
69
-
70
- // 中途取消
71
- p.cancel();
72
-
73
- // 不用等到resolve,res已经回来了
74
- vi.advanceTimersByTime(50);
75
- await Promise.resolve();
76
- expect(res).not.toBeUndefined();
77
-
78
- // 哪怕等到resolve回来,结果也不会错误
79
- vi.advanceTimersByTime(300);
80
- await Promise.resolve();
81
- await Promise.resolve();
82
- await Promise.resolve();
83
- expect(res!.ok).toBeFalsy();
84
- expect(res!.code).toBe(GenericError.Cancelled);
85
- });
86
- });
87
-
88
- describe('parallel promise', () => {
89
- beforeEach(() => {
90
- vi.useFakeTimers();
91
- });
92
-
93
- // 所有的promise都可以正常成功执行
94
- it('all promise success', async () => {
95
- let t = 0;
96
- const p1 = new Promise<number>((resolve, reject) => {
97
- resolve(1);
98
- }).then((value) => {
99
- t += value;
100
- });
101
- const p2 = makeCancelablePromise(() =>
102
- new Promise<number>((resolve, reject) => {
103
- setTimeout(() => resolve(2), 500);
104
- }).then((value) => {
105
- t += value;
106
- }),
107
- );
108
-
109
- parallelPromise([p1, p2]);
110
- vi.advanceTimersByTime(500);
111
- await Promise.resolve();
112
- expect(t).toBe(3);
113
- });
114
-
115
- // 单个promise reject,错误可以抛出,其他promise正常执行
116
- it('one promise reject, anthor run', async () => {
117
- let t = 0;
118
- const p1 = new Promise<number>((resolve, reject) => {
119
- reject(new Error('test error.'));
120
- }).then((value) => {
121
- t += value;
122
- });
123
- const p2 = new Promise<number>((resolve, reject) => {
124
- setTimeout(() => resolve(2), 500);
125
- }).then((value) => {
126
- t += value;
127
- });
128
-
129
- try {
130
- await parallelPromise([p1, p2]);
131
- expect(true).toBe(false);
132
- } catch (err: any) {
133
- expect(err.message).toBe('test error.');
134
- } finally {
135
- // 虽然p1失败了,但是p2还是正常执行了
136
- vi.advanceTimersByTime(500);
137
- await Promise.resolve();
138
- expect(t).toBe(2);
139
- }
140
- });
141
-
142
- // 单个promise reject,错误可以抛出,其他cancelablePromise尽量取消
143
- it('one promise reject, anthor cancel', async () => {
144
- let t = 0;
145
- const p1 = new Promise<number>((resolve, reject) => {
146
- reject(new Error('p1 error.'));
147
- }).then((value) => {
148
- t += value;
149
- });
150
- const p2 = makeCancelablePromise(() =>
151
- new Promise<number>((resolve, reject) => {
152
- setTimeout(() => resolve(2), 500);
153
- }).then((value) => {
154
- t += value;
155
- }),
156
- );
157
-
158
- try {
159
- await parallelPromise([p1, p2]);
160
- expect(true).toBe(false);
161
- } catch (err: any) {
162
- expect(err.message).toBe('p1 error.');
163
- } finally {
164
- expect(t).toBe(0);
165
- }
166
- });
167
-
168
- // 单个promise error,其他cancelablePromise尽量取消
169
- it('one promise error, anthor cancel', async () => {
170
- let t = 0;
171
- const p1 = new Promise<ILvErrorRef>((resolve) => {
172
- resolve(makeError(-1, 'p1 error.'));
173
- });
174
- const p2 = makeCancelablePromise(() =>
175
- new Promise<number>((resolve, reject) => {
176
- setTimeout(() => resolve(2), 500);
177
- }).then((value) => {
178
- t += value;
179
- }),
180
- );
181
-
182
- const result = await parallelPromise([p1, p2]);
183
- expect(result.ok).toBeFalsy();
184
- expect(result.msg).toBe('p1 error.');
185
- // p1失败了,p2被cancel了
186
- expect(t).toBe(0);
187
- });
188
- });
189
-
190
- describe('promiseWithTimeout', () => {
191
- beforeEach(() => {
192
- vi.useFakeTimers();
193
- });
194
-
195
- // 超时
196
- it('test1', async () => {
197
- const promise = makePromiseWithTimeout(() => {
198
- return new Promise((resolve) => {
199
- setTimeout(() => {
200
- resolve(233);
201
- }, 200);
202
- });
203
- }, 100);
204
- vi.advanceTimersByTime(150);
205
- await Promise.resolve();
206
- const result = await promise;
207
- expect(result.ok).toBeFalsy();
208
- expect(result.toString()).toBe('[2]operation(s) timed out..');
209
- });
210
-
211
- // 未超时
212
- it('test2', async () => {
213
- const promise = makePromiseWithTimeout((): Promise<number> => {
214
- return new Promise((resolve) => {
215
- setTimeout(() => {
216
- resolve(233);
217
- }, 200);
218
- });
219
- }, 300);
220
- vi.advanceTimersByTime(250);
221
- await Promise.resolve();
222
- const result = await promise;
223
- expect(result.ok).toBeTruthy();
224
- if (result.ok) {
225
- expect(result.value).toBe(233);
226
- } else {
227
- expect(true).toBe(false);
228
- }
229
- });
230
-
231
- // 超时但存在默认值
232
- it('test3', async () => {
233
- const promise = makePromiseWithTimeout(
234
- () => {
235
- return new Promise((resolve) => {
236
- setTimeout(() => {
237
- resolve(233);
238
- }, 200);
239
- });
240
- },
241
- 100,
242
- 666,
243
- );
244
- vi.advanceTimersByTime(150);
245
- await Promise.resolve();
246
- const result = await promise;
247
- expect(result.ok).toBeTruthy();
248
- if (result.ok) {
249
- expect(result.value).toBe(666);
250
- } else {
251
- expect(true).toBe(false);
252
- }
253
- });
254
- });
@@ -1,212 +0,0 @@
1
- import {
2
- makeOkWith,
3
- type ILvErrorOr,
4
- cancelledError,
5
- GenericError,
6
- timeoutError,
7
- type ILvErrorRef,
8
- makeOk,
9
- isLvErrorRef,
10
- } from '../error';
11
- import type { ICancellationToken } from '../async';
12
- import { CancellationTokenSource } from '../async';
13
-
14
- /**
15
- * 一般来说Promise常用的场景有:
16
- * 1. 单次异步调用(new Promise)
17
- * 2. 批量promise调用(Promise.all)
18
- * 3. promise竞速调用(Promise.race)
19
- *
20
- * 但是原生能力有如下的缺陷
21
- * 1. 不支持取消某一次promise调用
22
- * 2. 不支持错误语义,promise.catch的重视程度比try catch还低
23
- * 3. 超时行为需要基于race封装
24
- *
25
- * 针对这三点,基建侧提供了高阶的promise能力
26
- * 1. makeCancelablePromise 返回一个可取消的promise
27
- * const promise = makeCancelablePromise(() => { ... });
28
- * promise.then((res) => {
29
- * // res是一个ILvErrorRef对象
30
- * });
31
- * // 可以直接取消promise
32
- * promise.cancel();
33
- *
34
- * 2. parallelPromise 并发执行promise,会自动观测ILvErrorRef语义
35
- * 当单个promise出现错误返回时,promise执行失败,尽可能调用所有cancelablePromise
36
- * 当单个promise出现reject时,promise执行失败,尽可能调用所有cancelablePromise,并且将reject继续上抛
37
- *
38
- * 3. makePromiseWithTimeout 让promise支持超时,可以提供默认值
39
- *
40
- * ——————————————————
41
- * Promise.allSettled和Promise.any在实际使用中场景较少,暂不提供错误语义包装
42
- */
43
-
44
- //
45
- // 可以cancel的promise对象
46
- //
47
- export interface CancelablePromise<T> extends Promise<T> {
48
- cancel: () => void;
49
- }
50
-
51
- /**
52
- * 快速生成一个CancelablePromise对象
53
- */
54
- export function makeCancelablePromise<T>(
55
- callback: (token: ICancellationToken) => Promise<T | ILvErrorOr<T>>,
56
- ): CancelablePromise<ILvErrorOr<T>> {
57
- const source = new CancellationTokenSource();
58
- const thenable = callback(source.token);
59
- const promise = new Promise<ILvErrorOr<T>>((resolve, reject) => {
60
- const subscription = source.token.onCancellationRequested(() => {
61
- subscription.dispose();
62
- source.dispose();
63
- resolve(cancelledError());
64
- });
65
- Promise.resolve(thenable).then(
66
- (value) => {
67
- subscription.dispose();
68
- source.dispose();
69
- if (isLvErrorRef(value)) {
70
- resolve(value);
71
- } else {
72
- resolve(makeOkWith(value as T));
73
- }
74
- },
75
- (err) => {
76
- subscription.dispose();
77
- source.dispose();
78
- reject(err);
79
- },
80
- );
81
- });
82
- return new (class {
83
- cancel() {
84
- source.cancel();
85
- }
86
- then<TResult1 = T, TResult2 = never>(
87
- resolve?: ((value: ILvErrorOr<T>) => TResult1 | Promise<TResult1>) | undefined | null,
88
- reject?: ((reason: any) => TResult2 | Promise<TResult2>) | undefined | null,
89
- ): Promise<TResult1 | TResult2> {
90
- return promise.then(resolve, reject);
91
- }
92
- catch<TResult = never>(
93
- reject?: ((reason: any) => TResult | Promise<TResult>) | undefined | null,
94
- ): Promise<T | TResult> {
95
- return this.then(undefined, reject);
96
- }
97
- finally(onfinally?: (() => void) | undefined | null): Promise<ILvErrorOr<T>> {
98
- return promise.finally(onfinally);
99
- }
100
- })() as CancelablePromise<ILvErrorOr<T>>;
101
- }
102
-
103
- /**
104
- * 并行执行promise,当某一个失败,本次调用失败
105
- * 本质上和Promise.all差不多,相比较之下
106
- * 1. 包装了错误语义判断
107
- * 2. 当失败时,会尽可能尝试cancel其他promise
108
- *
109
- * 注意:某一个promise失败时,会尽可能尝试调用其他promise的cancel,但不保证一定有效
110
- * (有可能promiseA已经成功,但是primiseB在之后失败了)
111
- */
112
- export function parallelPromise(promiseList: Promise<any>[]): Promise<ILvErrorRef> {
113
- if (promiseList.length === 0) {
114
- return Promise.resolve(makeOk());
115
- }
116
-
117
- let todo = promiseList.length;
118
- const finish = () => {
119
- todo = -1;
120
- for (const promise of promiseList) {
121
- (promise as Partial<CancelablePromise<any>>).cancel?.();
122
- }
123
- };
124
-
125
- return new Promise<ILvErrorRef>((resolve, reject) => {
126
- for (const promise of promiseList) {
127
- promise
128
- // eslint-disable-next-line @typescript-eslint/no-loop-func
129
- .then((res) => {
130
- if (isLvErrorRef(res) && !res.ok) {
131
- finish();
132
- resolve(res as ILvErrorRef);
133
- return;
134
- }
135
- todo--;
136
- if (todo === 0) {
137
- resolve(makeOk());
138
- }
139
- })
140
- .catch((err) => {
141
- finish();
142
- reject(err);
143
- });
144
- }
145
- });
146
- }
147
-
148
- /**
149
- * 包装一个promise,提供超时能力
150
- */
151
- export function makePromiseWithTimeout<T>(
152
- callback: (token: ICancellationToken) => Promise<T | ILvErrorOr<T>>,
153
- timeout: number,
154
- defaultValue?: T, // 当发生超时时,提供的默认值
155
- ): Promise<ILvErrorOr<T>> {
156
- const cancellable = makeCancelablePromise<T>(callback);
157
- const timer = setTimeout(() => {
158
- cancellable.cancel();
159
- }, timeout);
160
- return cancellable.then((res: ILvErrorOr<T>) => {
161
- clearTimeout(timer);
162
- if (res.ok) {
163
- return res;
164
- }
165
- // 如果是被取消,触发了超时
166
- if (res.code === GenericError.Cancelled) {
167
- if (defaultValue !== undefined) {
168
- // 希望返回默认值
169
- return makeOkWith(defaultValue);
170
- }
171
- return timeoutError();
172
- } else {
173
- // 遇到其他错误时透传错误
174
- return res;
175
- }
176
- });
177
- }
178
-
179
- // 如果 proposal-promise-with-resolvers 通过了,那么这个函数就可以去掉了
180
- // https://github.com/microsoft/TypeScript/blob/1d96eb489e559f4f61522edb3c8b5987bbe948af/src/harness/util.ts#L115
181
- export interface Deferred<T> {
182
- resolve: (value: T | PromiseLike<T>) => void;
183
- reject: (reason?: unknown) => void;
184
- promise: Promise<T>;
185
- }
186
-
187
- export function defer<T = void>(): Deferred<T> {
188
- let resolve!: (value: T | PromiseLike<T>) => void;
189
- let reject!: (reason?: unknown) => void;
190
- const promise = new Promise<T>((_resolve, _reject) => {
191
- resolve = _resolve;
192
- reject = _reject;
193
- });
194
- return { resolve, reject, promise };
195
- }
196
-
197
- export function waitForAbortSignal(signal: AbortSignal) {
198
- const { promise, reject } = defer<never>();
199
-
200
- if (signal.aborted) {
201
- reject(signal.reason);
202
- }
203
-
204
- const handleAbort = () => {
205
- reject(signal.reason);
206
- signal.removeEventListener('abort', handleAbort);
207
- };
208
-
209
- signal.addEventListener('abort', handleAbort);
210
-
211
- return promise;
212
- }
@@ -1,31 +0,0 @@
1
- import type { IDisposable } from '../dispose';
2
- import { Task } from './core/task';
3
- import { getTimeout, makeTask } from './core/utils';
4
- import { getScheduler } from './core/scheduler';
5
- import type { PriorityLevel } from './type';
6
-
7
- export class CallbackToken implements IDisposable {
8
- constructor(private _task: Task) {}
9
-
10
- dispose() {
11
- this._task.clearCallback();
12
- }
13
-
14
- updatePriorityLevel(priorityLevel: PriorityLevel) {
15
- const callback = this._task.getCallback();
16
- if (!callback) {
17
- return;
18
- }
19
- this._task.clearCallback();
20
- const newTask = makeTask(callback, {
21
- priorityLevel,
22
- });
23
- const startTime = this._task.getStartTime();
24
- const timeout = getTimeout(priorityLevel);
25
- const expirationTime = startTime + timeout;
26
- newTask.setStartTime(startTime);
27
- newTask.setExpirationTime(expirationTime);
28
- getScheduler().addTask(newTask);
29
- this._task = newTask;
30
- }
31
- }
@@ -1,47 +0,0 @@
1
- import { Actuator } from './actuator';
2
- import { getScheduler } from './scheduler';
3
- import { Task } from './task';
4
- import { getCurrentTime } from './utils';
5
-
6
- const scheduler = getScheduler();
7
-
8
- describe('Callback Arguments', () => {
9
- let skipYieldCount: number = 0;
10
- beforeAll(() => {
11
- // mock该方法,否则不方便测试
12
- scheduler.shouldYieldToHost = vi.fn(() => {
13
- if (skipYieldCount > 0) {
14
- skipYieldCount--;
15
- return false;
16
- }
17
- return true;
18
- });
19
- });
20
-
21
- beforeEach(() => {
22
- scheduler.taskQueue.waitingTasks.clear();
23
- scheduler.taskQueue.timerTasks.clear();
24
-
25
- vi.useFakeTimers();
26
- });
27
-
28
- // 已经超出过期时间
29
- // didUserCallbackTimeout返回true
30
- // remainingTime返回10
31
- test('arguments1', async () => {
32
- skipYieldCount = 1;
33
- const fn = vi.fn();
34
- let currentTime = getCurrentTime();
35
- const task = new Task(fn, currentTime, currentTime + 10);
36
- scheduler.taskQueue.timerTasks.insert(task);
37
- const actuator = new Actuator(scheduler.taskQueue, scheduler);
38
- vi.advanceTimersByTime(10);
39
- await Promise.resolve();
40
-
41
- currentTime = getCurrentTime();
42
- expect(actuator.workLoop(true, currentTime, currentTime + 16)).toBeFalsy();
43
- expect(fn).toBeCalled();
44
- expect(fn.mock.calls[0][1]).toBeTruthy();
45
- expect(fn.mock.calls[0][2]).toBe(16);
46
- });
47
- });
@@ -1,82 +0,0 @@
1
- import { Actuator } from './actuator';
2
- import { getScheduler } from './scheduler';
3
- import { Task } from './task';
4
- import { getCurrentTime } from './utils';
5
-
6
- const scheduler = getScheduler();
7
-
8
- describe('Actuator', () => {
9
- let skipYieldCount: number = 0;
10
- beforeAll(() => {
11
- // mock该方法,否则不方便测试
12
- scheduler.shouldYieldToHost = vi.fn(() => {
13
- if (skipYieldCount > 0) {
14
- skipYieldCount--;
15
- return false;
16
- }
17
- return true;
18
- });
19
- });
20
-
21
- beforeEach(() => {
22
- scheduler.taskQueue.waitingTasks.clear();
23
- scheduler.taskQueue.timerTasks.clear();
24
- });
25
-
26
- // 等待队列为空
27
- test('workLoop1', () => {
28
- skipYieldCount = 1;
29
- const actuator = new Actuator(scheduler.taskQueue, scheduler);
30
- expect(actuator.workLoop(true, 0, 5)).toBeFalsy();
31
- });
32
-
33
- // 等待队列有内容
34
- test('workLoop2', () => {
35
- skipYieldCount = 1;
36
- const fn = vi.fn();
37
- const task = new Task(fn, 0, getCurrentTime() + 1000);
38
- scheduler.taskQueue.waitingTasks.insert(task);
39
- const actuator = new Actuator(scheduler.taskQueue, scheduler);
40
-
41
- expect(actuator.workLoop(true, 0, 5)).toBeFalsy();
42
- expect(fn).toBeCalled();
43
- });
44
-
45
- // 等待队列有内容,执行后还有内容
46
- test('workLoop3', () => {
47
- skipYieldCount = 1;
48
- const fn = vi.fn();
49
- const task1 = new Task(fn, 0, getCurrentTime() + 1000);
50
- const task2 = new Task(fn, 0, getCurrentTime() + 1000);
51
- scheduler.taskQueue.waitingTasks.insert(task1);
52
- scheduler.taskQueue.waitingTasks.insert(task2);
53
- const actuator = new Actuator(scheduler.taskQueue, scheduler);
54
-
55
- expect(actuator.workLoop(true, 0, 5)).toBeTruthy();
56
- expect(fn).toBeCalledTimes(1);
57
- });
58
-
59
- // 延时队列有内容,需要执行
60
- test('workLoop4', () => {
61
- skipYieldCount = 1;
62
- const fn = vi.fn();
63
- const task = new Task(fn, 0, getCurrentTime() + 1000);
64
- scheduler.taskQueue.timerTasks.insert(task);
65
- const actuator = new Actuator(scheduler.taskQueue, scheduler);
66
-
67
- expect(actuator.workLoop(true, 0, 5)).toBeFalsy();
68
- expect(fn).toBeCalled();
69
- });
70
-
71
- // 延时队列有内容,暂时无需执行
72
- test('workLoop5', () => {
73
- skipYieldCount = 1;
74
- const fn = vi.fn();
75
- const task = new Task(fn, 10, getCurrentTime() + 1000);
76
- scheduler.taskQueue.timerTasks.insert(task);
77
- const actuator = new Actuator(scheduler.taskQueue, scheduler);
78
-
79
- expect(actuator.workLoop(true, 0, 5)).toBeFalsy();
80
- expect(fn).not.toBeCalled();
81
- });
82
- });