@c9up/ream 0.1.3

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 (451) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/dist/Application.d.ts +71 -0
  4. package/dist/Application.d.ts.map +1 -0
  5. package/dist/Application.js +151 -0
  6. package/dist/Application.js.map +1 -0
  7. package/dist/Codemods.d.ts +16 -0
  8. package/dist/Codemods.d.ts.map +1 -0
  9. package/dist/Codemods.js +277 -0
  10. package/dist/Codemods.js.map +1 -0
  11. package/dist/ConfigLoader.d.ts +29 -0
  12. package/dist/ConfigLoader.d.ts.map +1 -0
  13. package/dist/ConfigLoader.js +43 -0
  14. package/dist/ConfigLoader.js.map +1 -0
  15. package/dist/ErrorBoundary.d.ts +51 -0
  16. package/dist/ErrorBoundary.d.ts.map +1 -0
  17. package/dist/ErrorBoundary.js +122 -0
  18. package/dist/ErrorBoundary.js.map +1 -0
  19. package/dist/GracefulShutdown.d.ts +28 -0
  20. package/dist/GracefulShutdown.d.ts.map +1 -0
  21. package/dist/GracefulShutdown.js +55 -0
  22. package/dist/GracefulShutdown.js.map +1 -0
  23. package/dist/HealthCheck.d.ts +42 -0
  24. package/dist/HealthCheck.d.ts.map +1 -0
  25. package/dist/HealthCheck.js +65 -0
  26. package/dist/HealthCheck.js.map +1 -0
  27. package/dist/HotReload.d.ts +28 -0
  28. package/dist/HotReload.d.ts.map +1 -0
  29. package/dist/HotReload.js +60 -0
  30. package/dist/HotReload.js.map +1 -0
  31. package/dist/HttpKernel.d.ts +62 -0
  32. package/dist/HttpKernel.d.ts.map +1 -0
  33. package/dist/HttpKernel.js +210 -0
  34. package/dist/HttpKernel.js.map +1 -0
  35. package/dist/Ignitor.d.ts +195 -0
  36. package/dist/Ignitor.d.ts.map +1 -0
  37. package/dist/Ignitor.js +505 -0
  38. package/dist/Ignitor.js.map +1 -0
  39. package/dist/Provider.d.ts +54 -0
  40. package/dist/Provider.d.ts.map +1 -0
  41. package/dist/Provider.js +37 -0
  42. package/dist/Provider.js.map +1 -0
  43. package/dist/bodyparser/BodyParserMiddleware.d.ts +38 -0
  44. package/dist/bodyparser/BodyParserMiddleware.d.ts.map +1 -0
  45. package/dist/bodyparser/BodyParserMiddleware.js +143 -0
  46. package/dist/bodyparser/BodyParserMiddleware.js.map +1 -0
  47. package/dist/bodyparser/MultipartFile.d.ts +77 -0
  48. package/dist/bodyparser/MultipartFile.d.ts.map +1 -0
  49. package/dist/bodyparser/MultipartFile.js +138 -0
  50. package/dist/bodyparser/MultipartFile.js.map +1 -0
  51. package/dist/bodyparser/parseSize.d.ts +6 -0
  52. package/dist/bodyparser/parseSize.d.ts.map +1 -0
  53. package/dist/bodyparser/parseSize.js +21 -0
  54. package/dist/bodyparser/parseSize.js.map +1 -0
  55. package/dist/bootstrap/hyper-server.d.ts +27 -0
  56. package/dist/bootstrap/hyper-server.d.ts.map +1 -0
  57. package/dist/bootstrap/hyper-server.js +63 -0
  58. package/dist/bootstrap/hyper-server.js.map +1 -0
  59. package/dist/console/CommandRunner.d.ts +18 -0
  60. package/dist/console/CommandRunner.d.ts.map +1 -0
  61. package/dist/console/CommandRunner.js +65 -0
  62. package/dist/console/CommandRunner.js.map +1 -0
  63. package/dist/container/Container.d.ts +60 -0
  64. package/dist/container/Container.d.ts.map +1 -0
  65. package/dist/container/Container.js +329 -0
  66. package/dist/container/Container.js.map +1 -0
  67. package/dist/container/types.d.ts +25 -0
  68. package/dist/container/types.d.ts.map +1 -0
  69. package/dist/container/types.js +6 -0
  70. package/dist/container/types.js.map +1 -0
  71. package/dist/decorators/Lazy.d.ts +19 -0
  72. package/dist/decorators/Lazy.d.ts.map +1 -0
  73. package/dist/decorators/Lazy.js +53 -0
  74. package/dist/decorators/Lazy.js.map +1 -0
  75. package/dist/decorators/Service.d.ts +48 -0
  76. package/dist/decorators/Service.d.ts.map +1 -0
  77. package/dist/decorators/Service.js +70 -0
  78. package/dist/decorators/Service.js.map +1 -0
  79. package/dist/errors/FuzzyMatcher.d.ts +41 -0
  80. package/dist/errors/FuzzyMatcher.d.ts.map +1 -0
  81. package/dist/errors/FuzzyMatcher.js +81 -0
  82. package/dist/errors/FuzzyMatcher.js.map +1 -0
  83. package/dist/errors/ModuleErrors.d.ts +41 -0
  84. package/dist/errors/ModuleErrors.d.ts.map +1 -0
  85. package/dist/errors/ModuleErrors.js +65 -0
  86. package/dist/errors/ModuleErrors.js.map +1 -0
  87. package/dist/errors/PipelineStageError.d.ts +31 -0
  88. package/dist/errors/PipelineStageError.d.ts.map +1 -0
  89. package/dist/errors/PipelineStageError.js +77 -0
  90. package/dist/errors/PipelineStageError.js.map +1 -0
  91. package/dist/errors/ReamError.d.ts +50 -0
  92. package/dist/errors/ReamError.d.ts.map +1 -0
  93. package/dist/errors/ReamError.js +108 -0
  94. package/dist/errors/ReamError.js.map +1 -0
  95. package/dist/events/Emitter.d.ts +124 -0
  96. package/dist/events/Emitter.d.ts.map +1 -0
  97. package/dist/events/Emitter.js +271 -0
  98. package/dist/events/Emitter.js.map +1 -0
  99. package/dist/events/EventsProvider.d.ts +28 -0
  100. package/dist/events/EventsProvider.d.ts.map +1 -0
  101. package/dist/events/EventsProvider.js +36 -0
  102. package/dist/events/EventsProvider.js.map +1 -0
  103. package/dist/events/config.d.ts +8 -0
  104. package/dist/events/config.d.ts.map +1 -0
  105. package/dist/events/config.js +4 -0
  106. package/dist/events/config.js.map +1 -0
  107. package/dist/events/configure.d.ts +10 -0
  108. package/dist/events/configure.d.ts.map +1 -0
  109. package/dist/events/configure.js +11 -0
  110. package/dist/events/configure.js.map +1 -0
  111. package/dist/events/helix/helpers.d.ts +62 -0
  112. package/dist/events/helix/helpers.d.ts.map +1 -0
  113. package/dist/events/helix/helpers.js +187 -0
  114. package/dist/events/helix/helpers.js.map +1 -0
  115. package/dist/events/index.d.ts +17 -0
  116. package/dist/events/index.d.ts.map +1 -0
  117. package/dist/events/index.js +15 -0
  118. package/dist/events/index.js.map +1 -0
  119. package/dist/events/native.d.ts +21 -0
  120. package/dist/events/native.d.ts.map +1 -0
  121. package/dist/events/native.js +17 -0
  122. package/dist/events/native.js.map +1 -0
  123. package/dist/events/services/main.d.ts +18 -0
  124. package/dist/events/services/main.d.ts.map +1 -0
  125. package/dist/events/services/main.js +31 -0
  126. package/dist/events/services/main.js.map +1 -0
  127. package/dist/events/testing/FakeBus.d.ts +66 -0
  128. package/dist/events/testing/FakeBus.d.ts.map +1 -0
  129. package/dist/events/testing/FakeBus.js +356 -0
  130. package/dist/events/testing/FakeBus.js.map +1 -0
  131. package/dist/graphql/GraphQLEngine.d.ts +69 -0
  132. package/dist/graphql/GraphQLEngine.d.ts.map +1 -0
  133. package/dist/graphql/GraphQLEngine.js +309 -0
  134. package/dist/graphql/GraphQLEngine.js.map +1 -0
  135. package/dist/graphql/GraphQLProvider.d.ts +32 -0
  136. package/dist/graphql/GraphQLProvider.d.ts.map +1 -0
  137. package/dist/graphql/GraphQLProvider.js +49 -0
  138. package/dist/graphql/GraphQLProvider.js.map +1 -0
  139. package/dist/helpers/base64.d.ts +40 -0
  140. package/dist/helpers/base64.d.ts.map +1 -0
  141. package/dist/helpers/base64.js +70 -0
  142. package/dist/helpers/base64.js.map +1 -0
  143. package/dist/helpers/index.d.ts +7 -0
  144. package/dist/helpers/index.d.ts.map +1 -0
  145. package/dist/helpers/index.js +5 -0
  146. package/dist/helpers/index.js.map +1 -0
  147. package/dist/helpers/is.d.ts +101 -0
  148. package/dist/helpers/is.d.ts.map +1 -0
  149. package/dist/helpers/is.js +151 -0
  150. package/dist/helpers/is.js.map +1 -0
  151. package/dist/helpers/napi-loader.d.ts +46 -0
  152. package/dist/helpers/napi-loader.d.ts.map +1 -0
  153. package/dist/helpers/napi-loader.js +69 -0
  154. package/dist/helpers/napi-loader.js.map +1 -0
  155. package/dist/helpers/safeEqual.d.ts +9 -0
  156. package/dist/helpers/safeEqual.d.ts.map +1 -0
  157. package/dist/helpers/safeEqual.js +16 -0
  158. package/dist/helpers/safeEqual.js.map +1 -0
  159. package/dist/helpers/string.d.ts +161 -0
  160. package/dist/helpers/string.d.ts.map +1 -0
  161. package/dist/helpers/string.js +429 -0
  162. package/dist/helpers/string.js.map +1 -0
  163. package/dist/helpers/types.d.ts +83 -0
  164. package/dist/helpers/types.d.ts.map +1 -0
  165. package/dist/helpers/types.js +6 -0
  166. package/dist/helpers/types.js.map +1 -0
  167. package/dist/http/Exception.d.ts +103 -0
  168. package/dist/http/Exception.d.ts.map +1 -0
  169. package/dist/http/Exception.js +228 -0
  170. package/dist/http/Exception.js.map +1 -0
  171. package/dist/http/HttpContext.d.ts +69 -0
  172. package/dist/http/HttpContext.d.ts.map +1 -0
  173. package/dist/http/HttpContext.js +55 -0
  174. package/dist/http/HttpContext.js.map +1 -0
  175. package/dist/http/RedirectBuilder.d.ts +31 -0
  176. package/dist/http/RedirectBuilder.d.ts.map +1 -0
  177. package/dist/http/RedirectBuilder.js +75 -0
  178. package/dist/http/RedirectBuilder.js.map +1 -0
  179. package/dist/http/Request.d.ts +160 -0
  180. package/dist/http/Request.d.ts.map +1 -0
  181. package/dist/http/Request.js +484 -0
  182. package/dist/http/Request.js.map +1 -0
  183. package/dist/http/Response.d.ts +114 -0
  184. package/dist/http/Response.d.ts.map +1 -0
  185. package/dist/http/Response.js +303 -0
  186. package/dist/http/Response.js.map +1 -0
  187. package/dist/http/SseStream.d.ts +89 -0
  188. package/dist/http/SseStream.d.ts.map +1 -0
  189. package/dist/http/SseStream.js +228 -0
  190. package/dist/http/SseStream.js.map +1 -0
  191. package/dist/http/urlDecode.d.ts +8 -0
  192. package/dist/http/urlDecode.d.ts.map +1 -0
  193. package/dist/http/urlDecode.js +18 -0
  194. package/dist/http/urlDecode.js.map +1 -0
  195. package/dist/index.d.ts +92 -0
  196. package/dist/index.d.ts.map +1 -0
  197. package/dist/index.js +67 -0
  198. package/dist/index.js.map +1 -0
  199. package/dist/middleware/Pipeline.d.ts +36 -0
  200. package/dist/middleware/Pipeline.d.ts.map +1 -0
  201. package/dist/middleware/Pipeline.js +104 -0
  202. package/dist/middleware/Pipeline.js.map +1 -0
  203. package/dist/openapi/OpenApiGenerator.d.ts +58 -0
  204. package/dist/openapi/OpenApiGenerator.d.ts.map +1 -0
  205. package/dist/openapi/OpenApiGenerator.js +192 -0
  206. package/dist/openapi/OpenApiGenerator.js.map +1 -0
  207. package/dist/openapi/OpenApiMiddleware.d.ts +24 -0
  208. package/dist/openapi/OpenApiMiddleware.d.ts.map +1 -0
  209. package/dist/openapi/OpenApiMiddleware.js +78 -0
  210. package/dist/openapi/OpenApiMiddleware.js.map +1 -0
  211. package/dist/openapi/OpenApiProvider.d.ts +36 -0
  212. package/dist/openapi/OpenApiProvider.d.ts.map +1 -0
  213. package/dist/openapi/OpenApiProvider.js +42 -0
  214. package/dist/openapi/OpenApiProvider.js.map +1 -0
  215. package/dist/resources/ApiResource.d.ts +45 -0
  216. package/dist/resources/ApiResource.d.ts.map +1 -0
  217. package/dist/resources/ApiResource.js +58 -0
  218. package/dist/resources/ApiResource.js.map +1 -0
  219. package/dist/router/Router.d.ts +205 -0
  220. package/dist/router/Router.d.ts.map +1 -0
  221. package/dist/router/Router.js +552 -0
  222. package/dist/router/Router.js.map +1 -0
  223. package/dist/rpc/RpcProvider.d.ts +34 -0
  224. package/dist/rpc/RpcProvider.d.ts.map +1 -0
  225. package/dist/rpc/RpcProvider.js +37 -0
  226. package/dist/rpc/RpcProvider.js.map +1 -0
  227. package/dist/rpc/RpcRouter.d.ts +61 -0
  228. package/dist/rpc/RpcRouter.d.ts.map +1 -0
  229. package/dist/rpc/RpcRouter.js +187 -0
  230. package/dist/rpc/RpcRouter.js.map +1 -0
  231. package/dist/scheduler/Schedule.d.ts +53 -0
  232. package/dist/scheduler/Schedule.d.ts.map +1 -0
  233. package/dist/scheduler/Schedule.js +76 -0
  234. package/dist/scheduler/Schedule.js.map +1 -0
  235. package/dist/scheduler/ScheduleProvider.d.ts +56 -0
  236. package/dist/scheduler/ScheduleProvider.d.ts.map +1 -0
  237. package/dist/scheduler/ScheduleProvider.js +145 -0
  238. package/dist/scheduler/ScheduleProvider.js.map +1 -0
  239. package/dist/scheduler/Scheduler.d.ts +209 -0
  240. package/dist/scheduler/Scheduler.d.ts.map +1 -0
  241. package/dist/scheduler/Scheduler.js +432 -0
  242. package/dist/scheduler/Scheduler.js.map +1 -0
  243. package/dist/scheduler/index.d.ts +14 -0
  244. package/dist/scheduler/index.d.ts.map +1 -0
  245. package/dist/scheduler/index.js +6 -0
  246. package/dist/scheduler/index.js.map +1 -0
  247. package/dist/scheduler/locks/LockBackend.d.ts +37 -0
  248. package/dist/scheduler/locks/LockBackend.d.ts.map +1 -0
  249. package/dist/scheduler/locks/LockBackend.js +13 -0
  250. package/dist/scheduler/locks/LockBackend.js.map +1 -0
  251. package/dist/scheduler/locks/MemoryLockBackend.d.ts +39 -0
  252. package/dist/scheduler/locks/MemoryLockBackend.d.ts.map +1 -0
  253. package/dist/scheduler/locks/MemoryLockBackend.js +71 -0
  254. package/dist/scheduler/locks/MemoryLockBackend.js.map +1 -0
  255. package/dist/scheduler/observability/ErrorReporter.d.ts +15 -0
  256. package/dist/scheduler/observability/ErrorReporter.d.ts.map +1 -0
  257. package/dist/scheduler/observability/ErrorReporter.js +13 -0
  258. package/dist/scheduler/observability/ErrorReporter.js.map +1 -0
  259. package/dist/scheduler/observability/ScheduleEvent.d.ts +57 -0
  260. package/dist/scheduler/observability/ScheduleEvent.d.ts.map +1 -0
  261. package/dist/scheduler/observability/ScheduleEvent.js +12 -0
  262. package/dist/scheduler/observability/ScheduleEvent.js.map +1 -0
  263. package/dist/scheduler/observability/ScheduleEventSink.d.ts +20 -0
  264. package/dist/scheduler/observability/ScheduleEventSink.d.ts.map +1 -0
  265. package/dist/scheduler/observability/ScheduleEventSink.js +17 -0
  266. package/dist/scheduler/observability/ScheduleEventSink.js.map +1 -0
  267. package/dist/scheduler/observability/StatsTracker.d.ts +50 -0
  268. package/dist/scheduler/observability/StatsTracker.d.ts.map +1 -0
  269. package/dist/scheduler/observability/StatsTracker.js +96 -0
  270. package/dist/scheduler/observability/StatsTracker.js.map +1 -0
  271. package/dist/security/CookieSigner.d.ts +13 -0
  272. package/dist/security/CookieSigner.d.ts.map +1 -0
  273. package/dist/security/CookieSigner.js +51 -0
  274. package/dist/security/CookieSigner.js.map +1 -0
  275. package/dist/security/SignedUrl.d.ts +17 -0
  276. package/dist/security/SignedUrl.d.ts.map +1 -0
  277. package/dist/security/SignedUrl.js +63 -0
  278. package/dist/security/SignedUrl.js.map +1 -0
  279. package/dist/security/crypto.d.ts +25 -0
  280. package/dist/security/crypto.d.ts.map +1 -0
  281. package/dist/security/crypto.js +82 -0
  282. package/dist/security/crypto.js.map +1 -0
  283. package/dist/server/HyperServer.d.ts +64 -0
  284. package/dist/server/HyperServer.d.ts.map +1 -0
  285. package/dist/server/HyperServer.js +54 -0
  286. package/dist/server/HyperServer.js.map +1 -0
  287. package/dist/server/Server.d.ts +68 -0
  288. package/dist/server/Server.d.ts.map +1 -0
  289. package/dist/server/Server.js +113 -0
  290. package/dist/server/Server.js.map +1 -0
  291. package/dist/services/app.d.ts +14 -0
  292. package/dist/services/app.d.ts.map +1 -0
  293. package/dist/services/app.js +27 -0
  294. package/dist/services/app.js.map +1 -0
  295. package/dist/services/router.d.ts +21 -0
  296. package/dist/services/router.d.ts.map +1 -0
  297. package/dist/services/router.js +36 -0
  298. package/dist/services/router.js.map +1 -0
  299. package/dist/services/server.d.ts +16 -0
  300. package/dist/services/server.d.ts.map +1 -0
  301. package/dist/services/server.js +32 -0
  302. package/dist/services/server.js.map +1 -0
  303. package/dist/session/Session.d.ts +88 -0
  304. package/dist/session/Session.d.ts.map +1 -0
  305. package/dist/session/Session.js +186 -0
  306. package/dist/session/Session.js.map +1 -0
  307. package/dist/session/SessionMiddleware.d.ts +16 -0
  308. package/dist/session/SessionMiddleware.d.ts.map +1 -0
  309. package/dist/session/SessionMiddleware.js +132 -0
  310. package/dist/session/SessionMiddleware.js.map +1 -0
  311. package/dist/session/drivers/CookieDriver.d.ts +17 -0
  312. package/dist/session/drivers/CookieDriver.d.ts.map +1 -0
  313. package/dist/session/drivers/CookieDriver.js +42 -0
  314. package/dist/session/drivers/CookieDriver.js.map +1 -0
  315. package/dist/session/drivers/MemoryDriver.d.ts +9 -0
  316. package/dist/session/drivers/MemoryDriver.d.ts.map +1 -0
  317. package/dist/session/drivers/MemoryDriver.js +24 -0
  318. package/dist/session/drivers/MemoryDriver.js.map +1 -0
  319. package/dist/storage/S3Driver.d.ts +27 -0
  320. package/dist/storage/S3Driver.d.ts.map +1 -0
  321. package/dist/storage/S3Driver.js +135 -0
  322. package/dist/storage/S3Driver.js.map +1 -0
  323. package/dist/storage/StaticMiddleware.d.ts +27 -0
  324. package/dist/storage/StaticMiddleware.d.ts.map +1 -0
  325. package/dist/storage/StaticMiddleware.js +153 -0
  326. package/dist/storage/StaticMiddleware.js.map +1 -0
  327. package/dist/storage/StaticProvider.d.ts +26 -0
  328. package/dist/storage/StaticProvider.d.ts.map +1 -0
  329. package/dist/storage/StaticProvider.js +31 -0
  330. package/dist/storage/StaticProvider.js.map +1 -0
  331. package/dist/storage/StorageManager.d.ts +31 -0
  332. package/dist/storage/StorageManager.d.ts.map +1 -0
  333. package/dist/storage/StorageManager.js +120 -0
  334. package/dist/storage/StorageManager.js.map +1 -0
  335. package/dist/testing/RequestBuilder.d.ts +67 -0
  336. package/dist/testing/RequestBuilder.d.ts.map +1 -0
  337. package/dist/testing/RequestBuilder.js +202 -0
  338. package/dist/testing/RequestBuilder.js.map +1 -0
  339. package/dist/testing/TestClient.d.ts +96 -0
  340. package/dist/testing/TestClient.d.ts.map +1 -0
  341. package/dist/testing/TestClient.js +263 -0
  342. package/dist/testing/TestClient.js.map +1 -0
  343. package/dist/types/helpers.d.ts +47 -0
  344. package/dist/types/helpers.d.ts.map +1 -0
  345. package/dist/types/helpers.js +5 -0
  346. package/dist/types/helpers.js.map +1 -0
  347. package/events.darwin-arm64.node +0 -0
  348. package/events.darwin-x64.node +0 -0
  349. package/events.linux-arm64-gnu.node +0 -0
  350. package/events.linux-x64-gnu.node +0 -0
  351. package/events.win32-x64-msvc.node +0 -0
  352. package/index.darwin-arm64.node +0 -0
  353. package/index.darwin-x64.node +0 -0
  354. package/index.linux-arm64-gnu.node +0 -0
  355. package/index.linux-x64-gnu.node +0 -0
  356. package/index.win32-x64-msvc.node +0 -0
  357. package/package.json +106 -0
  358. package/scheduler.darwin-arm64.node +0 -0
  359. package/scheduler.darwin-x64.node +0 -0
  360. package/scheduler.linux-arm64-gnu.node +0 -0
  361. package/scheduler.linux-x64-gnu.node +0 -0
  362. package/scheduler.win32-x64-msvc.node +0 -0
  363. package/scripts/copy-napi.mjs +113 -0
  364. package/src/Application.ts +177 -0
  365. package/src/Codemods.ts +343 -0
  366. package/src/ConfigLoader.ts +49 -0
  367. package/src/ErrorBoundary.ts +157 -0
  368. package/src/GracefulShutdown.ts +80 -0
  369. package/src/HealthCheck.ts +96 -0
  370. package/src/HotReload.ts +78 -0
  371. package/src/HttpKernel.ts +305 -0
  372. package/src/Ignitor.ts +656 -0
  373. package/src/Provider.ts +74 -0
  374. package/src/bodyparser/BodyParserMiddleware.ts +183 -0
  375. package/src/bodyparser/MultipartFile.ts +181 -0
  376. package/src/bodyparser/parseSize.ts +19 -0
  377. package/src/bootstrap/hyper-server.ts +78 -0
  378. package/src/console/CommandRunner.ts +82 -0
  379. package/src/container/Container.ts +383 -0
  380. package/src/container/types.ts +30 -0
  381. package/src/decorators/Lazy.ts +57 -0
  382. package/src/decorators/Service.ts +85 -0
  383. package/src/errors/FuzzyMatcher.ts +93 -0
  384. package/src/errors/ModuleErrors.ts +73 -0
  385. package/src/errors/PipelineStageError.ts +97 -0
  386. package/src/errors/ReamError.ts +138 -0
  387. package/src/events/Emitter.ts +333 -0
  388. package/src/events/EventsProvider.ts +58 -0
  389. package/src/events/config.ts +10 -0
  390. package/src/events/configure.ts +19 -0
  391. package/src/events/helix/helpers.ts +260 -0
  392. package/src/events/index.ts +22 -0
  393. package/src/events/native.ts +37 -0
  394. package/src/events/services/main.ts +39 -0
  395. package/src/events/testing/FakeBus.ts +420 -0
  396. package/src/graphql/GraphQLEngine.ts +421 -0
  397. package/src/graphql/GraphQLProvider.ts +59 -0
  398. package/src/helpers/base64.ts +72 -0
  399. package/src/helpers/index.ts +6 -0
  400. package/src/helpers/is.ts +162 -0
  401. package/src/helpers/napi-loader.ts +106 -0
  402. package/src/helpers/safeEqual.ts +15 -0
  403. package/src/helpers/string.ts +469 -0
  404. package/src/helpers/types.ts +100 -0
  405. package/src/http/Exception.ts +272 -0
  406. package/src/http/HttpContext.ts +108 -0
  407. package/src/http/RedirectBuilder.ts +89 -0
  408. package/src/http/Request.ts +540 -0
  409. package/src/http/Response.ts +351 -0
  410. package/src/http/SseStream.ts +250 -0
  411. package/src/http/urlDecode.ts +18 -0
  412. package/src/index.ts +263 -0
  413. package/src/middleware/Pipeline.ts +136 -0
  414. package/src/openapi/OpenApiGenerator.ts +254 -0
  415. package/src/openapi/OpenApiMiddleware.ts +101 -0
  416. package/src/openapi/OpenApiProvider.ts +67 -0
  417. package/src/resources/ApiResource.ts +79 -0
  418. package/src/router/Router.ts +733 -0
  419. package/src/rpc/RpcProvider.ts +54 -0
  420. package/src/rpc/RpcRouter.ts +243 -0
  421. package/src/scheduler/Schedule.ts +96 -0
  422. package/src/scheduler/ScheduleProvider.ts +177 -0
  423. package/src/scheduler/Scheduler.ts +601 -0
  424. package/src/scheduler/index.ts +24 -0
  425. package/src/scheduler/locks/LockBackend.ts +38 -0
  426. package/src/scheduler/locks/MemoryLockBackend.ts +85 -0
  427. package/src/scheduler/observability/ErrorReporter.ts +13 -0
  428. package/src/scheduler/observability/ScheduleEvent.ts +61 -0
  429. package/src/scheduler/observability/ScheduleEventSink.ts +21 -0
  430. package/src/scheduler/observability/StatsTracker.ts +134 -0
  431. package/src/security/CookieSigner.ts +54 -0
  432. package/src/security/SignedUrl.ts +71 -0
  433. package/src/security/crypto.ts +98 -0
  434. package/src/server/HyperServer.ts +121 -0
  435. package/src/server/Server.ts +147 -0
  436. package/src/services/app.ts +34 -0
  437. package/src/services/router.ts +44 -0
  438. package/src/services/server.ts +40 -0
  439. package/src/session/Session.ts +231 -0
  440. package/src/session/SessionMiddleware.ts +153 -0
  441. package/src/session/drivers/CookieDriver.ts +48 -0
  442. package/src/session/drivers/MemoryDriver.ts +29 -0
  443. package/src/storage/S3Driver.ts +171 -0
  444. package/src/storage/StaticMiddleware.ts +182 -0
  445. package/src/storage/StaticProvider.ts +40 -0
  446. package/src/storage/StorageManager.ts +142 -0
  447. package/src/testing/RequestBuilder.ts +275 -0
  448. package/src/testing/TestClient.ts +344 -0
  449. package/src/types/helpers.ts +52 -0
  450. package/swcrc.app.json +17 -0
  451. package/tsconfig.app.json +21 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * JSON-RPC 2.0 Router — dispatches RPC method calls to handlers.
3
+ *
4
+ * Same middleware/guard/validate pipeline as REST routes.
5
+ *
6
+ * Usage:
7
+ * rpc.method('task.validate', handler).guard('jwt').role('cs_member')
8
+ * rpc.namespace('task', TaskController) // every public method, DI-resolved per call
9
+ * rpc.group({ guard: 'jwt' }, (r) => { r.method('user.find', handler) })
10
+ *
11
+ * @implements MISS-27
12
+ */
13
+ import type { HttpContext } from '../http/HttpContext.js';
14
+ export type RpcHandler = (ctx: HttpContext, params: unknown) => Promise<unknown> | unknown;
15
+ export interface RpcMethodDefinition {
16
+ name: string;
17
+ handler: RpcHandler;
18
+ guards: string[];
19
+ roles: string[];
20
+ permissions: string[];
21
+ middleware: string[];
22
+ validator?: string;
23
+ }
24
+ export declare class RpcMethodBuilder {
25
+ #private;
26
+ constructor(def: RpcMethodDefinition);
27
+ guard(...guards: string[]): this;
28
+ role(...roles: string[]): this;
29
+ permission(...permissions: string[]): this;
30
+ validate(validator: string): this;
31
+ middleware(...names: string[]): this;
32
+ }
33
+ export declare class RpcRouter {
34
+ #private;
35
+ /**
36
+ * Set the IoC container used to resolve `namespace()` controllers — mirrors
37
+ * `GraphQLEngine.useContainer()` so RPC and GraphQL resolve class handlers the
38
+ * same way (fresh DI per call). Without a container, controllers fall back to
39
+ * `new Controller()`.
40
+ */
41
+ useContainer(container: {
42
+ make<T>(target: new (...args: unknown[]) => T): T;
43
+ }): void;
44
+ /** Register an RPC method. */
45
+ method(name: string, handler: RpcHandler): RpcMethodBuilder;
46
+ /** Register methods from a controller — auto-registers all public methods. */
47
+ namespace(prefix: string, controller: new (...args: unknown[]) => Record<string, (...args: unknown[]) => unknown>): void;
48
+ /** Group methods with shared guards/middleware. */
49
+ group(config: {
50
+ guard?: string;
51
+ guards?: string[];
52
+ middleware?: string[];
53
+ }, callback: (rpc: RpcRouter) => void): void;
54
+ /** Handle an incoming JSON-RPC request. */
55
+ handle(ctx: HttpContext): Promise<void>;
56
+ /** Get all registered method names. */
57
+ getMethods(): string[];
58
+ /** Get method definition for introspection. */
59
+ getMethod(name: string): RpcMethodDefinition | undefined;
60
+ }
61
+ //# sourceMappingURL=RpcRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RpcRouter.d.ts","sourceRoot":"","sources":["../../src/rpc/RpcRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAEzD,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;AAE1F,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,UAAU,CAAA;IACnB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,gBAAgB;;gBAGf,GAAG,EAAE,mBAAmB;IAIpC,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAKhC,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAK9B,UAAU,CAAC,GAAG,WAAW,EAAE,MAAM,EAAE,GAAG,IAAI;IAK1C,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKjC,UAAU,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;CAIrC;AA+DD,qBAAa,SAAS;;IAKpB;;;;;OAKG;IACH,YAAY,CAAC,SAAS,EAAE;QAAE,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;KAAE,GAAG,IAAI;IAIpF,8BAA8B;IAC9B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,gBAAgB;IAa3D,8EAA8E;IAC9E,SAAS,CACP,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,GACtF,IAAI;IAeP,mDAAmD;IACnD,KAAK,CACH,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,EACpE,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,GACjC,IAAI;IAWP,2CAA2C;IACrC,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD7C,uCAAuC;IACvC,UAAU,IAAI,MAAM,EAAE;IAItB,+CAA+C;IAC/C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;CAGzD"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * JSON-RPC 2.0 Router — dispatches RPC method calls to handlers.
3
+ *
4
+ * Same middleware/guard/validate pipeline as REST routes.
5
+ *
6
+ * Usage:
7
+ * rpc.method('task.validate', handler).guard('jwt').role('cs_member')
8
+ * rpc.namespace('task', TaskController) // every public method, DI-resolved per call
9
+ * rpc.group({ guard: 'jwt' }, (r) => { r.method('user.find', handler) })
10
+ *
11
+ * @implements MISS-27
12
+ */
13
+ export class RpcMethodBuilder {
14
+ #def;
15
+ constructor(def) {
16
+ this.#def = def;
17
+ }
18
+ guard(...guards) {
19
+ this.#def.guards.push(...guards);
20
+ return this;
21
+ }
22
+ role(...roles) {
23
+ this.#def.roles.push(...roles);
24
+ return this;
25
+ }
26
+ permission(...permissions) {
27
+ this.#def.permissions.push(...permissions);
28
+ return this;
29
+ }
30
+ validate(validator) {
31
+ this.#def.validator = validator;
32
+ return this;
33
+ }
34
+ middleware(...names) {
35
+ this.#def.middleware.push(...names);
36
+ return this;
37
+ }
38
+ }
39
+ /** Build a JSON-RPC 2.0 error envelope. */
40
+ function rpcError(code, message, id) {
41
+ return { jsonrpc: '2.0', error: { code, message }, id };
42
+ }
43
+ /** Validate the JSON-RPC envelope and extract method/params/id. */
44
+ function parseRpcRequest(request) {
45
+ if (!request || typeof request !== 'object') {
46
+ return { ok: false, response: rpcError(-32600, 'Invalid Request', null) };
47
+ }
48
+ // request is narrowed to a non-null object by the typeof check above.
49
+ const jsonrpc = 'jsonrpc' in request && typeof request.jsonrpc === 'string' ? request.jsonrpc : undefined;
50
+ const method = 'method' in request && typeof request.method === 'string' ? request.method : undefined;
51
+ const params = 'params' in request ? request.params : undefined;
52
+ const id = 'id' in request ? request.id : undefined;
53
+ if (jsonrpc !== '2.0' || !method) {
54
+ return { ok: false, response: rpcError(-32600, 'Invalid Request', id ?? null) };
55
+ }
56
+ return { ok: true, method, params, id };
57
+ }
58
+ /**
59
+ * Enforce the method's guards/roles/permissions against the request auth state.
60
+ * Returns the JSON-RPC error code+message to reject with, or undefined when the
61
+ * caller is authorized.
62
+ */
63
+ function checkRpcAuthorization(ctx, def) {
64
+ const needsAuth = def.guards.length > 0 || def.roles.length > 0 || def.permissions.length > 0;
65
+ if (needsAuth && !ctx.auth?.authenticated) {
66
+ return { code: -32003, message: 'Unauthorized' };
67
+ }
68
+ if (def.roles.length > 0) {
69
+ const userRoles = ctx.auth?.roles ?? [];
70
+ if (!def.roles.some((r) => userRoles.includes(r))) {
71
+ return { code: -32003, message: 'Insufficient role' };
72
+ }
73
+ }
74
+ if (def.permissions.length > 0) {
75
+ const userPerms = ctx.auth?.permissions ?? [];
76
+ if (!def.permissions.every((p) => userPerms.includes(p))) {
77
+ return { code: -32003, message: 'Insufficient permissions' };
78
+ }
79
+ }
80
+ return undefined;
81
+ }
82
+ export class RpcRouter {
83
+ #methods = new Map();
84
+ #groupConfig = null;
85
+ #container;
86
+ /**
87
+ * Set the IoC container used to resolve `namespace()` controllers — mirrors
88
+ * `GraphQLEngine.useContainer()` so RPC and GraphQL resolve class handlers the
89
+ * same way (fresh DI per call). Without a container, controllers fall back to
90
+ * `new Controller()`.
91
+ */
92
+ useContainer(container) {
93
+ this.#container = container;
94
+ }
95
+ /** Register an RPC method. */
96
+ method(name, handler) {
97
+ const def = {
98
+ name,
99
+ handler,
100
+ guards: [...(this.#groupConfig?.guards ?? [])],
101
+ roles: [...(this.#groupConfig?.roles ?? [])],
102
+ permissions: [],
103
+ middleware: [...(this.#groupConfig?.middleware ?? [])],
104
+ };
105
+ this.#methods.set(name, def);
106
+ return new RpcMethodBuilder(def);
107
+ }
108
+ /** Register methods from a controller — auto-registers all public methods. */
109
+ namespace(prefix, controller) {
110
+ const proto = controller.prototype;
111
+ const methods = Object.getOwnPropertyNames(proto).filter((m) => m !== 'constructor' && typeof proto[m] === 'function');
112
+ for (const methodName of methods) {
113
+ this.method(`${prefix}.${methodName}`, async (ctx, params) => {
114
+ // Resolve through the container on every call (fresh DI per request,
115
+ // like GraphQLEngine), falling back to a bare `new` when unset.
116
+ const instance = this.#container ? this.#container.make(controller) : new controller();
117
+ return instance[methodName](ctx, params);
118
+ });
119
+ }
120
+ }
121
+ /** Group methods with shared guards/middleware. */
122
+ group(config, callback) {
123
+ const prevConfig = this.#groupConfig;
124
+ this.#groupConfig = {
125
+ guards: [...(config.guards ?? []), ...(config.guard ? [config.guard] : [])],
126
+ roles: [],
127
+ middleware: config.middleware ?? [],
128
+ };
129
+ callback(this);
130
+ this.#groupConfig = prevConfig;
131
+ }
132
+ /** Handle an incoming JSON-RPC request. */
133
+ async handle(ctx) {
134
+ const body = ctx.request.body();
135
+ // Batch support (max 50 to prevent DoS)
136
+ if (Array.isArray(body)) {
137
+ if (body.length > 50) {
138
+ ctx.response.status(400).json({
139
+ jsonrpc: '2.0',
140
+ error: { code: -32600, message: 'Batch too large (max 50)' },
141
+ id: null,
142
+ });
143
+ return;
144
+ }
145
+ // Note: batch items share the same ctx (auth state). Each is processed sequentially.
146
+ const results = [];
147
+ for (const req of body) {
148
+ results.push(await this.#processOne(ctx, req));
149
+ }
150
+ ctx.response.status(200).json(results);
151
+ return;
152
+ }
153
+ const result = await this.#processOne(ctx, body);
154
+ ctx.response.status(200).json(result);
155
+ }
156
+ async #processOne(ctx, request) {
157
+ const parsed = parseRpcRequest(request);
158
+ if (!parsed.ok)
159
+ return parsed.response;
160
+ const { method, params, id } = parsed;
161
+ const def = this.#methods.get(method);
162
+ if (!def)
163
+ return rpcError(-32601, 'Method not found', id);
164
+ try {
165
+ const denied = checkRpcAuthorization(ctx, def);
166
+ if (denied)
167
+ return rpcError(denied.code, denied.message, id);
168
+ const result = await def.handler(ctx, params);
169
+ return { jsonrpc: '2.0', result, id };
170
+ }
171
+ catch (err) {
172
+ // Don't leak internal error details to caller
173
+ const isDev = process.env.NODE_ENV !== 'production';
174
+ const message = isDev && err instanceof Error ? err.message : 'Internal error';
175
+ return rpcError(-32603, message, id);
176
+ }
177
+ }
178
+ /** Get all registered method names. */
179
+ getMethods() {
180
+ return [...this.#methods.keys()];
181
+ }
182
+ /** Get method definition for introspection. */
183
+ getMethod(name) {
184
+ return this.#methods.get(name);
185
+ }
186
+ }
187
+ //# sourceMappingURL=RpcRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RpcRouter.js","sourceRoot":"","sources":["../../src/rpc/RpcRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAgBH,MAAM,OAAO,gBAAgB;IAC3B,IAAI,CAAqB;IAEzB,YAAY,GAAwB;QAClC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,GAAG,MAAgB;QACvB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAA;QAChC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAC,GAAG,KAAe;QACrB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAA;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,UAAU,CAAC,GAAG,WAAqB;QACjC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAA;QAC1C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ,CAAC,SAAiB;QACxB,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC/B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,UAAU,CAAC,GAAG,KAAe;QAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAA;QACnC,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AAQD,2CAA2C;AAC3C,SAAS,QAAQ,CAAC,IAAY,EAAE,OAAe,EAAE,EAAW;IAC1D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,CAAA;AACzD,CAAC;AAMD,mEAAmE;AACnE,SAAS,eAAe,CAAC,OAAgB;IACvC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,KAAK,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,CAAA;IAC3E,CAAC;IACD,sEAAsE;IACtE,MAAM,OAAO,GACX,SAAS,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;IAC3F,MAAM,MAAM,GACV,QAAQ,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;IACxF,MAAM,MAAM,GAAG,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;IAC/D,MAAM,EAAE,GAAG,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;IACnD,IAAI,OAAO,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACjC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE,IAAI,IAAI,CAAC,EAAE,CAAA;IACjF,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;AACzC,CAAC;AAED;;;;GAIG;AACH,SAAS,qBAAqB,CAC5B,GAAgB,EAChB,GAAwB;IAExB,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAA;IAC7F,IAAI,SAAS,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC;QAC1C,OAAO,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAA;IAClD,CAAC;IACD,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAA;QACvC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,OAAO,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAA;QACvD,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE,CAAA;QAC7C,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,OAAO,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAA;QAC9D,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,OAAO,SAAS;IACpB,QAAQ,GAAqC,IAAI,GAAG,EAAE,CAAA;IACtD,YAAY,GAAuE,IAAI,CAAA;IACvF,UAAU,CAAwD;IAElE;;;;;OAKG;IACH,YAAY,CAAC,SAAgE;QAC3E,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;IAC7B,CAAC;IAED,8BAA8B;IAC9B,MAAM,CAAC,IAAY,EAAE,OAAmB;QACtC,MAAM,GAAG,GAAwB;YAC/B,IAAI;YACJ,OAAO;YACP,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;YAC9C,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;YAC5C,WAAW,EAAE,EAAE;YACf,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC;SACvD,CAAA;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC5B,OAAO,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAA;IAClC,CAAC;IAED,8EAA8E;IAC9E,SAAS,CACP,MAAc,EACd,UAAuF;QAEvF,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAA;QAClC,MAAM,OAAO,GAAG,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,MAAM,CACtD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,aAAa,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,UAAU,CAC7D,CAAA;QACD,KAAK,MAAM,UAAU,IAAI,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;gBAC3D,qEAAqE;gBACrE,gEAAgE;gBAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAA;gBACtF,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;YAC1C,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,KAAK,CACH,MAAoE,EACpE,QAAkC;QAElC,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAA;QACpC,IAAI,CAAC,YAAY,GAAG;YAClB,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3E,KAAK,EAAE,EAAE;YACT,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE;SACpC,CAAA;QACD,QAAQ,CAAC,IAAI,CAAC,CAAA;QACd,IAAI,CAAC,YAAY,GAAG,UAAU,CAAA;IAChC,CAAC;IAED,2CAA2C;IAC3C,KAAK,CAAC,MAAM,CAAC,GAAgB;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;QAE/B,wCAAwC;QACxC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBACrB,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC5B,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,0BAA0B,EAAE;oBAC5D,EAAE,EAAE,IAAI;iBACT,CAAC,CAAA;gBACF,OAAM;YACR,CAAC;YACD,qFAAqF;YACrF,MAAM,OAAO,GAAc,EAAE,CAAA;YAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;YAChD,CAAC;YACD,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACtC,OAAM;QACR,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QAChD,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACvC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,GAAgB,EAAE,OAAgB;QAClD,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;QACvC,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,MAAM,CAAC,QAAQ,CAAA;QACtC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,CAAA;QAErC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACrC,IAAI,CAAC,GAAG;YAAE,OAAO,QAAQ,CAAC,CAAC,KAAK,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAA;QAEzD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;YAC9C,IAAI,MAAM;gBAAE,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;YAE5D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;YAC7C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,8CAA8C;YAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAA;YACnD,MAAM,OAAO,GAAG,KAAK,IAAI,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAA;YAC9E,OAAO,QAAQ,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAClC,CAAC;IAED,+CAA+C;IAC/C,SAAS,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;CACF"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * `@Schedule('cron-expr')` method decorator — declares a recurring task.
3
+ *
4
+ * Tasks are discovered at boot by `ScheduleProvider` iterating the IoC
5
+ * service registry, reading this metadata, and registering each entry
6
+ * with the Rust-backed `Scheduler` (Story 28.1). The Rust ticker owns
7
+ * the loop; TypeScript only declares *what* runs and *when*.
8
+ *
9
+ * @implements Story 28.2
10
+ */
11
+ import 'reflect-metadata';
12
+ import type { Constructor } from '../helpers/types.js';
13
+ export declare const SCHEDULE_METADATA_KEY: unique symbol;
14
+ export interface ScheduleMetadata {
15
+ cronExpr: string;
16
+ methodName: string | symbol;
17
+ target: Constructor;
18
+ }
19
+ /**
20
+ * Declares that a method should run on a cron schedule.
21
+ *
22
+ * Expressions are standard 5-field cron (minute hour day-of-month month
23
+ * day-of-week), evaluated in **UTC** by the Rust core — callers that
24
+ * want local-time semantics must pre-translate.
25
+ *
26
+ * Multiple `@Schedule` decorators on different methods of the same class
27
+ * accumulate into an array rather than overwriting each other. Metadata
28
+ * is stored with `Reflect.defineMetadata` under a stable symbol key on
29
+ * the class constructor; inherited metadata is NOT shared (each class
30
+ * owns its own array — subclasses that add schedules do not mutate the
31
+ * base class's array).
32
+ *
33
+ * Getters, setters, and static methods are rejected at decoration time
34
+ * with a clear `ReamError` so that misuse surfaces early rather than at
35
+ * first fire.
36
+ *
37
+ * Usage:
38
+ * ```ts
39
+ * @Service()
40
+ * class Cleanup {
41
+ * @Schedule('0 *\/5 * * *')
42
+ * async runCleanup() { ... }
43
+ * }
44
+ * ```
45
+ */
46
+ export declare function Schedule(cronExpr: string): MethodDecorator;
47
+ /**
48
+ * Return every `@Schedule` entry declared on `target` (empty array if
49
+ * none). Returns a shallow copy so callers cannot mutate the stored
50
+ * metadata by accident.
51
+ */
52
+ export declare function getScheduleMetadata(target: Constructor): ScheduleMetadata[];
53
+ //# sourceMappingURL=Schedule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Schedule.d.ts","sourceRoot":"","sources":["../../src/scheduler/Schedule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,kBAAkB,CAAA;AAEzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,eAAO,MAAM,qBAAqB,eAA0B,CAAA;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;IAC3B,MAAM,EAAE,WAAW,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAmC1D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB,EAAE,CAG3E"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * `@Schedule('cron-expr')` method decorator — declares a recurring task.
3
+ *
4
+ * Tasks are discovered at boot by `ScheduleProvider` iterating the IoC
5
+ * service registry, reading this metadata, and registering each entry
6
+ * with the Rust-backed `Scheduler` (Story 28.1). The Rust ticker owns
7
+ * the loop; TypeScript only declares *what* runs and *when*.
8
+ *
9
+ * @implements Story 28.2
10
+ */
11
+ import 'reflect-metadata';
12
+ import { ReamError } from '../errors/ReamError.js';
13
+ export const SCHEDULE_METADATA_KEY = Symbol('ream:schedule');
14
+ /**
15
+ * Declares that a method should run on a cron schedule.
16
+ *
17
+ * Expressions are standard 5-field cron (minute hour day-of-month month
18
+ * day-of-week), evaluated in **UTC** by the Rust core — callers that
19
+ * want local-time semantics must pre-translate.
20
+ *
21
+ * Multiple `@Schedule` decorators on different methods of the same class
22
+ * accumulate into an array rather than overwriting each other. Metadata
23
+ * is stored with `Reflect.defineMetadata` under a stable symbol key on
24
+ * the class constructor; inherited metadata is NOT shared (each class
25
+ * owns its own array — subclasses that add schedules do not mutate the
26
+ * base class's array).
27
+ *
28
+ * Getters, setters, and static methods are rejected at decoration time
29
+ * with a clear `ReamError` so that misuse surfaces early rather than at
30
+ * first fire.
31
+ *
32
+ * Usage:
33
+ * ```ts
34
+ * @Service()
35
+ * class Cleanup {
36
+ * @Schedule('0 *\/5 * * *')
37
+ * async runCleanup() { ... }
38
+ * }
39
+ * ```
40
+ */
41
+ export function Schedule(cronExpr) {
42
+ return (target, propertyKey, descriptor) => {
43
+ // Reject static methods. For a static, `target` IS the constructor
44
+ // (callable function); for an instance method, `target` is the
45
+ // prototype. We need the real class either way.
46
+ if (typeof target === 'function') {
47
+ throw new ReamError('SCHEDULE_INVALID_TARGET', `@Schedule cannot be applied to static method '${String(propertyKey)}'`, {
48
+ hint: 'Move the scheduled logic to an instance method, or register the task manually via Scheduler.register().',
49
+ });
50
+ }
51
+ // Reject getters/setters — `descriptor.value` is `undefined` for
52
+ // accessors, and the ticker needs a callable method.
53
+ if (descriptor && typeof descriptor.value !== 'function') {
54
+ throw new ReamError('SCHEDULE_INVALID_TARGET', `@Schedule cannot be applied to non-method '${String(propertyKey)}' (getters and setters are not supported)`, {
55
+ hint: 'Apply @Schedule to a regular method, not to an accessor.',
56
+ });
57
+ }
58
+ const ctor = target.constructor;
59
+ // getOwnMetadata — do NOT walk the prototype chain. A subclass must
60
+ // not mutate the base class's shared array; each class owns its own
61
+ // schedule list. Matches the convention in decorators/Service.ts.
62
+ const existing = Reflect.getOwnMetadata(SCHEDULE_METADATA_KEY, ctor) ?? [];
63
+ existing.push({ cronExpr, methodName: propertyKey, target: ctor });
64
+ Reflect.defineMetadata(SCHEDULE_METADATA_KEY, existing, ctor);
65
+ };
66
+ }
67
+ /**
68
+ * Return every `@Schedule` entry declared on `target` (empty array if
69
+ * none). Returns a shallow copy so callers cannot mutate the stored
70
+ * metadata by accident.
71
+ */
72
+ export function getScheduleMetadata(target) {
73
+ const stored = Reflect.getOwnMetadata(SCHEDULE_METADATA_KEY, target) ?? [];
74
+ return [...stored];
75
+ }
76
+ //# sourceMappingURL=Schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Schedule.js","sourceRoot":"","sources":["../../src/scheduler/Schedule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,kBAAkB,CAAA;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAGlD,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,eAAe,CAAC,CAAA;AAQ5D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,QAAQ,CAAC,QAAgB;IACvC,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE;QACzC,mEAAmE;QACnE,+DAA+D;QAC/D,gDAAgD;QAChD,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YACjC,MAAM,IAAI,SAAS,CACjB,yBAAyB,EACzB,iDAAiD,MAAM,CAAC,WAAW,CAAC,GAAG,EACvE;gBACE,IAAI,EAAE,yGAAyG;aAChH,CACF,CAAA;QACH,CAAC;QAED,iEAAiE;QACjE,qDAAqD;QACrD,IAAI,UAAU,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACzD,MAAM,IAAI,SAAS,CACjB,yBAAyB,EACzB,8CAA8C,MAAM,CAAC,WAAW,CAAC,2CAA2C,EAC5G;gBACE,IAAI,EAAE,0DAA0D;aACjE,CACF,CAAA;QACH,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,WAA0B,CAAA;QAC9C,oEAAoE;QACpE,oEAAoE;QACpE,kEAAkE;QAClE,MAAM,QAAQ,GAAuB,OAAO,CAAC,cAAc,CAAC,qBAAqB,EAAE,IAAI,CAAC,IAAI,EAAE,CAAA;QAC9F,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QAClE,OAAO,CAAC,cAAc,CAAC,qBAAqB,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;IAC/D,CAAC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAmB;IACrD,MAAM,MAAM,GAAuB,OAAO,CAAC,cAAc,CAAC,qBAAqB,EAAE,MAAM,CAAC,IAAI,EAAE,CAAA;IAC9F,OAAO,CAAC,GAAG,MAAM,CAAC,CAAA;AACpB,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * `ScheduleProvider` — wires `@Schedule`-decorated methods into the
3
+ * Rust-backed [`Scheduler`].
4
+ *
5
+ * Lifecycle:
6
+ * - `boot()` — walks the IoC service registry, reads each class's
7
+ * `@Schedule` metadata, and registers a callback per entry.
8
+ * Idempotent: calling `boot()` twice is a no-op on the second call.
9
+ * Partial failures are rolled back — if the Nth task's registration
10
+ * throws, tasks 1..N-1 registered in the same boot are unregistered
11
+ * before the error propagates, so the scheduler is never left in a
12
+ * half-registered state.
13
+ * - `start()` — launches the Rust tick loop.
14
+ * - `shutdown()` — cancels the Rust tick loop.
15
+ *
16
+ * The registered callback resolves the service **at invocation time**
17
+ * (not registration time) via `container.make(target)`, so every run
18
+ * receives freshly-DI'd dependencies for transient-scoped services.
19
+ *
20
+ * @implements Story 28.2
21
+ */
22
+ import type { AppContext } from '../Provider.js';
23
+ import { Provider } from '../Provider.js';
24
+ import { Scheduler } from './Scheduler.js';
25
+ export interface ScheduleProviderOptions {
26
+ /**
27
+ * Override the `Scheduler` instance — used by tests to inject a
28
+ * mock. Production code relies on the default (`new Scheduler()`).
29
+ */
30
+ scheduler?: Scheduler;
31
+ }
32
+ export declare class ScheduleProvider extends Provider {
33
+ #private;
34
+ readonly scheduler: Scheduler;
35
+ constructor(app: AppContext, options?: ScheduleProviderOptions);
36
+ /**
37
+ * Phase 1 — bind the scheduler into the IoC container under the
38
+ * stable token `'scheduler'`. CLI entrypoints
39
+ * (`ream schedule:list` / `ream schedule:run <name>`) retrieve the
40
+ * scheduler via `container.resolve('scheduler')` once the app has
41
+ * been booted through `Ignitor`. Consumers that import the
42
+ * provider directly still read the `readonly scheduler` field.
43
+ *
44
+ * Idempotent: re-registering the same provider instance (hot
45
+ * reload, repeated `app.start()` in tests) re-binds the same
46
+ * scheduler without error. A DIFFERENT `ScheduleProvider` trying
47
+ * to claim the `'scheduler'` token throws
48
+ * `SCHEDULE_PROVIDER_ALREADY_REGISTERED` so dueling providers do
49
+ * not silently overwrite each other.
50
+ */
51
+ register(): void;
52
+ boot(): Promise<void>;
53
+ start(): Promise<void>;
54
+ shutdown(): Promise<void>;
55
+ }
56
+ //# sourceMappingURL=ScheduleProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScheduleProvider.d.ts","sourceRoot":"","sources":["../../src/scheduler/ScheduleProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED,qBAAa,gBAAiB,SAAQ,QAAQ;;IAC5C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;gBAGjB,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,uBAA4B;IAKlE;;;;;;;;;;;;;;OAcG;IACM,QAAQ,IAAI,IAAI;IA4BV,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgFrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGzC"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * `ScheduleProvider` — wires `@Schedule`-decorated methods into the
3
+ * Rust-backed [`Scheduler`].
4
+ *
5
+ * Lifecycle:
6
+ * - `boot()` — walks the IoC service registry, reads each class's
7
+ * `@Schedule` metadata, and registers a callback per entry.
8
+ * Idempotent: calling `boot()` twice is a no-op on the second call.
9
+ * Partial failures are rolled back — if the Nth task's registration
10
+ * throws, tasks 1..N-1 registered in the same boot are unregistered
11
+ * before the error propagates, so the scheduler is never left in a
12
+ * half-registered state.
13
+ * - `start()` — launches the Rust tick loop.
14
+ * - `shutdown()` — cancels the Rust tick loop.
15
+ *
16
+ * The registered callback resolves the service **at invocation time**
17
+ * (not registration time) via `container.make(target)`, so every run
18
+ * receives freshly-DI'd dependencies for transient-scoped services.
19
+ *
20
+ * @implements Story 28.2
21
+ */
22
+ import { getServiceRegistry } from '../decorators/Service.js';
23
+ import { ReamError } from '../errors/ReamError.js';
24
+ import { Provider } from '../Provider.js';
25
+ import { getScheduleMetadata } from './Schedule.js';
26
+ import { Scheduler } from './Scheduler.js';
27
+ export class ScheduleProvider extends Provider {
28
+ scheduler;
29
+ #booted = false;
30
+ constructor(app, options = {}) {
31
+ super(app);
32
+ this.scheduler = options.scheduler ?? new Scheduler();
33
+ }
34
+ /**
35
+ * Phase 1 — bind the scheduler into the IoC container under the
36
+ * stable token `'scheduler'`. CLI entrypoints
37
+ * (`ream schedule:list` / `ream schedule:run <name>`) retrieve the
38
+ * scheduler via `container.resolve('scheduler')` once the app has
39
+ * been booted through `Ignitor`. Consumers that import the
40
+ * provider directly still read the `readonly scheduler` field.
41
+ *
42
+ * Idempotent: re-registering the same provider instance (hot
43
+ * reload, repeated `app.start()` in tests) re-binds the same
44
+ * scheduler without error. A DIFFERENT `ScheduleProvider` trying
45
+ * to claim the `'scheduler'` token throws
46
+ * `SCHEDULE_PROVIDER_ALREADY_REGISTERED` so dueling providers do
47
+ * not silently overwrite each other.
48
+ */
49
+ register() {
50
+ const scheduler = this.scheduler;
51
+ const container = this.app.container;
52
+ // Probe for an existing binding. The `make` / `resolve` API
53
+ // throws when unbound; use it to distinguish "same instance"
54
+ // from "another provider already claimed the token".
55
+ let existing;
56
+ try {
57
+ existing = container.resolve('scheduler');
58
+ }
59
+ catch {
60
+ existing = undefined;
61
+ }
62
+ if (existing !== undefined) {
63
+ if (existing === scheduler) {
64
+ // Same provider re-running its register phase — no-op.
65
+ return;
66
+ }
67
+ throw new ReamError('SCHEDULE_PROVIDER_ALREADY_REGISTERED', "Container token 'scheduler' is already bound to a different instance", {
68
+ hint: 'Only one ScheduleProvider can own the scheduler binding. Remove the duplicate provider from your reamrc.ts.',
69
+ });
70
+ }
71
+ container.singleton('scheduler', () => scheduler);
72
+ }
73
+ async boot() {
74
+ if (this.#booted)
75
+ return;
76
+ const registry = getServiceRegistry();
77
+ const registered = [];
78
+ try {
79
+ for (const [target] of registry) {
80
+ const schedules = getScheduleMetadata(target);
81
+ if (schedules.length === 0)
82
+ continue;
83
+ if (!target.name) {
84
+ throw new ReamError('SCHEDULE_ANONYMOUS_CLASS', 'Anonymous classes cannot declare @Schedule — task names would collide', {
85
+ hint: 'Name the class explicitly (e.g. `export class Jobs { ... }`) so task names are unique and debuggable.',
86
+ });
87
+ }
88
+ for (const { cronExpr, methodName } of schedules) {
89
+ // Reject symbol method keys — `String(Symbol('x'))` yields
90
+ // `Symbol(x)` which collides across distinct symbol instances
91
+ // sharing the same description. String keys are the
92
+ // documented contract.
93
+ if (typeof methodName === 'symbol') {
94
+ throw new ReamError('SCHEDULE_SYMBOL_METHOD', `@Schedule on symbol-keyed method is not supported on class '${target.name}'`, {
95
+ hint: 'Use a regular named method so the task can be addressed uniquely.',
96
+ });
97
+ }
98
+ const taskName = `${target.name}.${methodName}`;
99
+ try {
100
+ this.scheduler.register(taskName, cronExpr, async () => {
101
+ // Resolve from the container on every fire so transient
102
+ // services get a fresh instance each run.
103
+ const instance = this.app.container.make(target);
104
+ const method = instance[methodName];
105
+ if (typeof method !== 'function') {
106
+ throw new ReamError('SCHEDULE_METHOD_NOT_FOUND', `Scheduled method ${taskName} is not callable on resolved instance`);
107
+ }
108
+ await method.call(instance);
109
+ });
110
+ registered.push(taskName);
111
+ }
112
+ catch (cause) {
113
+ const inner = cause;
114
+ throw new ReamError('SCHEDULE_INVALID_CRON', `Failed to register scheduled task '${taskName}': ${inner.message ?? String(cause)}`, {
115
+ context: { task: taskName, cronExpr },
116
+ hint: inner.hint,
117
+ });
118
+ }
119
+ }
120
+ }
121
+ this.#booted = true;
122
+ }
123
+ catch (err) {
124
+ // Roll back any partial registrations so a retry does not hit
125
+ // DUPLICATE_TASK and the scheduler is never half-initialized.
126
+ for (const name of registered) {
127
+ try {
128
+ this.scheduler.unregister(name);
129
+ }
130
+ catch {
131
+ // Best-effort rollback; swallow secondary failures so the
132
+ // original error reaches the caller unchanged.
133
+ }
134
+ }
135
+ throw err;
136
+ }
137
+ }
138
+ async start() {
139
+ this.scheduler.start();
140
+ }
141
+ async shutdown() {
142
+ this.scheduler.stop();
143
+ }
144
+ }
145
+ //# sourceMappingURL=ScheduleProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScheduleProvider.js","sourceRoot":"","sources":["../../src/scheduler/ScheduleProvider.ts"],"names":[],"mappings":"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"}