@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,95 @@
1
+ import { sprintf } from './sprintf';
2
+
3
+ describe('sprintf', () => {
4
+ it('case1', () => {
5
+ expect(sprintf('lvweb yyds!!')).toBe('lvweb yyds!!');
6
+ });
7
+
8
+ // 没有传递参数,不进入匹配模式
9
+ it('case2', () => {
10
+ expect(sprintf('lv%% %dweb yyds!!')).toBe('lv%% %dweb yyds!!');
11
+ });
12
+
13
+ // 匹配数值
14
+ it('case3', () => {
15
+ expect(sprintf('lvweb %d yyds!!', 666)).toBe('lvweb 666 yyds!!');
16
+ });
17
+
18
+ // 匹配非数值
19
+ it('case4', () => {
20
+ expect(sprintf('lvweb %d yyds!!', 'not number')).toBe('lvweb NaN yyds!!');
21
+ });
22
+
23
+ // 匹配浮点数
24
+ it('case5', () => {
25
+ expect(sprintf('lvweb %d yyds!!', 1.888)).toBe('lvweb 1.888 yyds!!');
26
+ });
27
+
28
+ // 匹配字符串
29
+ it('case6', () => {
30
+ expect(sprintf('lvweb %s yyds!!', 'dddd')).toBe('lvweb dddd yyds!!');
31
+ });
32
+
33
+ // 匹配布尔
34
+ it('case7', () => {
35
+ expect(sprintf('lvweb %b yyds!!', true)).toBe('lvweb true yyds!!');
36
+ });
37
+
38
+ // 匹配布尔
39
+ it('case8', () => {
40
+ expect(sprintf('lvweb %b yyds!!', false)).toBe('lvweb false yyds!!');
41
+ });
42
+
43
+ // 转义%
44
+ it('case9', () => {
45
+ expect(sprintf('lvweb %% %s yyds!!', 'run')).toBe('lvweb % run yyds!!');
46
+ });
47
+
48
+ // 匹配对象
49
+ it('case10', () => {
50
+ expect(sprintf('lvweb %v yyds!!', { foo: 'bar' })).toBe('lvweb {"foo":"bar"} yyds!!');
51
+ });
52
+
53
+ it('case11', () => {
54
+ expect(sprintf('lvweb %v yyds!!', 233)).toBe('lvweb 233 yyds!!');
55
+ });
56
+
57
+ it('case12', () => {
58
+ expect(sprintf('lvweb %v yyds!!', false)).toBe('lvweb false yyds!!');
59
+ });
60
+
61
+ it('case13', () => {
62
+ expect(sprintf('lvweb %v yyds!!', 'dddd')).toBe('lvweb "dddd" yyds!!');
63
+ });
64
+
65
+ // 匹配对象,序列化错误
66
+ it('case14', () => {
67
+ const a: { [key: string]: any } = {};
68
+ a.a = a;
69
+ expect(sprintf('lvweb %v yyds!!', a)).toBe('[invalid formatted message]lvweb %v yyds!!');
70
+ });
71
+
72
+ // 匹配很多
73
+ it('case15', () => {
74
+ expect(sprintf('lvweb %d %b %s %v!!', 233, true, 'yyds', { foo: 'bar' })).toBe(
75
+ 'lvweb 233 true yyds {"foo":"bar"}!!',
76
+ );
77
+ });
78
+
79
+ // 参数数量对不上
80
+ it('case16', () => {
81
+ expect(sprintf('lvweb %d %b %s %s %v!!', 233, true, 'yyds', { foo: 'bar' })).toBe(
82
+ 'lvweb 233 true yyds [object Object] undefined!!',
83
+ );
84
+ });
85
+
86
+ // 参数数量多了,多余部分追加
87
+ it('case17', () => {
88
+ expect(sprintf('lvweb', 233, true, 'yyds', { foo: 'bar' })).toBe('lvweb 233 true yyds [object Object]');
89
+ });
90
+
91
+ // 参数数量多了,多余部分追加
92
+ it('case18', () => {
93
+ expect(sprintf('lvweb %d!!', 233, true, 'yyds')).toBe('lvweb 233!! true yyds');
94
+ });
95
+ });
@@ -0,0 +1,97 @@
1
+ import { lvAssertNotHere } from '../assert';
2
+
3
+ const regex = {
4
+ text: /^[^\x25]+/, // \x25 是 % 的十六进制表示
5
+ modulo: /^\x25\x25/, // %%转义
6
+ placeholder: /^\x25([vVbBdDsS])/,
7
+ };
8
+
9
+ type ParseResult = (string | { placeholder: string })[];
10
+
11
+ const cache = new Map<string, ParseResult>();
12
+
13
+ function parse(str: string) {
14
+ const result: ParseResult = [];
15
+ if (cache.has(str)) {
16
+ return cache.get(str)!;
17
+ }
18
+ let sub = str;
19
+ while (sub) {
20
+ let match = regex.text.exec(sub);
21
+ if (match) {
22
+ result.push(match[0]);
23
+ sub = sub.substring(match[0].length);
24
+ continue;
25
+ }
26
+ match = regex.modulo.exec(sub);
27
+ if (match) {
28
+ result.push('%');
29
+ sub = sub.substring(match[0].length);
30
+ continue;
31
+ }
32
+
33
+ // 一定匹配到了占位符
34
+ match = regex.placeholder.exec(sub);
35
+ if (match && match.length > 1) {
36
+ result.push({
37
+ placeholder: match[1],
38
+ });
39
+ sub = sub.substring(match[0].length);
40
+ } else {
41
+ lvAssertNotHere();
42
+ }
43
+ }
44
+ cache.set(str, result);
45
+ return result;
46
+ }
47
+
48
+ function replace(parseResult: ParseResult, ...args: any[]) {
49
+ let message = '';
50
+ let index = 0;
51
+ for (const t of parseResult) {
52
+ if (typeof t === 'string') {
53
+ message += t;
54
+ continue;
55
+ }
56
+
57
+ if (args[index] === undefined) {
58
+ message += 'undefined';
59
+ continue;
60
+ }
61
+
62
+ switch (t.placeholder.toLowerCase()) {
63
+ case 's':
64
+ message += String(args[index++]);
65
+ break;
66
+ case 'd':
67
+ message += Number(args[index++] as number);
68
+ break;
69
+ case 'b':
70
+ message += args[index++] as boolean;
71
+ break;
72
+ case 'v':
73
+ message += JSON.stringify(args[index++]);
74
+ break;
75
+ default:
76
+ lvAssertNotHere();
77
+ }
78
+ }
79
+ for (; index < args.length; index++) {
80
+ message += ` ${args[index]}`;
81
+ }
82
+
83
+ return message;
84
+ }
85
+
86
+ export function sprintf(message: string, ...args: any[]) {
87
+ if (!args.length) {
88
+ return message;
89
+ }
90
+ try {
91
+ const parseResult = parse(message);
92
+ const formatted = replace(parseResult, ...args);
93
+ return formatted;
94
+ } catch (e) {
95
+ return `[invalid formatted message]${message}`;
96
+ }
97
+ }
@@ -0,0 +1,181 @@
1
+ /* eslint-disable max-lines-per-function */
2
+ import { Graph } from './graph';
3
+
4
+ describe('Graph', () => {
5
+ let graph: Graph<string, string>;
6
+
7
+ beforeEach(() => {
8
+ graph = new Graph<string, string>((v) => v);
9
+ });
10
+
11
+ it('should create an empty graph', () => {
12
+ expect(graph.isEmpty()).toBe(true);
13
+ expect(graph.toString()).toBe('');
14
+ });
15
+
16
+ it('should add nodes to the graph', () => {
17
+ const nodeA = graph.lookupOrInsertNode('A');
18
+ const nodeB = graph.lookupOrInsertNode('B');
19
+ const nodeC = graph.lookupOrInsertNode('C');
20
+
21
+ expect(graph.isEmpty()).toBe(false);
22
+ expect(graph.toString().replace(/\s/g, '')).toBe(
23
+ `
24
+ A
25
+ (-> incoming)[]
26
+ (outgoing ->)[]
27
+
28
+ B
29
+ (-> incoming)[]
30
+ (outgoing ->)[]
31
+
32
+ C
33
+ (-> incoming)[]
34
+ (outgoing ->)[]`.replace(/\s/g, ''),
35
+ );
36
+
37
+ expect(nodeA).toBe(graph.lookup('A'));
38
+ expect(nodeB).toBe(graph.lookup('B'));
39
+ expect(nodeC).toBe(graph.lookup('C'));
40
+ });
41
+
42
+ it('should add edges to the graph', () => {
43
+ const nodeA = graph.lookupOrInsertNode('A');
44
+ const nodeB = graph.lookupOrInsertNode('B');
45
+ const nodeC = graph.lookupOrInsertNode('C');
46
+
47
+ graph.insertEdge(nodeA.data, nodeB.data);
48
+ graph.insertEdge(nodeA.data, nodeC.data);
49
+
50
+ expect(graph.toString().replace(/\s/g, '')).toBe(
51
+ `
52
+ A
53
+ (-> incoming)[]
54
+ (outgoing ->)[B,C]
55
+
56
+ B
57
+ (-> incoming)[A]
58
+ (outgoing ->)[]
59
+
60
+ C
61
+ (-> incoming)[A]
62
+ (outgoing ->)[]`.replace(/\s/g, ''),
63
+ );
64
+ });
65
+
66
+ it('should remove nodes and edges from the graph', () => {
67
+ const nodeA = graph.lookupOrInsertNode('A');
68
+ const nodeB = graph.lookupOrInsertNode('B');
69
+ const nodeC = graph.lookupOrInsertNode('C');
70
+ const nodeD = graph.lookupOrInsertNode('D');
71
+
72
+ expect(graph.isEmpty()).toBe(false);
73
+ expect(graph.toString().replace(/\s/g, '')).toBe(
74
+ `
75
+ A
76
+ (-> incoming)[]
77
+ (outgoing ->)[]
78
+
79
+ B
80
+ (-> incoming)[]
81
+ (outgoing ->)[]
82
+
83
+ C
84
+ (-> incoming)[]
85
+ (outgoing ->)[]
86
+
87
+ D
88
+ (-> incoming)[]
89
+ (outgoing ->)[]`.replace(/\s/g, ''),
90
+ );
91
+
92
+ graph.insertEdge(nodeA.data, nodeB.data);
93
+ graph.insertEdge(nodeA.data, nodeC.data);
94
+ graph.insertEdge(nodeB.data, nodeD.data);
95
+ graph.insertEdge(nodeC.data, nodeD.data);
96
+
97
+ expect(graph.toString().replace(/\s/g, '')).toBe(
98
+ `
99
+ A
100
+ (-> incoming)[]
101
+ (outgoing ->)[B,C]
102
+
103
+ B
104
+ (-> incoming)[A]
105
+ (outgoing ->)[D]
106
+
107
+ C
108
+ (-> incoming)[A]
109
+ (outgoing ->)[D]
110
+
111
+ D
112
+ (-> incoming)[B, C]
113
+ (outgoing ->)[]`.replace(/\s/g, ''),
114
+ );
115
+
116
+ graph.removeNode(nodeC.data);
117
+ expect(graph.toString().replace(/\s/g, '')).toBe(
118
+ `
119
+ A
120
+ (-> incoming)[]
121
+ (outgoing ->)[B]
122
+
123
+ B
124
+ (-> incoming)[A]
125
+ (outgoing ->)[D]
126
+
127
+ D
128
+ (-> incoming)[B]
129
+ (outgoing ->)[]`.replace(/\s/g, ''),
130
+ );
131
+
132
+ graph.removeNode(nodeD.data);
133
+ expect(graph.toString().replace(/\s/g, '')).toBe(
134
+ `
135
+ A
136
+ (-> incoming)[]
137
+ (outgoing ->)[B]
138
+
139
+ B
140
+ (-> incoming)[A]
141
+ (outgoing ->)[]`.replace(/\s/g, ''),
142
+ );
143
+
144
+ graph.removeNode(nodeA.data);
145
+ expect(graph.toString().replace(/\s/g, '')).toBe(
146
+ `
147
+ B
148
+ (-> incoming)[]
149
+ (outgoing ->)[]`.replace(/\s/g, ''),
150
+ );
151
+
152
+ graph.removeNode(nodeB.data);
153
+ expect(graph.isEmpty()).toBe(true);
154
+ });
155
+
156
+ it('should find the leafs of a graph', () => {
157
+ const nodeA = graph.lookupOrInsertNode('A');
158
+ const nodeB = graph.lookupOrInsertNode('B');
159
+ const nodeC = graph.lookupOrInsertNode('C');
160
+ const nodeD = graph.lookupOrInsertNode('D');
161
+
162
+ graph.insertEdge(nodeA.data, nodeB.data);
163
+ graph.insertEdge(nodeA.data, nodeC.data);
164
+ graph.insertEdge(nodeB.data, nodeD.data);
165
+ graph.insertEdge(nodeC.data, nodeD.data);
166
+
167
+ expect(graph.leafs().length).toBe(1);
168
+ expect(graph.leafs()[0].data).toBe(nodeD.data);
169
+
170
+ graph.removeNode(nodeA.data);
171
+
172
+ expect(graph.leafs().length).toBe(1);
173
+ expect(graph.leafs()[0].data).toBe(nodeD.data);
174
+
175
+ graph.removeNode(nodeD.data);
176
+
177
+ expect(graph.leafs().length).toBe(2);
178
+ expect(graph.leafs()[0].data).toBe(nodeB.data);
179
+ expect(graph.leafs()[1].data).toBe(nodeC.data);
180
+ });
181
+ });
@@ -0,0 +1,105 @@
1
+ class Node<K, T> {
2
+ readonly incoming = new Map<K, Node<K, T>>();
3
+ readonly outgoing = new Map<K, Node<K, T>>();
4
+
5
+ constructor(
6
+ public key: K,
7
+ public data: T,
8
+ ) {}
9
+ }
10
+
11
+ export class Graph<K, T> {
12
+ private readonly _nodes = new Map<K, Node<K, T>>();
13
+
14
+ constructor(private readonly _hashFn: (element: T) => K) {}
15
+
16
+ // 寻找所有的叶子节点
17
+ public leafs(): Node<K, T>[] {
18
+ const ret: Node<K, T>[] = [];
19
+ for (const node of this._nodes.values()) {
20
+ if (node.outgoing.size === 0) {
21
+ ret.push(node);
22
+ }
23
+ }
24
+ return ret;
25
+ }
26
+
27
+ // 插入一条边
28
+ public insertEdge(from: T, to: T): void {
29
+ const fromNode = this.lookupOrInsertNode(from);
30
+ const toNode = this.lookupOrInsertNode(to);
31
+
32
+ fromNode.outgoing.set(toNode.key, toNode);
33
+ toNode.incoming.set(fromNode.key, fromNode);
34
+ }
35
+
36
+ // 移除某个节点
37
+ public removeNode(data: T): void {
38
+ const key = this._hashFn(data);
39
+ this._nodes.delete(key);
40
+ for (const node of this._nodes.values()) {
41
+ node.outgoing.delete(key);
42
+ node.incoming.delete(key);
43
+ }
44
+ }
45
+
46
+ // 查找某个节点
47
+ public lookup(data: T): Node<K, T> | undefined {
48
+ return this._nodes.get(this._hashFn(data));
49
+ }
50
+
51
+ // 查找某个节点,不存在则插入
52
+ public lookupOrInsertNode(data: T): Node<K, T> {
53
+ const key = this._hashFn(data);
54
+ let node = this._nodes.get(key);
55
+
56
+ if (!node) {
57
+ node = new Node(key, data);
58
+ this._nodes.set(key, node);
59
+ }
60
+
61
+ return node;
62
+ }
63
+
64
+ public isEmpty(): boolean {
65
+ return this._nodes.size === 0;
66
+ }
67
+
68
+ public toString(): string {
69
+ const data: string[] = [];
70
+ for (const [key, value] of this._nodes) {
71
+ data.push(
72
+ `${key}\n\t(-> incoming)[${[...value.incoming.keys()].join(', ')}]\n\t(outgoing ->)[${[
73
+ ...value.outgoing.keys(),
74
+ ].join(',')}]\n`,
75
+ );
76
+ }
77
+ return data.join('\n');
78
+ }
79
+
80
+ public findCycleSlow() {
81
+ for (const [id, node] of this._nodes) {
82
+ const seen = new Set<K>([id]);
83
+ const res = this._findCycle(node, seen);
84
+ if (res) {
85
+ return res;
86
+ }
87
+ }
88
+ return undefined;
89
+ }
90
+
91
+ private _findCycle(node: Node<K, T>, seen: Set<K>): string | undefined {
92
+ for (const [id, outgoing] of node.outgoing) {
93
+ if (seen.has(id)) {
94
+ return [...seen, id].join(' -> ');
95
+ }
96
+ seen.add(id);
97
+ const value = this._findCycle(outgoing, seen);
98
+ if (value) {
99
+ return value;
100
+ }
101
+ seen.delete(id);
102
+ }
103
+ return undefined;
104
+ }
105
+ }
@@ -0,0 +1,8 @@
1
+ // 有向图
2
+ export { Graph } from './graph';
3
+
4
+ // 双向链表
5
+ export { LinkedList } from './linked-list';
6
+
7
+ // 小顶堆
8
+ export { MinHeap } from './min-heap';
@@ -0,0 +1,74 @@
1
+ import { LinkedList } from './linked-list';
2
+
3
+ describe('LinkedList', () => {
4
+ let list: LinkedList<number>;
5
+
6
+ beforeEach(() => {
7
+ list = new LinkedList<number>();
8
+ });
9
+
10
+ it('isEmpty should return true for an empty list', () => {
11
+ expect(list.isEmpty()).toBe(true);
12
+ });
13
+
14
+ it('isEmpty should return false when the list contains elements', () => {
15
+ list.push(1);
16
+
17
+ expect(list.isEmpty()).toBe(false);
18
+ });
19
+
20
+ it('clear should remove all elements from the list', () => {
21
+ list.push(1);
22
+ list.push(2);
23
+ list.push(3);
24
+ list.clear();
25
+
26
+ expect(list.isEmpty()).toBe(true);
27
+ });
28
+
29
+ it('unshift should add elements to the front of the list', () => {
30
+ list.unshift(1);
31
+ list.unshift(2);
32
+ list.unshift(3);
33
+
34
+ expect(list.toArray()).toEqual([3, 2, 1]);
35
+ });
36
+
37
+ it('push should add elements to the end of the list', () => {
38
+ list.push(1);
39
+ list.push(2);
40
+ list.push(3);
41
+
42
+ expect(list.toArray()).toEqual([1, 2, 3]);
43
+ });
44
+
45
+ it('shift should remove and return the first element of the list', () => {
46
+ list.push(1);
47
+ list.push(2);
48
+ list.push(3);
49
+
50
+ const value = list.shift();
51
+ expect(value).toBe(1);
52
+ expect(list.toArray()).toEqual([2, 3]);
53
+ });
54
+
55
+ it('shift should return undefined for an empty list', () => {
56
+ const value = list.shift();
57
+ expect(value).toBeNull();
58
+ });
59
+
60
+ it('pop should remove and return the last element of the list', () => {
61
+ list.push(1);
62
+ list.push(2);
63
+ list.push(3);
64
+
65
+ const value = list.pop();
66
+ expect(value).toBe(3);
67
+ expect(list.toArray()).toEqual([1, 2]);
68
+ });
69
+
70
+ it('pop should return undefined for an empty list', () => {
71
+ const value = list.pop();
72
+ expect(value).toBeNull();
73
+ });
74
+ });
@@ -0,0 +1,145 @@
1
+ class ListNode<T> {
2
+ constructor(
3
+ public value: T,
4
+ public next: ListNode<T> | null = null,
5
+ public prev: ListNode<T> | null = null,
6
+ ) {}
7
+ }
8
+
9
+ export class LinkedList<T> {
10
+ protected _head: ListNode<T> | null = null;
11
+ protected _tail: ListNode<T> | null = null;
12
+ protected _count = 0;
13
+
14
+ public get size(): number {
15
+ return this._count;
16
+ }
17
+
18
+ public get firstNode(): ListNode<T> | null {
19
+ return this._head;
20
+ }
21
+
22
+ public isEmpty(): boolean {
23
+ return this._head === null;
24
+ }
25
+
26
+ public clear(): void {
27
+ let current = this._head;
28
+ while (current !== null) {
29
+ const next = current.next;
30
+ current.prev = null;
31
+ current.next = null;
32
+ current = next;
33
+ }
34
+
35
+ this._head = null;
36
+ this._tail = null;
37
+ this._count = 0;
38
+ }
39
+
40
+ public unshift(value: T): LinkedList<T> {
41
+ const node = new ListNode(value);
42
+
43
+ if (this.isEmpty()) {
44
+ this._head = node;
45
+ this._tail = node;
46
+ } else {
47
+ const oldHead = this._head;
48
+ this._head = node;
49
+ node.next = oldHead;
50
+ oldHead!.prev = node;
51
+ }
52
+
53
+ this._count++;
54
+ return this;
55
+ }
56
+
57
+ public push(value: T): LinkedList<T> {
58
+ const node = new ListNode(value);
59
+
60
+ if (this.isEmpty()) {
61
+ this._head = node;
62
+ this._tail = node;
63
+ } else {
64
+ const oldTail = this._tail;
65
+ this._tail = node;
66
+ node.prev = oldTail;
67
+ oldTail!.next = node;
68
+ }
69
+
70
+ this._count++;
71
+ return this;
72
+ }
73
+
74
+ public shift(): T | null {
75
+ if (this.isEmpty()) {
76
+ return null;
77
+ }
78
+
79
+ const node = this._head!;
80
+ const value = node.value;
81
+ this._remove(node);
82
+ return value;
83
+ }
84
+
85
+ public pop(): T | null {
86
+ if (this.isEmpty()) {
87
+ return null;
88
+ }
89
+
90
+ const node = this._tail!;
91
+ const value = node.value;
92
+ this._remove(node);
93
+ return value;
94
+ }
95
+
96
+ public toArray(): T[] {
97
+ const result: T[] = [];
98
+ for (const value of this) {
99
+ result.push(value);
100
+ }
101
+ return result;
102
+ }
103
+
104
+ public *[Symbol.iterator](): Iterator<T> {
105
+ let current = this._head;
106
+ while (current !== null) {
107
+ yield current.value;
108
+ current = current.next;
109
+ }
110
+ }
111
+
112
+ protected _remove(node: ListNode<T>): void {
113
+ // 如果节点已经被移除(prev 和 next 都为 null),直接返回
114
+ if (node.prev === null && node.next === null && node !== this._head && node !== this._tail) {
115
+ return;
116
+ }
117
+
118
+ // 更新链表头尾指针
119
+ if (node === this._head) {
120
+ this._head = node.next;
121
+ if (this._head) {
122
+ this._head.prev = null;
123
+ }
124
+ }
125
+ if (node === this._tail) {
126
+ this._tail = node.prev;
127
+ if (this._tail) {
128
+ this._tail.next = null;
129
+ }
130
+ }
131
+
132
+ // 更新相邻节点的引用
133
+ if (node.prev) {
134
+ node.prev.next = node.next;
135
+ }
136
+ if (node.next) {
137
+ node.next.prev = node.prev;
138
+ }
139
+
140
+ // 清理被移除节点的引用
141
+ node.prev = null;
142
+ node.next = null;
143
+ this._count--;
144
+ }
145
+ }