@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.
Files changed (390) hide show
  1. package/README.md +24 -0
  2. package/dist/array/index.cjs +22 -0
  3. package/dist/array/index.cjs.map +1 -0
  4. package/dist/array/index.d.cts +13 -0
  5. package/dist/array/index.d.ts +13 -0
  6. package/dist/array/index.js +19 -0
  7. package/dist/array/index.js.map +1 -0
  8. package/dist/assert/index.cjs +29 -0
  9. package/dist/assert/index.cjs.map +1 -0
  10. package/dist/assert/index.d.cts +25 -0
  11. package/dist/assert/index.d.ts +25 -0
  12. package/dist/assert/index.js +24 -0
  13. package/dist/assert/index.js.map +1 -0
  14. package/dist/async/index.cjs +746 -0
  15. package/dist/async/index.cjs.map +1 -0
  16. package/dist/async/index.d.cts +47 -0
  17. package/dist/async/index.d.ts +47 -0
  18. package/dist/async/index.js +738 -0
  19. package/dist/async/index.js.map +1 -0
  20. package/dist/barrier-316Xonfd.d.cts +18 -0
  21. package/dist/barrier-316Xonfd.d.ts +18 -0
  22. package/dist/byte/index.cjs +59 -0
  23. package/dist/byte/index.cjs.map +1 -0
  24. package/dist/byte/index.d.cts +12 -0
  25. package/dist/byte/index.d.ts +12 -0
  26. package/dist/byte/index.js +49 -0
  27. package/dist/byte/index.js.map +1 -0
  28. package/dist/cache/index.cjs +418 -0
  29. package/dist/cache/index.cjs.map +1 -0
  30. package/dist/cache/index.d.cts +40 -0
  31. package/dist/cache/index.d.ts +40 -0
  32. package/dist/cache/index.js +415 -0
  33. package/dist/cache/index.js.map +1 -0
  34. package/dist/cancellation-BIIv2UJm.d.cts +25 -0
  35. package/dist/cancellation-ClqPPsV1.d.ts +25 -0
  36. package/dist/context/index.cjs +59 -0
  37. package/dist/context/index.cjs.map +1 -0
  38. package/dist/context/index.d.cts +33 -0
  39. package/dist/context/index.d.ts +33 -0
  40. package/dist/context/index.js +51 -0
  41. package/dist/context/index.js.map +1 -0
  42. package/dist/di/index.cjs +1965 -0
  43. package/dist/di/index.cjs.map +1 -0
  44. package/dist/di/index.d.cts +140 -0
  45. package/dist/di/index.d.ts +140 -0
  46. package/dist/di/index.js +1949 -0
  47. package/dist/di/index.js.map +1 -0
  48. package/dist/disposable-t-B15Nu57y.d.ts +93 -0
  49. package/dist/disposable-t-CVsiyHPL.d.cts +93 -0
  50. package/dist/dispose/index.cjs +356 -0
  51. package/dist/dispose/index.cjs.map +1 -0
  52. package/dist/dispose/index.d.cts +26 -0
  53. package/dist/dispose/index.d.ts +26 -0
  54. package/dist/dispose/index.js +340 -0
  55. package/dist/dispose/index.js.map +1 -0
  56. package/dist/dispose-base-CAeXDpjg.d.cts +6 -0
  57. package/dist/dispose-base-CAeXDpjg.d.ts +6 -0
  58. package/dist/emitter-CAfCtSTg.d.cts +35 -0
  59. package/dist/emitter-DeM5mlEm.d.ts +35 -0
  60. package/dist/error/index.cjs +145 -0
  61. package/dist/error/index.cjs.map +1 -0
  62. package/dist/error/index.d.cts +45 -0
  63. package/dist/error/index.d.ts +45 -0
  64. package/dist/error/index.js +126 -0
  65. package/dist/error/index.js.map +1 -0
  66. package/dist/error-base-B4zaiJ5m.d.cts +32 -0
  67. package/dist/error-base-B4zaiJ5m.d.ts +32 -0
  68. package/dist/event/index.cjs +550 -0
  69. package/dist/event/index.cjs.map +1 -0
  70. package/dist/event/index.d.cts +139 -0
  71. package/dist/event/index.d.ts +139 -0
  72. package/dist/event/index.js +538 -0
  73. package/dist/event/index.js.map +1 -0
  74. package/dist/function/index.cjs +132 -0
  75. package/dist/function/index.cjs.map +1 -0
  76. package/dist/function/index.d.cts +26 -0
  77. package/dist/function/index.d.ts +26 -0
  78. package/dist/function/index.js +129 -0
  79. package/dist/function/index.js.map +1 -0
  80. package/dist/graph-BGbNOniY.d.cts +23 -0
  81. package/dist/graph-BGbNOniY.d.ts +23 -0
  82. package/dist/hash/index.cjs +54 -0
  83. package/dist/hash/index.cjs.map +1 -0
  84. package/dist/hash/index.d.cts +5 -0
  85. package/dist/hash/index.d.ts +5 -0
  86. package/dist/hash/index.js +50 -0
  87. package/dist/hash/index.js.map +1 -0
  88. package/dist/instantiation-service.interface-CVFMBUUD.d.cts +78 -0
  89. package/dist/instantiation-service.interface-CVFMBUUD.d.ts +78 -0
  90. package/dist/json/index.cjs +28 -0
  91. package/dist/json/index.cjs.map +1 -0
  92. package/dist/json/index.d.cts +8 -0
  93. package/dist/json/index.d.ts +8 -0
  94. package/dist/json/index.js +26 -0
  95. package/dist/json/index.js.map +1 -0
  96. package/dist/launch/index.cjs +213 -0
  97. package/dist/launch/index.cjs.map +1 -0
  98. package/dist/launch/index.d.cts +46 -0
  99. package/dist/launch/index.d.ts +46 -0
  100. package/dist/launch/index.js +211 -0
  101. package/dist/launch/index.js.map +1 -0
  102. package/dist/linked-list-CUkue5DZ.d.cts +24 -0
  103. package/dist/linked-list-CUkue5DZ.d.ts +24 -0
  104. package/dist/lock/index.cjs +662 -0
  105. package/dist/lock/index.cjs.map +1 -0
  106. package/dist/lock/index.d.cts +145 -0
  107. package/dist/lock/index.d.ts +145 -0
  108. package/dist/lock/index.js +656 -0
  109. package/dist/lock/index.js.map +1 -0
  110. package/dist/lodash-es/index.cjs +14 -0
  111. package/dist/lodash-es/index.cjs.map +1 -0
  112. package/dist/lodash-es/index.d.cts +1 -0
  113. package/dist/lodash-es/index.d.ts +1 -0
  114. package/dist/lodash-es/index.js +3 -0
  115. package/dist/lodash-es/index.js.map +1 -0
  116. package/dist/math/index.cjs +161 -0
  117. package/dist/math/index.cjs.map +1 -0
  118. package/dist/math/index.d.cts +76 -0
  119. package/dist/math/index.d.ts +76 -0
  120. package/dist/math/index.js +156 -0
  121. package/dist/math/index.js.map +1 -0
  122. package/dist/network/index.cjs +91 -0
  123. package/dist/network/index.cjs.map +1 -0
  124. package/dist/network/index.d.cts +62 -0
  125. package/dist/network/index.d.ts +62 -0
  126. package/dist/network/index.js +82 -0
  127. package/dist/network/index.js.map +1 -0
  128. package/dist/objects/index.cjs +80 -0
  129. package/dist/objects/index.cjs.map +1 -0
  130. package/dist/objects/index.d.cts +11 -0
  131. package/dist/objects/index.d.ts +11 -0
  132. package/dist/objects/index.js +77 -0
  133. package/dist/objects/index.js.map +1 -0
  134. package/dist/platform/index.cjs +62 -0
  135. package/dist/platform/index.cjs.map +1 -0
  136. package/dist/platform/index.d.cts +21 -0
  137. package/dist/platform/index.d.ts +21 -0
  138. package/dist/platform/index.js +48 -0
  139. package/dist/platform/index.js.map +1 -0
  140. package/dist/promise/index.cjs +639 -0
  141. package/dist/promise/index.cjs.map +1 -0
  142. package/dist/promise/index.d.cts +63 -0
  143. package/dist/promise/index.d.ts +63 -0
  144. package/dist/promise/index.js +633 -0
  145. package/dist/promise/index.js.map +1 -0
  146. package/dist/scheduler/index.cjs +599 -0
  147. package/dist/scheduler/index.cjs.map +1 -0
  148. package/dist/scheduler/index.d.cts +57 -0
  149. package/dist/scheduler/index.d.ts +57 -0
  150. package/dist/scheduler/index.js +594 -0
  151. package/dist/scheduler/index.js.map +1 -0
  152. package/dist/sprintf/index.cjs +101 -0
  153. package/dist/sprintf/index.cjs.map +1 -0
  154. package/dist/sprintf/index.d.cts +3 -0
  155. package/dist/sprintf/index.d.ts +3 -0
  156. package/dist/sprintf/index.js +99 -0
  157. package/dist/sprintf/index.js.map +1 -0
  158. package/dist/structure/index.cjs +300 -0
  159. package/dist/structure/index.cjs.map +1 -0
  160. package/dist/structure/index.d.cts +21 -0
  161. package/dist/structure/index.d.ts +21 -0
  162. package/dist/structure/index.js +296 -0
  163. package/dist/structure/index.js.map +1 -0
  164. package/dist/type/index.cjs +4 -0
  165. package/dist/type/index.cjs.map +1 -0
  166. package/dist/type/index.d.cts +20 -0
  167. package/dist/type/index.d.ts +20 -0
  168. package/dist/type/index.js +3 -0
  169. package/dist/type/index.js.map +1 -0
  170. package/dist/undo-redo-stack/index.cjs +545 -0
  171. package/dist/undo-redo-stack/index.cjs.map +1 -0
  172. package/dist/undo-redo-stack/index.d.cts +130 -0
  173. package/dist/undo-redo-stack/index.d.ts +130 -0
  174. package/dist/undo-redo-stack/index.js +542 -0
  175. package/dist/undo-redo-stack/index.js.map +1 -0
  176. package/dist/uuid/index.cjs +67 -0
  177. package/dist/uuid/index.cjs.map +1 -0
  178. package/dist/uuid/index.d.cts +17 -0
  179. package/dist/uuid/index.d.ts +17 -0
  180. package/dist/uuid/index.js +61 -0
  181. package/dist/uuid/index.js.map +1 -0
  182. package/dist/worker/index.cjs +271 -0
  183. package/dist/worker/index.cjs.map +1 -0
  184. package/dist/worker/index.d.cts +66 -0
  185. package/dist/worker/index.d.ts +66 -0
  186. package/dist/worker/index.js +267 -0
  187. package/dist/worker/index.js.map +1 -0
  188. package/package.json +285 -0
  189. package/src/_internal/logger.ts +59 -0
  190. package/src/array/array.test.ts +35 -0
  191. package/src/array/array.ts +25 -0
  192. package/src/array/index.ts +1 -0
  193. package/src/assert/assert.test.ts +86 -0
  194. package/src/assert/assert.ts +42 -0
  195. package/src/assert/index.ts +2 -0
  196. package/src/async/barrier.test.ts +90 -0
  197. package/src/async/barrier.ts +58 -0
  198. package/src/async/cancellation.test.ts +85 -0
  199. package/src/async/cancellation.ts +193 -0
  200. package/src/async/index.ts +18 -0
  201. package/src/async/queue/queue.test.ts +70 -0
  202. package/src/async/queue/queue.ts +56 -0
  203. package/src/async/queue/task.test.ts +155 -0
  204. package/src/async/queue/task.ts +67 -0
  205. package/src/async/utils.test.ts +28 -0
  206. package/src/async/utils.ts +8 -0
  207. package/src/async/wait.ts +9 -0
  208. package/src/byte/format.test.ts +64 -0
  209. package/src/byte/format.ts +44 -0
  210. package/src/byte/index.ts +2 -0
  211. package/src/byte/node_modules/.vitest/results.json +1 -0
  212. package/src/byte/var.ts +11 -0
  213. package/src/cache/index.ts +2 -0
  214. package/src/cache/lru-with-timeout.test.ts +88 -0
  215. package/src/cache/lru-with-timeout.ts +85 -0
  216. package/src/cache/lru.test.ts +56 -0
  217. package/src/cache/lru.ts +59 -0
  218. package/src/context/context.test.ts +17 -0
  219. package/src/context/context.ts +60 -0
  220. package/src/context/index.ts +8 -0
  221. package/src/di/base.ts +73 -0
  222. package/src/di/container-service.test.ts +179 -0
  223. package/src/di/context.web.tsx +41 -0
  224. package/src/di/descriptor.ts +31 -0
  225. package/src/di/idle-value.test.ts +73 -0
  226. package/src/di/idle-value.ts +63 -0
  227. package/src/di/index.common.ts +32 -0
  228. package/src/di/index.ts +2 -0
  229. package/src/di/instantiation-service.interface.ts +46 -0
  230. package/src/di/instantiation-service.test.ts +337 -0
  231. package/src/di/instantiation-service.ts +468 -0
  232. package/src/di/lazy/foo.mock.ts +28 -0
  233. package/src/di/lazy/idle-load.ts +39 -0
  234. package/src/di/lazy/index.ts +4 -0
  235. package/src/di/lazy/lazy-service.test.ts +65 -0
  236. package/src/di/lazy/lazy-service.ts +71 -0
  237. package/src/di/lazy/type.ts +5 -0
  238. package/src/di/node_modules/.vitest/results.json +1 -0
  239. package/src/di/proxy-builder.test.ts +45 -0
  240. package/src/di/proxy-builder.ts +38 -0
  241. package/src/di/service-collection.test.ts +27 -0
  242. package/src/di/service-collection.ts +46 -0
  243. package/src/di/service-ownership-collection.test.ts +39 -0
  244. package/src/di/service-ownership-collection.ts +38 -0
  245. package/src/di/service-registry.test.ts +66 -0
  246. package/src/di/service-registry.ts +99 -0
  247. package/src/di/trace.ts +85 -0
  248. package/src/dispose/disposable-store.test.ts +57 -0
  249. package/src/dispose/disposable-store.ts +80 -0
  250. package/src/dispose/disposable-t.test.ts +123 -0
  251. package/src/dispose/disposable-t.ts +238 -0
  252. package/src/dispose/disposable-utils.test.ts +15 -0
  253. package/src/dispose/disposable-utils.ts +28 -0
  254. package/src/dispose/dispose-base.ts +9 -0
  255. package/src/dispose/index.ts +34 -0
  256. package/src/dispose/logger.test.ts +65 -0
  257. package/src/dispose/logger.ts +39 -0
  258. package/src/dispose/timer.test.ts +30 -0
  259. package/src/dispose/timer.ts +16 -0
  260. package/src/dispose/tracker.test.ts +51 -0
  261. package/src/dispose/tracker.ts +105 -0
  262. package/src/error/error-base.ts +45 -0
  263. package/src/error/error-code.ts +39 -0
  264. package/src/error/error-const.test.ts +30 -0
  265. package/src/error/error-const.ts +16 -0
  266. package/src/error/error-or.test.ts +44 -0
  267. package/src/error/error-or.ts +2 -0
  268. package/src/error/error-t.test.ts +116 -0
  269. package/src/error/error-t.ts +100 -0
  270. package/src/error/index.ts +24 -0
  271. package/src/error/node_modules/.vitest/results.json +1 -0
  272. package/src/event/disposable-linked-list.ts +29 -0
  273. package/src/event/emitter.test.ts +191 -0
  274. package/src/event/emitter.ts +162 -0
  275. package/src/event/error-handler.ts +22 -0
  276. package/src/event/index.ts +34 -0
  277. package/src/event/once.ts +29 -0
  278. package/src/event/phase-emitter.test.ts +212 -0
  279. package/src/event/phase-emitter.ts +209 -0
  280. package/src/event/shortcut-event-utils.ts +33 -0
  281. package/src/event/utils.ts +6 -0
  282. package/src/event/when.ts +40 -0
  283. package/src/function/debounce.test.ts +274 -0
  284. package/src/function/debounce.ts +168 -0
  285. package/src/function/index.ts +2 -0
  286. package/src/function/node_modules/.vitest/results.json +1 -0
  287. package/src/function/throttle.test.ts +179 -0
  288. package/src/function/throttle.ts +26 -0
  289. package/src/hash/hash-t.test.ts +100 -0
  290. package/src/hash/hash-t.ts +51 -0
  291. package/src/hash/index.ts +3 -0
  292. package/src/json/index.ts +1 -0
  293. package/src/json/node_modules/.vitest/results.json +1 -0
  294. package/src/json/parse.ts +19 -0
  295. package/src/launch/abstract-job.ts +45 -0
  296. package/src/launch/cost-recorder.ts +22 -0
  297. package/src/launch/index.ts +2 -0
  298. package/src/launch/job-scheduler.test.ts +122 -0
  299. package/src/launch/job-scheduler.ts +118 -0
  300. package/src/launch/node_modules/.vitest/deps/_metadata.json +8 -0
  301. package/src/launch/node_modules/.vitest/deps/package.json +3 -0
  302. package/src/launch/node_modules/.vitest/results.json +1 -0
  303. package/src/lock/README.md +11 -0
  304. package/src/lock/capability.test.ts +110 -0
  305. package/src/lock/capability.ts +89 -0
  306. package/src/lock/index.ts +15 -0
  307. package/src/lock/node_modules/.vitest/results.json +1 -0
  308. package/src/lock/semaphore.ts +21 -0
  309. package/src/lock/shared-mutex.test.ts +537 -0
  310. package/src/lock/shared-mutex.ts +242 -0
  311. package/src/lock/utils.test.ts +165 -0
  312. package/src/lock/utils.ts +135 -0
  313. package/src/lodash-es/index.ts +1 -0
  314. package/src/math/degree.ts +16 -0
  315. package/src/math/index.ts +7 -0
  316. package/src/math/math.test.ts +40 -0
  317. package/src/math/math.ts +64 -0
  318. package/src/math/node_modules/.vitest/results.json +1 -0
  319. package/src/math/vector.test.ts +73 -0
  320. package/src/math/vector.ts +114 -0
  321. package/src/network/client.interface.ts +104 -0
  322. package/src/network/client.web.ts +24 -0
  323. package/src/network/index.common.ts +10 -0
  324. package/src/network/index.ts +2 -0
  325. package/src/network/plugins/retry.ts +98 -0
  326. package/src/objects/deep-clone.test.ts +40 -0
  327. package/src/objects/deep-clone.ts +13 -0
  328. package/src/objects/deep-equal.test.ts +86 -0
  329. package/src/objects/deep-equal.ts +60 -0
  330. package/src/objects/index.ts +4 -0
  331. package/src/platform/index.ts +64 -0
  332. package/src/promise/index.ts +16 -0
  333. package/src/promise/promise.test.ts +254 -0
  334. package/src/promise/promise.ts +212 -0
  335. package/src/scheduler/callback-token.ts +31 -0
  336. package/src/scheduler/core/actuator-args.test.ts +47 -0
  337. package/src/scheduler/core/actuator.test.ts +82 -0
  338. package/src/scheduler/core/actuator.ts +58 -0
  339. package/src/scheduler/core/chunk-scheduler.test.ts +54 -0
  340. package/src/scheduler/core/chunk-scheduler.ts +28 -0
  341. package/src/scheduler/core/node_modules/.vitest/results.json +1 -0
  342. package/src/scheduler/core/scheduler.test.ts +328 -0
  343. package/src/scheduler/core/scheduler.ts +172 -0
  344. package/src/scheduler/core/task-queue.test.ts +78 -0
  345. package/src/scheduler/core/task-queue.ts +44 -0
  346. package/src/scheduler/core/task.test.ts +34 -0
  347. package/src/scheduler/core/task.ts +52 -0
  348. package/src/scheduler/core/utils.ts +48 -0
  349. package/src/scheduler/executor/abstract-executor.test.ts +44 -0
  350. package/src/scheduler/executor/abstract-executor.ts +38 -0
  351. package/src/scheduler/executor/executor.interface.ts +39 -0
  352. package/src/scheduler/executor/idle-callback-executor.test.ts +70 -0
  353. package/src/scheduler/executor/idle-callback-executor.ts +98 -0
  354. package/src/scheduler/executor/make-executor.ts +18 -0
  355. package/src/scheduler/executor/post-message-executor.test.ts +66 -0
  356. package/src/scheduler/executor/post-message-executor.ts +52 -0
  357. package/src/scheduler/index.ts +15 -0
  358. package/src/scheduler/lv-scheduler-callback.ts +19 -0
  359. package/src/scheduler/lv-scheduler-config.ts +17 -0
  360. package/src/scheduler/type.ts +48 -0
  361. package/src/sprintf/index.ts +2 -0
  362. package/src/sprintf/sprintf.test.ts +95 -0
  363. package/src/sprintf/sprintf.ts +97 -0
  364. package/src/structure/graph.test.ts +181 -0
  365. package/src/structure/graph.ts +105 -0
  366. package/src/structure/index.ts +8 -0
  367. package/src/structure/linked-list.test.ts +74 -0
  368. package/src/structure/linked-list.ts +145 -0
  369. package/src/structure/min-heap.test.ts +71 -0
  370. package/src/structure/min-heap.ts +91 -0
  371. package/src/type/REAME.md +2 -0
  372. package/src/type/distributive-omit.interface.ts +4 -0
  373. package/src/type/index.ts +3 -0
  374. package/src/type/object-key-paths.interface.ts +40 -0
  375. package/src/undo-redo-stack/README.md +61 -0
  376. package/src/undo-redo-stack/action-stack.test.ts +330 -0
  377. package/src/undo-redo-stack/action-stack.ts +150 -0
  378. package/src/undo-redo-stack/element.ts +4 -0
  379. package/src/undo-redo-stack/index.ts +7 -0
  380. package/src/undo-redo-stack/state-stack.test.ts +118 -0
  381. package/src/undo-redo-stack/state-stack.ts +133 -0
  382. package/src/uuid/index.ts +7 -0
  383. package/src/uuid/uuid.ts +86 -0
  384. package/src/worker/cors-worker.ts +38 -0
  385. package/src/worker/index.ts +4 -0
  386. package/src/worker/node_modules/.vitest/results.json +1 -0
  387. package/src/worker/promise-worker-main-thread.test.ts +91 -0
  388. package/src/worker/promise-worker-main-thread.ts +76 -0
  389. package/src/worker/promise-worker-worker-thread.ts +64 -0
  390. package/src/worker/promise-worker.interface.ts +15 -0
@@ -0,0 +1,34 @@
1
+ import { Task } from './task';
2
+
3
+ describe('Task', () => {
4
+ test('initialize', () => {
5
+ const callback = vi.fn();
6
+ const task = new Task(callback, 10, 20);
7
+ expect(task.getCallback()).toBe(callback);
8
+ expect(task.getStartTime()).toBe(10);
9
+ expect(task.getExpirationTime()).toBe(20);
10
+ expect(task.getSortIndex()).toBe(-1);
11
+ });
12
+
13
+ test('setCallback1', () => {
14
+ const callback = vi.fn();
15
+ const task = new Task(callback, 10, 20);
16
+ const callback2 = vi.fn();
17
+ expect(() => {
18
+ task.setCallback(callback2);
19
+ }).toThrowError();
20
+ });
21
+
22
+ test('setCallback2', () => {
23
+ const callback = vi.fn();
24
+ const task = new Task(callback, 10, 20);
25
+ task.clearCallback();
26
+ expect(task.getCallback()).toBeUndefined();
27
+
28
+ const callback2 = vi.fn();
29
+ expect(() => {
30
+ task.setCallback(callback2);
31
+ }).not.toThrowError();
32
+ expect(task.getCallback()).toBe(callback2);
33
+ });
34
+ });
@@ -0,0 +1,52 @@
1
+ import { lvAssert } from '../../assert';
2
+ import type { IScheduledCallback } from '../type';
3
+
4
+ export class Task {
5
+ private _callback?: IScheduledCallback;
6
+ private _sortIndex: number = -1;
7
+
8
+ constructor(
9
+ callback: IScheduledCallback,
10
+ private _startTime: number,
11
+ private _expirationTime: number,
12
+ ) {
13
+ this._callback = callback;
14
+ }
15
+
16
+ getCallback() {
17
+ return this._callback;
18
+ }
19
+
20
+ setCallback(callback: IScheduledCallback) {
21
+ lvAssert(this._callback === undefined, 'cant overlay callback.');
22
+ this._callback = callback;
23
+ }
24
+
25
+ clearCallback() {
26
+ this._callback = undefined;
27
+ }
28
+
29
+ getStartTime() {
30
+ return this._startTime;
31
+ }
32
+
33
+ setStartTime(startTime: number) {
34
+ this._startTime = startTime;
35
+ }
36
+
37
+ getExpirationTime() {
38
+ return this._expirationTime;
39
+ }
40
+
41
+ setExpirationTime(expirationTime: number) {
42
+ this._expirationTime = expirationTime;
43
+ }
44
+
45
+ setSortIndex(index: number) {
46
+ this._sortIndex = index;
47
+ }
48
+
49
+ getSortIndex() {
50
+ return this._sortIndex;
51
+ }
52
+ }
@@ -0,0 +1,48 @@
1
+ // Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2
+ // Math.pow(2, 30) - 1
3
+
4
+ import { Task } from './task';
5
+ import { PriorityLevel, type IScheduledCallback, type IOptions } from '../type';
6
+
7
+ // 0b111111111111111111111111111111
8
+ const maxSigned31BitInt = 1073741823;
9
+
10
+ // Times out immediately
11
+ const IMMEDIATE_PRIORITY_TIMEOUT = -1;
12
+ // Eventually times out
13
+ const USER_BLOCKING_PRIORITY_TIMEOUT = 250;
14
+ const NORMAL_PRIORITY_TIMEOUT = 5000;
15
+ const LOW_PRIORITY_TIMEOUT = 10000;
16
+ // Never times out
17
+ const IDLE_PRIORITY_TIMEOUT = maxSigned31BitInt;
18
+
19
+ export function getCurrentTime() {
20
+ return Date.now();
21
+ }
22
+
23
+ export function getTimeout(priorityLevel: PriorityLevel = PriorityLevel.NormalPriority) {
24
+ switch (priorityLevel) {
25
+ case PriorityLevel.ImmediatePriority:
26
+ return IMMEDIATE_PRIORITY_TIMEOUT;
27
+ case PriorityLevel.UserBlockingPriority:
28
+ return USER_BLOCKING_PRIORITY_TIMEOUT;
29
+ case PriorityLevel.IdlePriority:
30
+ return IDLE_PRIORITY_TIMEOUT;
31
+ case PriorityLevel.LowPriority:
32
+ return LOW_PRIORITY_TIMEOUT;
33
+ case PriorityLevel.NormalPriority:
34
+ default:
35
+ return NORMAL_PRIORITY_TIMEOUT;
36
+ }
37
+ }
38
+
39
+ export function makeTask(callback: IScheduledCallback, options: IOptions = {}) {
40
+ const currentTime = getCurrentTime();
41
+ const delay = options.delay ?? 0;
42
+ const timeout = getTimeout(options.priorityLevel);
43
+ const startTime = delay + currentTime;
44
+ const expirationTime = startTime + timeout;
45
+
46
+ const newTask = new Task(callback, startTime, expirationTime);
47
+ return newTask;
48
+ }
@@ -0,0 +1,44 @@
1
+ import { AbstractExecutor } from './abstract-executor';
2
+ import type { IExecutedCallback } from './executor.interface';
3
+
4
+ class TestExecutor extends AbstractExecutor {
5
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
6
+ public requestHostCallback(fn: IExecutedCallback) {}
7
+
8
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
9
+ public cancelHostCallback() {}
10
+ }
11
+
12
+ describe('AbstractExecutor', () => {
13
+ beforeEach(() => {
14
+ vi.useFakeTimers();
15
+ });
16
+
17
+ // 延迟任务调度正常执行
18
+ test('requestHostTimeout1', () => {
19
+ const testExecutor = new TestExecutor();
20
+ const fn = vi.fn();
21
+ testExecutor.requestHostTimeout(fn, 3);
22
+ vi.advanceTimersByTime(10);
23
+ expect(fn).toBeCalled();
24
+ });
25
+
26
+ // 重复进行延迟任务调度,报错
27
+ test('requestHostTimeout2', () => {
28
+ const testExecutor = new TestExecutor();
29
+ const fn = vi.fn();
30
+ testExecutor.requestHostTimeout(fn, 3);
31
+ expect(() => {
32
+ testExecutor.requestHostTimeout(fn, 3);
33
+ }).toThrowError();
34
+ });
35
+
36
+ test('cancelHostTimeout', () => {
37
+ const testExecutor = new TestExecutor();
38
+ const fn = vi.fn();
39
+ testExecutor.requestHostTimeout(fn, 3);
40
+ testExecutor.cancelHostTimeout();
41
+ vi.advanceTimersByTime(10);
42
+ expect(fn).not.toBeCalled();
43
+ });
44
+ });
@@ -0,0 +1,38 @@
1
+ import { lvAssert } from '../../assert';
2
+ import type { IExecutedCallback, IExecutor } from './executor.interface';
3
+
4
+ export abstract class AbstractExecutor implements IExecutor {
5
+ private _timeoutId: number = -1;
6
+ protected _deadline: number = 0;
7
+ protected _yieldInterval: number = 16;
8
+
9
+ get deadline() {
10
+ return this._deadline;
11
+ }
12
+
13
+ setFrameRate(fps: number) {
14
+ lvAssert(fps > 0 && fps <= 125);
15
+ this._yieldInterval = Math.floor(1000 / fps);
16
+ }
17
+
18
+ resetFrameRate() {
19
+ this._yieldInterval = 16;
20
+ }
21
+
22
+ public abstract requestHostCallback(fn: IExecutedCallback): void;
23
+ public abstract cancelHostCallback(): void;
24
+
25
+ public requestHostTimeout(fn: () => void, delayMs: number) {
26
+ lvAssert(this._timeoutId === -1, 'has request host timeout.');
27
+ clearTimeout(this._timeoutId);
28
+ this._timeoutId = setTimeout(() => {
29
+ this._timeoutId = -1;
30
+ fn();
31
+ }, delayMs) as unknown as number;
32
+ }
33
+
34
+ public cancelHostTimeout() {
35
+ clearTimeout(this._timeoutId);
36
+ this._timeoutId = -1;
37
+ }
38
+ }
@@ -0,0 +1,39 @@
1
+ export interface IExecutedCallback {
2
+ /**
3
+ * hasTimeRemaining 该回调执行时还有没有剩余时间片
4
+ * currentTime 执行该回调时时间
5
+ */
6
+ (hasTimeRemaining: boolean, currentTime: number, deadline: number): boolean;
7
+ }
8
+
9
+ export interface IExecutor {
10
+ /**
11
+ * 设置帧率,该值会影响每次执行的deadline
12
+ */
13
+ setFrameRate: (fps: number) => void;
14
+
15
+ /**
16
+ * 重置帧率
17
+ */
18
+ resetFrameRate: () => void;
19
+
20
+ /**
21
+ * 请求及时任务调用
22
+ */
23
+ requestHostCallback: (fn: IExecutedCallback) => void;
24
+
25
+ /**
26
+ * 取消及时任务调用
27
+ */
28
+ cancelHostCallback: () => void;
29
+
30
+ /**
31
+ * 请求延迟任务调用
32
+ */
33
+ requestHostTimeout: (fn: () => void, delayMs: number) => void;
34
+
35
+ /**
36
+ * 取消延迟任务调用
37
+ */
38
+ cancelHostTimeout: () => void;
39
+ }
@@ -0,0 +1,70 @@
1
+ import { IdleCallbackExecutor } from './idle-callback-executor';
2
+
3
+ describe('IdleCallbackExecutor', () => {
4
+ beforeEach(() => {
5
+ vi.useFakeTimers();
6
+ });
7
+
8
+ test('requestHostCallback1', async () => {
9
+ const idleCallbackExecutor = new IdleCallbackExecutor();
10
+ const fn1 = vi.fn();
11
+
12
+ idleCallbackExecutor.requestHostCallback(fn1);
13
+
14
+ vi.advanceTimersByTime(50);
15
+ expect(fn1).toBeCalled();
16
+ });
17
+
18
+ // 多次调度及时任务,后者覆盖
19
+ test('requestHostCallback2', async () => {
20
+ const idleCallbackExecutor = new IdleCallbackExecutor();
21
+ const fn1 = vi.fn();
22
+ const fn2 = vi.fn();
23
+
24
+ idleCallbackExecutor.requestHostCallback(fn1);
25
+ idleCallbackExecutor.requestHostCallback(fn2);
26
+
27
+ vi.advanceTimersByTime(50);
28
+ expect(fn1).not.toBeCalled();
29
+ expect(fn2).toBeCalled();
30
+ });
31
+
32
+ // 成功取消
33
+ test('cancelHostCallback1', async () => {
34
+ const idleCallbackExecutor = new IdleCallbackExecutor();
35
+ const fn1 = vi.fn();
36
+
37
+ idleCallbackExecutor.requestHostCallback(fn1);
38
+ idleCallbackExecutor.cancelHostCallback();
39
+
40
+ vi.advanceTimersByTime(50);
41
+ expect(fn1).not.toBeCalled();
42
+ });
43
+
44
+ // 成功取消,后续添加正常
45
+ test('cancelHostCallback2', async () => {
46
+ const idleCallbackExecutor = new IdleCallbackExecutor();
47
+ const fn1 = vi.fn();
48
+
49
+ idleCallbackExecutor.requestHostCallback(fn1);
50
+ idleCallbackExecutor.cancelHostCallback();
51
+ vi.advanceTimersByTime(50);
52
+ expect(fn1).not.toBeCalled();
53
+
54
+ idleCallbackExecutor.requestHostCallback(fn1);
55
+ vi.advanceTimersByTime(50);
56
+ expect(fn1).toBeCalled();
57
+ });
58
+
59
+ // 针对场景2的同步行为
60
+ test('cancelHostCallback3', async () => {
61
+ const idleCallbackExecutor = new IdleCallbackExecutor();
62
+ const fn1 = vi.fn();
63
+
64
+ idleCallbackExecutor.requestHostCallback(fn1);
65
+ idleCallbackExecutor.cancelHostCallback();
66
+ idleCallbackExecutor.requestHostCallback(fn1);
67
+ vi.advanceTimersByTime(50);
68
+ expect(fn1).toBeCalledTimes(1);
69
+ });
70
+ });
@@ -0,0 +1,98 @@
1
+ import type { IDisposable } from '../../dispose';
2
+ import { getCurrentTime } from '../core/utils';
3
+ import { AbstractExecutor } from './abstract-executor';
4
+ import type { IExecutedCallback } from './executor.interface';
5
+
6
+ declare function requestIdleCallback(
7
+ callback: (args: IdleDeadline) => void,
8
+ options?: { timeout: number },
9
+ ): number;
10
+ declare function cancelIdleCallback(handle: number): void;
11
+
12
+ export class IdleCallbackExecutor extends AbstractExecutor {
13
+ private _scheduledCallback?: IExecutedCallback;
14
+ private _disposable?: IDisposable;
15
+ private _runWhenIdle: (callback: (idle: IdleDeadline) => void, timeout?: number) => IDisposable;
16
+
17
+ constructor() {
18
+ super();
19
+ if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') {
20
+ this._runWhenIdle = (runner) => {
21
+ let disposed = false;
22
+ setTimeout(() => {
23
+ if (disposed) {
24
+ return;
25
+ }
26
+ const end = Date.now() + 15; // one frame at 64fps
27
+ runner(
28
+ Object.freeze({
29
+ didTimeout: true,
30
+ timeRemaining() {
31
+ return Math.max(0, end - Date.now());
32
+ },
33
+ }),
34
+ );
35
+ });
36
+ return {
37
+ dispose() {
38
+ if (disposed) {
39
+ return;
40
+ }
41
+ disposed = true;
42
+ },
43
+ };
44
+ };
45
+ } else {
46
+ this._runWhenIdle = (runner, timeout?) => {
47
+ const handle: number = requestIdleCallback(
48
+ runner,
49
+ typeof timeout === 'number' ? { timeout } : undefined,
50
+ );
51
+ let disposed = false;
52
+ return {
53
+ dispose() {
54
+ if (disposed) {
55
+ return;
56
+ }
57
+ disposed = true;
58
+ cancelIdleCallback(handle);
59
+ },
60
+ };
61
+ };
62
+ }
63
+ }
64
+
65
+ public requestHostCallback(fn: IExecutedCallback) {
66
+ this._scheduledCallback = fn;
67
+ if (!this._disposable) {
68
+ this._disposable = this._runWhenIdle(this._flushCallback);
69
+ }
70
+ }
71
+
72
+ public cancelHostCallback() {
73
+ this._disposable?.dispose();
74
+ this._scheduledCallback = undefined;
75
+ this._disposable = undefined;
76
+ }
77
+
78
+ private readonly _flushCallback = () => {
79
+ if (!this._scheduledCallback) {
80
+ return;
81
+ }
82
+ const currentTime = getCurrentTime();
83
+ const deadline = currentTime + this._yieldInterval;
84
+
85
+ try {
86
+ const hasMoreWork = this._scheduledCallback(true, currentTime, deadline);
87
+ if (!hasMoreWork) {
88
+ this._scheduledCallback = undefined;
89
+ this._disposable = undefined;
90
+ } else {
91
+ this._disposable = this._runWhenIdle(this._flushCallback);
92
+ }
93
+ } catch (err) {
94
+ this._disposable = this._runWhenIdle(this._flushCallback);
95
+ throw err;
96
+ }
97
+ };
98
+ }
@@ -0,0 +1,18 @@
1
+ import type { IExecutor } from './executor.interface';
2
+ import { IdleCallbackExecutor } from './idle-callback-executor';
3
+ import { PostMessageExecutor } from './post-message-executor';
4
+
5
+ declare const global: {
6
+ window?: any;
7
+ };
8
+
9
+ export function makeExecutor(): IExecutor {
10
+ try {
11
+ if (global.window) {
12
+ return new PostMessageExecutor();
13
+ }
14
+ } catch (e) {
15
+ // ...
16
+ }
17
+ return new IdleCallbackExecutor();
18
+ }
@@ -0,0 +1,66 @@
1
+ import { wait } from '../../async';
2
+ import { PostMessageExecutor } from './post-message-executor';
3
+
4
+ describe('PostMessageExecutor', () => {
5
+ test('requestHostCallback1', async () => {
6
+ const postMessageExecutor = new PostMessageExecutor();
7
+ const fn1 = vi.fn();
8
+
9
+ postMessageExecutor.requestHostCallback(fn1);
10
+
11
+ await wait(150);
12
+ expect(fn1).toBeCalled();
13
+ });
14
+
15
+ // 多次调度及时任务,后者覆盖
16
+ test('requestHostCallback2', async () => {
17
+ const postMessageExecutor = new PostMessageExecutor();
18
+ const fn1 = vi.fn();
19
+ const fn2 = vi.fn();
20
+
21
+ postMessageExecutor.requestHostCallback(fn1);
22
+ postMessageExecutor.requestHostCallback(fn2);
23
+
24
+ await wait(150);
25
+ expect(fn1).not.toBeCalled();
26
+ expect(fn2).toBeCalled();
27
+ });
28
+
29
+ // 成功取消
30
+ test('cancelHostCallback1', async () => {
31
+ const postMessageExecutor = new PostMessageExecutor();
32
+ const fn1 = vi.fn();
33
+
34
+ postMessageExecutor.requestHostCallback(fn1);
35
+ postMessageExecutor.cancelHostCallback();
36
+
37
+ await wait(150);
38
+ expect(fn1).not.toBeCalled();
39
+ });
40
+
41
+ // 成功取消,后续添加正常
42
+ test('cancelHostCallback2', async () => {
43
+ const postMessageExecutor = new PostMessageExecutor();
44
+ const fn1 = vi.fn();
45
+
46
+ postMessageExecutor.requestHostCallback(fn1);
47
+ postMessageExecutor.cancelHostCallback();
48
+ await wait(150);
49
+ expect(fn1).not.toBeCalled();
50
+
51
+ postMessageExecutor.requestHostCallback(fn1);
52
+ await wait(150);
53
+ expect(fn1).toBeCalled();
54
+ });
55
+
56
+ test('cancelHostCallback3', async () => {
57
+ const postMessageExecutor = new PostMessageExecutor();
58
+ const fn1 = vi.fn();
59
+
60
+ postMessageExecutor.requestHostCallback(fn1);
61
+ postMessageExecutor.cancelHostCallback();
62
+ postMessageExecutor.requestHostCallback(fn1);
63
+ await wait(150);
64
+ expect(fn1).toBeCalledTimes(1);
65
+ });
66
+ });
@@ -0,0 +1,52 @@
1
+ import { getCurrentTime } from '../core/utils';
2
+ import { AbstractExecutor } from './abstract-executor';
3
+ import type { IExecutedCallback } from './executor.interface';
4
+
5
+ export class PostMessageExecutor extends AbstractExecutor {
6
+ private _scheduledCallback?: IExecutedCallback;
7
+ private _isMessageLoopRunning: boolean = false;
8
+ private readonly _channel = new MessageChannel();
9
+
10
+ constructor() {
11
+ super();
12
+
13
+ this._channel.port1.onmessage = () => {
14
+ this._flushCallback();
15
+ };
16
+ }
17
+
18
+ public requestHostCallback(fn: IExecutedCallback) {
19
+ this._scheduledCallback = fn;
20
+ if (!this._isMessageLoopRunning) {
21
+ this._isMessageLoopRunning = true;
22
+ this._channel.port2.postMessage(null);
23
+ }
24
+ }
25
+
26
+ public cancelHostCallback() {
27
+ this._scheduledCallback = undefined;
28
+ }
29
+
30
+ private readonly _flushCallback = () => {
31
+ if (!this._scheduledCallback) {
32
+ this._isMessageLoopRunning = false;
33
+ return;
34
+ }
35
+
36
+ const currentTime = getCurrentTime();
37
+ const deadline = currentTime + this._yieldInterval;
38
+
39
+ try {
40
+ const hasMoreWork = this._scheduledCallback(true, currentTime, deadline);
41
+ if (!hasMoreWork) {
42
+ this._isMessageLoopRunning = false;
43
+ this._scheduledCallback = undefined;
44
+ } else {
45
+ this._channel.port2.postMessage(null);
46
+ }
47
+ } catch (err) {
48
+ this._channel.port2.postMessage(null);
49
+ throw err;
50
+ }
51
+ };
52
+ }
@@ -0,0 +1,15 @@
1
+ // 任务调度优先级
2
+ export { PriorityLevel } from './type';
3
+
4
+ // 分片调度器
5
+ export type { IChunkScheduler, IOptions as ISchedulerCallbackOptions } from './type';
6
+
7
+ // 执行一个调度任务
8
+ export { lvSchedulerCallback } from './lv-scheduler-callback';
9
+ export type { ILvCallbackToken } from './lv-scheduler-callback';
10
+
11
+ // 设置调度器配置
12
+ export { lvSchedulerConfig } from './lv-scheduler-config';
13
+
14
+ // 重置调度器配置
15
+ export { lvSchedulerResetConfig } from './lv-scheduler-config';
@@ -0,0 +1,19 @@
1
+ import { type IDisposable } from '../dispose';
2
+ import { getScheduler } from './core/scheduler';
3
+ import type { IOptions, IScheduledCallback, PriorityLevel } from './type';
4
+ import { makeTask } from './core/utils';
5
+ import { CallbackToken } from './callback-token';
6
+
7
+ export interface ILvCallbackToken extends IDisposable {
8
+ /**
9
+ * 更新优先级
10
+ */
11
+ updatePriorityLevel: (priorityLevel: PriorityLevel) => void;
12
+ }
13
+
14
+ export function lvSchedulerCallback(callback: IScheduledCallback, options: IOptions = {}): ILvCallbackToken {
15
+ const newTask = makeTask(callback, options);
16
+ getScheduler().addTask(newTask);
17
+
18
+ return new CallbackToken(newTask);
19
+ }
@@ -0,0 +1,17 @@
1
+ import { getScheduler } from './core/scheduler';
2
+ import type { IConfig } from './type';
3
+
4
+ export function lvSchedulerConfig(config: IConfig) {
5
+ if (config.fps !== undefined) {
6
+ getScheduler().executor.setFrameRate(config.fps);
7
+ }
8
+
9
+ if (config.enableInputPending !== undefined) {
10
+ getScheduler().setEnableInputPending(config.enableInputPending);
11
+ }
12
+ }
13
+
14
+ export function lvSchedulerResetConfig() {
15
+ getScheduler().executor.resetFrameRate();
16
+ getScheduler().setEnableInputPending(true);
17
+ }
@@ -0,0 +1,48 @@
1
+ // 任务调度的优先级,从高到低
2
+ export enum PriorityLevel {
3
+ /** 立即执行任务的优先级 */
4
+ ImmediatePriority,
5
+ /** 用户阻塞的优先级 */
6
+ UserBlockingPriority,
7
+ /** 普通优先级 */
8
+ NormalPriority,
9
+ /** 低优先级 */
10
+ LowPriority,
11
+ /** 闲置优先级 */
12
+ IdlePriority,
13
+ }
14
+
15
+ export interface IOptions {
16
+ delay?: number;
17
+ priorityLevel?: PriorityLevel;
18
+ }
19
+
20
+ export interface IConfig {
21
+ fps?: number;
22
+ enableInputPending?: boolean;
23
+ }
24
+
25
+ export interface IScheduledCallback {
26
+ /**
27
+ * @param chunkScheduler 分片调度器
28
+ * @param didUserCallbackTimeout 该callback执行时,是否已经超过了注册时设置的过期时间
29
+ * @param remainingTime 该callback执行时,当前调度loop中剩余的可用时间
30
+ */
31
+ (chunkScheduler: IChunkScheduler, didUserCallbackTimeout: boolean, remainingTime: number): void;
32
+ }
33
+
34
+ /**
35
+ * 分片调度器
36
+ * 支持将某个大的宏任务,拆成小的粒度执行
37
+ */
38
+ export interface IChunkScheduler {
39
+ /**
40
+ * 在分片结束状态下,启动一个新的任务进入调度器
41
+ */
42
+ execute: (callback: IScheduledCallback, options?: IOptions) => void;
43
+
44
+ /**
45
+ * 在分片结束状态下,延续当前任务(本质上是立即执行任务)
46
+ */
47
+ continueExecute: (callback: IScheduledCallback) => void;
48
+ }
@@ -0,0 +1,2 @@
1
+ // 格式化字符串
2
+ export { sprintf } from './sprintf';