@pattern-stack/codegen 0.10.0 → 0.11.0

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 (307) hide show
  1. package/CHANGELOG.md +135 -0
  2. package/README.md +5 -5
  3. package/consumer-skills/codegen/SKILL.md +2 -2
  4. package/consumer-skills/events/typed-bus-and-outbox.md +1 -1
  5. package/consumer-skills/{sync → integration}/SKILL.md +29 -29
  6. package/consumer-skills/{sync → integration}/audit-and-detection.md +22 -22
  7. package/consumer-skills/{sync → integration}/change-sources-and-sinks.md +60 -60
  8. package/consumer-skills/subsystems/SKILL.md +64 -8
  9. package/consumer-skills/subsystems/wiring-and-order.md +7 -7
  10. package/dist/runtime/base-classes/index.d.ts +4 -4
  11. package/dist/runtime/base-classes/index.js +35 -35
  12. package/dist/runtime/base-classes/index.js.map +1 -1
  13. package/dist/runtime/base-classes/{synced-entity-repository.d.ts → integrated-entity-repository.d.ts} +15 -15
  14. package/dist/runtime/base-classes/{synced-entity-repository.js → integrated-entity-repository.js} +21 -21
  15. package/dist/runtime/base-classes/integrated-entity-repository.js.map +1 -0
  16. package/dist/runtime/base-classes/{synced-entity-service.d.ts → integrated-entity-service.d.ts} +6 -6
  17. package/dist/runtime/base-classes/{synced-entity-service.js → integrated-entity-service.js} +4 -4
  18. package/dist/runtime/base-classes/integrated-entity-service.js.map +1 -0
  19. package/dist/runtime/base-classes/{sync-upsert-config.d.ts → integration-upsert-config.d.ts} +13 -13
  20. package/dist/runtime/base-classes/integration-upsert-config.js +1 -0
  21. package/dist/runtime/base-classes/{junction-sync-repository.d.ts → junction-integration-repository.d.ts} +11 -11
  22. package/dist/runtime/base-classes/{junction-sync-repository.js → junction-integration-repository.js} +15 -15
  23. package/dist/runtime/base-classes/junction-integration-repository.js.map +1 -0
  24. package/dist/runtime/subsystems/auth/auth-oauth-state.schema.js.map +1 -1
  25. package/dist/runtime/subsystems/auth/auth.module.d.ts +4 -4
  26. package/dist/runtime/subsystems/auth/auth.module.js +3 -3
  27. package/dist/runtime/subsystems/auth/auth.module.js.map +1 -1
  28. package/dist/runtime/subsystems/auth/auth.tokens.d.ts +8 -8
  29. package/dist/runtime/subsystems/auth/auth.tokens.js +6 -6
  30. package/dist/runtime/subsystems/auth/auth.tokens.js.map +1 -1
  31. package/dist/runtime/subsystems/auth/backends/state-store.drizzle-backend.js.map +1 -1
  32. package/dist/runtime/subsystems/auth/controllers/auth.controller.d.ts +2 -2
  33. package/dist/runtime/subsystems/auth/controllers/auth.controller.js +3 -3
  34. package/dist/runtime/subsystems/auth/controllers/auth.controller.js.map +1 -1
  35. package/dist/runtime/subsystems/auth/index.d.ts +3 -3
  36. package/dist/runtime/subsystems/auth/index.js +40 -40
  37. package/dist/runtime/subsystems/auth/index.js.map +1 -1
  38. package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -1
  39. package/dist/runtime/subsystems/auth/protocols/auth-strategy.d.ts +3 -3
  40. package/dist/runtime/subsystems/auth/protocols/{integration-store.d.ts → connection-store.d.ts} +20 -20
  41. package/dist/runtime/subsystems/auth/protocols/connection-store.js +1 -0
  42. package/dist/runtime/subsystems/auth/protocols/provider-strategy.d.ts +3 -3
  43. package/dist/runtime/subsystems/auth/runtime/{integration-broken.error.d.ts → connection-broken.error.d.ts} +5 -5
  44. package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js +19 -0
  45. package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js.map +1 -0
  46. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.d.ts +10 -10
  47. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js +28 -28
  48. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js.map +1 -1
  49. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.d.ts +1 -1
  50. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js +3 -3
  51. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js.map +1 -1
  52. package/dist/runtime/subsystems/bridge/bridge.module.d.ts +0 -1
  53. package/dist/runtime/subsystems/bridge/bridge.module.js +294 -710
  54. package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
  55. package/dist/runtime/subsystems/bridge/index.d.ts +0 -1
  56. package/dist/runtime/subsystems/bridge/index.js +248 -664
  57. package/dist/runtime/subsystems/bridge/index.js.map +1 -1
  58. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +18 -10
  59. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
  60. package/dist/runtime/subsystems/events/events.module.js +43 -244
  61. package/dist/runtime/subsystems/events/events.module.js.map +1 -1
  62. package/dist/runtime/subsystems/events/index.d.ts +0 -1
  63. package/dist/runtime/subsystems/events/index.js +39 -241
  64. package/dist/runtime/subsystems/events/index.js.map +1 -1
  65. package/dist/runtime/subsystems/index.d.ts +7 -7
  66. package/dist/runtime/subsystems/index.js +222 -839
  67. package/dist/runtime/subsystems/index.js.map +1 -1
  68. package/dist/runtime/subsystems/{sync → integration}/build-change-source.d.ts +3 -3
  69. package/dist/runtime/subsystems/{sync → integration}/build-change-source.js +3 -3
  70. package/dist/runtime/subsystems/integration/build-change-source.js.map +1 -0
  71. package/dist/runtime/subsystems/{sync → integration}/deep-equal.differ.d.ts +2 -2
  72. package/dist/runtime/subsystems/{sync → integration}/deep-equal.differ.js +1 -1
  73. package/dist/runtime/subsystems/integration/deep-equal.differ.js.map +1 -0
  74. package/dist/runtime/subsystems/{sync → integration}/detection-config.schema.d.ts +3 -3
  75. package/dist/runtime/subsystems/{sync → integration}/detection-config.schema.js +1 -1
  76. package/dist/runtime/subsystems/integration/detection-config.schema.js.map +1 -0
  77. package/dist/runtime/subsystems/{sync/execute-sync.use-case.d.ts → integration/execute-integration.use-case.d.ts} +13 -13
  78. package/dist/runtime/subsystems/{sync/execute-sync.use-case.js → integration/execute-integration.use-case.js} +30 -30
  79. package/dist/runtime/subsystems/integration/execute-integration.use-case.js.map +1 -0
  80. package/dist/runtime/subsystems/integration/index.d.ts +28 -0
  81. package/dist/runtime/subsystems/{sync → integration}/index.js +171 -171
  82. package/dist/runtime/subsystems/integration/index.js.map +1 -0
  83. package/dist/runtime/subsystems/{sync/sync-audit.schema.d.ts → integration/integration-audit.schema.d.ts} +64 -64
  84. package/dist/runtime/subsystems/{sync/sync-audit.schema.js → integration/integration-audit.schema.js} +47 -47
  85. package/dist/runtime/subsystems/integration/integration-audit.schema.js.map +1 -0
  86. package/dist/runtime/subsystems/{sync/sync-change-source.protocol.d.ts → integration/integration-change-source.protocol.d.ts} +10 -10
  87. package/dist/runtime/subsystems/integration/integration-change-source.protocol.js +1 -0
  88. package/dist/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.d.ts → integration/integration-cursor-store.drizzle-backend.d.ts} +1 -1
  89. package/dist/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.js → integration/integration-cursor-store.drizzle-backend.js} +65 -65
  90. package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js.map +1 -0
  91. package/dist/runtime/subsystems/{sync/sync-cursor-store.memory-backend.d.ts → integration/integration-cursor-store.memory-backend.d.ts} +6 -6
  92. package/dist/runtime/subsystems/{sync/sync-cursor-store.memory-backend.js → integration/integration-cursor-store.memory-backend.js} +5 -5
  93. package/dist/runtime/subsystems/integration/integration-cursor-store.memory-backend.js.map +1 -0
  94. package/dist/runtime/subsystems/{sync/sync-cursor-store.protocol.d.ts → integration/integration-cursor-store.protocol.d.ts} +13 -13
  95. package/dist/runtime/subsystems/integration/integration-cursor-store.protocol.js +1 -0
  96. package/dist/runtime/subsystems/{sync/sync-errors.d.ts → integration/integration-errors.d.ts} +2 -2
  97. package/dist/runtime/subsystems/{sync/sync-errors.js → integration/integration-errors.js} +3 -3
  98. package/dist/runtime/subsystems/integration/integration-errors.js.map +1 -0
  99. package/dist/runtime/subsystems/{sync/sync-field-diff.protocol.d.ts → integration/integration-field-diff.protocol.d.ts} +2 -2
  100. package/dist/runtime/subsystems/{sync/sync-field-diff.protocol.js → integration/integration-field-diff.protocol.js} +2 -2
  101. package/dist/runtime/subsystems/integration/integration-field-diff.protocol.js.map +1 -0
  102. package/dist/runtime/subsystems/{sync/sync-loopback.protocol.d.ts → integration/integration-loopback.protocol.d.ts} +2 -2
  103. package/dist/runtime/subsystems/integration/integration-loopback.protocol.js +1 -0
  104. package/dist/runtime/subsystems/{sync/sync-middleware.protocol.d.ts → integration/integration-middleware.protocol.d.ts} +5 -5
  105. package/dist/runtime/subsystems/integration/integration-middleware.protocol.js +1 -0
  106. package/dist/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.d.ts → integration/integration-run-recorder.drizzle-backend.d.ts} +5 -5
  107. package/dist/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.js → integration/integration-run-recorder.drizzle-backend.js} +73 -73
  108. package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js.map +1 -0
  109. package/dist/runtime/subsystems/{sync/sync-run-recorder.memory-backend.d.ts → integration/integration-run-recorder.memory-backend.d.ts} +15 -15
  110. package/dist/runtime/subsystems/{sync/sync-run-recorder.memory-backend.js → integration/integration-run-recorder.memory-backend.js} +11 -11
  111. package/dist/runtime/subsystems/integration/integration-run-recorder.memory-backend.js.map +1 -0
  112. package/dist/runtime/subsystems/{sync/sync-run-recorder.protocol.d.ts → integration/integration-run-recorder.protocol.d.ts} +25 -25
  113. package/dist/runtime/subsystems/integration/integration-run-recorder.protocol.js +1 -0
  114. package/dist/runtime/subsystems/{sync/sync-sink.protocol.d.ts → integration/integration-sink.protocol.d.ts} +5 -5
  115. package/dist/runtime/subsystems/integration/integration-sink.protocol.js +1 -0
  116. package/dist/runtime/subsystems/{sync/sync.module.d.ts → integration/integration.module.d.ts} +24 -24
  117. package/dist/runtime/subsystems/{sync/sync.module.js → integration/integration.module.js} +132 -132
  118. package/dist/runtime/subsystems/integration/integration.module.js.map +1 -0
  119. package/dist/runtime/subsystems/integration/integration.tokens.d.ts +47 -0
  120. package/dist/runtime/subsystems/integration/integration.tokens.js +18 -0
  121. package/dist/runtime/subsystems/integration/integration.tokens.js.map +1 -0
  122. package/dist/runtime/subsystems/{sync → integration}/loopback.middleware.d.ts +5 -5
  123. package/dist/runtime/subsystems/{sync → integration}/loopback.middleware.js +1 -1
  124. package/dist/runtime/subsystems/integration/loopback.middleware.js.map +1 -0
  125. package/dist/runtime/subsystems/{sync → integration}/poll-change-source.d.ts +5 -5
  126. package/dist/runtime/subsystems/{sync → integration}/poll-change-source.js +1 -1
  127. package/dist/runtime/subsystems/integration/poll-change-source.js.map +1 -0
  128. package/dist/runtime/subsystems/{sync → integration}/webhook-change-source.d.ts +5 -5
  129. package/dist/runtime/subsystems/{sync → integration}/webhook-change-source.js +1 -1
  130. package/dist/runtime/subsystems/integration/webhook-change-source.js.map +1 -0
  131. package/dist/runtime/subsystems/jobs/bullmq.config.d.ts +22 -3
  132. package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -1
  133. package/dist/runtime/subsystems/jobs/index.d.ts +1 -4
  134. package/dist/runtime/subsystems/jobs/index.js +87 -506
  135. package/dist/runtime/subsystems/jobs/index.js.map +1 -1
  136. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
  137. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +3 -0
  138. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -1
  139. package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +10 -3
  140. package/dist/runtime/subsystems/jobs/job-worker.module.js +248 -664
  141. package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
  142. package/dist/runtime/subsystems/jobs/jobs-domain.module.d.ts +0 -1
  143. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +89 -391
  144. package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
  145. package/dist/runtime/subsystems/observability/index.d.ts +4 -4
  146. package/dist/runtime/subsystems/observability/index.js +11 -11
  147. package/dist/runtime/subsystems/observability/index.js.map +1 -1
  148. package/dist/runtime/subsystems/observability/observability.module.d.ts +2 -2
  149. package/dist/runtime/subsystems/observability/observability.module.js +11 -11
  150. package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
  151. package/dist/runtime/subsystems/observability/observability.protocol.d.ts +11 -11
  152. package/dist/runtime/subsystems/observability/observability.service.d.ts +6 -6
  153. package/dist/runtime/subsystems/observability/observability.service.js +11 -11
  154. package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
  155. package/dist/runtime/subsystems/observability/observability.tokens.d.ts +1 -1
  156. package/dist/runtime/subsystems/observability/observability.tokens.js.map +1 -1
  157. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +3 -3
  158. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.js.map +1 -1
  159. package/dist/runtime/subsystems/observability/reporters/index.d.ts +3 -3
  160. package/dist/runtime/subsystems/observability/reporters/index.js.map +1 -1
  161. package/dist/src/cli/index.js +412 -302
  162. package/dist/src/cli/index.js.map +1 -1
  163. package/dist/src/index.d.ts +22 -22
  164. package/dist/src/index.js +191 -191
  165. package/dist/src/index.js.map +1 -1
  166. package/examples/auth-integrations/README.md +32 -32
  167. package/examples/auth-integrations/definitions/entities/{integration.yaml → connection.yaml} +10 -10
  168. package/examples/auth-integrations/runtime/{integrations/adapters/integration-grant-sink.adapter.ts → connections/adapters/connection-grant-sink.adapter.ts} +7 -7
  169. package/examples/auth-integrations/runtime/{integrations/adapters/integration-reader.adapter.ts → connections/adapters/connection-reader.adapter.ts} +10 -10
  170. package/examples/auth-integrations/runtime/{integrations/adapters/integration-token-writer.adapter.ts → connections/adapters/connection-token-writer.adapter.ts} +11 -11
  171. package/examples/auth-integrations/runtime/connections/connections-auth.module.ts +81 -0
  172. package/examples/auth-integrations/runtime/{integrations/facade/integrations.service.ts → connections/facade/connections.service.ts} +35 -35
  173. package/examples/auth-integrations/runtime/{integrations → connections}/oauth/use-cases/create-or-update-from-oauth-grant.use-case.ts +11 -11
  174. package/examples/auth-integrations/runtime/{integrations/oauth/use-cases/disconnect-integration.use-case.ts → connections/oauth/use-cases/disconnect-connection.use-case.ts} +6 -6
  175. package/examples/auth-integrations/runtime/connections/oauth/use-cases/list-user-connections.use-case.ts +21 -0
  176. package/examples/auth-integrations/runtime/connections/oauth/use-cases/mark-connection-requires-reauth.use-case.ts +21 -0
  177. package/package.json +1 -1
  178. package/runtime/base-classes/index.ts +8 -8
  179. package/runtime/base-classes/{synced-entity-repository.ts → integrated-entity-repository.ts} +36 -36
  180. package/runtime/base-classes/{synced-entity-service.ts → integrated-entity-service.ts} +6 -6
  181. package/runtime/base-classes/{sync-upsert-config.ts → integration-upsert-config.ts} +12 -12
  182. package/runtime/base-classes/{junction-sync-repository.ts → junction-integration-repository.ts} +28 -28
  183. package/runtime/subsystems/auth/auth-oauth-state.schema.ts +1 -1
  184. package/runtime/subsystems/auth/auth.module.ts +4 -4
  185. package/runtime/subsystems/auth/auth.tokens.ts +7 -7
  186. package/runtime/subsystems/auth/controllers/auth.controller.ts +7 -7
  187. package/runtime/subsystems/auth/index.ts +19 -19
  188. package/runtime/subsystems/auth/protocols/auth-strategy.ts +3 -3
  189. package/runtime/subsystems/auth/protocols/{integration-store.ts → connection-store.ts} +19 -19
  190. package/runtime/subsystems/auth/protocols/provider-strategy.ts +2 -2
  191. package/runtime/subsystems/auth/runtime/{integration-broken.error.ts → connection-broken.error.ts} +5 -5
  192. package/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.ts +35 -35
  193. package/runtime/subsystems/auth/runtime/with-auth-retry.ts +3 -3
  194. package/runtime/subsystems/events/event-bus.drizzle-backend.ts +32 -10
  195. package/runtime/subsystems/events/events.module.ts +38 -6
  196. package/runtime/subsystems/events/index.ts +7 -1
  197. package/runtime/subsystems/index.ts +11 -11
  198. package/runtime/subsystems/{sync → integration}/build-change-source.ts +3 -3
  199. package/runtime/subsystems/{sync → integration}/deep-equal.differ.ts +7 -7
  200. package/runtime/subsystems/{sync → integration}/detection-config.schema.ts +3 -3
  201. package/runtime/subsystems/{sync/execute-sync.use-case.ts → integration/execute-integration.use-case.ts} +40 -40
  202. package/runtime/subsystems/{sync → integration}/index.ts +47 -47
  203. package/runtime/subsystems/{sync/sync-audit.schema.ts → integration/integration-audit.schema.ts} +61 -61
  204. package/runtime/subsystems/{sync/sync-change-source.protocol.ts → integration/integration-change-source.protocol.ts} +9 -9
  205. package/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.ts → integration/integration-cursor-store.drizzle-backend.ts} +30 -30
  206. package/runtime/subsystems/{sync/sync-cursor-store.memory-backend.ts → integration/integration-cursor-store.memory-backend.ts} +9 -9
  207. package/runtime/subsystems/{sync/sync-cursor-store.protocol.ts → integration/integration-cursor-store.protocol.ts} +13 -13
  208. package/runtime/subsystems/{sync/sync-errors.ts → integration/integration-errors.ts} +3 -3
  209. package/runtime/subsystems/{sync/sync-field-diff.protocol.ts → integration/integration-field-diff.protocol.ts} +2 -2
  210. package/runtime/subsystems/{sync/sync-loopback.protocol.ts → integration/integration-loopback.protocol.ts} +2 -2
  211. package/runtime/subsystems/{sync/sync-middleware.protocol.ts → integration/integration-middleware.protocol.ts} +6 -6
  212. package/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.ts → integration/integration-run-recorder.drizzle-backend.ts} +39 -39
  213. package/runtime/subsystems/{sync/sync-run-recorder.memory-backend.ts → integration/integration-run-recorder.memory-backend.ts} +23 -23
  214. package/runtime/subsystems/{sync/sync-run-recorder.protocol.ts → integration/integration-run-recorder.protocol.ts} +25 -25
  215. package/runtime/subsystems/{sync/sync-sink.protocol.ts → integration/integration-sink.protocol.ts} +4 -4
  216. package/runtime/subsystems/{sync/sync.module.ts → integration/integration.module.ts} +48 -48
  217. package/runtime/subsystems/integration/integration.tokens.ts +49 -0
  218. package/runtime/subsystems/{sync → integration}/loopback.middleware.ts +5 -5
  219. package/runtime/subsystems/{sync → integration}/poll-change-source.ts +7 -7
  220. package/runtime/subsystems/{sync → integration}/webhook-change-source.ts +7 -7
  221. package/runtime/subsystems/jobs/bullmq.config.ts +23 -3
  222. package/runtime/subsystems/jobs/index.ts +13 -8
  223. package/runtime/subsystems/jobs/job-worker.bullmq-backend.ts +5 -2
  224. package/runtime/subsystems/jobs/job-worker.module.ts +27 -7
  225. package/runtime/subsystems/jobs/jobs-domain.module.ts +27 -2
  226. package/runtime/subsystems/observability/index.ts +1 -1
  227. package/runtime/subsystems/observability/observability.module.ts +2 -2
  228. package/runtime/subsystems/observability/observability.protocol.ts +11 -11
  229. package/runtime/subsystems/observability/observability.service.ts +13 -13
  230. package/runtime/subsystems/observability/observability.tokens.ts +1 -1
  231. package/src/patterns/library/index.ts +4 -4
  232. package/src/patterns/library/{synced.pattern.ts → integrated.pattern.ts} +12 -12
  233. package/src/patterns/library/junction.pattern.ts +1 -1
  234. package/src/patterns/pattern-definition.ts +3 -3
  235. package/templates/entity/new/backend/modules/core/{sync-source.ejs.t → integration-source.ejs.t} +6 -6
  236. package/templates/entity/new/backend/modules/core/{sync-source.providers.ejs.t → integration-source.providers.ejs.t} +2 -2
  237. package/templates/entity/new/clean-lite-ps/entity.ejs.t +1 -1
  238. package/templates/entity/new/clean-lite-ps/module.ejs.t +1 -1
  239. package/templates/entity/new/clean-lite-ps/prompt-extension.js +33 -33
  240. package/templates/entity/new/clean-lite-ps/repository.ejs.t +27 -27
  241. package/templates/entity/new/frontend/collections/collection.ejs.t +26 -1
  242. package/templates/entity/new/frontend/collections/collections-base.ejs.t +11 -0
  243. package/templates/entity/new/frontend/entity/combined.ejs.t +31 -1
  244. package/templates/entity/new/prompt.js +27 -15
  245. package/templates/junction/new/entity.ejs.t +1 -1
  246. package/templates/junction/new/prompt.js +24 -24
  247. package/templates/junction/new/repository.ejs.t +19 -19
  248. package/templates/subsystem/auth/auth-oauth-state.schema.ejs.t +2 -2
  249. package/templates/subsystem/auth-config/prompt.js +1 -1
  250. package/templates/subsystem/auth-integrations/app-module-hook.ejs.t +5 -5
  251. package/templates/subsystem/bridge/prompt.js +1 -1
  252. package/templates/subsystem/events/domain-events.schema.ejs.t +43 -2
  253. package/templates/subsystem/integration/integration-audit.schema.ejs.t +192 -0
  254. package/templates/subsystem/{sync → integration}/prompt.js +12 -12
  255. package/templates/subsystem/{sync-config/codegen-config-sync-block.ejs.t → integration-config/codegen-config-integration-block.ejs.t} +7 -7
  256. package/templates/subsystem/integration-config/prompt.js +22 -0
  257. package/templates/subsystem/jobs/worker.ejs.t +2 -2
  258. package/templates/subsystem/observability/main-hook.ejs.t +1 -1
  259. package/templates/subsystem/observability/prompt.js +1 -1
  260. package/templates/subsystem/openapi-config/prompt.js +1 -1
  261. package/dist/runtime/base-classes/junction-sync-repository.js.map +0 -1
  262. package/dist/runtime/base-classes/sync-upsert-config.js +0 -1
  263. package/dist/runtime/base-classes/synced-entity-repository.js.map +0 -1
  264. package/dist/runtime/base-classes/synced-entity-service.js.map +0 -1
  265. package/dist/runtime/subsystems/auth/protocols/integration-store.js +0 -1
  266. package/dist/runtime/subsystems/auth/runtime/integration-broken.error.js +0 -19
  267. package/dist/runtime/subsystems/auth/runtime/integration-broken.error.js.map +0 -1
  268. package/dist/runtime/subsystems/sync/build-change-source.js.map +0 -1
  269. package/dist/runtime/subsystems/sync/deep-equal.differ.js.map +0 -1
  270. package/dist/runtime/subsystems/sync/detection-config.schema.js.map +0 -1
  271. package/dist/runtime/subsystems/sync/execute-sync.use-case.js.map +0 -1
  272. package/dist/runtime/subsystems/sync/index.d.ts +0 -28
  273. package/dist/runtime/subsystems/sync/index.js.map +0 -1
  274. package/dist/runtime/subsystems/sync/loopback.middleware.js.map +0 -1
  275. package/dist/runtime/subsystems/sync/poll-change-source.js.map +0 -1
  276. package/dist/runtime/subsystems/sync/sync-audit.schema.js.map +0 -1
  277. package/dist/runtime/subsystems/sync/sync-change-source.protocol.js +0 -1
  278. package/dist/runtime/subsystems/sync/sync-cursor-store.drizzle-backend.js.map +0 -1
  279. package/dist/runtime/subsystems/sync/sync-cursor-store.memory-backend.js.map +0 -1
  280. package/dist/runtime/subsystems/sync/sync-cursor-store.protocol.js +0 -1
  281. package/dist/runtime/subsystems/sync/sync-errors.js.map +0 -1
  282. package/dist/runtime/subsystems/sync/sync-field-diff.protocol.js.map +0 -1
  283. package/dist/runtime/subsystems/sync/sync-loopback.protocol.js +0 -1
  284. package/dist/runtime/subsystems/sync/sync-middleware.protocol.js +0 -1
  285. package/dist/runtime/subsystems/sync/sync-run-recorder.drizzle-backend.js.map +0 -1
  286. package/dist/runtime/subsystems/sync/sync-run-recorder.memory-backend.js.map +0 -1
  287. package/dist/runtime/subsystems/sync/sync-run-recorder.protocol.js +0 -1
  288. package/dist/runtime/subsystems/sync/sync-sink.protocol.js +0 -1
  289. package/dist/runtime/subsystems/sync/sync.module.js.map +0 -1
  290. package/dist/runtime/subsystems/sync/sync.tokens.d.ts +0 -47
  291. package/dist/runtime/subsystems/sync/sync.tokens.js +0 -18
  292. package/dist/runtime/subsystems/sync/sync.tokens.js.map +0 -1
  293. package/dist/runtime/subsystems/sync/webhook-change-source.js.map +0 -1
  294. package/examples/auth-integrations/runtime/integrations/integrations-auth.module.ts +0 -81
  295. package/examples/auth-integrations/runtime/integrations/oauth/use-cases/list-user-integrations.use-case.ts +0 -21
  296. package/examples/auth-integrations/runtime/integrations/oauth/use-cases/mark-integration-requires-reauth.use-case.ts +0 -21
  297. package/runtime/subsystems/sync/sync.tokens.ts +0 -49
  298. package/templates/subsystem/sync/sync-audit.schema.ejs.t +0 -192
  299. package/templates/subsystem/sync-config/prompt.js +0 -22
  300. /package/dist/runtime/base-classes/{sync-upsert-config.js.map → integration-upsert-config.js.map} +0 -0
  301. /package/dist/runtime/subsystems/auth/protocols/{integration-store.js.map → connection-store.js.map} +0 -0
  302. /package/dist/runtime/subsystems/{sync/sync-change-source.protocol.js.map → integration/integration-change-source.protocol.js.map} +0 -0
  303. /package/dist/runtime/subsystems/{sync/sync-cursor-store.protocol.js.map → integration/integration-cursor-store.protocol.js.map} +0 -0
  304. /package/dist/runtime/subsystems/{sync/sync-loopback.protocol.js.map → integration/integration-loopback.protocol.js.map} +0 -0
  305. /package/dist/runtime/subsystems/{sync/sync-middleware.protocol.js.map → integration/integration-middleware.protocol.js.map} +0 -0
  306. /package/dist/runtime/subsystems/{sync/sync-run-recorder.protocol.js.map → integration/integration-run-recorder.protocol.js.map} +0 -0
  307. /package/dist/runtime/subsystems/{sync/sync-sink.protocol.js.map → integration/integration-sink.protocol.js.map} +0 -0
@@ -12,11 +12,11 @@ var __decorateParam = (index2, decorator) => (target, key) => decorator(target,
12
12
 
13
13
  // runtime/subsystems/jobs/job-worker.module.ts
14
14
  import {
15
- Inject as Inject8,
16
- Injectable as Injectable9,
17
- Logger as Logger6,
15
+ Inject as Inject7,
16
+ Injectable as Injectable8,
17
+ Logger as Logger4,
18
18
  Module as Module2,
19
- Optional as Optional3
19
+ Optional as Optional2
20
20
  } from "@nestjs/common";
21
21
 
22
22
  // runtime/constants/tokens.ts
@@ -878,394 +878,9 @@ DrizzleJobStepService = __decorateClass([
878
878
  __decorateParam(0, Inject3(DRIZZLE))
879
879
  ], DrizzleJobStepService);
880
880
 
881
- // runtime/subsystems/jobs/job-orchestrator.bullmq-backend.ts
882
- import { createHash } from "crypto";
883
- import { Inject as Inject4, Injectable as Injectable4, Logger as Logger2, Optional } from "@nestjs/common";
884
- import { eq as eq4 } from "drizzle-orm";
885
-
886
- // runtime/subsystems/jobs/pool-config.loader.ts
887
- import { existsSync, readFileSync } from "fs";
888
- import { resolve } from "path";
889
- import { parse as parseYaml } from "yaml";
890
- var FRAMEWORK_POOLS = Object.freeze({
891
- events_inbound: Object.freeze({
892
- queue: "jobs-events-inbound",
893
- concurrency: 20,
894
- reserved: true,
895
- description: "Inbound events drain (events subsystem outbox)."
896
- }),
897
- events_change: Object.freeze({
898
- queue: "jobs-events-change",
899
- concurrency: 30,
900
- reserved: true,
901
- description: "Change events drain (events subsystem outbox)."
902
- }),
903
- events_outbound: Object.freeze({
904
- queue: "jobs-events-outbound",
905
- concurrency: 10,
906
- reserved: true,
907
- description: "Outbound events drain (events subsystem outbox)."
908
- }),
909
- interactive: Object.freeze({
910
- queue: "jobs-interactive",
911
- concurrency: 20,
912
- reserved: false,
913
- description: "User-facing latency-sensitive jobs."
914
- }),
915
- batch: Object.freeze({
916
- queue: "jobs-batch",
917
- concurrency: 5,
918
- reserved: false,
919
- description: "Default pool for background jobs."
920
- })
921
- });
922
- var RESERVED_POOL_NAMES = new Set(
923
- Object.entries(FRAMEWORK_POOLS).filter(([, def]) => def.reserved).map(([name]) => name)
924
- );
925
- var cache = /* @__PURE__ */ new Map();
926
- function loadPoolConfig(configPath) {
927
- const resolved = resolve(configPath ?? `${process.cwd()}/codegen.config.yaml`);
928
- const cached = cache.get(resolved);
929
- if (cached) return cached;
930
- const merged = /* @__PURE__ */ new Map();
931
- for (const [name, def] of Object.entries(FRAMEWORK_POOLS)) {
932
- merged.set(name, { ...def });
933
- }
934
- if (!existsSync(resolved)) {
935
- cache.set(resolved, merged);
936
- return merged;
937
- }
938
- let raw;
939
- try {
940
- raw = parseYaml(readFileSync(resolved, "utf8"));
941
- } catch (err) {
942
- throw new Error(
943
- `pool-config.loader: failed to parse YAML at ${resolved}: ${err.message}`
944
- );
945
- }
946
- const userPools = extractUserPools(raw);
947
- for (const [name, userDef] of Object.entries(userPools)) {
948
- const existing = merged.get(name);
949
- if (existing) {
950
- const next = {
951
- queue: existing.queue,
952
- concurrency: typeof userDef.concurrency === "number" ? userDef.concurrency : existing.concurrency,
953
- reserved: existing.reserved,
954
- description: userDef.description ?? existing.description
955
- };
956
- merged.set(name, next);
957
- continue;
958
- }
959
- if (typeof userDef.queue !== "string" || userDef.queue.length === 0) {
960
- throw new Error(
961
- `pool-config.loader: pool '${name}' must declare a non-empty 'queue'.`
962
- );
963
- }
964
- if (typeof userDef.concurrency !== "number" || userDef.concurrency <= 0) {
965
- throw new Error(
966
- `pool-config.loader: pool '${name}' must declare a positive 'concurrency'.`
967
- );
968
- }
969
- if (userDef.reserved === true) {
970
- throw new Error(
971
- `pool-config.loader: user-defined pool '${name}' cannot set 'reserved: true' \u2014 reserved is framework-only.`
972
- );
973
- }
974
- merged.set(name, {
975
- queue: userDef.queue,
976
- concurrency: userDef.concurrency,
977
- reserved: false,
978
- description: userDef.description
979
- });
980
- }
981
- cache.set(resolved, merged);
982
- return merged;
983
- }
984
- function allNonReservedPoolNames(config) {
985
- const out = [];
986
- for (const [name, def] of config) {
987
- if (!def.reserved) out.push(name);
988
- }
989
- return out;
990
- }
991
- function allPoolNames(config) {
992
- return [...config.keys()];
993
- }
994
- function extractUserPools(raw) {
995
- if (!raw || typeof raw !== "object") return {};
996
- const jobs2 = raw.jobs;
997
- if (!jobs2 || typeof jobs2 !== "object") return {};
998
- const pools = jobs2.pools;
999
- if (!pools || typeof pools !== "object") return {};
1000
- const out = {};
1001
- for (const [name, def] of Object.entries(pools)) {
1002
- if (!def || typeof def !== "object") continue;
1003
- out[name] = def;
1004
- }
1005
- return out;
1006
- }
1007
-
1008
- // runtime/subsystems/jobs/bullmq.config.ts
1009
- var BULLMQ_CONNECTION = /* @__PURE__ */ Symbol("BULLMQ_CONNECTION");
1010
- var BULLMQ_RESOLVED_CONFIG = /* @__PURE__ */ Symbol("BULLMQ_RESOLVED_CONFIG");
1011
- var DEFAULT_REDIS_URL = "redis://localhost:6379";
1012
- var DEFAULT_BULL_BOARD_MOUNT = "/admin/queues";
1013
- function resolveBullMqConfig(ext) {
1014
- const url = ext?.redis_url ?? process.env.REDIS_URL ?? DEFAULT_REDIS_URL;
1015
- const resolved = {
1016
- connection: { url },
1017
- queuePrefix: ext?.queue_prefix
1018
- };
1019
- if (ext?.bull_board?.enabled) {
1020
- resolved.bullBoard = {
1021
- enabled: true,
1022
- mountPath: ext.bull_board.mount_path ?? DEFAULT_BULL_BOARD_MOUNT
1023
- };
1024
- }
1025
- return resolved;
1026
- }
1027
- function resolvePoolQueueName(pool, config, poolConfig = loadPoolConfig()) {
1028
- const alias = poolConfig.get(pool)?.queue ?? pool;
1029
- const prefix = config?.queuePrefix;
1030
- return prefix ? `${prefix}:${alias}` : alias;
1031
- }
1032
-
1033
- // runtime/subsystems/jobs/job-orchestrator.bullmq-backend.ts
1034
- function sha1JobId(idempotencyKey) {
1035
- return createHash("sha1").update(idempotencyKey).digest("hex");
1036
- }
1037
- var BullMQJobOrchestrator = class extends DrizzleJobOrchestrator {
1038
- constructor(db, multiTenant, connection, bullConfig = null) {
1039
- super(db, multiTenant);
1040
- this.connection = connection;
1041
- this.bullConfig = bullConfig;
1042
- this.bullDb = db;
1043
- }
1044
- connection;
1045
- bullConfig;
1046
- // TODO(logging-subsystem): swap to ILogger once ADR-028 lands
1047
- bullLogger = new Logger2(BullMQJobOrchestrator.name);
1048
- /** Lazily-opened `Queue` handles, one per pool. */
1049
- queues = /* @__PURE__ */ new Map();
1050
- /** Single FlowProducer for parent/child hierarchies. Lazily opened. */
1051
- _flow = null;
1052
- /**
1053
- * Cached `bullmq` value constructors, populated by `loadBullMq()` on first
1054
- * use (the `start`/`cancel`/`replay` entrypoints `await` it before touching
1055
- * a queue). Kept off the import graph so a `drizzle`-only consumer never
1056
- * resolves the optional `'bullmq'` package.
1057
- */
1058
- QueueCtor = null;
1059
- FlowProducerCtor = null;
1060
- bullMqLoad = null;
1061
- /**
1062
- * Own reference to the Drizzle client. `DrizzleJobOrchestrator.db` is
1063
- * `private` (can't be redeclared even privately in a subclass), and the
1064
- * spec forbids touching that file — so the subclass keeps its own handle
1065
- * under a distinct name (same instance, passed through to `super`) for the
1066
- * cancel-cascade snapshot + definition/run loads below.
1067
- */
1068
- bullDb;
1069
- /**
1070
- * Lazily load the optional `bullmq` package and cache its value
1071
- * constructors. Idempotent (single in-flight promise). Throws a friendly,
1072
- * actionable error when the consumer selected `backend: 'bullmq'` but did
1073
- * not install the package — mirrors `createRedisClient` in the redis event
1074
- * backend. Must be `await`ed before any `queueFor`/`flow` access.
1075
- */
1076
- async loadBullMq() {
1077
- if (this.QueueCtor && this.FlowProducerCtor) return;
1078
- if (!this.bullMqLoad) {
1079
- this.bullMqLoad = (async () => {
1080
- try {
1081
- const mod = await import("bullmq");
1082
- this.QueueCtor = mod.Queue;
1083
- this.FlowProducerCtor = mod.FlowProducer;
1084
- } catch {
1085
- throw new Error(
1086
- 'BullMQ backend requires the "bullmq" package. Install it with: npm install bullmq'
1087
- );
1088
- }
1089
- })();
1090
- }
1091
- await this.bullMqLoad;
1092
- }
1093
- /**
1094
- * Open (or reuse) the `Queue` for a pool. Synchronous — callers `await
1095
- * loadBullMq()` first so `QueueCtor` is populated.
1096
- */
1097
- queueFor(pool) {
1098
- if (!this.QueueCtor) {
1099
- throw new Error("BullMQJobOrchestrator: queueFor called before loadBullMq()");
1100
- }
1101
- const name = resolvePoolQueueName(pool, this.bullConfig);
1102
- let q = this.queues.get(name);
1103
- if (!q) {
1104
- q = new this.QueueCtor(name, { connection: this.connection });
1105
- this.queues.set(name, q);
1106
- }
1107
- return q;
1108
- }
1109
- flow() {
1110
- if (!this.FlowProducerCtor) {
1111
- throw new Error("BullMQJobOrchestrator: flow called before loadBullMq()");
1112
- }
1113
- if (!this._flow) {
1114
- this._flow = new this.FlowProducerCtor({ connection: this.connection });
1115
- }
1116
- return this._flow;
1117
- }
1118
- // ==========================================================================
1119
- // start — Postgres insert (super) + BullMQ dispatch
1120
- // ==========================================================================
1121
- async start(type, input, opts = {}, tx) {
1122
- const run = await super.start(type, input, opts, tx);
1123
- await this.dispatch(run, type);
1124
- return run;
1125
- }
1126
- /**
1127
- * Map a `job_run` row onto a BullMQ job via `queue.add`. When the run has a
1128
- * `parentRunId` we attach it to the parent's existing BullMQ job through the
1129
- * `parent: { id, queue }` opt — BullMQ then tracks the parent/child link in
1130
- * its own graph. (The FlowProducer is reserved for whole-tree atomic
1131
- * submits, exposed as an opt-in extension via `flowProducer()`; runtime
1132
- * `ctx.spawnChild` is incremental, so `queue.add` with a parent ref is the
1133
- * correct primitive here.)
1134
- *
1135
- * The `jobId` is colon-safe + stable: `sha1(dedupeKey)` when a dedupe key is
1136
- * present (so the same logical key dedups), else the `job_run.id` UUID
1137
- * (already colon-free).
1138
- *
1139
- * The domain `parentClosePolicy` cascade is still enforced in Postgres by
1140
- * the shared `cancel` path — BullMQ's parent link is dispatch bookkeeping,
1141
- * not the authority.
1142
- */
1143
- async dispatch(run, type) {
1144
- await this.loadBullMq();
1145
- const def = await this.loadDefinition(type);
1146
- const jobId = run.dedupeKey ? sha1JobId(run.dedupeKey) : run.id;
1147
- const jobOpts = {
1148
- jobId,
1149
- ...this.retryOpts(def),
1150
- ...this.dedupeOpts(run, def)
1151
- };
1152
- if (run.parentRunId) {
1153
- const parentRow = await this.loadRun(run.parentRunId);
1154
- if (parentRow) {
1155
- const parentJobId = parentRow.dedupeKey ? sha1JobId(parentRow.dedupeKey) : parentRow.id;
1156
- jobOpts.parent = {
1157
- id: parentJobId,
1158
- queue: resolvePoolQueueName(parentRow.pool, this.bullConfig)
1159
- };
1160
- }
1161
- }
1162
- const payload = { runId: run.id, type, input: run.input };
1163
- await this.queueFor(run.pool).add(type, payload, jobOpts);
1164
- }
1165
- /**
1166
- * Opt-in extension (spec §Extensions): expose the FlowProducer for
1167
- * consumers that want to submit a whole parent/child DAG atomically up
1168
- * front, rather than incrementally via `ctx.spawnChild`. Backend-specific —
1169
- * code using it is not portable to the Drizzle backend. Async because it
1170
- * lazily loads the optional `bullmq` package on first use.
1171
- */
1172
- async flowProducer() {
1173
- await this.loadBullMq();
1174
- return this.flow();
1175
- }
1176
- retryOpts(def) {
1177
- const policy = def.retryPolicy;
1178
- if (!policy) return {};
1179
- return {
1180
- attempts: policy.attempts,
1181
- backoff: {
1182
- type: policy.backoff === "exponential" ? "exponential" : "fixed",
1183
- delay: policy.baseMs
1184
- }
1185
- };
1186
- }
1187
- dedupeOpts(run, def) {
1188
- if (!run.dedupeKey || !def.dedupeWindowMs) return {};
1189
- return {
1190
- deduplication: {
1191
- id: sha1JobId(run.dedupeKey),
1192
- ttl: def.dedupeWindowMs
1193
- }
1194
- };
1195
- }
1196
- // ==========================================================================
1197
- // cancel — Postgres cascade (super) + remove from queue
1198
- // ==========================================================================
1199
- async cancel(runId, opts = {}) {
1200
- const target = await this.loadRun(runId);
1201
- await super.cancel(runId, opts);
1202
- if (!target) return;
1203
- await this.loadBullMq();
1204
- await this.removeFromQueue(target);
1205
- if (opts.cascade === false) return;
1206
- const descendants = await this.bullDb.select().from(jobRuns).where(eq4(jobRuns.rootRunId, target.rootRunId));
1207
- for (const child of descendants) {
1208
- if (child.id === runId) continue;
1209
- await this.removeFromQueue(child);
1210
- }
1211
- }
1212
- async removeFromQueue(run) {
1213
- const jobId = run.dedupeKey ? sha1JobId(run.dedupeKey) : run.id;
1214
- try {
1215
- const job = await this.queueFor(run.pool).getJob(jobId);
1216
- if (job) await job.remove();
1217
- } catch (err) {
1218
- this.bullLogger.warn(
1219
- `cancel: could not remove BullMQ job ${jobId} (pool=${run.pool}): ${err.message}`
1220
- );
1221
- }
1222
- }
1223
- // ==========================================================================
1224
- // replay — Postgres reset (super) + re-enqueue
1225
- // ==========================================================================
1226
- async replay(runId) {
1227
- const run = await super.replay(runId);
1228
- await this.dispatch(run, run.jobType);
1229
- return run;
1230
- }
1231
- // ==========================================================================
1232
- // Internals
1233
- // ==========================================================================
1234
- async loadDefinition(type) {
1235
- const [def] = await this.bullDb.select().from(jobs).where(eq4(jobs.type, type)).limit(1);
1236
- if (!def) {
1237
- throw new Error(`BullMQJobOrchestrator: no job definition for '${type}'`);
1238
- }
1239
- return def;
1240
- }
1241
- async loadRun(id) {
1242
- const [row] = await this.bullDb.select().from(jobRuns).where(eq4(jobRuns.id, id)).limit(1);
1243
- return row ?? null;
1244
- }
1245
- /** Close all open queue + flow connections. Called on module destroy. */
1246
- async closeConnections() {
1247
- for (const q of this.queues.values()) {
1248
- await q.close().catch(() => void 0);
1249
- }
1250
- this.queues.clear();
1251
- if (this._flow) {
1252
- await this._flow.close().catch(() => void 0);
1253
- this._flow = null;
1254
- }
1255
- }
1256
- };
1257
- BullMQJobOrchestrator = __decorateClass([
1258
- Injectable4(),
1259
- __decorateParam(0, Inject4(DRIZZLE)),
1260
- __decorateParam(1, Inject4(JOBS_MULTI_TENANT)),
1261
- __decorateParam(2, Inject4(BULLMQ_CONNECTION)),
1262
- __decorateParam(3, Optional()),
1263
- __decorateParam(3, Inject4(BULLMQ_RESOLVED_CONFIG))
1264
- ], BullMQJobOrchestrator);
1265
-
1266
881
  // runtime/subsystems/jobs/job-orchestrator.memory-backend.ts
1267
882
  import { randomUUID as randomUUID2 } from "crypto";
1268
- import { Inject as Inject5, Injectable as Injectable5, Logger as Logger3, Optional as Optional2 } from "@nestjs/common";
883
+ import { Inject as Inject4, Injectable as Injectable4, Logger as Logger2, Optional } from "@nestjs/common";
1269
884
  var QUEUED_RUN_AT = /* @__PURE__ */ new Date(864e13);
1270
885
  var TERMINAL_STATUSES2 = [
1271
886
  "completed",
@@ -1312,7 +927,7 @@ var MemoryJobOrchestrator = class {
1312
927
  stepService;
1313
928
  multiTenant;
1314
929
  moduleRef;
1315
- logger = new Logger3(MemoryJobOrchestrator.name);
930
+ logger = new Logger2(MemoryJobOrchestrator.name);
1316
931
  mutex = new PromiseMutex();
1317
932
  handlerRegistry = /* @__PURE__ */ new Map();
1318
933
  /**
@@ -1661,7 +1276,7 @@ var MemoryJobOrchestrator = class {
1661
1276
  run,
1662
1277
  step: this.makeStepFn(run),
1663
1278
  spawnChild: this.makeSpawnFn(run),
1664
- logger: new Logger3(`JobRun:${run.id}`)
1279
+ logger: new Logger2(`JobRun:${run.id}`)
1665
1280
  };
1666
1281
  const attemptsBefore = run.attempts ?? 0;
1667
1282
  try {
@@ -1834,9 +1449,9 @@ var MemoryJobOrchestrator = class {
1834
1449
  }
1835
1450
  };
1836
1451
  MemoryJobOrchestrator = __decorateClass([
1837
- Injectable5(),
1838
- __decorateParam(2, Inject5(JOBS_MULTI_TENANT)),
1839
- __decorateParam(3, Optional2())
1452
+ Injectable4(),
1453
+ __decorateParam(2, Inject4(JOBS_MULTI_TENANT)),
1454
+ __decorateParam(3, Optional())
1840
1455
  ], MemoryJobOrchestrator);
1841
1456
  function classifyError(err, policy, currentAttempts) {
1842
1457
  if (!policy) return "fail";
@@ -1870,7 +1485,7 @@ function serialiseError(err, attempt, retryable) {
1870
1485
  }
1871
1486
 
1872
1487
  // runtime/subsystems/jobs/job-run-service.memory-backend.ts
1873
- import { Inject as Inject6, Injectable as Injectable6 } from "@nestjs/common";
1488
+ import { Inject as Inject5, Injectable as Injectable5 } from "@nestjs/common";
1874
1489
  var NON_TERMINAL_STATUSES2 = [
1875
1490
  "pending",
1876
1491
  "running",
@@ -2037,9 +1652,9 @@ var MemoryJobRunService = class {
2037
1652
  }
2038
1653
  };
2039
1654
  MemoryJobRunService = __decorateClass([
2040
- Injectable6(),
2041
- __decorateParam(1, Inject6(JOB_ORCHESTRATOR)),
2042
- __decorateParam(2, Inject6(JOBS_MULTI_TENANT))
1655
+ Injectable5(),
1656
+ __decorateParam(1, Inject5(JOB_ORCHESTRATOR)),
1657
+ __decorateParam(2, Inject5(JOBS_MULTI_TENANT))
2043
1658
  ], MemoryJobRunService);
2044
1659
  function compareBy(a, b, order) {
2045
1660
  switch (order) {
@@ -2057,7 +1672,7 @@ function compareBy(a, b, order) {
2057
1672
 
2058
1673
  // runtime/subsystems/jobs/job-step-service.memory-backend.ts
2059
1674
  import { randomUUID as randomUUID3 } from "crypto";
2060
- import { Injectable as Injectable7 } from "@nestjs/common";
1675
+ import { Injectable as Injectable6 } from "@nestjs/common";
2061
1676
  var MemoryJobStepService = class {
2062
1677
  constructor(store) {
2063
1678
  this.store = store;
@@ -2150,7 +1765,7 @@ var MemoryJobStepService = class {
2150
1765
  }
2151
1766
  };
2152
1767
  MemoryJobStepService = __decorateClass([
2153
- Injectable7()
1768
+ Injectable6()
2154
1769
  ], MemoryJobStepService);
2155
1770
 
2156
1771
  // runtime/subsystems/jobs/memory-job-store.ts
@@ -2169,32 +1784,192 @@ var MemoryJobStore = class {
2169
1784
  }
2170
1785
  };
2171
1786
 
2172
- // runtime/subsystems/jobs/jobs-domain.module.ts
2173
- var JobsDomainModule = class {
2174
- static forRoot(opts) {
2175
- const multiTenant = opts.multiTenant ?? false;
2176
- const providers = [
2177
- // JOB-8 — boolean provider consumed by the four service-layer backends.
2178
- // Always provided (even when `multiTenant === false`) so `@Inject`
2179
- // always resolves; backends short-circuit the enforcement path when
2180
- // the value is `false`. See `jobs-domain.tokens.ts` for the claim-loop
2181
- // cross-tenant-by-design decision.
2182
- { provide: JOBS_MULTI_TENANT, useValue: multiTenant }
2183
- ];
2184
- if (opts.backend === "memory") {
2185
- const store = new MemoryJobStore();
2186
- providers.push({ provide: MemoryJobStore, useValue: store });
2187
- providers.push(MemoryJobStepService);
2188
- providers.push({ provide: JOB_STEP_SERVICE, useExisting: MemoryJobStepService });
2189
- providers.push(MemoryJobOrchestrator);
2190
- providers.push({ provide: JOB_ORCHESTRATOR, useExisting: MemoryJobOrchestrator });
2191
- providers.push(MemoryJobRunService);
2192
- providers.push({ provide: JOB_RUN_SERVICE, useExisting: MemoryJobRunService });
2193
- } else if (opts.backend === "bullmq") {
2194
- const resolved = resolveBullMqConfig(opts.extensions?.bullmq);
2195
- providers.push({ provide: BULLMQ_CONNECTION, useValue: resolved.connection });
2196
- providers.push({ provide: BULLMQ_RESOLVED_CONFIG, useValue: resolved });
2197
- providers.push({ provide: JOB_ORCHESTRATOR, useClass: BullMQJobOrchestrator });
1787
+ // runtime/subsystems/jobs/pool-config.loader.ts
1788
+ import { existsSync, readFileSync } from "fs";
1789
+ import { resolve } from "path";
1790
+ import { parse as parseYaml } from "yaml";
1791
+ var FRAMEWORK_POOLS = Object.freeze({
1792
+ events_inbound: Object.freeze({
1793
+ queue: "jobs-events-inbound",
1794
+ concurrency: 20,
1795
+ reserved: true,
1796
+ description: "Inbound events drain (events subsystem outbox)."
1797
+ }),
1798
+ events_change: Object.freeze({
1799
+ queue: "jobs-events-change",
1800
+ concurrency: 30,
1801
+ reserved: true,
1802
+ description: "Change events drain (events subsystem outbox)."
1803
+ }),
1804
+ events_outbound: Object.freeze({
1805
+ queue: "jobs-events-outbound",
1806
+ concurrency: 10,
1807
+ reserved: true,
1808
+ description: "Outbound events drain (events subsystem outbox)."
1809
+ }),
1810
+ interactive: Object.freeze({
1811
+ queue: "jobs-interactive",
1812
+ concurrency: 20,
1813
+ reserved: false,
1814
+ description: "User-facing latency-sensitive jobs."
1815
+ }),
1816
+ batch: Object.freeze({
1817
+ queue: "jobs-batch",
1818
+ concurrency: 5,
1819
+ reserved: false,
1820
+ description: "Default pool for background jobs."
1821
+ })
1822
+ });
1823
+ var RESERVED_POOL_NAMES = new Set(
1824
+ Object.entries(FRAMEWORK_POOLS).filter(([, def]) => def.reserved).map(([name]) => name)
1825
+ );
1826
+ var cache = /* @__PURE__ */ new Map();
1827
+ function loadPoolConfig(configPath) {
1828
+ const resolved = resolve(configPath ?? `${process.cwd()}/codegen.config.yaml`);
1829
+ const cached = cache.get(resolved);
1830
+ if (cached) return cached;
1831
+ const merged = /* @__PURE__ */ new Map();
1832
+ for (const [name, def] of Object.entries(FRAMEWORK_POOLS)) {
1833
+ merged.set(name, { ...def });
1834
+ }
1835
+ if (!existsSync(resolved)) {
1836
+ cache.set(resolved, merged);
1837
+ return merged;
1838
+ }
1839
+ let raw;
1840
+ try {
1841
+ raw = parseYaml(readFileSync(resolved, "utf8"));
1842
+ } catch (err) {
1843
+ throw new Error(
1844
+ `pool-config.loader: failed to parse YAML at ${resolved}: ${err.message}`
1845
+ );
1846
+ }
1847
+ const userPools = extractUserPools(raw);
1848
+ for (const [name, userDef] of Object.entries(userPools)) {
1849
+ const existing = merged.get(name);
1850
+ if (existing) {
1851
+ const next = {
1852
+ queue: existing.queue,
1853
+ concurrency: typeof userDef.concurrency === "number" ? userDef.concurrency : existing.concurrency,
1854
+ reserved: existing.reserved,
1855
+ description: userDef.description ?? existing.description
1856
+ };
1857
+ merged.set(name, next);
1858
+ continue;
1859
+ }
1860
+ if (typeof userDef.queue !== "string" || userDef.queue.length === 0) {
1861
+ throw new Error(
1862
+ `pool-config.loader: pool '${name}' must declare a non-empty 'queue'.`
1863
+ );
1864
+ }
1865
+ if (typeof userDef.concurrency !== "number" || userDef.concurrency <= 0) {
1866
+ throw new Error(
1867
+ `pool-config.loader: pool '${name}' must declare a positive 'concurrency'.`
1868
+ );
1869
+ }
1870
+ if (userDef.reserved === true) {
1871
+ throw new Error(
1872
+ `pool-config.loader: user-defined pool '${name}' cannot set 'reserved: true' \u2014 reserved is framework-only.`
1873
+ );
1874
+ }
1875
+ merged.set(name, {
1876
+ queue: userDef.queue,
1877
+ concurrency: userDef.concurrency,
1878
+ reserved: false,
1879
+ description: userDef.description
1880
+ });
1881
+ }
1882
+ cache.set(resolved, merged);
1883
+ return merged;
1884
+ }
1885
+ function allNonReservedPoolNames(config) {
1886
+ const out = [];
1887
+ for (const [name, def] of config) {
1888
+ if (!def.reserved) out.push(name);
1889
+ }
1890
+ return out;
1891
+ }
1892
+ function allPoolNames(config) {
1893
+ return [...config.keys()];
1894
+ }
1895
+ function extractUserPools(raw) {
1896
+ if (!raw || typeof raw !== "object") return {};
1897
+ const jobs2 = raw.jobs;
1898
+ if (!jobs2 || typeof jobs2 !== "object") return {};
1899
+ const pools = jobs2.pools;
1900
+ if (!pools || typeof pools !== "object") return {};
1901
+ const out = {};
1902
+ for (const [name, def] of Object.entries(pools)) {
1903
+ if (!def || typeof def !== "object") continue;
1904
+ out[name] = def;
1905
+ }
1906
+ return out;
1907
+ }
1908
+
1909
+ // runtime/subsystems/jobs/bullmq.config.ts
1910
+ var BULLMQ_CONNECTION = /* @__PURE__ */ Symbol("BULLMQ_CONNECTION");
1911
+ var BULLMQ_RESOLVED_CONFIG = /* @__PURE__ */ Symbol("BULLMQ_RESOLVED_CONFIG");
1912
+ var DEFAULT_REDIS_URL = "redis://localhost:6379";
1913
+ var DEFAULT_BULL_BOARD_MOUNT = "/admin/queues";
1914
+ function resolveBullMqConfig(ext) {
1915
+ const url = ext?.redis_url ?? process.env.REDIS_URL ?? DEFAULT_REDIS_URL;
1916
+ const resolved = {
1917
+ connection: { url },
1918
+ queuePrefix: ext?.queue_prefix
1919
+ };
1920
+ if (ext?.bull_board?.enabled) {
1921
+ resolved.bullBoard = {
1922
+ enabled: true,
1923
+ mountPath: ext.bull_board.mount_path ?? DEFAULT_BULL_BOARD_MOUNT
1924
+ };
1925
+ }
1926
+ return resolved;
1927
+ }
1928
+ function resolvePoolQueueName(pool, config, poolConfig = loadPoolConfig()) {
1929
+ const alias = poolConfig.get(pool)?.queue ?? pool;
1930
+ const prefix = config?.queuePrefix;
1931
+ return prefix ? `${prefix}:${alias}` : alias;
1932
+ }
1933
+
1934
+ // runtime/subsystems/jobs/jobs-domain.module.ts
1935
+ var JobsDomainModule = class {
1936
+ static forRoot(opts) {
1937
+ const multiTenant = opts.multiTenant ?? false;
1938
+ const providers = [
1939
+ // JOB-8 — boolean provider consumed by the four service-layer backends.
1940
+ // Always provided (even when `multiTenant === false`) so `@Inject`
1941
+ // always resolves; backends short-circuit the enforcement path when
1942
+ // the value is `false`. See `jobs-domain.tokens.ts` for the claim-loop
1943
+ // cross-tenant-by-design decision.
1944
+ { provide: JOBS_MULTI_TENANT, useValue: multiTenant }
1945
+ ];
1946
+ if (opts.backend === "memory") {
1947
+ const store = new MemoryJobStore();
1948
+ providers.push({ provide: MemoryJobStore, useValue: store });
1949
+ providers.push(MemoryJobStepService);
1950
+ providers.push({ provide: JOB_STEP_SERVICE, useExisting: MemoryJobStepService });
1951
+ providers.push(MemoryJobOrchestrator);
1952
+ providers.push({ provide: JOB_ORCHESTRATOR, useExisting: MemoryJobOrchestrator });
1953
+ providers.push(MemoryJobRunService);
1954
+ providers.push({ provide: JOB_RUN_SERVICE, useExisting: MemoryJobRunService });
1955
+ } else if (opts.backend === "bullmq") {
1956
+ const resolved = resolveBullMqConfig(opts.extensions?.bullmq);
1957
+ providers.push({ provide: BULLMQ_CONNECTION, useValue: resolved.connection });
1958
+ providers.push({ provide: BULLMQ_RESOLVED_CONFIG, useValue: resolved });
1959
+ providers.push({
1960
+ provide: JOB_ORCHESTRATOR,
1961
+ useFactory: async (...args) => {
1962
+ const specifier = "./job-orchestrator.bullmq-backend";
1963
+ const mod = await import(specifier);
1964
+ return new mod.BullMQJobOrchestrator(...args);
1965
+ },
1966
+ // The bullmq orchestrator constructor mirrors DrizzleJobOrchestrator's
1967
+ // injection list: DRIZZLE + JOBS_MULTI_TENANT + the resolved BullMQ
1968
+ // tokens. Importing token references would force a static dep on the
1969
+ // tokens file in this module's import graph; using the existing
1970
+ // symbols already in scope is sufficient.
1971
+ inject: [DRIZZLE, JOBS_MULTI_TENANT, BULLMQ_CONNECTION, BULLMQ_RESOLVED_CONFIG]
1972
+ });
2198
1973
  providers.push({ provide: JOB_RUN_SERVICE, useClass: DrizzleJobRunService });
2199
1974
  providers.push({ provide: JOB_STEP_SERVICE, useClass: DrizzleJobStepService });
2200
1975
  } else {
@@ -2224,8 +1999,8 @@ JobsDomainModule = __decorateClass([
2224
1999
  ], JobsDomainModule);
2225
2000
 
2226
2001
  // runtime/subsystems/jobs/job-worker.ts
2227
- import { Inject as Inject7, Injectable as Injectable8, Logger as Logger4 } from "@nestjs/common";
2228
- import { and as and4, asc as asc2, desc as desc3, eq as eq5, inArray as inArray3, lt as lt2, lte, sql as sql4 } from "drizzle-orm";
2002
+ import { Inject as Inject6, Injectable as Injectable7, Logger as Logger3 } from "@nestjs/common";
2003
+ import { and as and4, asc as asc2, desc as desc3, eq as eq4, inArray as inArray3, lt as lt2, lte, sql as sql4 } from "drizzle-orm";
2229
2004
  var JOB_WORKER_OPTIONS = /* @__PURE__ */ Symbol("JOB_WORKER_OPTIONS");
2230
2005
  var DEFAULT_POLL_INTERVAL_MS = 1e3;
2231
2006
  var DEFAULT_STALE_SWEEPER_INTERVAL_MS = 6e4;
@@ -2288,7 +2063,7 @@ var JobWorker = class {
2288
2063
  stepService;
2289
2064
  options;
2290
2065
  moduleRef;
2291
- logger = new Logger4(JobWorker.name);
2066
+ logger = new Logger3(JobWorker.name);
2292
2067
  shuttingDown = false;
2293
2068
  inFlight = /* @__PURE__ */ new Set();
2294
2069
  pollTimer = null;
@@ -2329,7 +2104,7 @@ var JobWorker = class {
2329
2104
  await this.drainInFlight();
2330
2105
  try {
2331
2106
  await this.db.update(jobRuns).set({ status: "pending", claimedAt: null, startedAt: null }).where(
2332
- and4(eq5(jobRuns.status, "running"), eq5(jobRuns.pool, this.options.pool))
2107
+ and4(eq4(jobRuns.status, "running"), eq4(jobRuns.pool, this.options.pool))
2333
2108
  );
2334
2109
  } catch (err) {
2335
2110
  this.logger.error(`shutdown reset failed: ${err.message}`);
@@ -2379,8 +2154,8 @@ var JobWorker = class {
2379
2154
  return this.db.transaction(async (tx) => {
2380
2155
  const candidates = await tx.select({ id: jobRuns.id }).from(jobRuns).where(
2381
2156
  and4(
2382
- eq5(jobRuns.status, "pending"),
2383
- eq5(jobRuns.pool, pool),
2157
+ eq4(jobRuns.status, "pending"),
2158
+ eq4(jobRuns.pool, pool),
2384
2159
  lte(jobRuns.runAt, /* @__PURE__ */ new Date())
2385
2160
  )
2386
2161
  ).orderBy(desc3(jobRuns.priority), asc2(jobRuns.runAt)).limit(1).for("update", { skipLocked: true });
@@ -2391,7 +2166,7 @@ var JobWorker = class {
2391
2166
  claimedAt: /* @__PURE__ */ new Date(),
2392
2167
  startedAt: /* @__PURE__ */ new Date(),
2393
2168
  updatedAt: /* @__PURE__ */ new Date()
2394
- }).where(eq5(jobRuns.id, candidate.id)).returning();
2169
+ }).where(eq4(jobRuns.id, candidate.id)).returning();
2395
2170
  return claimed ?? null;
2396
2171
  });
2397
2172
  }
@@ -2409,7 +2184,7 @@ var JobWorker = class {
2409
2184
  await this.db.transaction(async (tx) => {
2410
2185
  const threshold = new Date(Date.now() - this.staleThresholdMs);
2411
2186
  const stale = await tx.select({ id: jobRuns.id }).from(jobRuns).where(
2412
- and4(eq5(jobRuns.status, "running"), lt2(jobRuns.claimedAt, threshold))
2187
+ and4(eq4(jobRuns.status, "running"), lt2(jobRuns.claimedAt, threshold))
2413
2188
  ).for("update", { skipLocked: true });
2414
2189
  if (stale.length === 0) return;
2415
2190
  const ids = stale.map((r) => r.id);
@@ -2442,8 +2217,8 @@ var JobWorker = class {
2442
2217
  if (claimed.concurrencyKey) {
2443
2218
  const inflight = await this.db.select({ id: jobRuns.id }).from(jobRuns).where(
2444
2219
  and4(
2445
- eq5(jobRuns.concurrencyKey, claimed.concurrencyKey),
2446
- eq5(jobRuns.status, "running")
2220
+ eq4(jobRuns.concurrencyKey, claimed.concurrencyKey),
2221
+ eq4(jobRuns.status, "running")
2447
2222
  )
2448
2223
  );
2449
2224
  const other = inflight.find((r) => r.id !== claimed.id);
@@ -2453,7 +2228,7 @@ var JobWorker = class {
2453
2228
  claimedAt: null,
2454
2229
  startedAt: null,
2455
2230
  updatedAt: /* @__PURE__ */ new Date()
2456
- }).where(eq5(jobRuns.id, claimed.id));
2231
+ }).where(eq4(jobRuns.id, claimed.id));
2457
2232
  return;
2458
2233
  }
2459
2234
  }
@@ -2468,7 +2243,7 @@ var JobWorker = class {
2468
2243
  run: claimed,
2469
2244
  step: this.makeStepFn(claimed),
2470
2245
  spawnChild: this.makeSpawnFn(claimed),
2471
- logger: new Logger4(`JobRun:${claimed.id}`)
2246
+ logger: new Logger3(`JobRun:${claimed.id}`)
2472
2247
  };
2473
2248
  const attemptsBefore = claimed.attempts ?? 0;
2474
2249
  try {
@@ -2479,7 +2254,7 @@ var JobWorker = class {
2479
2254
  finishedAt: /* @__PURE__ */ new Date(),
2480
2255
  updatedAt: /* @__PURE__ */ new Date(),
2481
2256
  attempts: attemptsBefore + 1
2482
- }).where(eq5(jobRuns.id, claimed.id));
2257
+ }).where(eq4(jobRuns.id, claimed.id));
2483
2258
  } catch (err) {
2484
2259
  const policy = meta.retry;
2485
2260
  const decision = classifyError2(err, policy, attemptsBefore);
@@ -2494,7 +2269,7 @@ var JobWorker = class {
2494
2269
  claimedAt: null,
2495
2270
  error: serialiseError2(err, nextAttempts, true),
2496
2271
  updatedAt: /* @__PURE__ */ new Date()
2497
- }).where(eq5(jobRuns.id, claimed.id));
2272
+ }).where(eq4(jobRuns.id, claimed.id));
2498
2273
  } else {
2499
2274
  await this.markFailed(claimed, err, nextAttempts);
2500
2275
  }
@@ -2507,7 +2282,7 @@ var JobWorker = class {
2507
2282
  finishedAt: /* @__PURE__ */ new Date(),
2508
2283
  error: serialiseError2(err, finalAttempts, false),
2509
2284
  updatedAt: /* @__PURE__ */ new Date()
2510
- }).where(eq5(jobRuns.id, claimed.id));
2285
+ }).where(eq4(jobRuns.id, claimed.id));
2511
2286
  if (claimed.parentClosePolicy === "terminate") {
2512
2287
  try {
2513
2288
  await this.orchestrator.cancel(claimed.id, {
@@ -2610,215 +2385,14 @@ var JobWorker = class {
2610
2385
  // ============================================================================
2611
2386
  };
2612
2387
  JobWorker = __decorateClass([
2613
- Injectable8(),
2614
- __decorateParam(0, Inject7(DRIZZLE)),
2615
- __decorateParam(1, Inject7(JOB_ORCHESTRATOR)),
2616
- __decorateParam(2, Inject7(JOB_RUN_SERVICE)),
2617
- __decorateParam(3, Inject7(JOB_STEP_SERVICE)),
2618
- __decorateParam(4, Inject7(JOB_WORKER_OPTIONS))
2388
+ Injectable7(),
2389
+ __decorateParam(0, Inject6(DRIZZLE)),
2390
+ __decorateParam(1, Inject6(JOB_ORCHESTRATOR)),
2391
+ __decorateParam(2, Inject6(JOB_RUN_SERVICE)),
2392
+ __decorateParam(3, Inject6(JOB_STEP_SERVICE)),
2393
+ __decorateParam(4, Inject6(JOB_WORKER_OPTIONS))
2619
2394
  ], JobWorker);
2620
2395
 
2621
- // runtime/subsystems/jobs/job-worker.bullmq-backend.ts
2622
- import { Logger as Logger5 } from "@nestjs/common";
2623
- import { eq as eq6 } from "drizzle-orm";
2624
- function serialiseError3(err, attempt, retryable) {
2625
- const e = err;
2626
- return {
2627
- message: e?.message ?? String(err),
2628
- stack: e?.stack,
2629
- retryable,
2630
- attempt
2631
- };
2632
- }
2633
- var BullMQJobWorker = class _BullMQJobWorker {
2634
- constructor(db, orchestrator, stepService, options, moduleRef) {
2635
- this.db = db;
2636
- this.orchestrator = orchestrator;
2637
- this.stepService = stepService;
2638
- this.options = options;
2639
- this.moduleRef = moduleRef;
2640
- }
2641
- db;
2642
- orchestrator;
2643
- stepService;
2644
- options;
2645
- moduleRef;
2646
- logger = new Logger5(_BullMQJobWorker.name);
2647
- worker = null;
2648
- async onModuleInit() {
2649
- let WorkerCtor;
2650
- try {
2651
- const mod = await import("bullmq");
2652
- WorkerCtor = mod.Worker;
2653
- } catch {
2654
- throw new Error(
2655
- 'BullMQ backend requires the "bullmq" package. Install it with: npm install bullmq'
2656
- );
2657
- }
2658
- this.worker = new WorkerCtor(
2659
- this.options.queueName,
2660
- (job) => this.process(job),
2661
- {
2662
- connection: this.options.connection,
2663
- concurrency: this.options.concurrency
2664
- }
2665
- );
2666
- this.worker.on("failed", (job, err) => {
2667
- if (!job) return;
2668
- const attemptsMade = job.attemptsMade;
2669
- const maxAttempts = job.opts.attempts ?? 1;
2670
- if (attemptsMade >= maxAttempts) {
2671
- void this.markFailed(job.data.runId, err, attemptsMade);
2672
- }
2673
- });
2674
- this.logger.log(
2675
- `BullMQ worker started: pool='${this.options.pool}' queue='${this.options.queueName}' concurrency=${this.options.concurrency}`
2676
- );
2677
- }
2678
- async onModuleDestroy() {
2679
- if (this.worker) {
2680
- await this.worker.close();
2681
- this.worker = null;
2682
- }
2683
- }
2684
- /**
2685
- * Process one BullMQ job. Returns the handler output (stored by BullMQ as
2686
- * the job return value AND written to `job_run.output`). Throws on handler
2687
- * failure so BullMQ applies the retry policy.
2688
- */
2689
- async process(job) {
2690
- const { runId } = job.data;
2691
- const [row] = await this.db.select().from(jobRuns).where(eq6(jobRuns.id, runId)).limit(1);
2692
- if (!row) {
2693
- this.logger.warn(`process: job_run ${runId} not found; skipping`);
2694
- return {};
2695
- }
2696
- const run = row;
2697
- if (run.status === "canceled") {
2698
- return {};
2699
- }
2700
- const registryEntry = JOB_HANDLER_REGISTRY.get(run.jobType);
2701
- if (!registryEntry) {
2702
- throw new Error(
2703
- `No handler registered for jobType='${run.jobType}' (run ${run.id})`
2704
- );
2705
- }
2706
- await this.db.update(jobRuns).set({
2707
- status: "running",
2708
- claimedAt: /* @__PURE__ */ new Date(),
2709
- startedAt: /* @__PURE__ */ new Date(),
2710
- attempts: job.attemptsMade + 1,
2711
- updatedAt: /* @__PURE__ */ new Date()
2712
- }).where(eq6(jobRuns.id, run.id));
2713
- const HandlerClass = registryEntry.handlerClass;
2714
- const handler = this.moduleRef.get(
2715
- HandlerClass,
2716
- { strict: false }
2717
- );
2718
- const ctx = {
2719
- input: run.input,
2720
- run,
2721
- step: this.makeStepFn(run),
2722
- spawnChild: this.makeSpawnFn(run),
2723
- logger: new Logger5(`JobRun:${run.id}`)
2724
- };
2725
- const output = await handler.run(ctx);
2726
- await this.db.update(jobRuns).set({
2727
- status: "completed",
2728
- output: output ?? {},
2729
- finishedAt: /* @__PURE__ */ new Date(),
2730
- updatedAt: /* @__PURE__ */ new Date()
2731
- }).where(eq6(jobRuns.id, run.id));
2732
- return output ?? {};
2733
- }
2734
- async markFailed(runId, err, finalAttempts) {
2735
- const [row] = await this.db.select().from(jobRuns).where(eq6(jobRuns.id, runId)).limit(1);
2736
- if (!row) return;
2737
- const run = row;
2738
- await this.db.update(jobRuns).set({
2739
- status: "failed",
2740
- attempts: finalAttempts,
2741
- finishedAt: /* @__PURE__ */ new Date(),
2742
- error: serialiseError3(err, finalAttempts, false),
2743
- updatedAt: /* @__PURE__ */ new Date()
2744
- }).where(eq6(jobRuns.id, runId));
2745
- if (run.parentClosePolicy === "terminate") {
2746
- try {
2747
- await this.orchestrator.cancel(run.id, {
2748
- cascade: true,
2749
- reason: "parent-failed",
2750
- tenantId: run.tenantId
2751
- });
2752
- } catch (cascadeErr) {
2753
- this.logger.warn(
2754
- `cascade on failed run ${run.id}: ${cascadeErr.message}`
2755
- );
2756
- }
2757
- }
2758
- }
2759
- // ── ctx.step / ctx.spawnChild (mirror JobWorker) ──────────────────────────
2760
- makeStepFn(run) {
2761
- return async (stepId, fn, _opts) => {
2762
- void _opts;
2763
- const existing = await this.stepService.findStep(run.id, stepId);
2764
- if (existing?.status === "completed") {
2765
- return existing.output;
2766
- }
2767
- const nextAttempts = (existing?.attempts ?? 0) + 1;
2768
- const seq = nextAttempts;
2769
- await this.stepService.recordStep({
2770
- jobRunId: run.id,
2771
- stepId,
2772
- kind: "task",
2773
- seq,
2774
- status: "running",
2775
- startedAt: /* @__PURE__ */ new Date(),
2776
- attempts: nextAttempts
2777
- });
2778
- try {
2779
- const output = await fn();
2780
- await this.stepService.recordStep({
2781
- jobRunId: run.id,
2782
- stepId,
2783
- kind: "task",
2784
- seq,
2785
- status: "completed",
2786
- output,
2787
- finishedAt: /* @__PURE__ */ new Date(),
2788
- attempts: nextAttempts
2789
- });
2790
- return output;
2791
- } catch (err) {
2792
- await this.stepService.recordStep({
2793
- jobRunId: run.id,
2794
- stepId,
2795
- kind: "task",
2796
- seq,
2797
- status: "failed",
2798
- error: serialiseError3(err, nextAttempts, false),
2799
- finishedAt: /* @__PURE__ */ new Date(),
2800
- attempts: nextAttempts
2801
- });
2802
- throw err;
2803
- }
2804
- };
2805
- }
2806
- makeSpawnFn(run) {
2807
- return async (type, input, opts) => {
2808
- return this.orchestrator.start(type, input, {
2809
- parentRunId: run.id,
2810
- parentClosePolicy: opts?.closePolicy,
2811
- runAt: opts?.runAt,
2812
- priority: opts?.priority,
2813
- tags: opts?.tags,
2814
- triggerSource: "parent",
2815
- triggerRef: run.id,
2816
- tenantId: run.tenantId
2817
- });
2818
- };
2819
- }
2820
- };
2821
-
2822
2396
  // runtime/subsystems/jobs/job-worker.module.ts
2823
2397
  var DEFAULT_SHUTDOWN_TIMEOUT_MS2 = 3e4;
2824
2398
  var JOB_WORKER_MODULE_OPTIONS = /* @__PURE__ */ Symbol("JOB_WORKER_MODULE_OPTIONS");
@@ -2841,7 +2415,7 @@ var JobWorkerOrchestrator = class {
2841
2415
  moduleRef;
2842
2416
  bullConnection;
2843
2417
  bullConfig;
2844
- logger = new Logger6(JobWorkerOrchestrator.name);
2418
+ logger = new Logger4(JobWorkerOrchestrator.name);
2845
2419
  workers = [];
2846
2420
  // ============================================================================
2847
2421
  // Lifecycle
@@ -2871,7 +2445,7 @@ var JobWorkerOrchestrator = class {
2871
2445
  concurrency: def.concurrency,
2872
2446
  shutdownTimeoutMs: this.options.shutdownTimeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS2
2873
2447
  };
2874
- const worker = this.options.workerFactory ? this.options.workerFactory(workerOptions) : backend === "bullmq" ? this.spawnBullMQWorker(poolName, def.queue, def.concurrency, poolConfig) : this.spawnWorker(workerOptions);
2448
+ const worker = this.options.workerFactory ? this.options.workerFactory(workerOptions) : backend === "bullmq" ? await this.spawnBullMQWorker(poolName, def.queue, def.concurrency, poolConfig) : this.spawnWorker(workerOptions);
2875
2449
  await worker.onModuleInit();
2876
2450
  this.workers.push(worker);
2877
2451
  this.logger.log(
@@ -2971,7 +2545,15 @@ var JobWorkerOrchestrator = class {
2971
2545
  * orchestrator's `dispatch` via `resolvePoolQueueName(pool, …)` so producer
2972
2546
  * and consumer agree.
2973
2547
  */
2974
- spawnBullMQWorker(pool, _queueAlias, concurrency, poolConfig) {
2548
+ /**
2549
+ * #6 — async + dynamic-import. The `job-worker.bullmq-backend.ts` file is
2550
+ * filtered out of the vendor set for drizzle/memory installs (no `bullmq`
2551
+ * peer dep needed). The non-literal import specifier makes TS treat the
2552
+ * module as `any` so the consumer's tsc never tries to resolve an absent
2553
+ * file. This method is only entered when `backend === 'bullmq'` — at which
2554
+ * point the file IS vendored.
2555
+ */
2556
+ async spawnBullMQWorker(pool, _queueAlias, concurrency, poolConfig) {
2975
2557
  if (!this.db) {
2976
2558
  throw new Error(
2977
2559
  `JobWorkerModule: BullMQ worker spawning requires the Drizzle client (no DRIZZLE provider available) \u2014 job_run remains the source of truth.`
@@ -2988,7 +2570,9 @@ var JobWorkerOrchestrator = class {
2988
2570
  );
2989
2571
  }
2990
2572
  const queueName = resolvePoolQueueName(pool, this.bullConfig, poolConfig);
2991
- return new BullMQJobWorker(
2573
+ const specifier = "./job-worker.bullmq-backend";
2574
+ const mod = await import(specifier);
2575
+ return new mod.BullMQJobWorker(
2992
2576
  this.db,
2993
2577
  this.orchestrator,
2994
2578
  this.stepService,
@@ -3003,17 +2587,17 @@ var JobWorkerOrchestrator = class {
3003
2587
  }
3004
2588
  };
3005
2589
  JobWorkerOrchestrator = __decorateClass([
3006
- Injectable9(),
3007
- __decorateParam(0, Inject8(JOB_ORCHESTRATOR)),
3008
- __decorateParam(1, Inject8(JOB_RUN_SERVICE)),
3009
- __decorateParam(2, Inject8(JOB_STEP_SERVICE)),
3010
- __decorateParam(3, Inject8(JOB_WORKER_MODULE_OPTIONS)),
3011
- __decorateParam(4, Optional3()),
3012
- __decorateParam(4, Inject8(DRIZZLE)),
3013
- __decorateParam(6, Optional3()),
3014
- __decorateParam(6, Inject8(BULLMQ_CONNECTION)),
3015
- __decorateParam(7, Optional3()),
3016
- __decorateParam(7, Inject8(BULLMQ_RESOLVED_CONFIG))
2590
+ Injectable8(),
2591
+ __decorateParam(0, Inject7(JOB_ORCHESTRATOR)),
2592
+ __decorateParam(1, Inject7(JOB_RUN_SERVICE)),
2593
+ __decorateParam(2, Inject7(JOB_STEP_SERVICE)),
2594
+ __decorateParam(3, Inject7(JOB_WORKER_MODULE_OPTIONS)),
2595
+ __decorateParam(4, Optional2()),
2596
+ __decorateParam(4, Inject7(DRIZZLE)),
2597
+ __decorateParam(6, Optional2()),
2598
+ __decorateParam(6, Inject7(BULLMQ_CONNECTION)),
2599
+ __decorateParam(7, Optional2()),
2600
+ __decorateParam(7, Inject7(BULLMQ_RESOLVED_CONFIG))
3017
2601
  ], JobWorkerOrchestrator);
3018
2602
  var JobWorkerModule = class {
3019
2603
  static forRoot(opts) {