@classytic/arc 2.18.2 → 2.18.4
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.
- package/dist/{BaseController-DPwe89qs.mjs → BaseController-B-uXzf6I.mjs} +403 -216
- package/dist/{QueryCache-8YmAQ-zW.d.mts → QueryCache-Dsyv2mLS.d.mts} +1 -1
- package/dist/audit/index.d.mts +1 -1
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +4 -4
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-ClWxaceA.mjs → betterAuthOpenApi-DAAhMZff.mjs} +1 -1
- package/dist/{buildHandler-C_SkBNF3.mjs → buildHandler-Cvrc2p7r.mjs} +1 -1
- package/dist/cache/index.d.mts +3 -3
- package/dist/cache/index.mjs +3 -3
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/describe.mjs +1 -1
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.d.mts +1 -1
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.d.mts +1 -1
- package/dist/cli/commands/init.mjs +1 -1
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.mjs +2 -2
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +3 -3
- package/dist/{core-B41eZxyM.mjs → core-C88uIwd3.mjs} +161 -103
- package/dist/{createActionRouter-CRaIwB5S.mjs → createActionRouter-DGCCp-kP.mjs} +4 -2
- package/dist/{createAggregationRouter-n3O6WdLO.mjs → createAggregationRouter-Ca77b8iK.mjs} +3 -3
- package/dist/{createApp-DZvrb587.mjs → createApp-J1iPXY9p.mjs} +11 -11
- package/dist/{defineEvent-NPKUJRt8.mjs → defineEvent-DC981g-o.mjs} +1 -1
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-6mfTLBC-.mjs → elevation-BzhyVWfn.mjs} +1 -1
- package/dist/{eventPlugin-Dxp9JlKK.mjs → eventPlugin-Bw4bUDEO.mjs} +2 -2
- package/dist/{eventPlugin-DjEx_J3j.d.mts → eventPlugin-C1W1CRbf.d.mts} +1 -1
- package/dist/events/index.d.mts +8 -5
- package/dist/events/index.mjs +26 -7
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +52 -5
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +3 -3
- package/dist/{fastify-augmentation-CL48B6gW.d.mts → fastify-augmentation-BdCl_eNo.d.mts} +2 -2
- package/dist/{fields-DqZLp5d6.d.mts → fields-CKLrhyOb.d.mts} +1 -1
- package/dist/{generate-CcM24hoq.mjs → generate-BaxDdmJ8.mjs} +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.d.mts +2 -2
- package/dist/idempotency/index.mjs +1 -1
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{index-CNiryUMN.d.mts → index-Cvo1u9n6.d.mts} +3 -3
- package/dist/{index-C000faom.d.mts → index-QYma8mdC.d.mts} +215 -241
- package/dist/{index-3L-adFJO.d.mts → index-vcWUGkwf.d.mts} +3 -3
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +5 -5
- package/dist/{init-DQ_rY1J7.mjs → init-DSsdRfk9.mjs} +3 -3
- package/dist/integrations/event-gateway.d.mts +2 -2
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +2 -2
- package/dist/integrations/jobs.mjs +66 -1
- package/dist/integrations/mcp/index.d.mts +4 -4
- package/dist/integrations/mcp/index.mjs +1 -1
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/streamline.d.mts +16 -1
- package/dist/integrations/streamline.mjs +33 -2
- package/dist/integrations/websocket-pushref-redis.d.mts +1 -1
- package/dist/integrations/websocket-redis.d.mts +1 -1
- package/dist/integrations/websocket.d.mts +2 -2
- package/dist/{loadResourcesFromEntry-DCjYMgfC.mjs → loadResourcesFromEntry-XHNeUWpu.mjs} +1 -1
- package/dist/{mcpPlugin-BrepZ0cV.mjs → mcpPlugin-CzKdt3B8.mjs} +9 -9
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +1 -1
- package/dist/{openapi-CLZx9bwS.mjs → openapi-ButnRyOM.mjs} +5 -5
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +2 -2
- package/dist/{permissions-B1Qy55fg.mjs → permissions-3uzwkbQt.mjs} +99 -99
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/pipeline/index.mjs +1 -1
- package/dist/pipeline-D4sqiokR.mjs +336 -0
- package/dist/plugins/index.d.mts +5 -5
- package/dist/plugins/index.mjs +9 -9
- package/dist/plugins/response-cache.mjs +1 -1
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/presets/filesUpload.d.mts +4 -4
- package/dist/presets/filesUpload.mjs +2 -2
- package/dist/presets/index.d.mts +1 -1
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-BYbPobbF.mjs → presets-CF79RHEo.mjs} +1 -1
- package/dist/{queryCachePlugin-Do4P_WBC.d.mts → queryCachePlugin-Bd2tYgh5.d.mts} +2 -2
- package/dist/{queryCachePlugin-B4XMSSe7.mjs → queryCachePlugin-CnAeFqju.mjs} +3 -3
- package/dist/rateLimit-yKvxWAky.mjs +207 -0
- package/dist/{redis-cpqVb85w.d.mts → redis-3hqH_Qk_.d.mts} +1 -1
- package/dist/{redis-stream-BuiAS3aE.d.mts → redis-stream-BtEUtjxZ.d.mts} +5 -4
- package/dist/registerRoute-BEYn0ylk.mjs +108 -0
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{schemaIR-Bk6Tns82.mjs → schemaIR-CE6USIRi.mjs} +1 -1
- package/dist/scope/index.d.mts +2 -2
- package/dist/scope/index.mjs +2 -2
- package/dist/{sse-jh5OqFjR.mjs → sse-BrY1W6U8.mjs} +11 -2
- package/dist/testing/index.d.mts +2 -2
- package/dist/testing/index.mjs +12 -2
- package/dist/testing/storageContract.d.mts +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/storage.d.mts +1 -1
- package/dist/{types-DH-7WO64.d.mts → types-BWBcb88c.d.mts} +1 -1
- package/dist/{types-DEEWwQFR.d.mts → types-WVlAVp8T.d.mts} +10 -10
- package/dist/utils/index.d.mts +3 -3
- package/dist/utils/index.mjs +3 -3
- package/dist/{utils-BMQK8mRl.mjs → utils-xAQeDyU_.mjs} +1 -1
- package/dist/{validate-DFIP2VrM.mjs → validate-0__MuUsK.mjs} +201 -190
- package/dist/{versioning-5H4930tj.d.mts → versioning-BSEDGXKC.d.mts} +1 -1
- package/dist/{websocket-BZMUP7Gr.d.mts → websocket-BFBT5rH-.d.mts} +1 -1
- package/package.json +5 -5
- package/skills/arc/references/api-reference.md +1 -1
- package/dist/routerShared-Dl0A77Ba.mjs +0 -724
- /package/dist/{EventTransport-ClEDfiMS.mjs → EventTransport-7LPXLEUX.mjs} +0 -0
- /package/dist/{EventTransport-B1GFiYUy.d.mts → EventTransport-CaaXM5Y1.d.mts} +0 -0
- /package/dist/{HookSystem-Cmf7-Etp.mjs → HookSystem-BfCpWbwM.mjs} +0 -0
- /package/dist/{ResourceRegistry-CzSzVK1m.mjs → ResourceRegistry-CWmOggxS.mjs} +0 -0
- /package/dist/{actionPermissions-Bjmvn7Eb.mjs → actionPermissions-CX9QIMTd.mjs} +0 -0
- /package/dist/{caching-8MfrrUYU.mjs → caching-C0DdKiYB.mjs} +0 -0
- /package/dist/{elevation-DvwtjDwu.d.mts → elevation-DW90z5bT.d.mts} +0 -0
- /package/dist/{errorHandler-wQejMBT3.mjs → errorHandler-Bua97SEt.mjs} +0 -0
- /package/dist/{errorHandler-DuqTqeqn.d.mts → errorHandler-_Lp2k9M3.d.mts} +0 -0
- /package/dist/{errors-4ZloYFvm.d.mts → errors-DZOemeGa.d.mts} +0 -0
- /package/dist/{externalPaths-ClykOQqa.d.mts → externalPaths-DLle0R07.d.mts} +0 -0
- /package/dist/{generate-cRnsafMS.d.mts → generate-Dmk8cfvX.d.mts} +0 -0
- /package/dist/{init-D-vrTZ1G.d.mts → init-BS4Daqnv.d.mts} +0 -0
- /package/dist/{interface-DoE6UoC2.d.mts → interface-CsrGR8LF.d.mts} +0 -0
- /package/dist/{interface-BVkZsvEe.d.mts → interface-DL7LlWS5.d.mts} +0 -0
- /package/dist/{keys-DopsCuyQ.mjs → keys-B3yyBEyH.mjs} +0 -0
- /package/dist/{loadResources-fol6JuvW.mjs → loadResources-CwXt9MCh.mjs} +0 -0
- /package/dist/{memory-QOLe11D5.mjs → memory-TdTHCS9-.mjs} +0 -0
- /package/dist/{metrics-B-PU4-Yu.mjs → metrics-Da2EUPi9.mjs} +0 -0
- /package/dist/{multipartBody-VjVWmZl8.mjs → multipartBody-709YcXi1.mjs} +0 -0
- /package/dist/{pipe-DiCyvyPN.mjs → pipe-9Tl-OAus.mjs} +0 -0
- /package/dist/{pluralize-B9M8xvy-.mjs → pluralize-BxdUl2P4.mjs} +0 -0
- /package/dist/{preloadResources-BOXzPhKU.mjs → preloadResources-B-j-iqo-.mjs} +0 -0
- /package/dist/{pushref-registry-Bq_-EVsC.d.mts → pushref-registry-Dqclzjy7.d.mts} +0 -0
- /package/dist/{registry-BrlHkrRS.mjs → registry-Br15xdGM.mjs} +0 -0
- /package/dist/{replyHelpers-boS5Rx26.mjs → replyHelpers-DXHVxrrj.mjs} +0 -0
- /package/dist/{schemaConverter-De34B1ZG.mjs → schemaConverter-DatAaVNj.mjs} +0 -0
- /package/dist/{sessionManager-DlmaHUAl.d.mts → sessionManager-CyHpYXoB.d.mts} +0 -0
- /package/dist/{storage-BFmamN5m.d.mts → storage-C5q8fuEt.d.mts} +0 -0
- /package/dist/{store-helpers-5JgaxieH.mjs → store-helpers-DjSYI2uP.mjs} +0 -0
- /package/dist/{tracing-BYQ3hsbM.d.mts → tracing-Bnb1-YVd.d.mts} +0 -0
- /package/dist/{typeGuards-BzkXkvVv.mjs → typeGuards-CcFZXgU7.mjs} +0 -0
- /package/dist/{types-CfapW2t8.d.mts → types-BJwJN2Pg.d.mts} +0 -0
- /package/dist/{types-DV9WDfeg.mjs → types-D57iXYb8.mjs} +0 -0
- /package/dist/{versioning-CuIwUQZ2.mjs → versioning-C0K8KQLx.mjs} +0 -0
package/dist/docs/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { p as RegistryEntry } from "../index-
|
|
2
|
-
import { t as ExternalOpenApiPaths } from "../externalPaths-
|
|
1
|
+
import { p as RegistryEntry } from "../index-QYma8mdC.mjs";
|
|
2
|
+
import { t as ExternalOpenApiPaths } from "../externalPaths-DLle0R07.mjs";
|
|
3
3
|
import { FastifyPluginAsync } from "fastify";
|
|
4
4
|
|
|
5
5
|
//#region src/docs/openapi/types.d.ts
|
package/dist/docs/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as getUserRoles } from "../types-
|
|
2
|
-
import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-
|
|
1
|
+
import { t as getUserRoles } from "../types-D57iXYb8.mjs";
|
|
2
|
+
import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-ButnRyOM.mjs";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/docs/scalar.ts
|
|
5
5
|
const scalarPlugin = async (fastify, opts = {}) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
2
|
import { arcLog } from "./logger/index.mjs";
|
|
3
|
-
import { t as getUserRoles } from "./types-
|
|
3
|
+
import { t as getUserRoles } from "./types-D57iXYb8.mjs";
|
|
4
4
|
import fp from "fastify-plugin";
|
|
5
5
|
//#region src/scope/elevation.ts
|
|
6
6
|
var elevation_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
|
2
2
|
import { arcLog } from "./logger/index.mjs";
|
|
3
3
|
import { d as createDomainError } from "./errors-j4aJm1Wg.mjs";
|
|
4
4
|
import { n as requestContext } from "./requestContext-DDLS3NVU.mjs";
|
|
5
|
-
import { n as createEvent, t as MemoryEventTransport } from "./EventTransport-
|
|
5
|
+
import { n as createEvent, t as MemoryEventTransport } from "./EventTransport-7LPXLEUX.mjs";
|
|
6
6
|
import fp from "fastify-plugin";
|
|
7
7
|
//#region src/events/retry.ts
|
|
8
8
|
/**
|
|
@@ -115,7 +115,7 @@ const eventPlugin = async (fastify, opts = {}) => {
|
|
|
115
115
|
const validateMode = rawValidateMode ?? (registry ? "warn" : "off");
|
|
116
116
|
const warnOnDuplicate = rawWarnOnDuplicate ?? process.env.NODE_ENV !== "production";
|
|
117
117
|
const DUP_WINDOW_MS = 5e3;
|
|
118
|
-
const recentPublishes =
|
|
118
|
+
const recentPublishes = /* @__PURE__ */ new Map();
|
|
119
119
|
const evictExpiredPublishes = (now) => {
|
|
120
120
|
if (recentPublishes.size === 0) return;
|
|
121
121
|
for (const [key, timestamp] of recentPublishes) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-
|
|
1
|
+
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-CaaXM5Y1.mjs";
|
|
2
2
|
import { FastifyPluginAsync } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/events/defineEvent.d.ts
|
package/dist/events/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as EventTransport, i as EventLogger, n as DomainEvent, o as MemoryEventTransport, r as EventHandler, s as MemoryEventTransportOptions, t as DeadLetteredEvent } from "../EventTransport-
|
|
2
|
-
import { a as withRetry, c as EventDefinitionOutput, d as EventSchema, f as ValidationResult, i as createDeadLetterPublisher, l as EventRegistry, m as defineEvent, n as eventPlugin, o as CustomValidator, p as createEventRegistry, r as RetryOptions, s as EventDefinitionInput, t as EventPluginOptions, u as EventRegistryOptions } from "../eventPlugin-
|
|
1
|
+
import { a as EventTransport, i as EventLogger, n as DomainEvent, o as MemoryEventTransport, r as EventHandler, s as MemoryEventTransportOptions, t as DeadLetteredEvent } from "../EventTransport-CaaXM5Y1.mjs";
|
|
2
|
+
import { a as withRetry, c as EventDefinitionOutput, d as EventSchema, f as ValidationResult, i as createDeadLetterPublisher, l as EventRegistry, m as defineEvent, n as eventPlugin, o as CustomValidator, p as createEventRegistry, r as RetryOptions, s as EventDefinitionInput, t as EventPluginOptions, u as EventRegistryOptions } from "../eventPlugin-C1W1CRbf.mjs";
|
|
3
3
|
import { RedisEventTransportOptions, RedisLike } from "./transports/redis.mjs";
|
|
4
|
-
import { r as RedisStreamTransportOptions, t as RedisStreamLike } from "../redis-stream-
|
|
4
|
+
import { r as RedisStreamTransportOptions, t as RedisStreamLike } from "../redis-stream-BtEUtjxZ.mjs";
|
|
5
5
|
import { RepositoryLike } from "@classytic/repo-core/adapter";
|
|
6
6
|
|
|
7
7
|
//#region src/events/eventTypes.d.ts
|
|
@@ -511,8 +511,11 @@ declare class EventOutbox {
|
|
|
511
511
|
/**
|
|
512
512
|
* In-process attempt counter per event id. Accurate within this relay
|
|
513
513
|
* process; resets on restart. Populated as failures occur and cleared on
|
|
514
|
-
* successful ack or dead-letter transition
|
|
515
|
-
*
|
|
514
|
+
* successful ack or dead-letter transition; additionally hard-capped at
|
|
515
|
+
* {@link MAX_TRACKED_ATTEMPTS} (oldest-write evicted first) so events
|
|
516
|
+
* resolved by another relay worker can't accumulate forever. For durable
|
|
517
|
+
* authoritative counts, apps can query the store directly inside
|
|
518
|
+
* {@link OutboxFailurePolicy}.
|
|
516
519
|
*/
|
|
517
520
|
private readonly _attempts;
|
|
518
521
|
constructor(opts: EventOutboxOptions);
|
package/dist/events/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as MemoryEventTransport } from "../EventTransport-
|
|
2
|
-
import { n as defineEvent, t as createEventRegistry } from "../defineEvent-
|
|
3
|
-
import { i as withRetry, r as createDeadLetterPublisher, t as eventPlugin } from "../eventPlugin-
|
|
4
|
-
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-
|
|
1
|
+
import { t as MemoryEventTransport } from "../EventTransport-7LPXLEUX.mjs";
|
|
2
|
+
import { n as defineEvent, t as createEventRegistry } from "../defineEvent-DC981g-o.mjs";
|
|
3
|
+
import { i as withRetry, r as createDeadLetterPublisher, t as eventPlugin } from "../eventPlugin-Bw4bUDEO.mjs";
|
|
4
|
+
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-DjSYI2uP.mjs";
|
|
5
5
|
import { and, anyOf, eq, lte, ne, or } from "@classytic/repo-core/filter";
|
|
6
6
|
import { update } from "@classytic/repo-core/update";
|
|
7
7
|
//#region src/events/eventTypes.ts
|
|
@@ -352,6 +352,17 @@ function repositoryAsOutboxStore(repository) {
|
|
|
352
352
|
const DEFAULT_OUTBOX_RETENTION_MS = 10080 * 60 * 1e3;
|
|
353
353
|
const DEFAULT_LEASE_MS = 3e4;
|
|
354
354
|
/**
|
|
355
|
+
* Hard cap on the in-process attempt-counter map. Entries are cleared on
|
|
356
|
+
* local ack and on dead-letter, but an event that fails HERE and is later
|
|
357
|
+
* acked by a DIFFERENT relay worker (lease expiry → reclaim) never drains
|
|
358
|
+
* locally — without a cap the map grows for the life of the process in
|
|
359
|
+
* multi-worker deployments. Eviction is oldest-write-first; evicting an
|
|
360
|
+
* entry only resets its non-authoritative in-process count (the documented
|
|
361
|
+
* contract already says counts reset on restart — durable counts live in
|
|
362
|
+
* the store).
|
|
363
|
+
*/
|
|
364
|
+
const MAX_TRACKED_ATTEMPTS = 1e4;
|
|
365
|
+
/**
|
|
355
366
|
* Thrown by a store when `acknowledge` / `fail` is called by a consumer that
|
|
356
367
|
* does not own the event's current lease.
|
|
357
368
|
*
|
|
@@ -393,8 +404,11 @@ var EventOutbox = class {
|
|
|
393
404
|
/**
|
|
394
405
|
* In-process attempt counter per event id. Accurate within this relay
|
|
395
406
|
* process; resets on restart. Populated as failures occur and cleared on
|
|
396
|
-
* successful ack or dead-letter transition
|
|
397
|
-
*
|
|
407
|
+
* successful ack or dead-letter transition; additionally hard-capped at
|
|
408
|
+
* {@link MAX_TRACKED_ATTEMPTS} (oldest-write evicted first) so events
|
|
409
|
+
* resolved by another relay worker can't accumulate forever. For durable
|
|
410
|
+
* authoritative counts, apps can query the store directly inside
|
|
411
|
+
* {@link OutboxFailurePolicy}.
|
|
398
412
|
*/
|
|
399
413
|
_attempts = /* @__PURE__ */ new Map();
|
|
400
414
|
constructor(opts) {
|
|
@@ -578,7 +592,12 @@ var EventOutbox = class {
|
|
|
578
592
|
continue;
|
|
579
593
|
}
|
|
580
594
|
const attempts = (this._attempts.get(event.meta.id) ?? 0) + 1;
|
|
595
|
+
this._attempts.delete(event.meta.id);
|
|
581
596
|
this._attempts.set(event.meta.id, attempts);
|
|
597
|
+
if (this._attempts.size > MAX_TRACKED_ATTEMPTS) {
|
|
598
|
+
const oldest = this._attempts.keys().next().value;
|
|
599
|
+
if (oldest !== void 0) this._attempts.delete(oldest);
|
|
600
|
+
}
|
|
582
601
|
let failOpts = { consumerId: this._consumerId };
|
|
583
602
|
if (this._failurePolicy) try {
|
|
584
603
|
const decision = await this._failurePolicy({
|
|
@@ -738,7 +757,7 @@ function wrapWithSchema(definition, handler, options = {}) {
|
|
|
738
757
|
if (validate && definition.schema) result = validate(definition.schema, event.payload);
|
|
739
758
|
else if (registry) result = registry.validate(definition.name, event.payload, eventVersion);
|
|
740
759
|
else if (definition.schema) {
|
|
741
|
-
const { createEventRegistry } = await import("../defineEvent-
|
|
760
|
+
const { createEventRegistry } = await import("../defineEvent-DC981g-o.mjs").then((n) => n.r);
|
|
742
761
|
const adhoc = createEventRegistry();
|
|
743
762
|
adhoc.register(definition);
|
|
744
763
|
result = adhoc.validate(definition.name, event.payload);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as RedisStreamTransport, r as RedisStreamTransportOptions, t as RedisStreamLike } from "../../redis-stream-
|
|
1
|
+
import { n as RedisStreamTransport, r as RedisStreamTransportOptions, t as RedisStreamLike } from "../../redis-stream-BtEUtjxZ.mjs";
|
|
2
2
|
export { type RedisStreamLike, RedisStreamTransport, type RedisStreamTransportOptions };
|
|
@@ -32,6 +32,16 @@ import sjson from "secure-json-parse";
|
|
|
32
32
|
* await app.register(eventPlugin, { transport });
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
|
+
/**
|
|
36
|
+
* Hard cap on the failure-context map. Entries are deleted on local ack and
|
|
37
|
+
* on DLQ write, but a message that fails HERE and is later acked or
|
|
38
|
+
* dead-lettered by a DIFFERENT consumer in the group never gets cleared
|
|
39
|
+
* locally — without a cap the map grows for the life of the process in
|
|
40
|
+
* multi-consumer deployments. Eviction is oldest-first (Map insertion
|
|
41
|
+
* order); an evicted entry only degrades the eventual DLQ envelope to the
|
|
42
|
+
* existing cross-consumer fallback message, never loses the event itself.
|
|
43
|
+
*/
|
|
44
|
+
const MAX_FAILURE_CONTEXT_ENTRIES = 1024;
|
|
35
45
|
var RedisStreamTransport = class {
|
|
36
46
|
name = "redis-stream";
|
|
37
47
|
redis;
|
|
@@ -67,9 +77,10 @@ var RedisStreamTransport = class {
|
|
|
67
77
|
* Last-seen failure context per message id, populated when an in-process
|
|
68
78
|
* handler throws in {@link processEntry}. Consumed (and cleared) by
|
|
69
79
|
* {@link moveToDlq} so the dead-letter envelope carries the actual error
|
|
70
|
-
* message instead of opaque "reclaimed without context".
|
|
71
|
-
*
|
|
72
|
-
*
|
|
80
|
+
* message instead of opaque "reclaimed without context". Entries are
|
|
81
|
+
* deleted on ack and on DLQ write; messages resolved by ANOTHER consumer
|
|
82
|
+
* never drain locally, so the map is additionally hard-capped at
|
|
83
|
+
* {@link MAX_FAILURE_CONTEXT_ENTRIES} with oldest-first eviction.
|
|
73
84
|
*/
|
|
74
85
|
failureContext = /* @__PURE__ */ new Map();
|
|
75
86
|
/** One-shot guard so the "client lacks xrange" warning fires once per process. */
|
|
@@ -168,6 +179,7 @@ var RedisStreamTransport = class {
|
|
|
168
179
|
this.running = false;
|
|
169
180
|
this.generation++;
|
|
170
181
|
this.handlers.clear();
|
|
182
|
+
this.failureContext.clear();
|
|
171
183
|
if (this.pollPromise) {
|
|
172
184
|
if (await Promise.race([this.pollPromise.then(() => "drained"), this.sleep(this.closeTimeoutMs).then(() => "timeout")]) === "timeout") if (!this.externalLifecycle) {
|
|
173
185
|
if (typeof this.redis.disconnect === "function") this.redis.disconnect();
|
|
@@ -190,13 +202,16 @@ var RedisStreamTransport = class {
|
|
|
190
202
|
this.groupCreated = true;
|
|
191
203
|
}
|
|
192
204
|
async pollLoop(myGen) {
|
|
205
|
+
let pollErrorAttempts = 0;
|
|
193
206
|
while (this.running && this.generation === myGen) try {
|
|
194
207
|
await this.claimPending();
|
|
195
208
|
await this.readNewMessages();
|
|
209
|
+
pollErrorAttempts = 0;
|
|
196
210
|
} catch (err) {
|
|
197
211
|
if (this.running && this.generation === myGen) {
|
|
212
|
+
pollErrorAttempts++;
|
|
198
213
|
this.logger.error("[RedisStreamTransport] Poll error:", err);
|
|
199
|
-
await this.sleep(
|
|
214
|
+
await this.sleep(fullJitterBackoffMs(pollErrorAttempts));
|
|
200
215
|
}
|
|
201
216
|
}
|
|
202
217
|
}
|
|
@@ -207,7 +222,7 @@ var RedisStreamTransport = class {
|
|
|
207
222
|
}
|
|
208
223
|
async claimPending() {
|
|
209
224
|
try {
|
|
210
|
-
const pending = await this.redis.xpending(this.stream, this.group, "-", "+", 10);
|
|
225
|
+
const pending = await this.redis.xpending(this.stream, this.group, "-", "+", Math.max(this.batchSize, 10));
|
|
211
226
|
if (!pending || pending.length === 0) return;
|
|
212
227
|
const staleIds = [];
|
|
213
228
|
const overRetryIds = [];
|
|
@@ -251,6 +266,7 @@ var RedisStreamTransport = class {
|
|
|
251
266
|
}
|
|
252
267
|
const now = /* @__PURE__ */ new Date();
|
|
253
268
|
const prior = this.failureContext.get(messageId);
|
|
269
|
+
this.failureContext.delete(messageId);
|
|
254
270
|
this.failureContext.set(messageId, {
|
|
255
271
|
error: lastError ? toErrorRecord(lastError) : { message: "handler returned without acking — no error captured" },
|
|
256
272
|
firstFailedAt: prior?.firstFailedAt ?? now,
|
|
@@ -258,6 +274,10 @@ var RedisStreamTransport = class {
|
|
|
258
274
|
attempts: (prior?.attempts ?? 0) + 1,
|
|
259
275
|
handlerName: lastHandlerName ?? prior?.handlerName
|
|
260
276
|
});
|
|
277
|
+
if (this.failureContext.size > MAX_FAILURE_CONTEXT_ENTRIES) {
|
|
278
|
+
const oldest = this.failureContext.keys().next().value;
|
|
279
|
+
if (oldest !== void 0) this.failureContext.delete(oldest);
|
|
280
|
+
}
|
|
261
281
|
}
|
|
262
282
|
getMatchingHandlers(eventType) {
|
|
263
283
|
const matched = [];
|
|
@@ -347,6 +367,33 @@ var RedisStreamTransport = class {
|
|
|
347
367
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
348
368
|
}
|
|
349
369
|
};
|
|
370
|
+
/** Poll-error backoff tuning — see {@link fullJitterBackoffMs}. */
|
|
371
|
+
const POLL_ERROR_BACKOFF_BASE_MS = 1e3;
|
|
372
|
+
const POLL_ERROR_BACKOFF_MAX_MS = 3e4;
|
|
373
|
+
const POLL_ERROR_BACKOFF_FLOOR_MS = 100;
|
|
374
|
+
/**
|
|
375
|
+
* Exponential backoff with full jitter for poll-error retries.
|
|
376
|
+
*
|
|
377
|
+
* The delay is drawn uniformly from the capped exponential window
|
|
378
|
+
* `[floor, min(max, base * 2^(attempt-1))]` — the AWS "full jitter"
|
|
379
|
+
* strategy. Full jitter decorrelates a fleet of consumers that all observed
|
|
380
|
+
* the same Redis blip; the small floor keeps a near-zero draw from
|
|
381
|
+
* hot-spinning the loop while Redis is hard-down.
|
|
382
|
+
*
|
|
383
|
+
* Sibling of `exponentialBackoff()` in `src/events/outbox.ts`, which is a
|
|
384
|
+
* PUBLIC store-author helper with additive jitter and `Date` (retryAt)
|
|
385
|
+
* semantics. Deliberately not shared: the two have different jitter models
|
|
386
|
+
* and audiences, and coupling them would hang this internal tuning off the
|
|
387
|
+
* public API surface.
|
|
388
|
+
*
|
|
389
|
+
* @param attempt 1-indexed consecutive poll-error count (reset on success)
|
|
390
|
+
* @param random injectable for deterministic tests; defaults to `Math.random`
|
|
391
|
+
*/
|
|
392
|
+
function fullJitterBackoffMs(attempt, random = Math.random) {
|
|
393
|
+
const exp = POLL_ERROR_BACKOFF_BASE_MS * 2 ** (Math.max(1, Math.floor(attempt)) - 1);
|
|
394
|
+
const capped = Math.min(POLL_ERROR_BACKOFF_MAX_MS, exp);
|
|
395
|
+
return POLL_ERROR_BACKOFF_FLOOR_MS + random() * (capped - POLL_ERROR_BACKOFF_FLOOR_MS);
|
|
396
|
+
}
|
|
350
397
|
/**
|
|
351
398
|
* Convert a thrown value into the `DeadLetteredEvent.error` shape — message
|
|
352
399
|
* always present, optional `code` (string only) and `stack`. Centralised so
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "../../EventTransport-
|
|
1
|
+
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "../../EventTransport-CaaXM5Y1.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/events/transports/redis.d.ts
|
|
4
4
|
interface RedisLike {
|
package/dist/factory/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as CustomPluginAuthOption, c as RawBodyOptions, d as preloadResourcesAsync, f as LoadResourcesOptions, h as loadResources, i as CustomAuthenticatorOption, l as UnderPressureOptions, m as ResourceModule, n as BetterAuthOption, o as JwtAuthOption, p as ResourceLike, r as CreateAppOptions, s as MultipartOptions, t as AuthOption, u as preloadResources } from "../types-
|
|
1
|
+
import { a as CustomPluginAuthOption, c as RawBodyOptions, d as preloadResourcesAsync, f as LoadResourcesOptions, h as loadResources, i as CustomAuthenticatorOption, l as UnderPressureOptions, m as ResourceModule, n as BetterAuthOption, o as JwtAuthOption, p as ResourceLike, r as CreateAppOptions, s as MultipartOptions, t as AuthOption, u as preloadResources } from "../types-WVlAVp8T.mjs";
|
|
2
2
|
import { FastifyInstance, FastifyServerOptions } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/factory/createApp.d.ts
|
package/dist/factory/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as preloadResourcesAsync, t as preloadResources } from "../preloadResources-
|
|
2
|
-
import { a as edgePreset, c as testingPreset, i as developmentPreset, n as createApp, o as getPreset, s as productionPreset, t as ArcFactory } from "../createApp-
|
|
3
|
-
import { t as loadResources } from "../loadResources-
|
|
1
|
+
import { n as preloadResourcesAsync, t as preloadResources } from "../preloadResources-B-j-iqo-.mjs";
|
|
2
|
+
import { a as edgePreset, c as testingPreset, i as developmentPreset, n as createApp, o as getPreset, s as productionPreset, t as ArcFactory } from "../createApp-J1iPXY9p.mjs";
|
|
3
|
+
import { t as loadResources } from "../loadResources-CwXt9MCh.mjs";
|
|
4
4
|
//#region src/factory/edge.ts
|
|
5
5
|
/**
|
|
6
6
|
* Convert a Fastify app into a Web Standards fetch handler.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as ExternalOpenApiPaths } from "./externalPaths-
|
|
1
|
+
import { yn as HookSystem, z as ResourceRegistry } from "./index-QYma8mdC.mjs";
|
|
2
|
+
import { t as ExternalOpenApiPaths } from "./externalPaths-DLle0R07.mjs";
|
|
3
3
|
import { FastifyPluginAsync } from "fastify";
|
|
4
4
|
|
|
5
5
|
//#region src/core/arcCorePlugin.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as pluralize } from "./pluralize-
|
|
1
|
+
import { t as pluralize } from "./pluralize-BxdUl2P4.mjs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
//#region src/cli/commands/generate/name-helpers.ts
|
package/dist/hooks/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Cn as afterUpdate, Dn as createHookSystem, En as beforeUpdate, On as defineHook, Sn as afterDelete, Tn as beforeDelete, _n as HookPhase, bn as HookSystemOptions, gn as HookOperation, hn as HookHandler, mn as HookContext, pn as DefineHookOptions, vn as HookRegistration, wn as beforeCreate, xn as afterCreate, yn as HookSystem } from "../index-QYma8mdC.mjs";
|
|
2
2
|
export { type DefineHookOptions, type HookContext, type HookHandler, type HookOperation, type HookPhase, type HookRegistration, HookSystem, type HookSystemOptions, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
|
package/dist/hooks/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as beforeCreate, c as createHookSystem, i as afterUpdate, l as defineHook, n as afterCreate, o as beforeDelete, r as afterDelete, s as beforeUpdate, t as HookSystem } from "../HookSystem-
|
|
1
|
+
import { a as beforeCreate, c as createHookSystem, i as afterUpdate, l as defineHook, n as afterCreate, o as beforeDelete, r as afterDelete, s as beforeUpdate, t as HookSystem } from "../HookSystem-BfCpWbwM.mjs";
|
|
2
2
|
export { HookSystem, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as createIdempotencyResult, n as IdempotencyResult, r as IdempotencyStore, t as IdempotencyLock } from "../interface-
|
|
2
|
-
import { i as RedisIdempotencyStoreOptions, n as RedisClient } from "../redis-
|
|
1
|
+
import { i as createIdempotencyResult, n as IdempotencyResult, r as IdempotencyStore, t as IdempotencyLock } from "../interface-CsrGR8LF.mjs";
|
|
2
|
+
import { i as RedisIdempotencyStoreOptions, n as RedisClient } from "../redis-3hqH_Qk_.mjs";
|
|
3
3
|
import { FastifyPluginAsync } from "fastify";
|
|
4
4
|
import { RepositoryLike } from "@classytic/repo-core/adapter";
|
|
5
5
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-
|
|
1
|
+
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-DjSYI2uP.mjs";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
import { and, eq, exists, gt, lt, or, startsWith } from "@classytic/repo-core/filter";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as UpstashRedisLike, i as RedisIdempotencyStoreOptions, n as RedisClient, o as ioredisAsIdempotencyClient, r as RedisIdempotencyStore, s as upstashAsIdempotencyClient, t as IoredisLike } from "../redis-
|
|
1
|
+
import { a as UpstashRedisLike, i as RedisIdempotencyStoreOptions, n as RedisClient, o as ioredisAsIdempotencyClient, r as RedisIdempotencyStore, s as upstashAsIdempotencyClient, t as IoredisLike } from "../redis-3hqH_Qk_.mjs";
|
|
2
2
|
export { type IoredisLike, type RedisClient, RedisIdempotencyStore, type RedisIdempotencyStoreOptions, type UpstashRedisLike, ioredisAsIdempotencyClient, upstashAsIdempotencyClient };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as RequestContext, F as FastifyWithDecorators, H as ActionDefinition, K as ArcFieldRule, Kt as AnyRecord, L as RequestWithExtras, T as CrudRouterOptions, Tt as AggregationConfig, V as ResourceDefinition, bt as IRequestContext, ft as RouteMcpConfig, mt as RouteSchemaOptions, q as CrudController, st as ResourceConfig, vt as IController, yt as IControllerResponse } from "./index-
|
|
2
|
-
import { i as RequestScope } from "./types-
|
|
3
|
-
import { c as PermissionCheck } from "./fields-
|
|
1
|
+
import { C as RequestContext, F as FastifyWithDecorators, H as ActionDefinition, K as ArcFieldRule, Kt as AnyRecord, L as RequestWithExtras, T as CrudRouterOptions, Tt as AggregationConfig, V as ResourceDefinition, bt as IRequestContext, ft as RouteMcpConfig, mt as RouteSchemaOptions, q as CrudController, st as ResourceConfig, vt as IController, yt as IControllerResponse } from "./index-QYma8mdC.mjs";
|
|
2
|
+
import { i as RequestScope } from "./types-BJwJN2Pg.mjs";
|
|
3
|
+
import { c as PermissionCheck } from "./fields-CKLrhyOb.mjs";
|
|
4
4
|
import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { AggDateBucket, AggMeasure, AggTopN } from "@classytic/repo-core/repository";
|