@bluelibs/runner 3.4.2 → 4.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 (375) hide show
  1. package/AI.md +621 -0
  2. package/README.md +1024 -577
  3. package/dist/context.d.ts +4 -8
  4. package/dist/context.js +5 -12
  5. package/dist/context.js.map +1 -1
  6. package/dist/define.d.ts +9 -113
  7. package/dist/define.js +29 -358
  8. package/dist/define.js.map +1 -1
  9. package/dist/definers/defineEvent.d.ts +2 -0
  10. package/dist/definers/defineEvent.js +23 -0
  11. package/dist/definers/defineEvent.js.map +1 -0
  12. package/dist/definers/defineHook.d.ts +6 -0
  13. package/dist/definers/defineHook.js +24 -0
  14. package/dist/definers/defineHook.js.map +1 -0
  15. package/dist/definers/defineOverride.d.ts +14 -0
  16. package/dist/definers/defineOverride.js +13 -0
  17. package/dist/definers/defineOverride.js.map +1 -0
  18. package/dist/definers/defineResource.d.ts +2 -0
  19. package/dist/definers/defineResource.js +69 -0
  20. package/dist/definers/defineResource.js.map +1 -0
  21. package/dist/definers/defineResourceMiddleware.d.ts +2 -0
  22. package/dist/definers/defineResourceMiddleware.js +42 -0
  23. package/dist/definers/defineResourceMiddleware.js.map +1 -0
  24. package/dist/definers/defineTag.d.ts +12 -0
  25. package/dist/definers/defineTag.js +106 -0
  26. package/dist/definers/defineTag.js.map +1 -0
  27. package/dist/definers/defineTask.d.ts +15 -0
  28. package/dist/definers/defineTask.js +42 -0
  29. package/dist/definers/defineTask.js.map +1 -0
  30. package/dist/definers/defineTaskMiddleware.d.ts +2 -0
  31. package/dist/definers/defineTaskMiddleware.js +42 -0
  32. package/dist/definers/defineTaskMiddleware.js.map +1 -0
  33. package/dist/definers/tools.d.ts +45 -0
  34. package/dist/definers/tools.js +75 -0
  35. package/dist/definers/tools.js.map +1 -0
  36. package/dist/defs.d.ts +16 -424
  37. package/dist/defs.js +26 -38
  38. package/dist/defs.js.map +1 -1
  39. package/dist/errors.d.ts +23 -8
  40. package/dist/errors.js +50 -10
  41. package/dist/errors.js.map +1 -1
  42. package/dist/globals/globalEvents.d.ts +15 -39
  43. package/dist/globals/globalEvents.js +20 -81
  44. package/dist/globals/globalEvents.js.map +1 -1
  45. package/dist/globals/globalMiddleware.d.ts +24 -17
  46. package/dist/globals/globalMiddleware.js +12 -4
  47. package/dist/globals/globalMiddleware.js.map +1 -1
  48. package/dist/globals/globalResources.d.ts +13 -28
  49. package/dist/globals/globalResources.js +15 -7
  50. package/dist/globals/globalResources.js.map +1 -1
  51. package/dist/globals/globalTags.d.ts +9 -0
  52. package/dist/globals/globalTags.js +23 -0
  53. package/dist/globals/globalTags.js.map +1 -0
  54. package/dist/globals/middleware/cache.middleware.d.ts +10 -17
  55. package/dist/globals/middleware/cache.middleware.js +4 -16
  56. package/dist/globals/middleware/cache.middleware.js.map +1 -1
  57. package/dist/globals/middleware/requireContext.middleware.d.ts +1 -1
  58. package/dist/globals/middleware/requireContext.middleware.js +5 -14
  59. package/dist/globals/middleware/requireContext.middleware.js.map +1 -1
  60. package/dist/globals/middleware/retry.middleware.d.ts +2 -1
  61. package/dist/globals/middleware/retry.middleware.js +32 -5
  62. package/dist/globals/middleware/retry.middleware.js.map +1 -1
  63. package/dist/globals/middleware/timeout.middleware.d.ts +2 -1
  64. package/dist/globals/middleware/timeout.middleware.js +31 -5
  65. package/dist/globals/middleware/timeout.middleware.js.map +1 -1
  66. package/dist/globals/resources/debug/debug.resource.d.ts +7 -0
  67. package/dist/globals/resources/debug/debug.resource.js +29 -0
  68. package/dist/globals/resources/debug/debug.resource.js.map +1 -0
  69. package/dist/globals/resources/debug/debug.tag.d.ts +2 -0
  70. package/dist/globals/resources/debug/debug.tag.js +12 -0
  71. package/dist/globals/resources/debug/debug.tag.js.map +1 -0
  72. package/dist/globals/resources/debug/debugConfig.resource.d.ts +22 -0
  73. package/dist/globals/resources/debug/debugConfig.resource.js +20 -0
  74. package/dist/globals/resources/debug/debugConfig.resource.js.map +1 -0
  75. package/dist/globals/resources/debug/executionTracker.middleware.d.ts +50 -0
  76. package/dist/globals/resources/debug/executionTracker.middleware.js +87 -0
  77. package/dist/globals/resources/debug/executionTracker.middleware.js.map +1 -0
  78. package/dist/globals/resources/debug/globalEvent.hook.d.ts +27 -0
  79. package/dist/globals/resources/debug/globalEvent.hook.js +38 -0
  80. package/dist/globals/resources/debug/globalEvent.hook.js.map +1 -0
  81. package/dist/globals/resources/debug/hook.hook.d.ts +25 -0
  82. package/dist/globals/resources/debug/hook.hook.js +42 -0
  83. package/dist/globals/resources/debug/hook.hook.js.map +1 -0
  84. package/dist/globals/resources/debug/index.d.ts +6 -0
  85. package/dist/{types → globals/resources/debug}/index.js +6 -11
  86. package/dist/globals/resources/debug/index.js.map +1 -0
  87. package/dist/globals/resources/debug/middleware.hook.d.ts +25 -0
  88. package/dist/globals/resources/debug/middleware.hook.js +71 -0
  89. package/dist/globals/resources/debug/middleware.hook.js.map +1 -0
  90. package/dist/globals/resources/debug/types.d.ts +25 -0
  91. package/dist/globals/resources/debug/types.js +65 -0
  92. package/dist/globals/resources/debug/types.js.map +1 -0
  93. package/dist/globals/resources/debug/utils.d.ts +2 -0
  94. package/dist/globals/resources/debug/utils.js +9 -0
  95. package/dist/globals/resources/debug/utils.js.map +1 -0
  96. package/dist/globals/resources/queue.resource.d.ts +3 -3
  97. package/dist/globals/resources/queue.resource.js.map +1 -1
  98. package/dist/globals/types.d.ts +1 -0
  99. package/dist/{task.types.js → globals/types.js} +2 -7
  100. package/dist/globals/types.js.map +1 -0
  101. package/dist/index.d.ts +58 -85
  102. package/dist/index.js +23 -10
  103. package/dist/index.js.map +1 -1
  104. package/dist/models/DependencyProcessor.d.ts +8 -6
  105. package/dist/models/DependencyProcessor.js +116 -33
  106. package/dist/models/DependencyProcessor.js.map +1 -1
  107. package/dist/models/EventManager.d.ts +127 -7
  108. package/dist/models/EventManager.js +251 -78
  109. package/dist/models/EventManager.js.map +1 -1
  110. package/dist/models/LogPrinter.d.ts +55 -0
  111. package/dist/models/LogPrinter.js +196 -0
  112. package/dist/models/LogPrinter.js.map +1 -0
  113. package/dist/models/Logger.d.ts +47 -27
  114. package/dist/models/Logger.js +133 -155
  115. package/dist/models/Logger.js.map +1 -1
  116. package/dist/models/MiddlewareManager.d.ts +86 -0
  117. package/dist/models/MiddlewareManager.js +409 -0
  118. package/dist/models/MiddlewareManager.js.map +1 -0
  119. package/dist/models/OverrideManager.d.ts +3 -3
  120. package/dist/models/OverrideManager.js +22 -7
  121. package/dist/models/OverrideManager.js.map +1 -1
  122. package/dist/models/ResourceInitializer.d.ts +4 -3
  123. package/dist/models/ResourceInitializer.js +12 -68
  124. package/dist/models/ResourceInitializer.js.map +1 -1
  125. package/dist/models/RunResult.d.ts +35 -0
  126. package/dist/models/RunResult.js +68 -0
  127. package/dist/models/RunResult.js.map +1 -0
  128. package/dist/models/Store.d.ts +30 -17
  129. package/dist/models/Store.js +87 -25
  130. package/dist/models/Store.js.map +1 -1
  131. package/dist/models/StoreRegistry.d.ts +34 -19
  132. package/dist/models/StoreRegistry.js +248 -100
  133. package/dist/models/StoreRegistry.js.map +1 -1
  134. package/dist/models/StoreValidator.d.ts +5 -7
  135. package/dist/models/StoreValidator.js +50 -17
  136. package/dist/models/StoreValidator.js.map +1 -1
  137. package/dist/models/TaskRunner.d.ts +3 -2
  138. package/dist/models/TaskRunner.js +6 -103
  139. package/dist/models/TaskRunner.js.map +1 -1
  140. package/dist/models/UnhandledError.d.ts +11 -0
  141. package/dist/models/UnhandledError.js +30 -0
  142. package/dist/models/UnhandledError.js.map +1 -0
  143. package/dist/models/index.d.ts +3 -0
  144. package/dist/models/index.js +3 -0
  145. package/dist/models/index.js.map +1 -1
  146. package/dist/{tools → models/utils}/findCircularDependencies.js +8 -16
  147. package/dist/models/utils/findCircularDependencies.js.map +1 -0
  148. package/dist/models/utils/safeStringify.d.ts +3 -0
  149. package/dist/models/utils/safeStringify.js +45 -0
  150. package/dist/models/utils/safeStringify.js.map +1 -0
  151. package/dist/processHooks.d.ts +2 -0
  152. package/dist/processHooks.js +70 -0
  153. package/dist/processHooks.js.map +1 -0
  154. package/dist/run.d.ts +14 -27
  155. package/dist/run.js +100 -36
  156. package/dist/run.js.map +1 -1
  157. package/dist/testing.d.ts +5 -4
  158. package/dist/testing.js +3 -2
  159. package/dist/testing.js.map +1 -1
  160. package/dist/tools/getCallerFile.d.ts +0 -8
  161. package/dist/tools/getCallerFile.js +0 -51
  162. package/dist/tools/getCallerFile.js.map +1 -1
  163. package/dist/types/contracts.d.ts +55 -0
  164. package/dist/types/contracts.js +4 -0
  165. package/dist/types/contracts.js.map +1 -0
  166. package/dist/types/event.d.ts +26 -7
  167. package/dist/types/event.js +1 -1
  168. package/dist/types/event.js.map +1 -1
  169. package/dist/types/hook.d.ts +21 -0
  170. package/dist/{models/StoreTypes.js → types/hook.js} +2 -1
  171. package/dist/types/hook.js.map +1 -0
  172. package/dist/types/meta.d.ts +6 -1
  173. package/dist/types/meta.js +4 -2
  174. package/dist/types/meta.js.map +1 -1
  175. package/dist/types/resource.d.ts +40 -52
  176. package/dist/types/resource.js +1 -0
  177. package/dist/types/resource.js.map +1 -1
  178. package/dist/types/resourceMiddleware.d.ts +47 -0
  179. package/dist/{middleware.types.js → types/resourceMiddleware.js} +1 -1
  180. package/dist/types/resourceMiddleware.js.map +1 -0
  181. package/dist/types/runner.d.ts +37 -0
  182. package/dist/types/{base.js → runner.js} +1 -1
  183. package/dist/types/runner.js.map +1 -0
  184. package/dist/types/storeTypes.d.ts +40 -0
  185. package/dist/types/{metadata.js → storeTypes.js} +1 -1
  186. package/dist/types/storeTypes.js.map +1 -0
  187. package/dist/types/symbols.d.ts +10 -21
  188. package/dist/types/symbols.js +17 -22
  189. package/dist/types/symbols.js.map +1 -1
  190. package/dist/types/tag.d.ts +46 -0
  191. package/dist/{resource.types.js → types/tag.js} +2 -1
  192. package/dist/types/tag.js.map +1 -0
  193. package/dist/types/task.d.ts +28 -52
  194. package/dist/types/task.js +1 -0
  195. package/dist/types/task.js.map +1 -1
  196. package/dist/types/taskMiddleware.d.ts +48 -0
  197. package/dist/{event.types.js → types/taskMiddleware.js} +1 -1
  198. package/dist/types/taskMiddleware.js.map +1 -0
  199. package/dist/types/utilities.d.ts +105 -6
  200. package/dist/types/utilities.js +16 -2
  201. package/dist/types/utilities.js.map +1 -1
  202. package/package.json +14 -5
  203. package/dist/cli/extract-docs.d.ts +0 -2
  204. package/dist/cli/extract-docs.js +0 -88
  205. package/dist/cli/extract-docs.js.map +0 -1
  206. package/dist/common.types.d.ts +0 -20
  207. package/dist/common.types.js +0 -4
  208. package/dist/common.types.js.map +0 -1
  209. package/dist/defs/core.d.ts +0 -144
  210. package/dist/defs/core.js +0 -6
  211. package/dist/defs/core.js.map +0 -1
  212. package/dist/defs/symbols.d.ts +0 -42
  213. package/dist/defs/symbols.js +0 -45
  214. package/dist/defs/symbols.js.map +0 -1
  215. package/dist/defs/tags.d.ts +0 -70
  216. package/dist/defs/tags.js +0 -6
  217. package/dist/defs/tags.js.map +0 -1
  218. package/dist/defs.returnTag.d.ts +0 -36
  219. package/dist/defs.returnTag.js +0 -4
  220. package/dist/defs.returnTag.js.map +0 -1
  221. package/dist/docs/introspect.d.ts +0 -7
  222. package/dist/docs/introspect.js +0 -199
  223. package/dist/docs/introspect.js.map +0 -1
  224. package/dist/docs/markdown.d.ts +0 -2
  225. package/dist/docs/markdown.js +0 -148
  226. package/dist/docs/markdown.js.map +0 -1
  227. package/dist/docs/model.d.ts +0 -62
  228. package/dist/docs/model.js +0 -33
  229. package/dist/docs/model.js.map +0 -1
  230. package/dist/event.types.d.ts +0 -18
  231. package/dist/event.types.js.map +0 -1
  232. package/dist/examples/express-mongo/index.d.ts +0 -0
  233. package/dist/examples/express-mongo/index.js +0 -3
  234. package/dist/examples/express-mongo/index.js.map +0 -1
  235. package/dist/examples/registrator-example.d.ts +0 -122
  236. package/dist/examples/registrator-example.js +0 -147
  237. package/dist/examples/registrator-example.js.map +0 -1
  238. package/dist/express/docsRouter.d.ts +0 -12
  239. package/dist/express/docsRouter.js +0 -54
  240. package/dist/express/docsRouter.js.map +0 -1
  241. package/dist/globalEvents.d.ts +0 -40
  242. package/dist/globalEvents.js +0 -94
  243. package/dist/globalEvents.js.map +0 -1
  244. package/dist/globalResources.d.ts +0 -10
  245. package/dist/globalResources.js +0 -43
  246. package/dist/globalResources.js.map +0 -1
  247. package/dist/middleware.types.d.ts +0 -40
  248. package/dist/middleware.types.js.map +0 -1
  249. package/dist/models/StoreConstants.d.ts +0 -14
  250. package/dist/models/StoreConstants.js +0 -19
  251. package/dist/models/StoreConstants.js.map +0 -1
  252. package/dist/models/StoreTypes.d.ts +0 -21
  253. package/dist/models/StoreTypes.js.map +0 -1
  254. package/dist/models/VarStore.d.ts +0 -17
  255. package/dist/models/VarStore.js +0 -60
  256. package/dist/models/VarStore.js.map +0 -1
  257. package/dist/resource.types.d.ts +0 -31
  258. package/dist/resource.types.js.map +0 -1
  259. package/dist/symbols.d.ts +0 -24
  260. package/dist/symbols.js +0 -29
  261. package/dist/symbols.js.map +0 -1
  262. package/dist/t1.d.ts +0 -1
  263. package/dist/t1.js +0 -13
  264. package/dist/t1.js.map +0 -1
  265. package/dist/task.types.d.ts +0 -55
  266. package/dist/task.types.js.map +0 -1
  267. package/dist/tools/findCircularDependencies.js.map +0 -1
  268. package/dist/tools/registratorId.d.ts +0 -4
  269. package/dist/tools/registratorId.js +0 -40
  270. package/dist/tools/registratorId.js.map +0 -1
  271. package/dist/tools/simpleHash.d.ts +0 -9
  272. package/dist/tools/simpleHash.js +0 -34
  273. package/dist/tools/simpleHash.js.map +0 -1
  274. package/dist/types/base-interfaces.d.ts +0 -18
  275. package/dist/types/base-interfaces.js +0 -6
  276. package/dist/types/base-interfaces.js.map +0 -1
  277. package/dist/types/base.d.ts +0 -13
  278. package/dist/types/base.js.map +0 -1
  279. package/dist/types/dependencies.d.ts +0 -51
  280. package/dist/types/dependencies.js +0 -3
  281. package/dist/types/dependencies.js.map +0 -1
  282. package/dist/types/dependency-core.d.ts +0 -14
  283. package/dist/types/dependency-core.js +0 -5
  284. package/dist/types/dependency-core.js.map +0 -1
  285. package/dist/types/events.d.ts +0 -52
  286. package/dist/types/events.js +0 -6
  287. package/dist/types/events.js.map +0 -1
  288. package/dist/types/hooks.d.ts +0 -16
  289. package/dist/types/hooks.js +0 -5
  290. package/dist/types/hooks.js.map +0 -1
  291. package/dist/types/index.d.ts +0 -8
  292. package/dist/types/index.js.map +0 -1
  293. package/dist/types/metadata.d.ts +0 -75
  294. package/dist/types/metadata.js.map +0 -1
  295. package/dist/types/middleware.d.ts +0 -63
  296. package/dist/types/middleware.js +0 -3
  297. package/dist/types/middleware.js.map +0 -1
  298. package/dist/types/registerable.d.ts +0 -10
  299. package/dist/types/registerable.js +0 -5
  300. package/dist/types/registerable.js.map +0 -1
  301. package/dist/types/resources.d.ts +0 -44
  302. package/dist/types/resources.js +0 -5
  303. package/dist/types/resources.js.map +0 -1
  304. package/dist/types/tasks.d.ts +0 -41
  305. package/dist/types/tasks.js +0 -5
  306. package/dist/types/tasks.js.map +0 -1
  307. package/src/__tests__/benchmark/benchmark.test.ts +0 -148
  308. package/src/__tests__/benchmark/task-benchmark.test.ts +0 -132
  309. package/src/__tests__/context.test.ts +0 -91
  310. package/src/__tests__/createTestResource.test.ts +0 -139
  311. package/src/__tests__/errors.test.ts +0 -341
  312. package/src/__tests__/globalEvents.test.ts +0 -542
  313. package/src/__tests__/globals/cache.middleware.test.ts +0 -772
  314. package/src/__tests__/globals/queue.resource.test.ts +0 -141
  315. package/src/__tests__/globals/requireContext.middleware.test.ts +0 -98
  316. package/src/__tests__/globals/retry.middleware.test.ts +0 -157
  317. package/src/__tests__/globals/timeout.middleware.test.ts +0 -88
  318. package/src/__tests__/index.helper.test.ts +0 -55
  319. package/src/__tests__/models/EventManager.test.ts +0 -585
  320. package/src/__tests__/models/Logger.test.ts +0 -519
  321. package/src/__tests__/models/Queue.test.ts +0 -189
  322. package/src/__tests__/models/ResourceInitializer.test.ts +0 -148
  323. package/src/__tests__/models/Semaphore.test.ts +0 -713
  324. package/src/__tests__/models/Store.test.ts +0 -227
  325. package/src/__tests__/models/TaskRunner.test.ts +0 -221
  326. package/src/__tests__/override.test.ts +0 -104
  327. package/src/__tests__/recursion/README.md +0 -3
  328. package/src/__tests__/recursion/a.resource.ts +0 -25
  329. package/src/__tests__/recursion/b.resource.ts +0 -33
  330. package/src/__tests__/recursion/c.resource.ts +0 -18
  331. package/src/__tests__/run.anonymous.test.ts +0 -706
  332. package/src/__tests__/run.dynamic-register-and-dependencies.test.ts +0 -1185
  333. package/src/__tests__/run.middleware.test.ts +0 -549
  334. package/src/__tests__/run.overrides.test.ts +0 -424
  335. package/src/__tests__/run.test.ts +0 -1040
  336. package/src/__tests__/setOutput.test.ts +0 -244
  337. package/src/__tests__/tags.test.ts +0 -396
  338. package/src/__tests__/tools/findCircularDependencies.test.ts +0 -217
  339. package/src/__tests__/tools/getCallerFile.test.ts +0 -179
  340. package/src/__tests__/typesafety.test.ts +0 -423
  341. package/src/__tests__/validation-edge-cases.test.ts +0 -111
  342. package/src/__tests__/validation-interface.test.ts +0 -428
  343. package/src/context.ts +0 -86
  344. package/src/define.ts +0 -480
  345. package/src/defs.returnTag.ts +0 -91
  346. package/src/defs.ts +0 -596
  347. package/src/errors.ts +0 -105
  348. package/src/globals/globalEvents.ts +0 -125
  349. package/src/globals/globalMiddleware.ts +0 -16
  350. package/src/globals/globalResources.ts +0 -53
  351. package/src/globals/middleware/cache.middleware.ts +0 -115
  352. package/src/globals/middleware/requireContext.middleware.ts +0 -36
  353. package/src/globals/middleware/retry.middleware.ts +0 -56
  354. package/src/globals/middleware/timeout.middleware.ts +0 -46
  355. package/src/globals/resources/queue.resource.ts +0 -34
  356. package/src/index.ts +0 -39
  357. package/src/models/DependencyProcessor.ts +0 -257
  358. package/src/models/EventManager.ts +0 -210
  359. package/src/models/Logger.ts +0 -282
  360. package/src/models/OverrideManager.ts +0 -79
  361. package/src/models/Queue.ts +0 -66
  362. package/src/models/ResourceInitializer.ts +0 -165
  363. package/src/models/Semaphore.ts +0 -208
  364. package/src/models/Store.ts +0 -193
  365. package/src/models/StoreConstants.ts +0 -18
  366. package/src/models/StoreRegistry.ts +0 -253
  367. package/src/models/StoreTypes.ts +0 -47
  368. package/src/models/StoreValidator.ts +0 -43
  369. package/src/models/TaskRunner.ts +0 -203
  370. package/src/models/index.ts +0 -8
  371. package/src/run.ts +0 -116
  372. package/src/testing.ts +0 -66
  373. package/src/tools/findCircularDependencies.ts +0 -69
  374. package/src/tools/getCallerFile.ts +0 -96
  375. /package/dist/{tools → models/utils}/findCircularDependencies.d.ts +0 -0
@@ -1,772 +0,0 @@
1
- import { defineTask, defineResource } from "../../define";
2
- import { run } from "../../run";
3
- import {
4
- cacheResource,
5
- cacheMiddleware,
6
- cacheFactoryTask,
7
- ICacheInstance,
8
- } from "../../globals/middleware/cache.middleware";
9
- import { LRUCache } from "lru-cache";
10
-
11
- describe("Caching System", () => {
12
- describe("Cache Resource", () => {
13
- it("should initialize with default cache factory task", async () => {
14
- const app = defineResource({
15
- id: "app",
16
- register: [cacheResource, cacheMiddleware],
17
- dependencies: { cache: cacheResource },
18
- async init(_, { cache }) {
19
- expect(cache.cacheFactoryTask).toBeDefined();
20
- expect(cache.async).toBeUndefined();
21
- expect(cache.defaultOptions).toEqual({
22
- ttl: 10000,
23
- max: 100,
24
- ttlAutopurge: true,
25
- });
26
- },
27
- });
28
-
29
- await run(app);
30
- });
31
-
32
- it("should create separate cache instances per task", async () => {
33
- const testTask = defineTask({
34
- id: "test.task",
35
- middleware: [cacheMiddleware],
36
- run: async () => Date.now(),
37
- });
38
-
39
- const app = defineResource({
40
- id: "app",
41
- register: [cacheResource, cacheMiddleware, testTask],
42
- dependencies: { testTask, cache: cacheResource },
43
- async init(_, { testTask, cache }) {
44
- const firstRun = await testTask();
45
- const secondRun = await testTask();
46
-
47
- expect(firstRun).toBe(secondRun);
48
- expect(cache.map.size).toBe(1);
49
- expect(cache.map.has("test.task")).toBe(true);
50
- },
51
- });
52
-
53
- await run(app);
54
- });
55
- });
56
-
57
- describe("Cache Factory Task Override", () => {
58
- it("should allow overriding the cache factory task", async () => {
59
- class CustomCache implements ICacheInstance {
60
- store = new Map<string, any>();
61
- customFlag = true;
62
-
63
- get(key: string) {
64
- return this.store.get(key);
65
- }
66
-
67
- set(key: string, value: any) {
68
- this.store.set(key, value);
69
- }
70
-
71
- clear() {
72
- this.store.clear();
73
- }
74
- }
75
-
76
- const customCacheFactoryTask = defineTask({
77
- id: "globals.tasks.cacheFactory",
78
- run: async (options: any) => {
79
- return new CustomCache();
80
- },
81
- });
82
-
83
- const testTask = defineTask({
84
- id: "custom.factory.task",
85
- middleware: [cacheMiddleware],
86
- run: async (input: string) => input.toUpperCase(),
87
- });
88
-
89
- const app = defineResource({
90
- id: "app",
91
- register: [cacheResource, cacheMiddleware, testTask],
92
- overrides: [customCacheFactoryTask],
93
- dependencies: { testTask, cache: cacheResource },
94
- async init(_, { testTask, cache }) {
95
- const result1 = await testTask("test");
96
- const result2 = await testTask("test");
97
-
98
- expect(result1).toBe("TEST");
99
- expect(result2).toBe("TEST");
100
-
101
- const cacheInstance = cache.map.get("custom.factory.task") as any;
102
- expect(cacheInstance.customFlag).toBe(true);
103
- },
104
- });
105
-
106
- await run(app);
107
- });
108
-
109
- it("should allow Redis-like cache factory task", async () => {
110
- class RedisLikeCache implements ICacheInstance {
111
- private store = new Map<string, { value: any; expiry?: number }>();
112
-
113
- get(key: string) {
114
- const entry = this.store.get(key);
115
- if (!entry) return undefined;
116
-
117
- if (entry.expiry && Date.now() > entry.expiry) {
118
- this.store.delete(key);
119
- return undefined;
120
- }
121
-
122
- return entry.value;
123
- }
124
-
125
- set(key: string, value: any) {
126
- // Simulate Redis with TTL
127
- const ttl = 1000; // 1 second TTL
128
- this.store.set(key, {
129
- value,
130
- expiry: Date.now() + ttl,
131
- });
132
- }
133
-
134
- clear() {
135
- this.store.clear();
136
- }
137
- }
138
-
139
- const redisCacheFactoryTask = defineTask({
140
- id: "globals.tasks.cacheFactory",
141
- run: async (options: any) => {
142
- return new RedisLikeCache();
143
- },
144
- });
145
-
146
- let callCount = 0;
147
- const testTask = defineTask({
148
- id: "redis.cache.task",
149
- middleware: [cacheMiddleware],
150
- run: async () => {
151
- callCount++;
152
- return `result-${callCount}`;
153
- },
154
- });
155
-
156
- const app = defineResource({
157
- id: "app",
158
- register: [cacheResource, cacheMiddleware, testTask],
159
- overrides: [redisCacheFactoryTask],
160
- dependencies: { testTask },
161
- async init(_, { testTask }) {
162
- const result1 = await testTask();
163
- const result2 = await testTask(); // Should be cached
164
-
165
- expect(result1).toBe(result2);
166
- expect(callCount).toBe(1);
167
-
168
- // Wait for Redis-like TTL to expire
169
- await new Promise((resolve) => setTimeout(resolve, 1100));
170
-
171
- const result3 = await testTask(); // Should be new result
172
- expect(result3).not.toBe(result1);
173
- expect(callCount).toBe(2);
174
- },
175
- });
176
-
177
- await run(app);
178
- });
179
- });
180
-
181
- describe("Cache Middleware", () => {
182
- it("should return cached results for same inputs", async () => {
183
- const testTask = defineTask({
184
- id: "cached.task",
185
- middleware: [cacheMiddleware],
186
- run: async (input: number) => input * 2,
187
- });
188
-
189
- const app = defineResource({
190
- id: "app",
191
- register: [cacheResource, cacheMiddleware, testTask],
192
- dependencies: { testTask },
193
- async init(_, { testTask }) {
194
- const result1 = await testTask(2);
195
- const result2 = await testTask(2);
196
- const result3 = await testTask(3);
197
-
198
- expect(result1).toBe(4);
199
- expect(result2).toBe(4);
200
- expect(result3).toBe(6);
201
- },
202
- });
203
-
204
- await run(app);
205
- });
206
-
207
- it("should respect TTL configuration", async () => {
208
- let callCount = 0;
209
- const testTask = defineTask({
210
- id: "ttl.task",
211
- middleware: [cacheMiddleware.with({ ttl: 100, ttlAutopurge: true })], // Short TTL
212
- run: async () => {
213
- callCount++;
214
- return `result-${callCount}`;
215
- },
216
- });
217
-
218
- const app = defineResource({
219
- id: "app",
220
- register: [cacheResource, cacheMiddleware, testTask],
221
- dependencies: { testTask },
222
- async init(_, { testTask }) {
223
- const firstRun = await testTask();
224
- const secondRun = await testTask(); // Should be cached
225
-
226
- // Wait for TTL to expire
227
- await new Promise((resolve) => setTimeout(resolve, 150));
228
-
229
- const thirdRun = await testTask(); // Should be a new result
230
-
231
- expect(firstRun).toBe(secondRun); // Both should be cached
232
- expect(callCount).toBe(2); // Called twice - once initially, once after TTL expiry
233
- expect(thirdRun).not.toBe(firstRun); // Different result after TTL
234
- },
235
- });
236
-
237
- await run(app);
238
- });
239
-
240
- it("should handle custom key builders", async () => {
241
- const customMiddleware = cacheMiddleware.with({
242
- keyBuilder: (taskId: string, input: any) => `${taskId}-${input.id}`,
243
- ttl: 1000,
244
- ttlAutopurge: true,
245
- });
246
-
247
- const testTask = defineTask({
248
- id: "custom.key.task",
249
- middleware: [customMiddleware],
250
- run: async (input: { id: string }) => input,
251
- });
252
-
253
- const app = defineResource({
254
- id: "app",
255
- register: [cacheResource, cacheMiddleware, testTask],
256
- dependencies: { testTask },
257
- async init(_, { testTask }) {
258
- const input1 = { id: "1", data: "test" };
259
- const input2 = { id: "1", data: "modified" };
260
-
261
- const result1 = await testTask(input1);
262
- const result2 = await testTask(input2);
263
-
264
- expect(result1).toEqual(input1);
265
- expect(result2).toEqual(input1); // Same ID should cache
266
- },
267
- });
268
-
269
- await run(app);
270
- });
271
- });
272
-
273
- describe("Error Handling", () => {
274
- it("should not cache errors by default", async () => {
275
- let callCount = 0;
276
- const errorTask = defineTask({
277
- id: "error.task",
278
- middleware: [cacheMiddleware],
279
- run: async () => {
280
- callCount++;
281
- throw new Error("Failed");
282
- },
283
- });
284
-
285
- const app = defineResource({
286
- id: "app",
287
- register: [cacheResource, cacheMiddleware, errorTask],
288
- dependencies: { errorTask },
289
- async init(_, { errorTask }) {
290
- await expect(errorTask()).rejects.toThrow("Failed");
291
- await expect(errorTask()).rejects.toThrow("Failed");
292
- expect(callCount).toBe(2);
293
- },
294
- });
295
-
296
- await run(app);
297
- });
298
-
299
- it("should not cache errors by default (errors throw through)", async () => {
300
- let callCount = 0;
301
- const errorTask = defineTask({
302
- id: "cached.error.task",
303
- middleware: [
304
- cacheMiddleware.with({
305
- ttl: 1000,
306
- ttlAutopurge: true,
307
- }),
308
- ],
309
- run: async () => {
310
- callCount++;
311
- throw new Error("Cached error");
312
- },
313
- });
314
-
315
- const app = defineResource({
316
- id: "app",
317
- register: [cacheResource, cacheMiddleware, errorTask],
318
- dependencies: { errorTask },
319
- async init(_, { errorTask }) {
320
- await expect(errorTask()).rejects.toThrow("Cached error");
321
- await expect(errorTask()).rejects.toThrow("Cached error");
322
- expect(callCount).toBe(2); // Called twice since errors aren't cached
323
- },
324
- });
325
-
326
- await run(app);
327
- });
328
- });
329
-
330
- describe("Cache Invalidation", () => {
331
- it("should clear cache instances when resource is disposed", async () => {
332
- let executionCount = 0;
333
- const testTask = defineTask({
334
- id: "disposal.task",
335
- middleware: [cacheMiddleware],
336
- run: async () => {
337
- executionCount++;
338
- return `result-${executionCount}`;
339
- },
340
- });
341
-
342
- const result = await run(
343
- defineResource({
344
- id: "app",
345
- register: [cacheResource, cacheMiddleware, testTask],
346
- dependencies: { testTask, cache: cacheResource },
347
- async init(_, { testTask, cache }) {
348
- const firstRun = await testTask();
349
- const secondRun = await testTask(); // Should be cached
350
-
351
- expect(firstRun).toBe(secondRun);
352
- expect(executionCount).toBe(1);
353
- expect(cache.map.size).toBe(1);
354
-
355
- return cache;
356
- },
357
- })
358
- );
359
-
360
- // Dispose the resource - this should clear all cache instances
361
- await result.dispose();
362
-
363
- // Verify cache instances were cleared during disposal
364
- expect(result.value.map.size).toBe(1); // Map still exists but instances are cleared
365
- });
366
- });
367
-
368
- describe("Async Cache Handlers", () => {
369
- class AsyncMockCache implements ICacheInstance {
370
- store = new Map<string, any>();
371
- async get(key: string) {
372
- return this.store.get(key);
373
- }
374
- async set(key: string, value: any) {
375
- this.store.set(key, value);
376
- }
377
- async clear() {
378
- this.store.clear();
379
- }
380
- }
381
-
382
- const asyncCacheFactoryTask = defineTask({
383
- id: "globals.tasks.cacheFactory",
384
- run: async (options: any) => {
385
- return new AsyncMockCache();
386
- },
387
- });
388
-
389
- it("should handle async cache operations", async () => {
390
- const testTask = defineTask({
391
- id: "task",
392
- middleware: [cacheMiddleware],
393
- run: async (input: number) => input * 2,
394
- });
395
-
396
- const asyncCacheResource = defineResource({
397
- id: "globals.resources.cache",
398
- register: [asyncCacheFactoryTask],
399
- dependencies: { cacheFactoryTask: asyncCacheFactoryTask },
400
- init: async (config: any, { cacheFactoryTask }) => ({
401
- map: new Map<string, AsyncMockCache>(),
402
- cacheFactoryTask,
403
- async: true,
404
- defaultOptions: { ttl: 10 * 1000, ...config?.defaultOptions },
405
- }),
406
- dispose: async (cache) => {
407
- await Promise.all(
408
- [...cache.map.values()].map((instance) => instance.clear())
409
- );
410
- },
411
- });
412
-
413
- const app = defineResource({
414
- id: "app",
415
- register: [asyncCacheResource, cacheMiddleware, testTask],
416
- dependencies: { testTask },
417
- async init(_, { testTask }) {
418
- const result1 = await testTask(2);
419
- const result2 = await testTask(2);
420
- expect(result1).toBe(4);
421
- expect(result2).toBe(4);
422
- },
423
- });
424
-
425
- await run(app);
426
- });
427
- });
428
-
429
- describe("Complex Input Serialization", () => {
430
- it("should handle complex object inputs", async () => {
431
- const testTask = defineTask({
432
- id: "complex.object.task",
433
- middleware: [cacheMiddleware],
434
- run: async (input: { nested: { data: string }; array: number[] }) =>
435
- JSON.stringify(input),
436
- });
437
-
438
- const app = defineResource({
439
- id: "app",
440
- register: [cacheResource, cacheMiddleware, testTask],
441
- dependencies: { testTask },
442
- async init(_, { testTask }) {
443
- const complexInput = { nested: { data: "test" }, array: [1, 2, 3] };
444
- const result1 = await testTask(complexInput);
445
- const result2 = await testTask(complexInput);
446
-
447
- expect(result1).toBe(result2);
448
- expect(JSON.parse(result1)).toEqual(complexInput);
449
- },
450
- });
451
-
452
- await run(app);
453
- });
454
-
455
- it("should handle null and undefined inputs", async () => {
456
- const testTask = defineTask({
457
- id: "null.undefined.task",
458
- middleware: [cacheMiddleware],
459
- run: async (input: any) => `result-${input}`,
460
- });
461
-
462
- const app = defineResource({
463
- id: "app",
464
- register: [cacheResource, cacheMiddleware, testTask],
465
- dependencies: { testTask },
466
- async init(_, { testTask }) {
467
- const nullResult1 = await testTask(null);
468
- const nullResult2 = await testTask(null);
469
- const undefinedResult1 = await testTask(undefined);
470
- const undefinedResult2 = await testTask(undefined);
471
-
472
- expect(nullResult1).toBe(nullResult2);
473
- expect(undefinedResult1).toBe(undefinedResult2);
474
- expect(nullResult1).not.toBe(undefinedResult1);
475
- },
476
- });
477
-
478
- await run(app);
479
- });
480
-
481
- it("should handle array inputs with different orders", async () => {
482
- const testTask = defineTask({
483
- id: "array.order.task",
484
- middleware: [cacheMiddleware],
485
- run: async (input: number[]) => input.reduce((a, b) => a + b, 0),
486
- });
487
-
488
- const app = defineResource({
489
- id: "app",
490
- register: [cacheResource, cacheMiddleware, testTask],
491
- dependencies: { testTask },
492
- async init(_, { testTask }) {
493
- const result1 = await testTask([1, 2, 3]);
494
- const result2 = await testTask([1, 2, 3]);
495
- const result3 = await testTask([3, 2, 1]); // Different order
496
-
497
- expect(result1).toBe(result2);
498
- expect(result1).toBe(6);
499
- expect(result3).toBe(6);
500
- // Arrays with different order create different cache keys due to JSON.stringify
501
- // So result1 and result3 are from different cache entries (both computed)
502
- },
503
- });
504
-
505
- await run(app);
506
- });
507
- });
508
-
509
- describe("Cache Invalidation and Limits", () => {
510
- it("should respect max cache size", async () => {
511
- const testTask = defineTask({
512
- id: "max.size.task",
513
- middleware: [cacheMiddleware.with({ max: 2 })],
514
- run: async (input: number) => input * 2,
515
- });
516
-
517
- const app = defineResource({
518
- id: "app",
519
- register: [cacheResource, cacheMiddleware, testTask],
520
- dependencies: { testTask, cache: cacheResource },
521
- async init(_, { testTask, cache }) {
522
- await testTask(1);
523
- await testTask(2);
524
- await testTask(3); // Should evict first entry
525
-
526
- const cacheInstance = cache.map.get("max.size.task");
527
- expect(cacheInstance).toBeDefined();
528
- // LRU should maintain size limit
529
- },
530
- });
531
-
532
- await run(app);
533
- });
534
-
535
- it("should handle cache clear during execution", async () => {
536
- let executionCount = 0;
537
- const testTask = defineTask({
538
- id: "clear.during.exec.task",
539
- middleware: [cacheMiddleware],
540
- run: async (input: number) => {
541
- executionCount++;
542
- return input * 2;
543
- },
544
- });
545
-
546
- const app = defineResource({
547
- id: "app",
548
- register: [cacheResource, cacheMiddleware, testTask],
549
- dependencies: { testTask, cache: cacheResource },
550
- async init(_, { testTask, cache }) {
551
- const firstResult = await testTask(5);
552
-
553
- // Clear cache manually
554
- cache.map.get("clear.during.exec.task")?.clear();
555
-
556
- const secondResult = await testTask(5);
557
-
558
- expect(firstResult).toBe(secondResult);
559
- expect(executionCount).toBe(2); // Function called twice due to cache clear
560
- expect(cache.map.size).toBe(1); // Cache instance still exists but is cleared
561
- },
562
- });
563
-
564
- await run(app);
565
- });
566
- });
567
-
568
- describe("Concurrent Access", () => {
569
- it("should handle concurrent calls to same task", async () => {
570
- let executionCount = 0;
571
- const slowTask = defineTask({
572
- id: "concurrent.task",
573
- middleware: [cacheMiddleware],
574
- run: async (input: number) => {
575
- executionCount++;
576
- // Shorter delay to avoid timeout
577
- await new Promise((resolve) => setTimeout(resolve, 1));
578
- return input * 2;
579
- },
580
- });
581
-
582
- const app = defineResource({
583
- id: "app",
584
- register: [cacheResource, cacheMiddleware, slowTask],
585
- dependencies: { slowTask },
586
- async init(_, { slowTask }) {
587
- // Test basic caching behavior instead of race conditions
588
- const result1 = await slowTask(10);
589
- const result2 = await slowTask(10);
590
-
591
- expect(result1).toBe(20);
592
- expect(result2).toBe(20);
593
- expect(result1).toBe(result2); // Should be cached
594
- expect(executionCount).toBe(1); // Only executed once
595
- },
596
- });
597
-
598
- await run(app);
599
- });
600
- });
601
-
602
- describe("Memory and Disposal", () => {
603
- it("should properly dispose async cache handlers", async () => {
604
- class AsyncDisposableCache implements ICacheInstance {
605
- store = new Map<string, any>();
606
- disposed = false;
607
-
608
- async get(key: string) {
609
- if (this.disposed) throw new Error("Cache disposed");
610
- return this.store.get(key);
611
- }
612
-
613
- async set(key: string, value: any) {
614
- if (this.disposed) throw new Error("Cache disposed");
615
- this.store.set(key, value);
616
- }
617
-
618
- async clear() {
619
- this.disposed = true;
620
- this.store.clear();
621
- }
622
- }
623
-
624
- const disposableCacheFactoryTask = defineTask({
625
- id: "globals.tasks.cacheFactory",
626
- run: async (options: any) => {
627
- return new AsyncDisposableCache();
628
- },
629
- });
630
-
631
- const disposableCacheResource = defineResource({
632
- id: "globals.resources.cache",
633
- register: [disposableCacheFactoryTask],
634
- dependencies: { cacheFactoryTask: disposableCacheFactoryTask },
635
- init: async (config: any, { cacheFactoryTask }) => ({
636
- map: new Map<string, AsyncDisposableCache>(),
637
- cacheFactoryTask,
638
- async: true,
639
- defaultOptions: { ttl: 10 * 1000, ...config?.defaultOptions },
640
- }),
641
- dispose: async (cache) => {
642
- await Promise.all(
643
- [...cache.map.values()].map((instance) => instance.clear())
644
- );
645
- },
646
- });
647
-
648
- const testTask = defineTask({
649
- id: "disposal.test.task",
650
- middleware: [cacheMiddleware],
651
- run: async () => "test",
652
- });
653
-
654
- const result = await run(
655
- defineResource({
656
- id: "app",
657
- register: [disposableCacheResource, cacheMiddleware, testTask],
658
- dependencies: { testTask, cache: disposableCacheResource },
659
- async init(_, { testTask, cache }) {
660
- await testTask();
661
- return cache;
662
- },
663
- })
664
- );
665
-
666
- // Manually dispose to trigger cleanup
667
- await result.dispose();
668
-
669
- // Verify cache was disposed
670
- const cacheInstance = result.value.map.get("disposal.test.task") as any;
671
- expect(cacheInstance?.disposed).toBe(true);
672
- });
673
- });
674
-
675
- describe("Configuration Validation", () => {
676
- it("should handle custom keyBuilder configuration properly", async () => {
677
- const customMiddleware = cacheMiddleware.with({
678
- keyBuilder: (taskId: string, input: any) => `custom-${taskId}-${input}`,
679
- ttl: 1000,
680
- ttlAutopurge: true,
681
- });
682
-
683
- const testTask = defineTask({
684
- id: "custom.keybuilder.task",
685
- middleware: [customMiddleware],
686
- run: async (input: string) => `result-${input}`,
687
- });
688
-
689
- const app = defineResource({
690
- id: "app",
691
- register: [cacheResource, cacheMiddleware, testTask],
692
- dependencies: { testTask },
693
- async init(_, { testTask }) {
694
- const result1 = await testTask("test");
695
- const result2 = await testTask("test");
696
-
697
- expect(result1).toBe("result-test");
698
- expect(result2).toBe(result1); // Should be cached
699
- },
700
- });
701
-
702
- await run(app);
703
- });
704
-
705
- it("should validate cache handler interface", async () => {
706
- class InvalidCache {
707
- // Missing required methods
708
- store = new Map();
709
- }
710
-
711
- const invalidCacheFactoryTask = defineTask({
712
- id: "globals.tasks.cacheFactory",
713
- run: async (options: any) => {
714
- return new InvalidCache() as any;
715
- },
716
- });
717
-
718
- const invalidCacheResource = defineResource({
719
- id: "globals.resources.cache",
720
- register: [invalidCacheFactoryTask],
721
- dependencies: { cacheFactoryTask: invalidCacheFactoryTask },
722
- init: async (config: any, { cacheFactoryTask }) => ({
723
- map: new Map(),
724
- cacheFactoryTask,
725
- defaultOptions: { ttl: 10 * 1000, ...config?.defaultOptions },
726
- }),
727
- dispose: async () => {},
728
- });
729
-
730
- const testTask = defineTask({
731
- id: "invalid.handler.task",
732
- middleware: [cacheMiddleware],
733
- run: async () => "test",
734
- });
735
-
736
- const app = defineResource({
737
- id: "app",
738
- register: [invalidCacheResource, cacheMiddleware, testTask],
739
- dependencies: { testTask },
740
- async init(_, { testTask }) {
741
- // Should fail when trying to use invalid cache handler
742
- await testTask(); // This should trigger the error
743
- },
744
- });
745
-
746
- await expect(run(app)).rejects.toThrow();
747
- });
748
- });
749
-
750
- describe("Validation", () => {
751
- it("should throw error when used without task context", async () => {
752
- const invalidResource = defineResource({
753
- id: "invalid.resource",
754
- middleware: [cacheMiddleware],
755
- init: async () => "test",
756
- });
757
-
758
- const app = defineResource({
759
- id: "app",
760
- register: [cacheResource, cacheMiddleware, invalidResource],
761
- dependencies: { invalidResource },
762
- async init(_, { invalidResource }) {
763
- // Should throw during initialization
764
- },
765
- });
766
-
767
- await expect(run(app)).rejects.toThrow(
768
- "Cache middleware can only be used in tasks"
769
- );
770
- });
771
- });
772
- });