@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,1040 +0,0 @@
1
- import {
2
- defineTask,
3
- defineResource,
4
- defineEvent,
5
- defineMiddleware,
6
- } from "../define";
7
- import { run } from "../run";
8
- import { globalResources } from "../globals/globalResources";
9
-
10
- describe("main exports", () => {
11
- it("should export all public APIs correctly", async () => {
12
- // Test main index exports for 100% coverage
13
- const mainExports = await import("../index");
14
-
15
- expect(typeof mainExports.task).toBe("function");
16
- expect(typeof mainExports.resource).toBe("function");
17
- expect(typeof mainExports.event).toBe("function");
18
- expect(typeof mainExports.middleware).toBe("function");
19
- expect(typeof mainExports.index).toBe("function");
20
- expect(typeof mainExports.tag).toBe("function");
21
- expect(typeof mainExports.run).toBe("function");
22
- expect(typeof mainExports.createContext).toBe("function");
23
- expect(typeof mainExports.globals).toBe("object");
24
- expect(typeof mainExports.definitions).toBe("object");
25
- expect(typeof mainExports.Store).toBe("function");
26
- expect(typeof mainExports.EventManager).toBe("function");
27
- expect(typeof mainExports.TaskRunner).toBe("function");
28
- expect(typeof mainExports.Queue).toBe("function");
29
- expect(typeof mainExports.Semaphore).toBe("function");
30
-
31
- // Test that aliases work the same as direct imports
32
- const directTask = defineTask({ id: "test", run: async () => "direct" });
33
- const aliasTask = mainExports.task({
34
- id: "test2",
35
- run: async () => "alias",
36
- });
37
-
38
- expect(directTask.id).toBe("test");
39
- expect(aliasTask.id).toBe("test2");
40
-
41
- // Test tag exports work
42
- const testTag = mainExports.tag<{ value: number }>({ id: "test.tag" });
43
- const testTag2 = mainExports.tag<{ name: string }>({ id: "test.tag2" });
44
-
45
- expect(testTag.id).toBe("test.tag");
46
- expect(testTag2.id).toBe("test.tag2");
47
- expect(typeof testTag.with).toBe("function");
48
- expect(typeof testTag2.extract).toBe("function");
49
-
50
- // Test createContext export
51
- const TestContext = mainExports.createContext<string>("test.context");
52
- expect(typeof TestContext.provide).toBe("function");
53
- expect(typeof TestContext.use).toBe("function");
54
-
55
- // Test globals sub-properties for complete coverage
56
- expect(typeof mainExports.globals.events).toBe("object");
57
- expect(typeof mainExports.globals.resources).toBe("object");
58
- expect(typeof mainExports.globals.middlewares).toBe("object");
59
- });
60
- });
61
-
62
- describe("run", () => {
63
- // Tasks
64
- describe("Tasks", () => {
65
- it("should be able to register an task and execute it", async () => {
66
- const testTask = defineTask({
67
- id: "test.task",
68
- run: async () => "Hello, World!",
69
- });
70
-
71
- const app = defineResource({
72
- id: "app",
73
- dependencies: { testTask },
74
- register: [testTask],
75
- async init(_, { testTask }) {
76
- const result = await testTask();
77
- expect(result).toBe("Hello, World!");
78
- },
79
- });
80
-
81
- await run(app);
82
- });
83
-
84
- it("should be able to register an task with dependencies and execute it", async () => {
85
- const dependencyTask = defineTask({
86
- id: "dependency.task",
87
- run: async (_, { d1 }) => {
88
- return "Dependency";
89
- },
90
- });
91
-
92
- const testTask = defineTask({
93
- id: "test.task",
94
- dependencies: { dependencyTask },
95
- run: async (_, deps) => {
96
- const dep = await deps.dependencyTask();
97
- return `Hello, ${dep}!`;
98
- },
99
- });
100
-
101
- const app = defineResource({
102
- id: "app",
103
- register: [dependencyTask, testTask],
104
- dependencies: { testTask },
105
- async init(_, { testTask }) {
106
- const result = await testTask();
107
- expect(result).toBe("Hello, Dependency!");
108
- },
109
- });
110
-
111
- await run(app);
112
- });
113
-
114
- it("should be able to register an task that emits an event", async () => {
115
- const testEvent = defineEvent<{ message: string }>({ id: "test.event" });
116
- const eventHandler = jest.fn();
117
-
118
- const testTask = defineTask({
119
- id: "test.task",
120
- dependencies: { testEvent },
121
- run: async (_, { testEvent }) => {
122
- await testEvent({ message: "Event emitted" });
123
- return "Task completed";
124
- },
125
- });
126
-
127
- const handlerTask = defineTask({
128
- id: "handler.task",
129
- on: testEvent,
130
- run: eventHandler,
131
- });
132
-
133
- const app = defineResource({
134
- id: "app",
135
- register: [testEvent, testTask, handlerTask],
136
- dependencies: { testTask },
137
- async init(_, { testTask }) {
138
- await testTask();
139
- expect(eventHandler).toHaveBeenCalled();
140
- },
141
- });
142
-
143
- await run(app);
144
- });
145
-
146
- it("should emit the proper beforeRun, afterRun, onError events and I can listen to them", async () => {
147
- const beforeRunHandler = jest.fn();
148
- const afterRunHandler = jest.fn();
149
- const onErrorHandler = jest.fn();
150
-
151
- const testTask = defineTask({
152
- id: "test.task",
153
- run: async () => "Task executed",
154
- });
155
-
156
- const onBeforeRun = defineTask({
157
- id: "on.before.run",
158
- on: testTask.events.beforeRun,
159
- run: beforeRunHandler,
160
- });
161
-
162
- const onAfterRun = defineTask({
163
- id: "on.after.run",
164
- on: testTask.events.afterRun,
165
- run: afterRunHandler,
166
- });
167
-
168
- const onError = defineTask({
169
- id: "on.error",
170
- on: testTask.events.onError,
171
- run: onErrorHandler,
172
- });
173
-
174
- const app = defineResource({
175
- id: "app",
176
- register: [testTask, onBeforeRun, onAfterRun, onError],
177
- dependencies: { testTask },
178
- async init(_, { testTask }) {
179
- await testTask();
180
- expect(beforeRunHandler).toHaveBeenCalled();
181
- expect(afterRunHandler).toHaveBeenCalled();
182
- expect(onErrorHandler).not.toHaveBeenCalled();
183
- },
184
- });
185
-
186
- await run(app);
187
- });
188
-
189
- it("should propagate the error to the parent", async () => {
190
- const testTask = defineTask({
191
- id: "test.task",
192
- run: async () => {
193
- throw new Error("Task failed");
194
- },
195
- });
196
-
197
- let value = false;
198
- const errorHook = jest.fn();
199
-
200
- const handler = defineTask({
201
- id: "handler",
202
- on: testTask.events.onError,
203
- run: errorHook,
204
- });
205
-
206
- const app = defineResource({
207
- id: "app",
208
- register: [testTask, handler],
209
- dependencies: { testTask },
210
- async init(_, { testTask }) {
211
- await testTask();
212
- },
213
- });
214
-
215
- await expect(run(app)).rejects.toThrow("Task failed");
216
- expect(errorHook).toHaveBeenCalled();
217
- });
218
-
219
- it("should be able to register an task with middleware and execute it, ensuring the middleware is called in the correct order", async () => {
220
- const order: string[] = [];
221
-
222
- const testMiddleware1 = defineMiddleware({
223
- id: "test.middleware1",
224
- run: async ({ next }) => {
225
- order.push("middleware1 before");
226
- const result = await next();
227
- order.push("middleware1 after");
228
- return result;
229
- },
230
- });
231
-
232
- const testMiddleware2 = defineMiddleware({
233
- id: "test.middleware2",
234
- run: async ({ next }) => {
235
- order.push("middleware2 before");
236
- const result = await next();
237
- order.push("middleware2 after");
238
- return result;
239
- },
240
- });
241
-
242
- const testTask = defineTask({
243
- id: "test.task",
244
- middleware: [testMiddleware1, testMiddleware2],
245
- run: async () => {
246
- order.push("task");
247
- return "Task executed";
248
- },
249
- });
250
-
251
- const app = defineResource({
252
- id: "app",
253
- register: [testMiddleware1, testMiddleware2, testTask],
254
- dependencies: { testTask },
255
- async init(_, { testTask }) {
256
- await testTask();
257
- },
258
- });
259
-
260
- await run(app);
261
-
262
- expect(order).toEqual([
263
- "middleware1 before",
264
- "middleware2 before",
265
- "task",
266
- "middleware2 after",
267
- "middleware1 after",
268
- ]);
269
- });
270
-
271
- it("should be able to register an task with middleware that has dependencies and execute it", async () => {
272
- const dependencyResource = defineResource({
273
- id: "dependency.resource",
274
- init: async () => "Dependency Value",
275
- });
276
-
277
- const testMiddleware = defineMiddleware({
278
- id: "test.middleware",
279
- dependencies: { dependencyResource },
280
- run: async ({ next }, { dependencyResource }) => {
281
- const result = await next();
282
- return `${result} - ${dependencyResource}`;
283
- },
284
- });
285
-
286
- const testTask = defineTask({
287
- id: "test.task",
288
- middleware: [testMiddleware],
289
- run: async () => "Task executed",
290
- });
291
-
292
- const app = defineResource({
293
- id: "app",
294
- dependencies: { testTask },
295
- register: [dependencyResource, testMiddleware, testTask],
296
- async init(_, { testTask }) {
297
- const result = await testTask();
298
- expect(result).toBe("Task executed - Dependency Value");
299
- },
300
- });
301
-
302
- await run(app);
303
- });
304
-
305
- it("should throw an error if there's an infinite dependency", async () => {
306
- const task1: any = defineTask({
307
- id: "task1",
308
- dependencies: (): any => ({ task2 }), // Corrected line
309
- run: async () => "Task 1",
310
- });
311
-
312
- const task2: any = defineTask({
313
- id: "task2",
314
- dependencies: { task1 },
315
- run: async () => "Task 2",
316
- });
317
-
318
- // define circular dependency resources
319
- const resource1: any = defineResource({
320
- id: "resource1",
321
- dependencies: (): any => ({
322
- resource2,
323
- }),
324
- init: async () => "Resource 1",
325
- });
326
-
327
- const resource2 = defineResource({
328
- id: "resource2",
329
- dependencies: { resource1 },
330
- init: async () => "Resource 2",
331
- });
332
-
333
- task1.dependencies.task2 = task2;
334
-
335
- const app = defineResource({
336
- id: "app",
337
- register: [resource1, resource2],
338
- });
339
-
340
- await expect(run(app)).rejects.toThrow(/Circular dependencies detected/);
341
- });
342
-
343
- it("should be able to listen to an event through the 'on' property", async () => {
344
- const testEvent = defineEvent<{ message: string }>({ id: "test.event" });
345
- const eventHandler = jest.fn();
346
-
347
- const task = defineTask({
348
- id: "app",
349
- on: testEvent,
350
- async run(event) {
351
- eventHandler();
352
- },
353
- });
354
-
355
- const app = defineResource({
356
- id: "app.resource",
357
- register: [testEvent, task],
358
- dependencies: { task, testEvent },
359
- async init(_, deps) {
360
- await deps.testEvent({ message: "Event emitted" });
361
- },
362
- });
363
-
364
- await run(app);
365
- expect(eventHandler).toHaveBeenCalled();
366
- });
367
-
368
- it("should avoid infinite recursion by omitting task emissions recursively", async () => {
369
- const testEvent = defineEvent<{ message: string }>({ id: "test.event" });
370
- const eventHandler = jest.fn();
371
-
372
- const task = defineTask({
373
- id: "app",
374
- on: testEvent,
375
- dependencies: { testEvent },
376
- async run(event, { testEvent }) {
377
- eventHandler();
378
- await testEvent({ message: "Event emitted" });
379
- },
380
- });
381
-
382
- const app = defineResource({
383
- id: "app.resource",
384
- register: [testEvent, task],
385
- dependencies: { task, testEvent },
386
- async init(_, deps) {
387
- await deps.testEvent({ message: "Event emitted" });
388
- },
389
- });
390
-
391
- await run(app);
392
- expect(eventHandler).toHaveBeenCalled();
393
- });
394
-
395
- it("should be able to listen to global events", async () => {
396
- const testEvent = defineEvent<{ message: string }>({ id: "test.event" });
397
- const eventHandler = jest.fn();
398
- let isReady = false;
399
- let matched = false;
400
-
401
- const dummyResource = defineResource({
402
- id: "dummy",
403
- init: async () => "dummy",
404
- });
405
- const task = defineTask({
406
- id: "app",
407
- on: "*",
408
- dependencies: { dummyResource },
409
- async run(event, { dummyResource }) {
410
- if (dummyResource === "dummy") {
411
- matched = true;
412
- }
413
- isReady && eventHandler();
414
- },
415
- });
416
-
417
- const app = defineResource({
418
- id: "app.resource",
419
- register: [testEvent, task, dummyResource],
420
- dependencies: { task, testEvent },
421
- async init(_, deps) {
422
- isReady = true;
423
- await deps.testEvent({ message: "Event emitted" });
424
- },
425
- });
426
-
427
- await run(app);
428
- expect(eventHandler).toHaveBeenCalled();
429
- expect(matched).toBe(true);
430
- });
431
- });
432
-
433
- // Resources
434
- describe("Resources", () => {
435
- it("should be able to register a resource and get its value", async () => {
436
- const testResource = defineResource({
437
- id: "test.resource",
438
- init: async () => "Resource Value",
439
- });
440
-
441
- const app = defineResource({
442
- id: "app",
443
- register: [testResource],
444
- dependencies: { testResource },
445
- async init(_, { testResource }) {
446
- expect(testResource).toBe("Resource Value");
447
- },
448
- });
449
-
450
- await run(app);
451
- });
452
-
453
- it("should be able to register a resource with dependencies and get its value", async () => {
454
- const dependencyResource = defineResource({
455
- id: "dependency.resource",
456
- init: async () => "Dependency",
457
- });
458
-
459
- const testResource = defineResource({
460
- id: "test.resource",
461
- dependencies: { dependencyResource },
462
- init: async (_, { dependencyResource }) =>
463
- `Hello, ${dependencyResource}!`,
464
- });
465
-
466
- const app = defineResource({
467
- id: "app",
468
- register: [dependencyResource, testResource],
469
- dependencies: { testResource },
470
- async init(_, { testResource }) {
471
- expect(testResource).toBe("Hello, Dependency!");
472
- },
473
- });
474
-
475
- await run(app);
476
- });
477
-
478
- it("should allow to register a resource without an init task", async () => {
479
- const mockFn = jest.fn();
480
- const testResourceWithInit = defineResource({
481
- id: "test.resource.with.init",
482
- init: mockFn,
483
- });
484
-
485
- const testResource = defineResource({
486
- id: "test.resource",
487
- register: [testResourceWithInit],
488
- });
489
-
490
- const app = defineResource({
491
- id: "app",
492
- register: [testResource],
493
- });
494
-
495
- await run(app);
496
- expect(mockFn).toHaveBeenCalled();
497
- });
498
-
499
- it("should be able to register a resource with configuration and get its value", async () => {
500
- const testResource = defineResource({
501
- id: "test.resource",
502
- init: async (config: { prefix: string }) => `${config.prefix} World!`,
503
- });
504
-
505
- const t2 = defineResource({
506
- id: "test.r2",
507
- async init() {},
508
- });
509
-
510
- const typeTest = defineResource({
511
- id: "typeTest",
512
- register: [
513
- t2,
514
- testResource.with({
515
- prefix: "Hello,",
516
- }),
517
- ],
518
- });
519
-
520
- const app = defineResource({
521
- id: "app",
522
- dependencies: { testResource },
523
- register: [testResource.with({ prefix: "Hello," })],
524
- async init(_, { testResource }) {
525
- expect(testResource).toBe("Hello, World!");
526
- },
527
- });
528
-
529
- await run(app);
530
- });
531
-
532
- it("should allow suppression of an error", async () => {
533
- const supressMock = jest.fn();
534
- const erroringResource = defineResource({
535
- id: "error.resource",
536
- init: async () => {
537
- // we do this so it doesn't become a never.
538
- if (true === true) {
539
- throw new Error("Init failed");
540
- }
541
- },
542
- });
543
- const erroringTask = defineTask({
544
- id: "error.task",
545
- run: async (event) => {
546
- if (true === true) {
547
- throw new Error("Run failed");
548
- }
549
- },
550
- });
551
-
552
- const resourceErrorHandler = defineTask({
553
- id: "resourcehandler",
554
- on: erroringResource.events.onError,
555
- run: async (event) => {
556
- supressMock();
557
- event.data.suppress();
558
- },
559
- });
560
-
561
- const taskErrorHandler = defineTask({
562
- id: "taskhandler",
563
- on: erroringTask.events.onError,
564
- run: async (event) => {
565
- supressMock();
566
- event.data.suppress();
567
- },
568
- });
569
-
570
- const app = defineResource({
571
- id: "app",
572
- register: [
573
- erroringResource,
574
- erroringTask,
575
- resourceErrorHandler,
576
- taskErrorHandler,
577
- ],
578
- dependencies: { erroringResource, erroringTask },
579
- async init(_, { erroringResource, erroringTask }) {
580
- expect(erroringResource).toBeUndefined();
581
- expect(await erroringTask()).toBeUndefined();
582
-
583
- return "ok";
584
- },
585
- });
586
-
587
- const result = await run(app);
588
- expect(result.value).toBe("ok");
589
- expect(supressMock).toHaveBeenCalledTimes(2);
590
- });
591
- });
592
-
593
- it("should be able to register as a function", async () => {
594
- const mockFn = jest.fn();
595
- const testResource = defineResource({
596
- id: "test.resource",
597
- init: mockFn,
598
- });
599
-
600
- const app = defineResource({
601
- id: "app",
602
- register: () => [testResource],
603
- });
604
-
605
- await run(app);
606
- expect(mockFn).toHaveBeenCalled();
607
- });
608
-
609
- it("should be able to register a dependency via function", async () => {
610
- const mockFn = jest.fn();
611
- const testResource = defineResource({
612
- id: "test.resource",
613
- init: async () => {
614
- mockFn();
615
- return "XXX";
616
- },
617
- });
618
-
619
- const app = defineResource({
620
- id: "app",
621
- dependencies: () => ({ testResource }),
622
- register: () => [testResource],
623
- async init(_, { testResource }) {
624
- expect(testResource).toBe("XXX"); // that's what the mock function returns.
625
- },
626
- });
627
-
628
- await run(app);
629
- expect(mockFn).toHaveBeenCalled();
630
- });
631
-
632
- it("resources - should be able to register a dependency via function", async () => {
633
- const mockFn = jest.fn();
634
- const testResource = defineResource({
635
- id: "test.resource",
636
- init: async () => {
637
- mockFn();
638
- return "XXX";
639
- },
640
- });
641
-
642
- const middle = defineResource({
643
- id: "middle",
644
- dependencies: () => ({ testResource }),
645
- register: () => [testResource],
646
- async init(_, { testResource }) {
647
- expect(testResource).toBe("XXX");
648
- return "middle";
649
- },
650
- });
651
-
652
- const app = defineResource({
653
- id: "app",
654
- dependencies: () => ({ middle }),
655
- register: () => [middle],
656
- async init(_, { middle }) {
657
- expect(middle).toBe("middle");
658
- },
659
- });
660
-
661
- await run(app);
662
- expect(mockFn).toHaveBeenCalled();
663
- });
664
-
665
- it("tasks - should be able to register a dependency via function", async () => {
666
- const mockFn = jest.fn();
667
- const testTask = defineTask({
668
- id: "test.task",
669
- run: async () => {
670
- mockFn();
671
- return "XXX";
672
- },
673
- });
674
-
675
- const middle = defineTask({
676
- id: "middle",
677
- dependencies: () => ({ testTask }),
678
- async run(_, { testTask }) {
679
- expect(await testTask()).toBe("XXX");
680
- return "middle";
681
- },
682
- });
683
-
684
- const app = defineResource({
685
- id: "app",
686
- dependencies: () => ({ middle }),
687
- register: () => [middle, testTask],
688
- async init(_, { middle }) {
689
- expect(await middle()).toBe("middle");
690
- },
691
- });
692
-
693
- await run(app);
694
- expect(mockFn).toHaveBeenCalled();
695
- });
696
-
697
- describe("disposal", () => {
698
- it("should be able to dispose of a resource", async () => {
699
- const disposeFn = jest.fn();
700
- const testResource = defineResource({
701
- id: "test.resource",
702
- dispose: disposeFn,
703
- init: async () => "Resource Value",
704
- });
705
-
706
- const app = defineResource({
707
- id: "app",
708
- register: [testResource],
709
- dependencies: { testResource },
710
- async init(_, { testResource }) {
711
- expect(testResource).toBe("Resource Value");
712
- return testResource;
713
- },
714
- });
715
-
716
- const result = await run(app);
717
- expect(result.value).toBe("Resource Value");
718
- await result.dispose();
719
- expect(disposeFn).toHaveBeenCalledWith(
720
- "Resource Value",
721
- {},
722
- {},
723
- undefined
724
- );
725
- });
726
-
727
- it("should work with primitive return values", async () => {
728
- const disposeFn = jest.fn();
729
- const testResource = defineResource({
730
- id: "test.resource",
731
- dispose: disposeFn,
732
- init: async () => "Resource Value",
733
- });
734
-
735
- const app = defineResource({
736
- id: "app",
737
- register: [testResource],
738
- dependencies: { testResource },
739
- async init(_, { testResource }) {
740
- return 42; // primitive number
741
- },
742
- });
743
-
744
- const result = await run(app);
745
- expect(result.value + 1).toBe(43); // should work as number
746
- expect(result.value).toBe(42);
747
- await result.dispose();
748
- expect(disposeFn).toHaveBeenCalled();
749
- });
750
-
751
- it("should work with object return values", async () => {
752
- const disposeFn = jest.fn();
753
- const testResource = defineResource({
754
- id: "test.resource",
755
- dispose: disposeFn,
756
- init: async () => "Resource Value",
757
- });
758
-
759
- const app = defineResource({
760
- id: "app",
761
- register: [testResource],
762
- dependencies: { testResource },
763
- async init(_, { testResource }) {
764
- return { api: "server", value: 42 };
765
- },
766
- });
767
-
768
- const result = await run(app);
769
- expect(result.value.api).toBe("server");
770
- expect(result.value.value).toBe(42);
771
- await result.dispose();
772
- expect(disposeFn).toHaveBeenCalled();
773
- });
774
-
775
- it("should work with null return values", async () => {
776
- const disposeFn = jest.fn();
777
- const testResource = defineResource({
778
- id: "test.resource",
779
- dispose: disposeFn,
780
- init: async () => "Resource Value",
781
- });
782
-
783
- const app = defineResource({
784
- id: "app",
785
- register: [testResource],
786
- dependencies: { testResource },
787
- async init(_, { testResource }) {
788
- return null; // null return value
789
- },
790
- });
791
-
792
- const result = await run(app);
793
- expect(result.value).toBe(null);
794
- await result.dispose();
795
- expect(disposeFn).toHaveBeenCalled();
796
- });
797
-
798
- it("should work with undefined return values", async () => {
799
- const disposeFn = jest.fn();
800
- const testResource = defineResource({
801
- id: "test.resource",
802
- dispose: disposeFn,
803
- init: async () => "Resource Value",
804
- });
805
-
806
- const app = defineResource({
807
- id: "app",
808
- register: [testResource],
809
- dependencies: { testResource },
810
- async init(_, { testResource }) {
811
- return undefined; // undefined return value
812
- },
813
- });
814
-
815
- const result = await run(app);
816
- expect(result.value).toBe(undefined);
817
- await result.dispose();
818
- expect(disposeFn).toHaveBeenCalled();
819
- });
820
-
821
- it("should work with boolean return values", async () => {
822
- const disposeFn = jest.fn();
823
- const testResource = defineResource({
824
- id: "test.resource",
825
- dispose: disposeFn,
826
- init: async () => "Resource Value",
827
- });
828
-
829
- const app = defineResource({
830
- id: "app",
831
- register: [testResource],
832
- dependencies: { testResource },
833
- async init(_, { testResource }) {
834
- return true; // boolean return value
835
- },
836
- });
837
-
838
- const result = await run(app);
839
- expect(result.value).toBe(true);
840
- await result.dispose();
841
- expect(disposeFn).toHaveBeenCalled();
842
- });
843
-
844
- it("should forward string methods correctly", async () => {
845
- const disposeFn = jest.fn();
846
- const testResource = defineResource({
847
- id: "test.resource",
848
- dispose: disposeFn,
849
- init: async () => "Resource Value",
850
- });
851
-
852
- const app = defineResource({
853
- id: "app",
854
- register: [testResource],
855
- dependencies: { testResource },
856
- async init(_, { testResource }) {
857
- return "hello world test"; // string return value
858
- },
859
- });
860
-
861
- const result = await run(app);
862
- expect(result.value).toBe("hello world test");
863
- await result.dispose();
864
- expect(disposeFn).toHaveBeenCalled();
865
- });
866
-
867
- it("should work with symbol return values", async () => {
868
- const disposeFn = jest.fn();
869
- const testResource = defineResource({
870
- id: "test.resource",
871
- dispose: disposeFn,
872
- init: async () => "Resource Value",
873
- });
874
-
875
- const app = defineResource({
876
- id: "app",
877
- register: [testResource],
878
- dependencies: { testResource },
879
- async init(_, { testResource }) {
880
- return Symbol("test"); // symbol return value
881
- },
882
- });
883
-
884
- const result = await run(app);
885
- expect(typeof result.value).toBe("symbol");
886
- expect(result.value.toString()).toBe("Symbol(test)");
887
- await result.dispose();
888
- expect(disposeFn).toHaveBeenCalled();
889
- });
890
-
891
- it("should work with bigint return values", async () => {
892
- const disposeFn = jest.fn();
893
- const testResource = defineResource({
894
- id: "test.resource",
895
- dispose: disposeFn,
896
- init: async () => "Resource Value",
897
- });
898
-
899
- const app = defineResource({
900
- id: "app",
901
- register: [testResource],
902
- dependencies: { testResource },
903
- async init(_, { testResource }) {
904
- return BigInt(123); // bigint return value
905
- },
906
- });
907
-
908
- const result = await run(app);
909
- expect(typeof result.value).toBe("bigint");
910
- expect(result.value).toBe(BigInt(123));
911
- expect(result.value.toString()).toBe("123");
912
- await result.dispose();
913
- expect(disposeFn).toHaveBeenCalled();
914
- });
915
- });
916
-
917
- describe("private context resources", () => {
918
- it("should share private context between init and dispose", async () => {
919
- const disposeFn = jest.fn();
920
- const dbResource = defineResource({
921
- id: "db.resource",
922
- context: () => ({ connections: [] as string[] }),
923
- async init(config, deps, context) {
924
- context.connections.push("main-db");
925
- // @ts-expect-error - should not allow access to non-existent properties
926
- context.nonExistentProperty;
927
- // @ts-expect-error - should not allow writing to non-existent properties
928
- context.anotherProperty = "test";
929
- return "connected";
930
- },
931
- async dispose(value, config, deps, context) {
932
- expect(context.connections).toEqual(["main-db"]);
933
- disposeFn();
934
-
935
- context.connections.length = 0; // cleanup
936
- // @ts-expect-error - should not allow access to non-existent properties in dispose
937
- context.undefinedProperty;
938
- },
939
- });
940
-
941
- const app = defineResource({
942
- id: "app",
943
- register: [dbResource],
944
- dependencies: { dbResource },
945
- async init(_, { dbResource }) {
946
- return dbResource;
947
- },
948
- });
949
-
950
- const result = await run(app);
951
- await result.dispose();
952
-
953
- expect(disposeFn).toHaveBeenCalled();
954
- });
955
-
956
- it("should work without context", async () => {
957
- const simpleResource = defineResource({
958
- id: "simple.resource",
959
- async init(config, deps) {
960
- return "simple value";
961
- },
962
- });
963
-
964
- const app = defineResource({
965
- id: "app",
966
- register: [simpleResource],
967
- dependencies: { simpleResource },
968
- async init(_, { simpleResource }) {
969
- return simpleResource;
970
- },
971
- });
972
-
973
- const result = await run(app);
974
- expect(result.value).toBe("simple value");
975
- await result.dispose();
976
- });
977
-
978
- it("should work with private context and dispose only", async () => {
979
- const disposeFn = jest.fn();
980
-
981
- // Test dispose function with private context but no init
982
- const contextOnlyResource = defineResource({
983
- id: "context.only",
984
- context: () => ({ cleanupTasks: ["task1", "task2"] }),
985
- // This resource only has dispose, testing the private context in dispose scenario
986
- dispose: async function (value, config, deps, context) {
987
- // When there's no init, dispose still gets called but private context should be available
988
- // Note: This won't have private context since init wasn't called
989
- disposeFn();
990
- },
991
- });
992
-
993
- const app = defineResource({
994
- id: "app",
995
- register: [contextOnlyResource],
996
- dependencies: { contextOnlyResource },
997
- async init(_, { contextOnlyResource }) {
998
- // Resource without init should be undefined
999
- expect(contextOnlyResource).toBeUndefined();
1000
- return "app started";
1001
- },
1002
- });
1003
-
1004
- const result = await run(app);
1005
- expect(result.value).toBe("app started");
1006
- await result.dispose();
1007
- expect(disposeFn).toHaveBeenCalled();
1008
- });
1009
-
1010
- it("should handle resources without init method and proper disposal types", async () => {
1011
- const disposeFn = jest.fn();
1012
-
1013
- // Resource without init - just registers other resources
1014
- const registrationOnlyResource = defineResource({
1015
- id: "registration.only",
1016
- // No init method
1017
- dispose: disposeFn,
1018
- register: [],
1019
- });
1020
-
1021
- const app = defineResource({
1022
- id: "app",
1023
- register: [registrationOnlyResource],
1024
- dependencies: { registrationOnlyResource },
1025
- async init(_, { registrationOnlyResource }) {
1026
- // registrationOnlyResource should be undefined since no init
1027
- expect(registrationOnlyResource).toBeUndefined();
1028
- return 42;
1029
- },
1030
- });
1031
-
1032
- const result = await run(app);
1033
- expect(result.value).toBe(42);
1034
- await result.dispose();
1035
-
1036
- // dispose should be called with undefined value since no init
1037
- expect(disposeFn).toHaveBeenCalledWith(undefined, {}, {}, {});
1038
- });
1039
- });
1040
- });