@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,150 @@
1
+ import { Emitter, type Event } from '../event';
2
+ import type { IActionStackElement } from './element';
3
+
4
+ export class BaseActionUndoRedoStack<T extends IActionStackElement> {
5
+ // 当undo结束后触发
6
+ public onDidUndo: Event<[T[]]>;
7
+ // 当redo结束后触发
8
+ public onDidRedo: Event<[T[]]>;
9
+ // 当栈发生变化时触发
10
+ public onStackChange: Event<[]>;
11
+
12
+ protected readonly _past: T[] = [];
13
+ protected readonly _future: T[] = [];
14
+
15
+ protected _onDidUndo = new Emitter<[T[]]>();
16
+ protected _onDidRedo = new Emitter<[T[]]>();
17
+ protected _onStackChange = new Emitter<[]>();
18
+
19
+ constructor(protected readonly _limitSize = Infinity) {
20
+ this.onDidUndo = this._onDidUndo.event;
21
+ this.onDidRedo = this._onDidRedo.event;
22
+ this.onStackChange = this._onStackChange.event;
23
+ }
24
+
25
+ /**
26
+ * 进行撤销
27
+ *
28
+ * 注意:该方法不允许被子类重写
29
+ */
30
+ readonly undo = (): void => {
31
+ if (!this.canUndo()) {
32
+ return;
33
+ }
34
+ const elements = this._popPastElements();
35
+ if (elements.length <= 0) {
36
+ return;
37
+ }
38
+ for (const elem of elements) {
39
+ elem.undo();
40
+ this._future.push(elem);
41
+ }
42
+ this._onDidUndo.fire(elements);
43
+ this._onStackChange.fire();
44
+ };
45
+
46
+ /**
47
+ * 进行重做
48
+ *
49
+ * 注意:该方法不允许被子类重写
50
+ */
51
+ readonly redo = (): void => {
52
+ if (!this.canRedo()) {
53
+ return;
54
+ }
55
+ const elements = this._popFutureElements();
56
+ if (elements.length <= 0) {
57
+ return;
58
+ }
59
+ for (const elem of elements) {
60
+ elem.redo();
61
+ this._past.push(elem);
62
+ }
63
+ this._onDidRedo.fire(elements);
64
+ this._onStackChange.fire();
65
+ };
66
+
67
+ /**
68
+ * 追加操作进入栈中
69
+ *
70
+ * 注意:该方法不允许被子类重写
71
+ */
72
+ readonly pushElement = (element: T): void => {
73
+ this._future.length = 0;
74
+ if (this._isOverflow(element)) {
75
+ this._past.shift();
76
+ }
77
+ this._past.push(element);
78
+ this._onStackChange.fire();
79
+ };
80
+
81
+ /**
82
+ * 是否可以撤销。子类可以重写
83
+ */
84
+ public canUndo(): boolean {
85
+ return this._past.length > 0;
86
+ }
87
+
88
+ /**
89
+ * 是否可以重做。子类可以重写
90
+ */
91
+ public canRedo(): boolean {
92
+ return this._future.length > 0;
93
+ }
94
+
95
+ /**
96
+ * 清除undo
97
+ */
98
+ public clearUndo(): void {
99
+ if (this._past.length === 0) {
100
+ return;
101
+ }
102
+ this._past.length = 0;
103
+ this._onStackChange.fire();
104
+ }
105
+
106
+ /**
107
+ * 清除redo
108
+ */
109
+ public clearRedo(): void {
110
+ if (this._future.length === 0) {
111
+ return;
112
+ }
113
+ this._future.length = 0;
114
+ this._onStackChange.fire();
115
+ }
116
+
117
+ /**
118
+ * 重置栈
119
+ * 清空undo和redo
120
+ */
121
+ public reset(): void {
122
+ if (this._past.length === 0 && this._future.length === 0) {
123
+ return;
124
+ }
125
+ this._past.length = 0;
126
+ this._future.length = 0;
127
+ this._onStackChange.fire();
128
+ }
129
+
130
+ /**
131
+ * 在undo时找出Past中的元素。子类可以重写
132
+ */
133
+ protected _popPastElements(): T[] {
134
+ return this._past.length ? [this._past.pop()!] : [];
135
+ }
136
+
137
+ /**
138
+ * 在redo时找出Future中的元素。子类可以重写
139
+ */
140
+ protected _popFutureElements(): T[] {
141
+ return this._future.length ? [this._future.pop()!] : [];
142
+ }
143
+
144
+ /**
145
+ * 判断新添加元素,是否会超出栈的大小。子类可以重写
146
+ */
147
+ protected _isOverflow(_elem: T) {
148
+ return this._past.length >= this._limitSize;
149
+ }
150
+ }
@@ -0,0 +1,4 @@
1
+ export interface IActionStackElement {
2
+ undo: () => void;
3
+ redo: () => void;
4
+ }
@@ -0,0 +1,7 @@
1
+ // 基础的行为undoredo栈
2
+ export { BaseActionUndoRedoStack } from './action-stack';
3
+ // 行为undoredo栈中基础的元素接口
4
+ export type { IActionStackElement } from './element';
5
+
6
+ // 状态undoredo栈
7
+ export { StateUndoRedoStack } from './state-stack';
@@ -0,0 +1,118 @@
1
+ import { StateUndoRedoStack } from './state-stack';
2
+
3
+ describe('StateUndoRedoStack', () => {
4
+ it('undo', () => {
5
+ const fn = vi.fn();
6
+ const stack = new StateUndoRedoStack<string>('initial');
7
+ stack.onDidRedo(fn);
8
+ stack.onDidUndo(fn);
9
+ expect(stack.currentState).toBe('initial');
10
+ expect(stack.canUndo()).toBeFalsy();
11
+ expect(stack.canUndo()).toBeFalsy();
12
+
13
+ stack.pushElement('1');
14
+ stack.pushElement('2');
15
+ stack.pushElement('3');
16
+ expect(stack.currentState).toBe('3');
17
+
18
+ stack.undo();
19
+ expect(stack.currentState).toBe('2');
20
+ expect(fn).toBeCalledWith('2');
21
+
22
+ stack.undo();
23
+ expect(stack.currentState).toBe('1');
24
+ expect(fn).toBeCalledWith('1');
25
+
26
+ stack.undo();
27
+ expect(stack.currentState).toBe('initial');
28
+ expect(fn).toBeCalledWith('initial');
29
+ expect(stack.canUndo()).toBeFalsy();
30
+ });
31
+
32
+ it('redo', () => {
33
+ const fn = vi.fn();
34
+ const stack = new StateUndoRedoStack<string>('initial');
35
+ stack.onDidRedo(fn);
36
+ stack.onDidUndo(fn);
37
+ expect(stack.currentState).toBe('initial');
38
+ expect(stack.canUndo()).toBeFalsy();
39
+ expect(stack.canUndo()).toBeFalsy();
40
+
41
+ stack.pushElement('1');
42
+ stack.pushElement('2');
43
+ stack.pushElement('3');
44
+
45
+ stack.undo();
46
+ expect(stack.currentState).toBe('2');
47
+ expect(fn).toBeCalledWith('2');
48
+ expect(stack.canRedo()).toBeTruthy();
49
+
50
+ stack.redo();
51
+ expect(stack.canRedo()).toBeFalsy();
52
+ expect(stack.currentState).toBe('3');
53
+ expect(fn).toBeCalledWith('3');
54
+
55
+ stack.undo();
56
+ stack.undo();
57
+ expect(stack.currentState).toBe('1');
58
+ expect(fn).toBeCalledWith('1');
59
+ expect(stack.canRedo()).toBeTruthy();
60
+
61
+ stack.pushElement('4');
62
+ expect(stack.canRedo()).toBeFalsy();
63
+
64
+ stack.undo();
65
+ expect(stack.currentState).toBe('1');
66
+ expect(fn).toBeCalledWith('1');
67
+ expect(stack.canRedo()).toBeTruthy();
68
+
69
+ stack.redo();
70
+ expect(stack.canRedo()).toBeFalsy();
71
+ expect(stack.currentState).toBe('4');
72
+ expect(fn).toBeCalledWith('4');
73
+ });
74
+
75
+ it('clear', () => {
76
+ const fn = vi.fn();
77
+ const stack = new StateUndoRedoStack<string>('initial');
78
+ stack.onStackChange(fn);
79
+
80
+ // 本身没有元素,所以没有抛出事件
81
+ stack.clearRedo();
82
+ stack.clearUndo();
83
+ stack.reset('initial');
84
+ expect(fn).toBeCalledTimes(0);
85
+
86
+ // reset后的state不一样,所以会触发回调
87
+ stack.reset('initial2');
88
+ expect(fn).toBeCalledTimes(1);
89
+
90
+ // 有undo元素,但是清除
91
+ stack.pushElement('1');
92
+ fn.mockReset();
93
+ expect(stack.canUndo()).toBeTruthy();
94
+ stack.clearUndo();
95
+ expect(fn).toBeCalledTimes(1);
96
+ expect(stack.canUndo()).toBeFalsy();
97
+
98
+ // 有redo元素,但是清除
99
+ stack.pushElement('1');
100
+ stack.pushElement('2');
101
+ stack.pushElement('3');
102
+ stack.undo();
103
+ fn.mockReset();
104
+ expect(stack.canRedo()).toBeTruthy();
105
+ stack.clearRedo();
106
+ expect(fn).toBeCalledTimes(1);
107
+ expect(stack.canRedo()).toBeFalsy();
108
+
109
+ stack.undo();
110
+ expect(stack.canUndo()).toBeTruthy();
111
+ expect(stack.canRedo()).toBeTruthy();
112
+ fn.mockReset();
113
+ stack.reset('initial');
114
+ expect(fn).toBeCalledTimes(1);
115
+ expect(stack.canUndo()).toBeFalsy();
116
+ expect(stack.canRedo()).toBeFalsy();
117
+ });
118
+ });
@@ -0,0 +1,133 @@
1
+ import type { Event } from '../event';
2
+ import { Emitter } from '../event';
3
+
4
+ export class StateUndoRedoStack<T> {
5
+ // 当undo结束后触发
6
+ public onDidUndo: Event<[T]>;
7
+ // 当redo结束后触发
8
+ public onDidRedo: Event<[T]>;
9
+ // 当栈发生变化时触发
10
+ public onStackChange: Event<[]>;
11
+
12
+ protected readonly _past: T[] = [];
13
+ protected readonly _future: T[] = [];
14
+
15
+ protected _onDidUndo = new Emitter<[T]>();
16
+ protected _onDidRedo = new Emitter<[T]>();
17
+ protected _onStackChange = new Emitter<[]>();
18
+
19
+ constructor(
20
+ protected _currentState: T,
21
+ protected readonly _limitSize = Infinity,
22
+ ) {
23
+ this.onDidUndo = this._onDidUndo.event;
24
+ this.onDidRedo = this._onDidRedo.event;
25
+ this.onStackChange = this._onStackChange.event;
26
+ }
27
+
28
+ get currentState() {
29
+ return this._currentState;
30
+ }
31
+
32
+ /**
33
+ * 进行撤销
34
+ */
35
+ public undo() {
36
+ if (!this.canUndo()) {
37
+ return;
38
+ }
39
+ this._future.push(this._currentState);
40
+ this._currentState = this._past.pop()!;
41
+ this._onDidUndo.fire(this._currentState);
42
+ this._onStackChange.fire();
43
+ }
44
+
45
+ /**
46
+ * 进行重做
47
+ *
48
+ * 注意:该方法不允许被子类重写
49
+ */
50
+ public redo() {
51
+ if (!this.canRedo()) {
52
+ return;
53
+ }
54
+ this._past.push(this._currentState);
55
+ this._currentState = this._future.pop()!;
56
+ this._onDidRedo.fire(this._currentState);
57
+ this._onStackChange.fire();
58
+ }
59
+
60
+ /**
61
+ * 追加操作进入栈中
62
+ *
63
+ * 注意:该方法不允许被子类重写
64
+ */
65
+ public pushElement(element: T) {
66
+ this._future.length = 0;
67
+ if (this._isOverflow(element)) {
68
+ this._past.shift();
69
+ }
70
+ if (this._currentState) {
71
+ this._past.push(this._currentState);
72
+ }
73
+ this._currentState = element;
74
+ this._onStackChange.fire();
75
+ }
76
+
77
+ /**
78
+ * 是否可以撤销
79
+ */
80
+ public canUndo(): boolean {
81
+ return this._past.length > 0;
82
+ }
83
+
84
+ /**
85
+ * 是否可以重做
86
+ */
87
+ public canRedo(): boolean {
88
+ return this._future.length > 0;
89
+ }
90
+
91
+ /**
92
+ * 清除undo
93
+ */
94
+ public clearUndo(): void {
95
+ if (this._past.length === 0) {
96
+ return;
97
+ }
98
+ this._past.length = 0;
99
+ this._onStackChange.fire();
100
+ }
101
+
102
+ /**
103
+ * 清除redo
104
+ */
105
+ public clearRedo(): void {
106
+ if (this._future.length === 0) {
107
+ return;
108
+ }
109
+ this._future.length = 0;
110
+ this._onStackChange.fire();
111
+ }
112
+
113
+ /**
114
+ * 重置栈
115
+ * 清空undo和redo
116
+ */
117
+ public reset(state: T): void {
118
+ if (this._past.length === 0 && this._future.length === 0 && this._currentState === state) {
119
+ return;
120
+ }
121
+ this._past.length = 0;
122
+ this._future.length = 0;
123
+ this._currentState = state;
124
+ this._onStackChange.fire();
125
+ }
126
+
127
+ /**
128
+ * 判断新添加元素,是否会超出栈的大小
129
+ */
130
+ protected _isOverflow(_elem: T) {
131
+ return this._past.length >= this._limitSize;
132
+ }
133
+ }
@@ -0,0 +1,7 @@
1
+ export { uuid } from './uuid';
2
+ export { upperCaseUuid } from './uuid';
3
+
4
+ export { generateUuid } from './uuid';
5
+ export { generateUpperCaseUuid } from './uuid';
6
+
7
+ export { isUuid } from './uuid';
@@ -0,0 +1,86 @@
1
+ declare const crypto:
2
+ | undefined
3
+ | {
4
+ // https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#browser_compatibility
5
+ getRandomValues?: (data: Uint8Array) => Uint8Array;
6
+ // https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID#browser_compatibility
7
+ randomUUID?: () => UuidString;
8
+ };
9
+
10
+ const pattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11
+
12
+ type UuidString = `${string}-${string}-${string}-${string}-${string}`;
13
+
14
+ /**
15
+ * 判断一个字符串,是否是标准的UUID
16
+ */
17
+ export function isUuid(value: string): boolean {
18
+ return pattern.test(value);
19
+ }
20
+
21
+ /**
22
+ * 生成一个标准的UUID
23
+ */
24
+ export const generateUuid = ((): (() => UuidString) => {
25
+ // 优先使用 randomUUID
26
+ if (typeof crypto === 'object' && typeof crypto.randomUUID === 'function') {
27
+ return crypto.randomUUID.bind(crypto);
28
+ }
29
+
30
+ // 其次尝试使用 randomValues
31
+ let getRandomValues: (bucket: Uint8Array) => Uint8Array;
32
+ if (typeof crypto === 'object' && typeof crypto.getRandomValues === 'function') {
33
+ getRandomValues = crypto.getRandomValues.bind(crypto);
34
+ } else {
35
+ getRandomValues = function (bucket: Uint8Array): Uint8Array {
36
+ for (let i = 0; i < bucket.length; i++) {
37
+ bucket[i] = Math.floor(Math.random() * 256);
38
+ }
39
+ return bucket;
40
+ };
41
+ }
42
+
43
+ const data = new Uint8Array(16);
44
+ const hex: string[] = [];
45
+ for (let i = 0; i < 256; i++) {
46
+ hex.push(i.toString(16).padStart(2, '0'));
47
+ }
48
+
49
+ return (): UuidString => {
50
+ getRandomValues(data);
51
+
52
+ data[6] = (data[6] & 0x0f) | 0x40;
53
+ data[8] = (data[8] & 0x3f) | 0x80;
54
+
55
+ let i = 0;
56
+ let result = '';
57
+ result += hex[data[i++]];
58
+ result += hex[data[i++]];
59
+ result += hex[data[i++]];
60
+ result += hex[data[i++]];
61
+ result += '-';
62
+ result += hex[data[i++]];
63
+ result += hex[data[i++]];
64
+ result += '-';
65
+ result += hex[data[i++]];
66
+ result += hex[data[i++]];
67
+ result += '-';
68
+ result += hex[data[i++]];
69
+ result += hex[data[i++]];
70
+ result += '-';
71
+ result += hex[data[i++]];
72
+ result += hex[data[i++]];
73
+ result += hex[data[i++]];
74
+ result += hex[data[i++]];
75
+ result += hex[data[i++]];
76
+ result += hex[data[i++]];
77
+ return result as UuidString;
78
+ };
79
+ })();
80
+
81
+ /**
82
+ * 生成一个标准且字母大写的UUID
83
+ */
84
+ export const generateUpperCaseUuid = () => generateUuid().toUpperCase();
85
+ export const uuid = generateUuid;
86
+ export const upperCaseUuid = generateUpperCaseUuid;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * 将 worker 转 inline worker 的帮助函数,为了性能考虑,SCM 会在构建线上项目时将资源依赖都打包上传到 cdn 处。
3
+ * 包括 worker.js,但是这种策略违反同源加载策略。所以为了应对这种问题,我们需要将 worker 进行强制内联处理.
4
+ *
5
+ * 由于 webpack AST 的约束限制.必须严格使用以下语法申明 worker:
6
+ * new Worker(new URL('xxx.js', import.meta.url)
7
+ * 字符上必须严格匹配。所以导入使用 CorsWorker 时,需要将其强行 alias
8
+ * import { CorsWorker as Worker } from '@byted-image/lv-bedrock/worker';
9
+ * )
10
+ */
11
+ import type { IDisposable } from '@/dispose';
12
+
13
+ export class CorsWorker implements IDisposable {
14
+ private readonly _worker: Worker;
15
+
16
+ constructor(url: string | URL) {
17
+ const absoluteUrl = new URL(url, window.location.href).toString();
18
+ const workerSource = `\
19
+ const urlString = ${JSON.stringify(absoluteUrl)}
20
+ const originURL = new URL(urlString)
21
+ const originalImportScripts = self.importScripts
22
+ self.importScripts = (url) => originalImportScripts.call(self, new URL(url, originURL).toString())
23
+ importScripts(urlString);
24
+ `;
25
+ const blob = new Blob([workerSource], { type: 'application/javascript' });
26
+ const objectURL = URL.createObjectURL(blob);
27
+ this._worker = new Worker(objectURL);
28
+ URL.revokeObjectURL(objectURL);
29
+ }
30
+
31
+ getWorker() {
32
+ return this._worker;
33
+ }
34
+
35
+ dispose(): void {
36
+ this._worker.terminate();
37
+ }
38
+ }
@@ -0,0 +1,4 @@
1
+ export { CorsWorker } from './cors-worker';
2
+ export { PromiseWorkerWorkerThread } from './promise-worker-worker-thread';
3
+ export { PromiseWorkerMainThread } from './promise-worker-main-thread';
4
+ export type { PromiseWorkerRequest, PromiseWorkerResponse } from './promise-worker.interface';
@@ -0,0 +1 @@
1
+ {"version":"1.0.1","results":[[":promise-worker-main-thread.test.ts",{"duration":3,"failed":false}]]}
@@ -0,0 +1,91 @@
1
+ import { lvAssert } from '@/assert';
2
+ import { PromiseWorkerMainThread } from './promise-worker-main-thread';
3
+
4
+ class MockWebWorker {
5
+ public onmessage: ((e: MessageEvent) => void) | null = null;
6
+ public postMessage!: (message: any) => void;
7
+
8
+ constructor(postMessage: any) {
9
+ this.postMessage = postMessage;
10
+ }
11
+
12
+ triggerMessage(e: MessageEvent) {
13
+ this.onmessage!(e);
14
+ }
15
+
16
+ terminate() {
17
+ // ...
18
+ }
19
+ }
20
+
21
+ describe('promise-worker-main-thread', () => {
22
+ // 普通open
23
+ test('base1', async () => {
24
+ const fn1 = vi.fn();
25
+ const postMessageFn = vi.fn();
26
+
27
+ const worker = new MockWebWorker(postMessageFn);
28
+ worker.onmessage = fn1;
29
+ const mainThread = new PromiseWorkerMainThread(worker as any as Worker);
30
+
31
+ const task = {};
32
+ const defer = mainThread.sendTaskToWorker(task);
33
+ expect(postMessageFn).toBeCalledWith(expect.objectContaining(task));
34
+
35
+ const [firstArg] = postMessageFn.mock.calls[0];
36
+
37
+ const resp = {
38
+ pid: firstArg.pid,
39
+ code: 0,
40
+ data: 1,
41
+ };
42
+ const resp1 = {
43
+ pid: `${firstArg.pid}1111`,
44
+ code: 0,
45
+ data: 1,
46
+ };
47
+ // @ts-expect-error type error 不去模拟完整的 MessageEvent 对象了。就将就一个用到的数据结构算了
48
+ expect(() => worker.onmessage({ data: resp1 })).toThrowError();
49
+ expect(fn1).toBeCalledWith({ data: resp1 }); // 外面的监听正常触发
50
+
51
+ await new Promise(process.nextTick);
52
+
53
+ // @ts-expect-error type error
54
+ worker.onmessage({ data: resp });
55
+ expect(fn1).toBeCalledWith({ data: resp }); // 外面的监听正常触发
56
+ await new Promise(process.nextTick);
57
+
58
+ const res = await defer;
59
+ expect(res.ok).toBe(true);
60
+ lvAssert(res.ok)
61
+ expect(res.code).toBe(0);
62
+ expect(res.value).toBe(resp.data);
63
+ });
64
+
65
+ test('reject', async () => {
66
+ const fn1 = vi.fn();
67
+ const postMessageFn = vi.fn();
68
+
69
+ const worker = new MockWebWorker(postMessageFn);
70
+ worker.onmessage = fn1;
71
+ const mainThread = new PromiseWorkerMainThread(worker as any as Worker);
72
+
73
+ const task = {};
74
+ const defer = mainThread.sendTaskToWorker(task);
75
+ expect(postMessageFn).toBeCalledWith(expect.objectContaining(task));
76
+
77
+ const [firstArg] = postMessageFn.mock.calls[0];
78
+ const resp = {
79
+ pid: firstArg.pid,
80
+ code: -1,
81
+ msg: 'error',
82
+ };
83
+ // @ts-expect-error type error 不去模拟完整的 MessageEvent 对象了。就将就一个用到的数据结构算了
84
+ worker.onmessage({ data: resp });
85
+
86
+ const res = await defer;
87
+ expect(res.ok).toBe(false);
88
+ expect(res.code).toBe(-1);
89
+ expect(res.msg).toBe('error');
90
+ });
91
+ });