@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
@@ -88,7 +88,7 @@ interface MemoryEventTransportOptions {
88
88
  */
89
89
  declare class MemoryEventTransport implements EventTransport {
90
90
  readonly name = "memory";
91
- private handlers;
91
+ private router;
92
92
  private logger;
93
93
  private onHandlerError;
94
94
  private handlerDispatch;
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
- import { r as workSeedFromEvent, t as runWorkScope } from "./workScope-BhsWde4k.mjs";
3
- import { createEvent, matchEventPattern } from "@classytic/primitives/events";
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ import { r as workSeedFromEvent, t as runWorkScope } from "./workScope-zpPyge4t.mjs";
3
+ import { createEvent, createEventRouter } from "@classytic/primitives/events";
4
4
  //#region src/events/EventTransport.ts
5
5
  /**
6
6
  * Internal arc events module — concrete in-memory transport.
@@ -77,7 +77,7 @@ function resolveEventTransport(fastify) {
77
77
  */
78
78
  var MemoryEventTransport = class {
79
79
  name = "memory";
80
- handlers = /* @__PURE__ */ new Map();
80
+ router = createEventRouter();
81
81
  logger;
82
82
  onHandlerError;
83
83
  handlerDispatch;
@@ -103,9 +103,8 @@ var MemoryEventTransport = class {
103
103
  return runWorkScope(workSeedFromEvent(event), () => this.dispatch(event));
104
104
  }
105
105
  async dispatch(event) {
106
- const allHandlers = /* @__PURE__ */ new Set();
107
- for (const [pattern, handlers] of this.handlers) if (matchEventPattern(pattern, event.type)) for (const h of handlers) allHandlers.add(h);
108
- if (allHandlers.size === 0 && this.onUnroutedEvent) try {
106
+ const allHandlers = this.router.route(event.type);
107
+ if (allHandlers.length === 0 && this.onUnroutedEvent) try {
109
108
  this.onUnroutedEvent(event);
110
109
  } catch (err) {
111
110
  try {
@@ -132,7 +131,7 @@ var MemoryEventTransport = class {
132
131
  * written not to reject, and `allSettled` means the next person to add a
133
132
  * timeout or a metric to it cannot silently break that.
134
133
  */
135
- const pending = [...allHandlers];
134
+ const pending = allHandlers;
136
135
  if (this.handlerConcurrency >= pending.length) await Promise.allSettled(pending.map(run));
137
136
  else {
138
137
  let next = 0;
@@ -154,7 +153,7 @@ var MemoryEventTransport = class {
154
153
  * finds nothing. A broker-backed transport has no such ambiguity — publish
155
154
  * means "durably handed off" and redelivery is the consumer group's job.
156
155
  */
157
- if (failures.length > 0 && this.onHandlerError === "throw") throw new AggregateError(failures, `[EventTransport] ${failures.length} handler(s) failed for ${event.type}`);
156
+ if (failures.length > 0 && this.onHandlerError === "throw") throw new AggregateError(failures, `[EventTransport] ${failures.length} handler(s) failed for ${event.type}: ${describeFailures(failures)}`);
158
157
  }
159
158
  /**
160
159
  * Reference `publishMany` implementation — delegates to `publish()` in order.
@@ -175,19 +174,25 @@ var MemoryEventTransport = class {
175
174
  return results;
176
175
  }
177
176
  async subscribe(pattern, handler) {
178
- if (!this.handlers.has(pattern)) this.handlers.set(pattern, /* @__PURE__ */ new Set());
179
- this.handlers.get(pattern)?.add(handler);
177
+ this.router.add(pattern, handler);
180
178
  return () => {
181
- const set = this.handlers.get(pattern);
182
- if (set) {
183
- set.delete(handler);
184
- if (set.size === 0) this.handlers.delete(pattern);
185
- }
179
+ this.router.remove(pattern, handler);
186
180
  };
187
181
  }
188
182
  async close() {
189
- this.handlers.clear();
183
+ this.router.clear();
190
184
  }
191
185
  };
186
+ /** Per-cause and total caps, so a dead-lettered row's `lastError` stays readable and bounded. */
187
+ const CAUSE_MESSAGE_MAX = 300;
188
+ const FAILURES_MESSAGE_MAX = 1500;
189
+ /** Every cause's message, `; `-joined and truncated — the aggregate names what failed. */
190
+ function describeFailures(failures) {
191
+ const joined = failures.map((err) => {
192
+ const message = err instanceof Error ? err.message : String(err);
193
+ return message.length > CAUSE_MESSAGE_MAX ? `${message.slice(0, CAUSE_MESSAGE_MAX)}…` : message;
194
+ }).join("; ");
195
+ return joined.length > FAILURES_MESSAGE_MAX ? `${joined.slice(0, FAILURES_MESSAGE_MAX)}… (${failures.length} causes)` : joined;
196
+ }
192
197
  //#endregion
193
198
  export { resolveEventTransport as i, MemoryEventTransport as n, createEvent as r, ARC_EVENT_TRANSPORT as t };
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
- import { t as buildRequestScopeProjection } from "./projection-Uvgp-EEj.mjs";
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ import { t as buildRequestScopeProjection } from "./projection-Ce4aQhQk.mjs";
3
3
  //#region src/hooks/HookSystem.ts
4
4
  /**
5
5
  * Hook System
@@ -27,10 +27,14 @@ interface QueryCacheConfig {
27
27
  jitter?: number;
28
28
  }
29
29
  type CacheStatus = "fresh" | "stale" | "miss";
30
- interface CacheResult<T> {
30
+ /** A miss carries no data — narrow on `status` before reading `data`. */
31
+ type CacheResult<T> = {
32
+ status: "miss";
33
+ data: undefined;
34
+ } | {
35
+ status: "fresh" | "stale";
31
36
  data: T;
32
- status: CacheStatus;
33
- }
37
+ };
34
38
  declare class QueryCache {
35
39
  private readonly store;
36
40
  constructor(store: CacheStore);
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
2
- import "./constants-BxLgNFF7.mjs";
1
+ /*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
2
+ import "./constants-Cu7Mx7_U.mjs";
3
3
  //#region src/registry/ResourceRegistry.ts
4
4
  /**
5
5
  * Resource Registry
@@ -17,13 +17,29 @@ var ResourceRegistry = class {
17
17
  * runtime-only handle is still reachable.
18
18
  */
19
19
  _adapters;
20
+ /** The mounted definitions, in registration order — see `getDefinitions`. */
21
+ _definitions;
20
22
  _frozen;
21
23
  constructor() {
22
24
  this._resources = /* @__PURE__ */ new Map();
23
25
  this._adapters = /* @__PURE__ */ new Map();
26
+ this._definitions = /* @__PURE__ */ new Map();
24
27
  this._frozen = false;
25
28
  }
26
29
  /**
30
+ * The live `ResourceDefinition`s that mounted, in registration order — what a host hands to
31
+ * `mcpPlugin({ resources })` or a docs generator instead of re-collecting them. A resource
32
+ * declaring `skipRegistry` (incl. `customRoutesOnly`) opted out and is absent. Fresh array per call.
33
+ * One composed module's share: `getModuleResources(fastify, name)` from `@classytic/arc/factory`.
34
+ */
35
+ getDefinitions() {
36
+ return [...this._definitions.values()];
37
+ }
38
+ /** The live definition registered under `name`, or `undefined`. */
39
+ getDefinition(name) {
40
+ return this._definitions.get(name);
41
+ }
42
+ /**
27
43
  * Get the live `DataAdapter` for a registered resource — the handle whose
28
44
  * `.repository` cascade / cleanup helpers actually call. Returns `undefined`
29
45
  * when the resource is unknown OR was registered without an adapter
@@ -33,12 +49,22 @@ var ResourceRegistry = class {
33
49
  getAdapter(name) {
34
50
  return this._adapters.get(name);
35
51
  }
52
+ /** Set only by an explicit `strictResources: false`: a duplicate name keeps the FIRST entry. */
53
+ _tolerateDuplicates = false;
54
+ /** Accept a duplicate resource name (the host opted out of `strictResources`; it was warned). */
55
+ tolerateDuplicateNames() {
56
+ this._tolerateDuplicates = true;
57
+ }
36
58
  /**
37
- * Register a resource
59
+ * Register a resource. A duplicate name throws — a resource missing from the registry still
60
+ * serves traffic but vanishes from introspection, the permission matrix and MCP.
38
61
  */
39
62
  register(resource, options = {}) {
40
63
  if (this._frozen) throw new Error(`Registry frozen. Cannot register '${resource.name}' after startup.`);
41
- if (this._resources.has(resource.name)) throw new Error(`Resource '${resource.name}' already registered.`);
64
+ if (this._resources.has(resource.name)) {
65
+ if (this._tolerateDuplicates) return this;
66
+ throw new Error(`Resource '${resource.name}' already registered.`);
67
+ }
42
68
  const entry = {
43
69
  name: resource.name,
44
70
  displayName: resource.displayName,
@@ -62,12 +88,21 @@ var ResourceRegistry = class {
62
88
  permissions: r.permissions,
63
89
  capability: r.capability,
64
90
  raw: r.rawHandler !== void 0,
65
- schema: r.schema
91
+ schema: r.schema,
92
+ ...(r.config?.idempotency)?.required === true ? { idempotency: {
93
+ required: true,
94
+ ...(r.config?.idempotency)?.dedup === "handler" ? {
95
+ dedup: "handler",
96
+ owner: String((r.config?.idempotency)?.owner)
97
+ } : {}
98
+ } } : {}
66
99
  })),
67
100
  events: Object.keys(resource.events ?? {}),
68
101
  registeredAt: (/* @__PURE__ */ new Date()).toISOString(),
69
102
  disableDefaultRoutes: resource.disableDefaultRoutes,
70
103
  tenantField: resource.tenantField,
104
+ idField: resource.idField,
105
+ versionField: resource.versionField,
71
106
  resolvedTenantPurge: resource.resolvedTenantPurge,
72
107
  updateMethod: resource.updateMethod,
73
108
  disabledRoutes: resource.disabledRoutes ? [...resource.disabledRoutes] : void 0,
@@ -76,6 +111,7 @@ var ResourceRegistry = class {
76
111
  fields: resource.fields && Object.keys(resource.fields).length > 0 ? resource.fields : void 0,
77
112
  pipelineSteps: extractPipelineSteps(resource.pipe),
78
113
  rateLimit: resource.rateLimit,
114
+ idempotency: resource.idempotency,
79
115
  audit: resource.audit,
80
116
  actionPermissions: resource.actionPermissions,
81
117
  actions: resource.actions ? Object.entries(resource.actions).map(([name, entry]) => {
@@ -86,6 +122,7 @@ var ResourceRegistry = class {
86
122
  schema: entry.schema,
87
123
  permissions: entry.permissions,
88
124
  mcp: entry.mcp,
125
+ idempotency: entry.idempotency,
89
126
  id: entry.id
90
127
  };
91
128
  }) : void 0,
@@ -108,6 +145,7 @@ var ResourceRegistry = class {
108
145
  };
109
146
  this._resources.set(resource.name, entry);
110
147
  if (resource.adapter) this._adapters.set(resource.name, resource.adapter);
148
+ this._definitions.set(resource.name, resource);
111
149
  return this;
112
150
  }
113
151
  /**
@@ -303,16 +341,9 @@ var ResourceRegistry = class {
303
341
  reset() {
304
342
  this._resources.clear();
305
343
  this._adapters.clear();
344
+ this._definitions.clear();
306
345
  this._frozen = false;
307
346
  }
308
- /** @internal Alias for unfreeze() */
309
- _unfreeze() {
310
- this.unfreeze();
311
- }
312
- /** @internal Alias for reset() */
313
- _clear() {
314
- this.reset();
315
- }
316
347
  /**
317
348
  * Group by key
318
349
  */