@classytic/arc 2.41.0 → 2.43.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 (230) hide show
  1. package/dist/{EventTransport-CbUKDzZZ.d.mts → EventTransport-CiicKz2Z.d.mts} +1 -1
  2. package/dist/{EventTransport-n7qO5Cz3.mjs → EventTransport-tzA7CAB4.mjs} +22 -17
  3. package/dist/{HookSystem-CxvZBo77.mjs → HookSystem-B6UaKRbF.mjs} +2 -2
  4. package/dist/{QueryCache-DFA-QrU9.d.mts → QueryCache--5uAuYPW.d.mts} +7 -3
  5. package/dist/{ResourceRegistry-Cu7uTJp9.mjs → ResourceRegistry-CuCARu2B.mjs} +44 -13
  6. package/dist/actionPermissions-BotX1YOa.mjs +776 -0
  7. package/dist/audit/index.d.mts +43 -5
  8. package/dist/audit/index.mjs +48 -26
  9. package/dist/auth/audit.mjs +1 -1
  10. package/dist/auth/index.d.mts +43 -13
  11. package/dist/auth/index.mjs +130 -155
  12. package/dist/auth/redis-session.mjs +1 -1
  13. package/dist/{authorizationDecision-2YY_Kaj1.mjs → authorizationDecision-DQYrkl5f.mjs} +7 -102
  14. package/dist/{base-CxrV1LmG.d.mts → base-CZyixEQR.d.mts} +27 -5
  15. package/dist/boundedMap-BULzfXYU.mjs +57 -0
  16. package/dist/{buildHandler-CUhjGHGZ.mjs → buildHandler-CRQ8EcX5.mjs} +4 -4
  17. package/dist/cache/index.d.mts +22 -34
  18. package/dist/cache/index.mjs +4 -4
  19. package/dist/{caching-DsWDjIxx.mjs → caching-Cc2M1DwO.mjs} +3 -3
  20. package/dist/claimed-B10RTfkM.mjs +8 -0
  21. package/dist/cleanup/index.d.mts +6 -10
  22. package/dist/cleanup/index.mjs +27 -73
  23. package/dist/cli/commands/describe.d.mts +4 -2
  24. package/dist/cli/commands/describe.mjs +7 -4
  25. package/dist/cli/commands/docs.mjs +3 -3
  26. package/dist/cli/commands/doctor.mjs +1 -1
  27. package/dist/cli/commands/generate.mjs +2 -2
  28. package/dist/cli/commands/init.mjs +2 -2
  29. package/dist/cli/commands/introspect.mjs +2 -2
  30. package/dist/cli/index.mjs +3 -3
  31. package/dist/{constants-BxLgNFF7.mjs → constants-Cu7Mx7_U.mjs} +4 -2
  32. package/dist/context/index.d.mts +2 -5
  33. package/dist/context/index.mjs +18 -38
  34. package/dist/core/index.d.mts +3 -3
  35. package/dist/core/index.mjs +8 -8
  36. package/dist/{core-iNGqYerO.mjs → core-Cb0LjccA.mjs} +5 -4
  37. package/dist/{createActionRouter-BBlbPs3k.mjs → createActionRouter-xjqonMRO.mjs} +87 -39
  38. package/dist/{createAggregationRouter-Dv5SuK2x.mjs → createAggregationRouter-zRYWw_5D.mjs} +11 -8
  39. package/dist/{preloadResources-Bbp4QJ8V.mjs → createApp-D-953ZAq.mjs} +299 -390
  40. package/dist/{createMcpServer-CbDWkZ1T.d.mts → createMcpServer-C9cxS8zt.d.mts} +1 -1
  41. package/dist/{defineAggregation-UyeurGkp.mjs → defineAggregation-Bm8RjMbq.mjs} +1 -1
  42. package/dist/{defineResource-DzGT-2LP.mjs → defineResource-DIC7JZGU.mjs} +118 -1024
  43. package/dist/discovery/index.mjs +1 -1
  44. package/dist/docs/index.d.mts +10 -4
  45. package/dist/docs/index.mjs +4 -4
  46. package/dist/{elevation-BXCfVcNG.d.mts → elevation-BW2J3tNj.d.mts} +1 -2
  47. package/dist/{elevation-BF-vhGxY.mjs → elevation-DG8SrLN-.mjs} +41 -12
  48. package/dist/encryption/index.mjs +3 -3
  49. package/dist/{errorHandler-CIMkCOWm.mjs → errorHandler-BnfDviL1.mjs} +26 -5
  50. package/dist/{errors-C_YhELhe.mjs → errors-CtrywMHP.mjs} +58 -23
  51. package/dist/{errors-BGdVwP25.d.mts → errors-JYc9vwqE.d.mts} +9 -0
  52. package/dist/{eventPlugin-B52abJ8W.d.mts → eventPlugin-BtmA4-3P.d.mts} +65 -9
  53. package/dist/{eventPlugin-CmXaPWLv.mjs → eventPlugin-Q6BhzHzs.mjs} +82 -21
  54. package/dist/{subscribe-helpers-AVYPgqTl.mjs → eventTypes-Cdhm6ZlV.mjs} +151 -17
  55. package/dist/events/index.d.mts +33 -8
  56. package/dist/events/index.mjs +49 -53
  57. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  58. package/dist/events/transports/redis-stream-entry.mjs +139 -157
  59. package/dist/events/transports/redis.d.mts +1 -1
  60. package/dist/events/transports/redis.mjs +2 -2
  61. package/dist/factory/index.d.mts +32 -17
  62. package/dist/factory/index.mjs +213 -32
  63. package/dist/{fastify-augmentation-Cq2nHVaW.d.mts → fastify-augmentation-DhUJ-mvo.d.mts} +11 -25
  64. package/dist/{fields-I_EeRWND.d.mts → fields-BBSpf8pS.d.mts} +1 -1
  65. package/dist/{fields-BTyPLHK0.mjs → fields-ToPYpMqS.mjs} +1 -1
  66. package/dist/filter-merge-IpGywvym.mjs +99 -0
  67. package/dist/{generate-D_YmiCNf.mjs → generate-DRTkLlIl.mjs} +2 -2
  68. package/dist/{headers-CNECDE6q.mjs → headers-BbkIF6vA.mjs} +2 -2
  69. package/dist/health-D-Ft6JM6.mjs +22 -0
  70. package/dist/{health-CxQzbJmr.mjs → health-DqbsG-_w.mjs} +115 -55
  71. package/dist/hooks/index.d.mts +2 -2
  72. package/dist/hooks/index.mjs +2 -2
  73. package/dist/idempotency/index.d.mts +31 -7
  74. package/dist/idempotency/index.mjs +155 -98
  75. package/dist/idempotency/redis.d.mts +1 -1
  76. package/dist/idempotency/redis.mjs +48 -11
  77. package/dist/{index-BHdZD8zK.d.mts → index-Bxriq3so.d.mts} +84 -21
  78. package/dist/{preloadResources-CjS2OfpU.d.mts → index-C8zVGYsk.d.mts} +37 -38
  79. package/dist/{index-D4u76eQW.d.mts → index-CRoPtISf.d.mts} +23 -73
  80. package/dist/{index-CbJiYrfv.d.mts → index-Chgz3d0i.d.mts} +1 -1
  81. package/dist/index-JdbZAIsm.d.mts +510 -0
  82. package/dist/{index-DHbyPo5j.d.mts → index-mqaqZNpe.d.mts} +253 -254
  83. package/dist/index.d.mts +8 -8
  84. package/dist/index.mjs +11 -11
  85. package/dist/{init-Y2MlSN9n.mjs → init-B_oUYDXI.mjs} +1 -1
  86. package/dist/integrations/event-gateway.d.mts +8 -3
  87. package/dist/integrations/event-gateway.mjs +4 -4
  88. package/dist/integrations/index.d.mts +3 -3
  89. package/dist/integrations/index.mjs +1 -1
  90. package/dist/integrations/jobs/index.d.mts +1 -1
  91. package/dist/integrations/jobs/index.mjs +18 -5
  92. package/dist/integrations/mcp/index.d.mts +72 -59
  93. package/dist/integrations/mcp/index.mjs +19 -4
  94. package/dist/integrations/mcp/testing.d.mts +2 -2
  95. package/dist/integrations/mcp/testing.mjs +2 -2
  96. package/dist/integrations/streamline.d.mts +78 -136
  97. package/dist/integrations/streamline.mjs +116 -54
  98. package/dist/integrations/webhooks.d.mts +60 -120
  99. package/dist/integrations/webhooks.mjs +36 -80
  100. package/dist/integrations/websocket-pushref-redis.d.mts +1 -1
  101. package/dist/integrations/websocket-pushref-redis.mjs +1 -1
  102. package/dist/integrations/websocket-redis.d.mts +1 -1
  103. package/dist/integrations/websocket-redis.mjs +1 -1
  104. package/dist/integrations/websocket.d.mts +3 -3
  105. package/dist/integrations/websocket.mjs +2 -2
  106. package/dist/{interface-DEWNOMza.d.mts → interface-C0395yUN.d.mts} +13 -1
  107. package/dist/{jsonBody-Cq9KYl2Z.mjs → jsonBody-B4YVGcql.mjs} +2 -2
  108. package/dist/{keys-Cmv4cBRa.mjs → keys-B2KtgMLJ.mjs} +7 -18
  109. package/dist/{loadResources-CblF7xt2.mjs → loadResources-Dn4lalw2.mjs} +3 -3
  110. package/dist/{loadResourcesFromEntry-99fIMC3p.mjs → loadResourcesFromEntry-3sLYbuse.mjs} +2 -2
  111. package/dist/logger/index.d.mts +1 -8
  112. package/dist/logger/index.mjs +3 -153
  113. package/dist/logger-DXjfIqjV.mjs +160 -0
  114. package/dist/{mcpPlugin-xF3Gw-HW.mjs → mcpPlugin-C08HalN5.mjs} +433 -170
  115. package/dist/{memory-CpDZ9NPw.mjs → memory-9Cp7611C.mjs} +36 -34
  116. package/dist/{metrics-BaKnq8ag.mjs → metrics-CWI11eRu.mjs} +39 -72
  117. package/dist/middleware/index.d.mts +2 -2
  118. package/dist/middleware/index.mjs +3 -3
  119. package/dist/migrations/index.mjs +2 -2
  120. package/dist/{module-BkQEesNQ.mjs → module-BSvOQC7E.mjs} +8 -8
  121. package/dist/multiTenant-cY0FkDiA.d.mts +104 -0
  122. package/dist/{multipartBody-C92aJ8am.mjs → multipartBody-CXM2a-Dy.mjs} +46 -7
  123. package/dist/{openapi-C3LFRzPq.mjs → openapi-DT_G4VhY.mjs} +48 -10
  124. package/dist/outbox-admin/index.d.mts +3 -3
  125. package/dist/outbox-admin/index.mjs +6 -18
  126. package/dist/{outbox-module-dsCyLxXH.mjs → outbox-module-Bjgzl6tg.mjs} +203 -33
  127. package/dist/{outbox-module-BHdUnuuK.d.mts → outbox-module-gZCHoE4H.d.mts} +79 -6
  128. package/dist/permissions/index.d.mts +5 -4
  129. package/dist/permissions/index.mjs +8 -6
  130. package/dist/{permissions-DiHXy8Ck.mjs → permissions-Cm0uYHvd.mjs} +149 -33
  131. package/dist/{pipe-CBVmUJ-j.mjs → pipe-BqeGT6UO.mjs} +2 -2
  132. package/dist/pipeline/index.d.mts +2 -2
  133. package/dist/pipeline/index.mjs +2 -2
  134. package/dist/plan-FVR6LP59.mjs +565 -0
  135. package/dist/{BaseController-DYJRZ0EJ.mjs → plugin-BccET1tL.mjs} +1256 -344
  136. package/dist/plugins/index.d.mts +14 -11
  137. package/dist/plugins/index.mjs +44 -22
  138. package/dist/plugins/response-cache.mjs +8 -14
  139. package/dist/plugins/tracing-entry.mjs +2 -2
  140. package/dist/{pluralize-2_U6QZQg.mjs → pluralize-CVIOcgMF.mjs} +1 -1
  141. package/dist/presets/filesUpload.d.mts +2 -2
  142. package/dist/presets/filesUpload.mjs +5 -5
  143. package/dist/presets/index.d.mts +26 -31
  144. package/dist/presets/index.mjs +4 -4
  145. package/dist/presets/multiTenant.d.mts +2 -107
  146. package/dist/presets/multiTenant.mjs +22 -162
  147. package/dist/presets/search.d.mts +2 -2
  148. package/dist/presets/search.mjs +2 -2
  149. package/dist/{presets-BdlugYTc.mjs → presets-Cpvj6fGO.mjs} +99 -107
  150. package/dist/{projection-Uvgp-EEj.mjs → projection-Ce4aQhQk.mjs} +2 -2
  151. package/dist/{pushref-registry-Dov9l4qE.d.mts → pushref-registry-UxCkoA4C.d.mts} +1 -1
  152. package/dist/{queryCachePlugin-BzqxconG.d.mts → queryCachePlugin-C2lZjTxk.d.mts} +1 -1
  153. package/dist/{queryCachePlugin-B5F09bYr.mjs → queryCachePlugin-CFWNH8aT.mjs} +12 -14
  154. package/dist/{rateLimitKey-CK-EU2L8.mjs → rateLimitKey-C4O-kPm0.mjs} +1 -1
  155. package/dist/{realtime-FnnD0n3Z.mjs → realtime-DmPE9S54.mjs} +25 -21
  156. package/dist/redis-stream-BMk-bpQS.d.mts +219 -0
  157. package/dist/{redis-Bzi1y3F9.d.mts → redis-vLvtcGy_.d.mts} +13 -24
  158. package/dist/redisShapes-CQksY67q.d.mts +55 -0
  159. package/dist/registry/index.d.mts +9 -4
  160. package/dist/registry/index.mjs +4 -4
  161. package/dist/{registry-D3y8VEJ1.mjs → registry-Bcz9G1bh.mjs} +10 -8
  162. package/dist/{renewingLease-B3VYh5aU.mjs → renewingLease-qODa7KJQ.mjs} +1 -1
  163. package/dist/{replyHelpers-DPHsdw-5.mjs → replyHelpers-CG_VtVgS.mjs} +2 -2
  164. package/dist/{requestContext-cSVKnYPk.mjs → requestContext-Dsu9P1bV.mjs} +1 -1
  165. package/dist/requirement-CbiLdQ1n.d.mts +22 -0
  166. package/dist/requirement-KDdoRcOP.mjs +35 -0
  167. package/dist/resourceRateLimit-Wf6d6FL9.d.mts +30 -0
  168. package/dist/resourceRateLimit-dSjVr1pk.mjs +180 -0
  169. package/dist/{rolldown-runtime-DjDuyglE.mjs → rolldown-runtime-D1w9Y1VJ.mjs} +1 -1
  170. package/dist/routeValidator-D36SW8qt.mjs +70 -0
  171. package/dist/{runtimeCapabilities-DSA_dH1_.mjs → runtimeCapabilities-0tccjRlj.mjs} +1 -1
  172. package/dist/{schedules-BktJb3Y3.mjs → schedules-C-OpmHBq.mjs} +46 -37
  173. package/dist/{schemaConverter-BLCSmNbr.mjs → schemaConverter-BORek3O-.mjs} +2 -2
  174. package/dist/{schemaIR-K16Bb5BX.mjs → schemaIR-C7Vbp71I.mjs} +2 -2
  175. package/dist/schemas/index.d.mts +10 -0
  176. package/dist/schemas/index.mjs +8 -3
  177. package/dist/scim/index.mjs +2 -2
  178. package/dist/scope/index.d.mts +2 -2
  179. package/dist/scope/index.mjs +6 -6
  180. package/dist/{scope-jSxuBTFM.mjs → scope-DQthe88b.mjs} +4 -4
  181. package/dist/shutdown-MqA81z_P.mjs +59 -0
  182. package/dist/{simpleEqualityMatcher-BiOnyflP.mjs → simpleEqualityMatcher-auW8QjXN.mjs} +1 -1
  183. package/dist/{sse-CH7Slxc1.mjs → sse-CYzQBVFe.mjs} +11 -15
  184. package/dist/{sseStream-CN-Lh1Tu.mjs → sseStream-B5_Afiqn.mjs} +2 -2
  185. package/dist/{store-helpers-9DX9-1j_.mjs → store-helpers-BOzk-CuX.mjs} +1 -1
  186. package/dist/{streaming-dvppnxsr.mjs → streaming-DjTQhZrN.mjs} +1 -1
  187. package/dist/subscriberIdentity-CW39uA8G.mjs +28 -0
  188. package/dist/tenancy--ed9eH_z.mjs +43 -0
  189. package/dist/tenantPreparation-BKon6Yox.mjs +67 -0
  190. package/dist/testing/cleanupStoreContract.mjs +1 -1
  191. package/dist/testing/index.d.mts +193 -175
  192. package/dist/testing/index.mjs +286 -212
  193. package/dist/testing/outboxStoreContract.mjs +137 -2
  194. package/dist/testing/requiredPorts.d.mts +17 -0
  195. package/dist/testing/requiredPorts.mjs +65 -0
  196. package/dist/testing/storageContract.mjs +1 -1
  197. package/dist/timing-qczZ0YC-.mjs +46 -0
  198. package/dist/{transactionContext-DCWMI6hV.mjs → transactionContext-DjFkrNG6.mjs} +1 -1
  199. package/dist/{typeGuards-D7tHFdH6.mjs → typeGuards-CySF12G-.mjs} +1 -1
  200. package/dist/types/index.d.mts +4 -4
  201. package/dist/types/index.mjs +1 -1
  202. package/dist/types/storage.mjs +1 -1
  203. package/dist/{types-CWQn9-IC.d.mts → types-B4Aq4Sdj.d.mts} +22 -9
  204. package/dist/{types-DfVDvkdP.d.mts → types-BJ-2XqVF.d.mts} +189 -204
  205. package/dist/{types-CDy3-zw1.mjs → types-Bk9NOgOC.mjs} +4 -4
  206. package/dist/usage/index.d.mts +2 -3
  207. package/dist/usage/index.mjs +5 -5
  208. package/dist/{userHelpers-DDMOZ_Pm.mjs → userHelpers-aklawRaK.mjs} +1 -1
  209. package/dist/utils/index.d.mts +84 -223
  210. package/dist/utils/index.mjs +13 -12
  211. package/dist/{utils-B-zj_b__.mjs → utils-ec1oTo1n.mjs} +315 -404
  212. package/dist/{validate-R0G_JrnK.mjs → validate-9yzHC1e2.mjs} +6 -14
  213. package/dist/{versioning-D6JIK8Tk.d.mts → versioning-Bsb51gGT.d.mts} +28 -13
  214. package/dist/{versioning-DuVWcu-F.mjs → versioning-fhhWHV74.mjs} +4 -4
  215. package/dist/{websocket-BOXVggMf.d.mts → websocket-Cs4awVyD.d.mts} +1 -1
  216. package/dist/{workScope-BhsWde4k.mjs → workScope-zpPyge4t.mjs} +2 -2
  217. package/package.json +578 -574
  218. package/skills/arc/SKILL.md +13 -4
  219. package/skills/arc/references/auth.md +8 -5
  220. package/skills/arc/references/integrations.md +1 -1
  221. package/skills/arc/references/mcp.md +8 -6
  222. package/skills/arc/references/multi-tenancy.md +19 -14
  223. package/skills/arc/references/production.md +27 -10
  224. package/dist/actionPermissions-DPwPWPOV.mjs +0 -350
  225. package/dist/index-CFfLKMH4.d.mts +0 -290
  226. package/dist/interface-BIpgzbZl.mjs +0 -17
  227. package/dist/redis-stream-BPKscsTB.d.mts +0 -260
  228. package/dist/registerRoute-DRsSHPSM.mjs +0 -364
  229. package/dist/sync/changelog.d.mts +0 -3
  230. package/dist/sync/changelog.mjs +0 -3
@@ -1,8 +1,64 @@
1
- /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
- import { r as mergeHealthChecks, t as healthPlugin } from "../health-CxQzbJmr.mjs";
3
- import { S as resolveModule, _ as describeResolvedModule, a as createApp, b as collectModuleWorkflows, c as edgePreset, d as testingPreset, f as workerPreset, g as subscribeModuleEventHandlers, h as orderModules, i as DEFAULT_LOGGER_REDACT_PATHS, l as getPreset, m as hasModule, n as preloadResourcesAsync, p as getModuleState, r as ArcFactory, s as developmentPreset, t as preloadResources, u as productionPreset, v as collectModuleHealthChecks, x as resolveContribution, y as collectModuleScheduledJobs } from "../preloadResources-Bbp4QJ8V.mjs";
4
- import { a as lazyModuleExports, i as hasModuleExports, n as getModuleExports, o as lazyRequiredModuleExports, r as getOptionalModuleExports, t as defineModule } from "../module-BkQEesNQ.mjs";
5
- import { t as loadResources } from "../loadResources-CblF7xt2.mjs";
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ import { r as mergeHealthChecks, t as healthPlugin } from "../health-DqbsG-_w.mjs";
3
+ import { a as developmentPreset, c as productionPreset, d as getModuleResources, f as getModuleState, g as collectModuleWorkflows, l as testingPreset, m as subscribeModuleEventHandlers, n as DEFAULT_LOGGER_REDACT_PATHS, o as edgePreset, p as hasModule, r as createApp, s as getPreset, t as ArcFactory, u as workerPreset } from "../createApp-D-953ZAq.mjs";
4
+ import { _ as dependentsOf, b as verifyEventDurability, d as resolveModule, g as crudEventsOf, h as buildModuleGraph, i as planModules, m as analyzeModuleGraph, o as resolveModuleClosure, p as activateBridges, r as compositionProblems, s as orderModules, t as assertComposable, u as resolveContribution, v as eventTopology, x as verifyModuleGraph, y as renderModuleGraph } from "../plan-FVR6LP59.mjs";
5
+ import { a as lazyModuleExports, i as hasModuleExports, n as getModuleExports, o as lazyRequiredModuleExports, r as getOptionalModuleExports, t as defineModule } from "../module-BSvOQC7E.mjs";
6
+ import { t as loadResources } from "../loadResources-Dn4lalw2.mjs";
7
+ //#region src/factory/module/asyncapi.ts
8
+ /**
9
+ * The module graph as an AsyncAPI 3.0 document — one channel per event (addressed by the event
10
+ * name, payload from the event registry), a `send` operation for its owner and a `receive` for
11
+ * every consumer (wildcards resolved). The standard format tooling, docs and contract tests read.
12
+ */
13
+ /** A JSON-Pointer-safe id for an event name. */
14
+ const idOf = (event) => event.replace(/[^A-Za-z0-9_.-]/g, "_");
15
+ function toAsyncApi(graph, catalog, info, analysis = analyzeModuleGraph(graph)) {
16
+ const byName = new Map(catalog.map((entry) => [entry.name, entry]));
17
+ const channels = {};
18
+ const messages = {};
19
+ const operations = {};
20
+ const kindOf = new Map(graph.modules.map((m) => [m.name, m.kind]));
21
+ const ensureChannel = (event) => {
22
+ const id = idOf(event);
23
+ if (channels[id]) return id;
24
+ const entry = byName.get(event);
25
+ messages[id] = {
26
+ name: event,
27
+ ...entry?.description ? { summary: entry.description } : {},
28
+ payload: entry?.schema ?? {},
29
+ ...entry ? { "x-version": entry.version } : { "x-uncatalogued": true }
30
+ };
31
+ channels[id] = {
32
+ address: event,
33
+ messages: { [id]: { $ref: `#/components/messages/${id}` } }
34
+ };
35
+ return id;
36
+ };
37
+ const operation = (module, action, event) => {
38
+ const id = ensureChannel(event);
39
+ operations[`${module}.${action}.${id}`] = {
40
+ action,
41
+ channel: { $ref: `#/channels/${id}` },
42
+ messages: [{ $ref: `#/channels/${id}/messages/${id}` }],
43
+ tags: [{ name: module }],
44
+ "x-arc-kind": kindOf.get(module)
45
+ };
46
+ };
47
+ for (const [event, owners] of analysis.owners) for (const owner of owners) operation(owner, "send", event);
48
+ for (const [consumer, byPattern] of analysis.reaches) for (const events of byPattern.values()) for (const event of events) operation(consumer, "receive", event);
49
+ return {
50
+ asyncapi: "3.0.0",
51
+ info: {
52
+ title: info.title,
53
+ version: info.version,
54
+ ...info.description ? { description: info.description } : {}
55
+ },
56
+ channels,
57
+ operations,
58
+ components: { messages }
59
+ };
60
+ }
61
+ //#endregion
6
62
  //#region src/factory/module/extend.ts
7
63
  /** Concatenate two contributions, resolving factories only when arc asks. */
8
64
  function mergeContribution(own, extra) {
@@ -33,6 +89,19 @@ function mergeNames(own, extra) {
33
89
  if (extra === void 0) return own;
34
90
  return [.../* @__PURE__ */ new Set([...own, ...extra])];
35
91
  }
92
+ function mergeRequires(own, extra) {
93
+ if (own === void 0) return extra;
94
+ if (extra === void 0) return own;
95
+ const ports = mergeNames(own.ports, extra.ports);
96
+ const required = new Set(ports ?? []);
97
+ const optional = mergeNames(own.optionalPorts, extra.optionalPorts)?.filter((p) => !required.has(p));
98
+ const modules = mergeNames(own.modules, extra.modules);
99
+ return {
100
+ ...ports ? { ports } : {},
101
+ ...optional && optional.length > 0 ? { optionalPorts: optional } : {},
102
+ ...modules ? { modules } : {}
103
+ };
104
+ }
36
105
  function mergeOwns(own, extra) {
37
106
  if (own === "provided" || extra === "provided") return "provided";
38
107
  return mergeNames(own, extra);
@@ -110,7 +179,12 @@ function extendModule(mod, extension) {
110
179
  const set = (key, value) => {
111
180
  if (value !== void 0) out[key] = value;
112
181
  };
182
+ if (extension.kind !== void 0) {
183
+ if (mod.kind !== void 0 && mod.kind !== extension.kind) throw new Error(`[arc] extendModule("${mod.name}"): the module declares kind "${mod.kind}"; refusing to relabel it "${extension.kind}". A kind changes activation and ordering — change it in the module.`);
184
+ out.kind = extension.kind;
185
+ }
113
186
  set("dependsOn", mergeNames(mod.dependsOn, extension.dependsOn));
187
+ set("requires", mergeRequires(mod.requires, extension.requires));
114
188
  set("owns", mergeOwns(mod.owns, extension.owns));
115
189
  set("resources", mergeContribution(mod.resources, extension.resources));
116
190
  set("eventHandlers", mergeContribution(mod.eventHandlers, extension.eventHandlers));
@@ -121,10 +195,64 @@ function extendModule(mod, extension) {
121
195
  set("plugins", mergeHook(mod.plugins, extension.plugins));
122
196
  set("afterResources", mergeHook(mod.afterResources, extension.afterResources));
123
197
  set("onClose", mergeOnClose(mod.onClose, extension.onClose));
198
+ set("publishes", mergeArray(mod.publishes, extension.publishes));
199
+ if (extension.eventNamespace !== void 0) set("eventNamespace", mergeNames(mod.eventNamespace === void 0 ? [mod.name] : [mod.eventNamespace].flat(), [extension.eventNamespace].flat()));
124
200
  if (extension.bootstrap) out.bootstrap = extension.bootstrap(mod.bootstrap);
125
201
  return out;
126
202
  }
127
203
  //#endregion
204
+ //#region src/factory/module/relay-nudge.ts
205
+ function isRelayFromModule(relay) {
206
+ return typeof relay === "object" && relay !== null && "fromModule" in relay;
207
+ }
208
+ /**
209
+ * Merge an `afterCommit` nudge into a runtime whose `dispatch` is `'relay'`.
210
+ *
211
+ * - `'inline'` / no dispatch: returned untouched.
212
+ * - `'relay'` + a resolvable `relay`: `afterCommit` nudges; a host's own hook runs first.
213
+ * - `'relay'` + no `relay`: THROWS — a worker-drained deployment and a forgotten wire
214
+ * look identical, so the host has to say which.
215
+ */
216
+ function withRelayNudge(label, runtime, relay) {
217
+ if (!runtime || typeof runtime !== "object") return runtime;
218
+ const rt = runtime;
219
+ if (rt.dispatch !== "relay") return runtime;
220
+ if (relay === void 0) throw new Error(`[${label}] runtime.dispatch is 'relay' but no \`relay\` was given. Pass the outbox module's exports (\`{ requestDrain }\`, a thunk, or \`{ fromModule: 'outbox' }\`) so a committed write is delivered now — or \`relay: 'external'\` when a separate relay process drains the outbox.`);
221
+ const resolved = relay;
222
+ if (resolved === "external") return runtime;
223
+ if (typeof resolved !== "function" && !("requestDrain" in resolved)) throw new Error(`[${label}] withRelayNudge received the unresolved \`{ fromModule }\` form — createRelayNudge resolves it after resources; a direct caller passes \`{ requestDrain }\` or a thunk.`);
224
+ const hostAfterCommit = typeof rt.afterCommit === "function" ? rt.afterCommit : void 0;
225
+ const drain = typeof resolved === "function" ? () => resolved().requestDrain() : () => resolved.requestDrain();
226
+ return {
227
+ ...rt,
228
+ afterCommit: (info) => {
229
+ try {
230
+ hostAfterCommit?.(info);
231
+ } finally {
232
+ drain();
233
+ }
234
+ }
235
+ };
236
+ }
237
+ /** The one way a module wires `relay` — `{ fromModule }` included. */
238
+ function createRelayNudge(label, relay) {
239
+ if (!isRelayFromModule(relay)) return { apply: (runtime) => withRelayNudge(label, runtime, relay) };
240
+ const moduleName = relay.fromModule;
241
+ let moduleDrain;
242
+ const thunk = () => {
243
+ if (!moduleDrain) throw new Error(`[${label}] the relay drain from module "${moduleName}" is not resolved yet — a write committed before afterResources ran. Mount the outbox module alongside this one, or pass \`relay\` directly.`);
244
+ return { requestDrain: moduleDrain };
245
+ };
246
+ return {
247
+ apply: (runtime) => withRelayNudge(label, runtime, thunk),
248
+ afterResources: async (fastify) => {
249
+ const exports = getModuleExports(fastify, moduleName);
250
+ if (typeof exports?.requestDrain !== "function") throw new Error(`[${label}] module "${moduleName}" exports no requestDrain(), so a committed write cannot nudge the relay. Arc >=2.40 adds it to createOutboxModule; pass \`relay: 'external'\` if a separate process drains the outbox.`);
251
+ moduleDrain = exports.requestDrain;
252
+ }
253
+ };
254
+ }
255
+ //#endregion
128
256
  //#region src/factory/createWorker.ts
129
257
  async function createWorker(options, workerOptions = {}) {
130
258
  const { auth: _auth, helmet: _helmet, cors: _cors, rateLimit: _rateLimit, multipart: _multipart, rawBody: _rawBody, sensible: _sensible, underPressure: _underPressure, replyHelpers: _replyHelpers, ...runtimeOptions } = options;
@@ -139,32 +267,41 @@ async function createWorker(options, workerOptions = {}) {
139
267
  preset: "worker",
140
268
  arcPlugins: workerArcPlugins
141
269
  });
142
- if (workerOptions.health) {
143
- const { port, host = "0.0.0.0", checks = [] } = workerOptions.health;
144
- const moduleChecks = app.arc?.healthChecks ?? [];
145
- const mergedChecks = mergeHealthChecks([
146
- {
147
- owner: "the module graph",
148
- checks: moduleChecks
149
- },
150
- {
151
- owner: "shared arcPlugins.health",
152
- checks: sharedHealth.checks
153
- },
154
- {
155
- owner: "the worker probe",
156
- checks
157
- }
158
- ]);
159
- await app.register(healthPlugin, {
160
- ...sharedHealth,
161
- checks: mergedChecks
162
- });
163
- await app.listen({
164
- port,
165
- host
166
- });
167
- } else await app.ready();
270
+ try {
271
+ if (workerOptions.health) {
272
+ const { port, host = "0.0.0.0", checks = [] } = workerOptions.health;
273
+ const moduleChecks = app.arc?.healthChecks ?? [];
274
+ const mergedChecks = mergeHealthChecks([
275
+ {
276
+ owner: "the module graph",
277
+ checks: moduleChecks
278
+ },
279
+ {
280
+ owner: "shared arcPlugins.health",
281
+ checks: sharedHealth.checks
282
+ },
283
+ {
284
+ owner: "the worker probe",
285
+ checks
286
+ }
287
+ ]);
288
+ await app.register(healthPlugin, {
289
+ ...sharedHealth,
290
+ checks: mergedChecks
291
+ });
292
+ await app.listen({
293
+ port,
294
+ host
295
+ });
296
+ } else await app.ready();
297
+ } catch (err) {
298
+ try {
299
+ await app.close();
300
+ } catch (closeErr) {
301
+ app.log.error({ err: closeErr }, "[arc] failed worker startup cleanup failed");
302
+ }
303
+ throw err;
304
+ }
168
305
  let closed = false;
169
306
  return {
170
307
  app,
@@ -243,4 +380,48 @@ function payloadTooLarge(limit) {
243
380
  });
244
381
  }
245
382
  //#endregion
246
- export { ArcFactory, DEFAULT_LOGGER_REDACT_PATHS, collectModuleHealthChecks, collectModuleScheduledJobs, collectModuleWorkflows, createApp, createWorker, defineModule, describeResolvedModule, developmentPreset, edgePreset, extendModule, getModuleExports, getModuleState, getOptionalModuleExports, getPreset, hasModule, hasModuleExports, lazyModuleExports, lazyRequiredModuleExports, loadResources, orderModules, preloadResources, preloadResourcesAsync, productionPreset, resolveContribution, resolveModule, subscribeModuleEventHandlers, testingPreset, toFetchHandler };
383
+ //#region src/factory/preloadResources.ts
384
+ /**
385
+ * Normalize an eager `import.meta.glob` result into a `ResourceLike[]`.
386
+ *
387
+ * Accepts either:
388
+ * - `{ import: 'default' }` form: values are the resource directly
389
+ * - default form: values are the full module — picks first export with `toPlugin()`
390
+ *
391
+ * Throws if any module doesn't yield a valid `ResourceLike`.
392
+ */
393
+ function preloadResources(globResult) {
394
+ const resources = [];
395
+ for (const [path, value] of Object.entries(globResult)) {
396
+ const resource = pickResource(value);
397
+ if (!resource) throw new Error(`preloadResources: ${path} does not export a valid resource.\n Expected: a default export OR a named export with toPlugin().`);
398
+ resources.push(resource);
399
+ }
400
+ return resources.sort((a, b) => (a.name ?? "").localeCompare(b.name ?? ""));
401
+ }
402
+ /**
403
+ * Normalize a lazy `import.meta.glob` result into a `Promise<ResourceLike[]>`.
404
+ *
405
+ * Use this when resources depend on prior bootstrap (e.g., engine init) and
406
+ * cannot be evaluated at import time of the preload file.
407
+ */
408
+ async function preloadResourcesAsync(globResult) {
409
+ return (await Promise.all(Object.entries(globResult).map(async ([path, loader]) => {
410
+ const resource = pickResource(await loader());
411
+ if (!resource) throw new Error(`preloadResourcesAsync: ${path} does not export a valid resource.\n Expected: a default export OR a named export with toPlugin().`);
412
+ return resource;
413
+ }))).sort((a, b) => (a.name ?? "").localeCompare(b.name ?? ""));
414
+ }
415
+ function pickResource(value) {
416
+ if (!value || typeof value !== "object") return void 0;
417
+ if (typeof value.toPlugin === "function") return value;
418
+ const mod = value;
419
+ const candidates = [
420
+ mod.default,
421
+ mod.resource,
422
+ ...Object.values(mod)
423
+ ];
424
+ for (const c of candidates) if (c && typeof c === "object" && typeof c.toPlugin === "function") return c;
425
+ }
426
+ //#endregion
427
+ export { ArcFactory, DEFAULT_LOGGER_REDACT_PATHS, activateBridges, analyzeModuleGraph, assertComposable, buildModuleGraph, collectModuleWorkflows, compositionProblems, createApp, createRelayNudge, createWorker, crudEventsOf, defineModule, dependentsOf, developmentPreset, edgePreset, eventTopology, extendModule, getModuleExports, getModuleResources, getModuleState, getOptionalModuleExports, getPreset, hasModule, hasModuleExports, lazyModuleExports, lazyRequiredModuleExports, loadResources, orderModules, planModules, preloadResources, preloadResourcesAsync, productionPreset, renderModuleGraph, resolveContribution, resolveModule, resolveModuleClosure, subscribeModuleEventHandlers, testingPreset, toAsyncApi, toFetchHandler, verifyEventDurability, verifyModuleGraph, withRelayNudge };
@@ -1,8 +1,8 @@
1
1
 
2
- import { on as HookSystem, z as ResourceRegistry } from "./index-DHbyPo5j.mjs";
2
+ import { M as ResourceRegistry, on as HookSystem } from "./index-mqaqZNpe.mjs";
3
3
  import { t as ExternalOpenApiPaths } from "./externalPaths-CmGOxOtD.mjs";
4
- import { _ as HealthCheck, f as ScheduleDefinition, r as ArcModuleRegistry, t as ArcModule } from "./types-DfVDvkdP.mjs";
5
- import { s as ModuleState } from "./index-CFfLKMH4.mjs";
4
+ import { b as ScheduleDefinition, i as ArcModuleRegistry, n as ArcModule, w as HealthCheck } from "./types-BJ-2XqVF.mjs";
5
+ import { L as ModuleGraph, s as ModuleState } from "./index-JdbZAIsm.mjs";
6
6
  import { FastifyPluginAsync } from "fastify";
7
7
  //#region src/factory/module/descriptor.d.ts
8
8
  /**
@@ -65,26 +65,6 @@ interface ResolvedModuleDescriptor {
65
65
  readonly owns: readonly string[];
66
66
  readonly lifecycle: ResolvedModuleLifecycle;
67
67
  }
68
- /** Minimal resource shape the descriptor reads. Structural — matches `ResourceLike`. */
69
- interface DescribableResource {
70
- readonly name?: string | undefined;
71
- readonly prefix?: string | undefined;
72
- readonly skipGlobalPrefix?: boolean | undefined;
73
- }
74
- /**
75
- * Build a descriptor. Called by `registerResources` once per module, after
76
- * resources are resolved and `owns` is effective.
77
- *
78
- * Frozen at every level: a descriptor is a snapshot of a completed decision,
79
- * and a consumer mutating it would silently disagree with the running app.
80
- */
81
- declare function describeResolvedModule(input: {
82
- readonly name: string;
83
- readonly dependsOn?: readonly string[] | undefined;
84
- readonly resources: readonly DescribableResource[];
85
- readonly owns: readonly string[];
86
- readonly lifecycle: ResolvedModuleLifecycle;
87
- }): ResolvedModuleDescriptor;
88
68
  //#endregion
89
69
  //#region src/core/arcCorePlugin.d.ts
90
70
  interface ArcCorePluginOptions {
@@ -159,6 +139,13 @@ interface ArcCore {
159
139
  * or hand to tooling.
160
140
  */
161
141
  moduleDescriptors?: readonly ResolvedModuleDescriptor[];
142
+ /** Active modules, the events each owns and consumes, and the bridges left inactive. */
143
+ moduleGraph?: ModuleGraph;
144
+ /**
145
+ * Event types actually published with no declared owner (and no external source) — observed
146
+ * at the transport while `moduleGraph.events` is on. A test asserts it empty after a flow.
147
+ */
148
+ undeclaredEvents?: ReadonlySet<string>;
162
149
  /**
163
150
  * Module-contributed recurring schedules, resolved once in dependency order
164
151
  * and frozen after bootstraps. The same definitions are executed by Arc's
@@ -166,7 +153,6 @@ interface ArcCore {
166
153
  */
167
154
  scheduledJobs?: readonly Readonly<ScheduleDefinition>[];
168
155
  }
169
- declare const arcCorePlugin: FastifyPluginAsync<ArcCorePluginOptions>;
170
156
  declare const _default: FastifyPluginAsync<ArcCorePluginOptions>;
171
157
  //#endregion
172
158
  //#region src/types/fastify-augmentation.d.ts
@@ -176,4 +162,4 @@ declare module "fastify" {
176
162
  }
177
163
  }
178
164
  //#endregion
179
- export { arcCorePlugin as a, ResolvedResourceDescriptor as c, _default as i, describeResolvedModule as l, ArcCorePluginOptions as n, ResolvedModuleDescriptor as o, PluginMeta as r, ResolvedModuleLifecycle as s, ArcCore as t };
165
+ export { ResolvedModuleDescriptor as a, _default as i, ArcCorePluginOptions as n, ResolvedModuleLifecycle as o, PluginMeta as r, ResolvedResourceDescriptor as s, ArcCore as t };
@@ -119,4 +119,4 @@ declare function applyFieldWritePermissions<T extends Record<string, unknown>>(b
119
119
  */
120
120
  declare function resolveEffectiveRoles(userRoles: readonly string[], orgRoles: readonly string[]): string[];
121
121
  //#endregion
122
- export { applyFieldWritePermissions as a, applyFieldReadPermissions as i, FieldPermissionMap as n, fields as o, FieldPermissionType as r, resolveEffectiveRoles as s, FieldPermission as t };
122
+ export { applyFieldReadPermissions as a, resolveEffectiveRoles as c, FieldWritePermissionResult as i, FieldPermissionMap as n, applyFieldWritePermissions as o, FieldPermissionType as r, fields as s, FieldPermission as t };
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
2
  //#region src/permissions/fields.ts
3
3
  /**
4
4
  * Field-Level Permissions
@@ -0,0 +1,99 @@
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ //#region src/permissions/filter-merge.ts
3
+ /**
4
+ * Policy-filter composition — logical AND, never last-writer-wins.
5
+ *
6
+ * Row-level policy filters can arrive from several INDEPENDENT sources for one
7
+ * request: a tenant preset, an `ownedByUser` grant, an `allOf(...)` branch, a
8
+ * host permission check. Every one of them is a RESTRICTION the row must
9
+ * satisfy, so composing them is logical AND.
10
+ *
11
+ * The historical `{ ...base, ...incoming }` shallow spread did NOT implement AND:
12
+ * when two sources constrained the SAME key with different values, the later one
13
+ * silently REPLACED the earlier one — widening (or erasing) a restriction another
14
+ * layer deliberately imposed. That is a defense-in-depth defect, not a
15
+ * refinement. "Later can refine" is only sound when the refinement is provably
16
+ * narrower, and a bare overwrite proves nothing.
17
+ *
18
+ * {@link conjoinPolicyFilters} composes with AND semantics while preserving the
19
+ * common case byte-for-byte:
20
+ *
21
+ * - key present on only one side → carried through flat. Non-overlapping
22
+ * filters (the ~99% case) produce exactly the same object the old spread did,
23
+ * so there is ZERO behavior change for them.
24
+ * - same key, deep-equal value → kept once (idempotent — e.g. two checks
25
+ * both pinning the same `organizationId`).
26
+ * - same key, DIFFERENT value → BOTH constraints are preserved under an
27
+ * `$and`, so a row must satisfy both. For flat equality that conjunction is
28
+ * unsatisfiable, so the query returns nothing — the safe, correct outcome for
29
+ * contradictory policies (deny), and the earlier restriction is never dropped.
30
+ *
31
+ * Adapter safety: mongokit / sqlitekit compile `$and` natively at the DB layer,
32
+ * and arc's in-memory `simpleEqualityMatcher` (AccessControl.checkPolicyFilters)
33
+ * already fail-closes on operator-shaped filters. So a produced `$and` is either
34
+ * evaluated correctly by the DB or rejected fail-closed in memory — both safe.
35
+ *
36
+ * This is the pragmatic, adapter-neutral form of the AND semantics. A canonical
37
+ * filter IR in `repo-core` (nested and/or/not nodes each adapter compiles) is the
38
+ * fuller design, but this closes the security defect without one.
39
+ */
40
+ /**
41
+ * Validate + return a `$and` operand's fragment array. A security-policy
42
+ * normalizer must NEVER silently drop a malformed constraint — a non-array
43
+ * `$and` (e.g. `{ $and: { organizationId: "a" } }`) is a policy bug, so fail
44
+ * loud (fail-closed) rather than discard the restriction it was meant to carry.
45
+ */
46
+ function coercePolicyAnd(value) {
47
+ if (!Array.isArray(value)) throw new Error(`conjoinPolicyFilters: malformed '$and' — expected an array of filter fragments, got ${value === null ? "null" : typeof value}. A policy filter constraint must not be silently dropped.`);
48
+ return value;
49
+ }
50
+ /** Are two flat policy-filter values equivalent for conjunction purposes? */
51
+ function filterValueEqual(a, b) {
52
+ if (Object.is(a, b)) return true;
53
+ if (a !== null && b !== null && typeof a === "object" && typeof b === "object") try {
54
+ return JSON.stringify(a) === JSON.stringify(b);
55
+ } catch {
56
+ return false;
57
+ }
58
+ return false;
59
+ }
60
+ /**
61
+ * Conjoin two policy-filter maps with AND semantics. Never silently overwrites a
62
+ * same-key constraint with a different value — conflicting keys are preserved
63
+ * under `$and`. See the module doc for the full contract.
64
+ */
65
+ function conjoinPolicyFilters(base, incoming) {
66
+ const baseEmpty = !base || Object.keys(base).length === 0;
67
+ const incomingEmpty = !incoming || Object.keys(incoming).length === 0;
68
+ if (baseEmpty) return incomingEmpty ? {} : { ...incoming };
69
+ if (incomingEmpty) return { ...base };
70
+ const result = {};
71
+ const andParts = [];
72
+ const baseAnd = base.$and;
73
+ if (baseAnd !== void 0) andParts.push(...coercePolicyAnd(baseAnd));
74
+ for (const [key, value] of Object.entries(base)) {
75
+ if (key === "$and") continue;
76
+ result[key] = value;
77
+ }
78
+ for (const [key, value] of Object.entries(incoming)) {
79
+ if (key === "$and") {
80
+ andParts.push(...coercePolicyAnd(value));
81
+ continue;
82
+ }
83
+ if (!(key in result)) {
84
+ result[key] = value;
85
+ continue;
86
+ }
87
+ if (filterValueEqual(result[key], value)) continue;
88
+ andParts.push({ [key]: result[key] }, { [key]: value });
89
+ delete result[key];
90
+ }
91
+ if (andParts.length > 0) result.$and = andParts;
92
+ for (const source of [base, incoming]) for (const symbol of Object.getOwnPropertySymbols(source)) {
93
+ const descriptor = Object.getOwnPropertyDescriptor(source, symbol);
94
+ if (descriptor) Object.defineProperty(result, symbol, descriptor);
95
+ }
96
+ return result;
97
+ }
98
+ //#endregion
99
+ export { conjoinPolicyFilters as t };
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
- import { t as pluralize } from "./pluralize-2_U6QZQg.mjs";
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ import { t as pluralize } from "./pluralize-CVIOcgMF.mjs";
3
3
  import { join } from "node:path";
4
4
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
5
  //#region src/cli/commands/generate/name-helpers.ts
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
- import { u as ValidationError } from "./errors-C_YhELhe.mjs";
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ import { u as ValidationError } from "./errors-CtrywMHP.mjs";
3
3
  //#region src/utils/headers.ts
4
4
  /**
5
5
  * Canonical header typing + accessor.
@@ -0,0 +1,22 @@
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ //#region src/events/outbox/health.ts
3
+ /** Pending age past which the relay counts as stalled. */
4
+ const DEFAULT_RELAY_LAG_UNHEALTHY_MS = 3e5;
5
+ function canReportHealth(store) {
6
+ return typeof store.countByStatus === "function" && typeof store.oldestPendingAgeMs === "function";
7
+ }
8
+ async function readOutboxHealth(store, relayLagUnhealthyMs = DEFAULT_RELAY_LAG_UNHEALTHY_MS) {
9
+ const [pending, deadLetter, relayLagMs] = await Promise.all([
10
+ store.countByStatus("pending"),
11
+ store.countByStatus("dead_letter"),
12
+ store.oldestPendingAgeMs()
13
+ ]);
14
+ return {
15
+ pending,
16
+ deadLetter,
17
+ relayLagMs,
18
+ healthy: deadLetter === 0 && (relayLagMs === null || relayLagMs < relayLagUnhealthyMs)
19
+ };
20
+ }
21
+ //#endregion
22
+ export { canReportHealth as n, readOutboxHealth as r, DEFAULT_RELAY_LAG_UNHEALTHY_MS as t };