@classytic/arc 2.33.0 → 2.35.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.
- package/dist/{BaseController-CaQC5EXX.mjs → BaseController-C-pofd0v.mjs} +131 -16
- package/dist/{EventTransport-tq4CEB-q.mjs → EventTransport-BrPeGUil.mjs} +1 -1
- package/dist/{HookSystem-DqXkMXkB.mjs → HookSystem-LlPm3Anm.mjs} +6 -4
- package/dist/{ResourceRegistry-DoALUlOO.mjs → ResourceRegistry-yuD1Ra53.mjs} +2 -2
- package/dist/{pipeline-q69DZzgG.mjs → actionPermissions-LFuOra7W.mjs} +30 -7
- package/dist/audit/index.d.mts +2 -2
- package/dist/audit/index.mjs +2 -2
- package/dist/auth/audit.mjs +1 -1
- package/dist/auth/index.d.mts +2 -2
- package/dist/auth/index.mjs +6 -6
- package/dist/auth/redis-session.mjs +1 -1
- package/dist/{authorizationDecision-B3mP_QTy.mjs → authorizationDecision-DYXBBgtg.mjs} +6 -2
- package/dist/{base-Csjc2oF-.d.mts → base-GZU3LlzP.d.mts} +1 -1
- package/dist/{buildHandler-DLE9xX-V.mjs → buildHandler-Do9aMIvL.mjs} +4 -4
- package/dist/cache/index.mjs +4 -4
- package/dist/{caching-BcGmvnHh.mjs → caching-cN5X9VEL.mjs} +2 -2
- package/dist/cleanup/index.d.mts +2 -2
- package/dist/cleanup/index.mjs +4 -4
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/describe.mjs +3 -3
- package/dist/cli/commands/docs.mjs +3 -3
- package/dist/cli/commands/doctor.mjs +1 -1
- package/dist/cli/commands/generate.mjs +2 -2
- package/dist/cli/commands/init.mjs +2 -2
- package/dist/cli/commands/introspect.mjs +2 -2
- package/dist/cli/index.mjs +3 -3
- package/dist/{constants-BxCoxmiN.mjs → constants-BhzLXCfN.mjs} +1 -1
- package/dist/context/index.d.mts +16 -1
- package/dist/context/index.mjs +64 -4
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +8 -8
- package/dist/{core-dxhcHhUD.mjs → core-DdEvmmkY.mjs} +3 -3
- package/dist/{createActionRouter-DVpoA0do.mjs → createActionRouter-EYWgd0ly.mjs} +27 -64
- package/dist/{createAggregationRouter-B_B48JZ-.mjs → createAggregationRouter-ByOK9Iev.mjs} +7 -7
- package/dist/defineAggregation-DoIijIFq.mjs +25 -0
- package/dist/{defineResource-DR9vsUYy.mjs → defineResource-BOrGeocE.mjs} +62 -66
- package/dist/discovery/index.mjs +1 -1
- package/dist/docs/index.d.mts +1 -1
- package/dist/docs/index.mjs +3 -3
- package/dist/{elevation-B0tlY8y1.mjs → elevation-tGIAldco.mjs} +4 -4
- package/dist/encryption/index.mjs +3 -3
- package/dist/{errorHandler-C7xBqHsI.mjs → errorHandler-BbQ1nQdk.mjs} +3 -3
- package/dist/{errors-Cd_yy7aW.mjs → errors-CLid6atr.mjs} +1 -1
- package/dist/{eventPlugin-DSNEZWfV.d.mts → eventPlugin-B47sfCJ8.d.mts} +1 -1
- package/dist/{eventPlugin-Dar8qRaj.mjs → eventPlugin-ClPn5kjn.mjs} +5 -5
- package/dist/events/index.d.mts +2 -2
- package/dist/events/index.mjs +5 -5
- package/dist/events/transports/redis-stream-entry.mjs +1 -1
- package/dist/events/transports/redis.mjs +1 -1
- package/dist/factory/index.d.mts +5 -5
- package/dist/factory/index.mjs +5 -6
- package/dist/{fastify-augmentation-DVsTAy6X.d.mts → fastify-augmentation-CMMTL3cj.d.mts} +3 -3
- package/dist/{fields-CojeUkS4.mjs → fields-UtpiJO5R.mjs} +1 -1
- package/dist/{generate-DiB0nHPR.mjs → generate-BoAVy3_b.mjs} +2 -2
- package/dist/{headers-CveNO9gR.mjs → headers-DODWf7aC.mjs} +2 -2
- package/dist/{health-CasG2A28.mjs → health-_Zs3R_Sb.mjs} +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +2 -2
- package/dist/idempotency/index.mjs +23 -58
- package/dist/idempotency/redis.mjs +1 -1
- package/dist/{index-C5NnMEKF.d.mts → index-C50BUxKs.d.mts} +1 -1
- package/dist/{index-BcR2bFZQ.d.mts → index-C5K78SXo.d.mts} +33 -105
- package/dist/{index-ugr1tQlW.d.mts → index-CJCcbADG.d.mts} +1 -1
- package/dist/{index-B-DvUzsr.d.mts → index-K7auNNW0.d.mts} +2 -2
- package/dist/{index-Brin0ODU.d.mts → index-h-mTgMqy.d.mts} +21 -31
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +12 -12
- package/dist/{init-mdJ-v4Xp.mjs → init-Ce4R0ZGK.mjs} +1 -1
- package/dist/integrations/event-gateway.mjs +2 -2
- package/dist/integrations/index.d.mts +2 -2
- package/dist/integrations/index.mjs +1 -1
- package/dist/integrations/jobs/index.d.mts +1 -1
- package/dist/integrations/jobs/index.mjs +2 -2
- package/dist/integrations/mcp/index.d.mts +4 -4
- package/dist/integrations/mcp/index.mjs +2 -2
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +3 -3
- package/dist/integrations/streamline.mjs +3 -3
- package/dist/integrations/webhooks.d.mts +1 -1
- package/dist/integrations/webhooks.mjs +11 -24
- package/dist/integrations/websocket-pushref-redis.mjs +1 -1
- package/dist/integrations/websocket-redis.mjs +1 -1
- package/dist/integrations/websocket.mjs +1 -1
- package/dist/{interface-DznJrm9R.mjs → interface-my7sxjw5.mjs} +1 -1
- package/dist/{jsonBody-CfGH-GxO.mjs → jsonBody-CVKA7C5m.mjs} +2 -2
- package/dist/{keys-WeKvY1dE.mjs → keys-GlU7XpmG.mjs} +1 -1
- package/dist/{loadResources-Bj-aSsXi.mjs → loadResources-DdQb0qgV.mjs} +2 -2
- package/dist/{loadResourcesFromEntry-DwaxNcE2.mjs → loadResourcesFromEntry-s6aGs6-0.mjs} +2 -2
- package/dist/logger/index.d.mts +23 -4
- package/dist/logger/index.mjs +50 -7
- package/dist/{mcpPlugin-aJg5TqHi.mjs → mcpPlugin-DkzZ7Nfx.mjs} +15 -16
- package/dist/{memory-qYSB7rMQ.mjs → memory-BwedEXau.mjs} +2 -2
- package/dist/{metrics-D7uchLjN.mjs → metrics-5LNPvL3P.mjs} +2 -2
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +3 -3
- package/dist/migrations/index.mjs +7 -4
- package/dist/{module-CwKsgZXp.mjs → module-Bh5OC7ww.mjs} +1 -1
- package/dist/{multipartBody-4w-S3-PU.mjs → multipartBody-DjilSDAT.mjs} +1 -1
- package/dist/{openapi-BN5cQaO2.mjs → openapi-ItLH12_L.mjs} +6 -6
- package/dist/outbox-admin/index.d.mts +2 -2
- package/dist/outbox-admin/index.mjs +4 -4
- package/dist/{outbox-module-CXB79bvt.mjs → outbox-module-SGIZz6oS.mjs} +14 -5
- package/dist/{outbox-module-D-VFq37T.d.mts → outbox-module-b1TyDGGi.d.mts} +40 -3
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +5 -5
- package/dist/{permissions-BAfwgBxc.mjs → permissions-CpSBlFXZ.mjs} +6 -6
- package/dist/{pipe-BzzoEhHj.mjs → pipe-DNOuCfAs.mjs} +2 -2
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/pipeline/index.mjs +2 -2
- package/dist/plugins/index.d.mts +92 -7
- package/dist/plugins/index.mjs +168 -17
- package/dist/plugins/response-cache.mjs +2 -2
- package/dist/plugins/tracing-entry.mjs +2 -2
- package/dist/{pluralize-B7xf8qZF.mjs → pluralize-DGAQQKL8.mjs} +1 -1
- package/dist/{preloadResources-g07ldtzh.d.mts → preloadResources--ZtY9pe9.d.mts} +54 -270
- package/dist/{createApp-CLGegqiG.mjs → preloadResources-DYMzmUk1.mjs} +112 -31
- package/dist/presets/filesUpload.d.mts +3 -3
- package/dist/presets/filesUpload.mjs +5 -5
- package/dist/presets/index.d.mts +2 -2
- package/dist/presets/index.mjs +2 -2
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +3 -3
- package/dist/presets/search.d.mts +9 -47
- package/dist/presets/search.mjs +2 -2
- package/dist/{presets-D-h0uWtP.mjs → presets-Bi0Z6Iq8.mjs} +4 -4
- package/dist/{projection-BKM0Ui-s.mjs → projection-aevMua7Q.mjs} +2 -2
- package/dist/{queryCachePlugin-DhsZ0ZIc.mjs → queryCachePlugin-BI7Z88Cx.mjs} +5 -5
- package/dist/{rateLimitKey-XngqVNEV.mjs → rateLimitKey-pyevMUVf.mjs} +1 -1
- package/dist/{realtime-CTkv3O59.mjs → realtime-Cfl2bVjj.mjs} +9 -9
- package/dist/{rateLimit-D4-ASwsI.mjs → registerRoute-u1opU66a.mjs} +114 -3
- package/dist/registry/index.d.mts +2 -2
- package/dist/registry/index.mjs +3 -3
- package/dist/{registry-CLxCR5LF.mjs → registry-B4sf9Rfm.mjs} +15 -56
- package/dist/{renewingLease-BnWtbA2U.mjs → renewingLease-5ESPMxp0.mjs} +14 -2
- package/dist/{replyHelpers-BSBVCwL3.mjs → replyHelpers-2jfmMnnV.mjs} +2 -2
- package/dist/{requestContext-uYE35JxI.mjs → requestContext-DzOUGNdY.mjs} +1 -1
- package/dist/{rolldown-runtime-DNg-KNCk.mjs → rolldown-runtime-CEvvVXTC.mjs} +1 -1
- package/dist/{runtimeCapabilities-Dm88DaTW.mjs → runtimeCapabilities-BagWc3TI.mjs} +1 -1
- package/dist/{schedules-CAcZgia0.mjs → schedules-BLpZLWGF.mjs} +6 -4
- package/dist/{schemaConverter-XH1RZRyu.mjs → schemaConverter-D2_bHGil.mjs} +19 -32
- package/dist/{schemaIR-CDvclAew.mjs → schemaIR-s3-ouZmP.mjs} +2 -2
- package/dist/schemas/index.mjs +1 -1
- package/dist/scim/index.mjs +2 -2
- package/dist/scope/index.d.mts +1 -1
- package/dist/scope/index.mjs +5 -5
- package/dist/{scope-BaWcqBvr.mjs → scope-DgepeCv6.mjs} +4 -4
- package/dist/simpleEqualityMatcher-BO-sFTQf.mjs +43 -0
- package/dist/{sse-Cf0jUHsh.mjs → sse-DUIP1XH6.mjs} +5 -5
- package/dist/{sseStream-Bvpi-UXQ.mjs → sseStream-ByFGyIVr.mjs} +2 -2
- package/dist/{store-helpers-B88p99Z2.mjs → store-helpers-kIJCY0wI.mjs} +1 -1
- package/dist/{streaming-DsT1B5zJ.mjs → streaming-DOpZVht6.mjs} +1 -1
- package/dist/{subscribe-helpers-CLIOHsOK.mjs → subscribe-helpers-Dh2BnzJf.mjs} +12 -46
- package/dist/sync/changelog.mjs +1 -1
- package/dist/testing/cleanupStoreContract.mjs +1 -1
- package/dist/testing/index.d.mts +6 -6
- package/dist/testing/index.mjs +10 -11
- package/dist/testing/outboxStoreContract.mjs +1 -1
- package/dist/testing/storageContract.mjs +1 -1
- package/dist/{transactionContext-BYtWnwAS.mjs → transactionContext-BTZzEcRo.mjs} +1 -1
- package/dist/{typeGuards-jjKJDN13.mjs → typeGuards-B-_jqaMi.mjs} +1 -1
- package/dist/types/index.d.mts +3 -3
- package/dist/types/index.mjs +1 -1
- package/dist/types/storage.mjs +1 -1
- package/dist/{types-BcTumAz_.d.mts → types-DDD5RKTu.d.mts} +30 -87
- package/dist/{types-BfC83KsP.d.mts → types-DSvHH0uR.d.mts} +1 -1
- package/dist/{types-ChuShpCP.d.mts → types-Ddl9OjmE.d.mts} +18 -121
- package/dist/{types-CoqIRrkY.mjs → types-GY4kATJb.mjs} +10 -53
- package/dist/usage/index.d.mts +2 -2
- package/dist/usage/index.mjs +0 -0
- package/dist/{userHelpers-CWF5pbZD.mjs → userHelpers-AKcB4V03.mjs} +1 -1
- package/dist/utils/index.d.mts +16 -42
- package/dist/utils/index.mjs +11 -11
- package/dist/{utils-h1V_sT-t.mjs → utils-CBK9HQOI.mjs} +3 -3
- package/dist/{validate-CdQlz52F.mjs → validate-dosAIvQU.mjs} +2 -2
- package/dist/{versioning-rZbyLVD-.mjs → versioning-BbTs4pwM.mjs} +3 -3
- package/package.json +8 -8
- package/skills/arc/SKILL.md +9 -9
- package/skills/arc/references/api-reference.md +1 -1
- package/dist/actionPermissions-CUeCmpUd.mjs +0 -25
- package/dist/defineAggregation-Nv-DwfOf.mjs +0 -48
- package/dist/preloadResources-BkyqeTDz.mjs +0 -46
- package/dist/registerRoute-DNnd3vkz.mjs +0 -113
- package/dist/repositoryFilter-DKny7PDn.mjs +0 -45
- package/dist/simpleEqualityMatcher-Se8VrsaP.mjs +0 -69
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { Ct as PipelineStep, Fn as IControllerResponse, St as PipelineContext, _t as Guard, bt as OperationFilter, vt as Interceptor, wt as Transform, xt as PipelineConfig, yt as NextFunction } from "../index-
|
|
2
|
+
import { Ct as PipelineStep, Fn as IControllerResponse, St as PipelineContext, _t as Guard, bt as OperationFilter, vt as Interceptor, wt as Transform, xt as PipelineConfig, yt as NextFunction } from "../index-C5K78SXo.mjs";
|
|
3
3
|
//#region src/pipeline/guard.d.ts
|
|
4
4
|
interface GuardOptions {
|
|
5
5
|
operations?: OperationFilter;
|
package/dist/pipeline/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { n as pipe, t as executePipeline } from "../pipe-
|
|
1
|
+
/*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as pipe, t as executePipeline } from "../pipe-DNOuCfAs.mjs";
|
|
3
3
|
//#region src/pipeline/guard.ts
|
|
4
4
|
/**
|
|
5
5
|
* Create a named guard.
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
import { t as AnyRecord } from "../base-
|
|
3
|
-
import { At as RouteDefinition, J as PresetHook, Q as MiddlewareConfig, et as RouteSchemaOptions } from "../index-
|
|
2
|
+
import { t as AnyRecord } from "../base-GZU3LlzP.mjs";
|
|
3
|
+
import { At as RouteDefinition, J as PresetHook, Q as MiddlewareConfig, et as RouteSchemaOptions } from "../index-C5K78SXo.mjs";
|
|
4
4
|
import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-DI5AN2b5.mjs";
|
|
5
|
-
import { _ as HealthCheck, b as healthPlugin, f as ScheduleDefinition, g as schedulesPlugin, h as _default$
|
|
6
|
-
import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-
|
|
7
|
-
import { _ as CachingRule, a as MetricsCollector, c as metricsPlugin, d as _default$
|
|
5
|
+
import { _ as HealthCheck, b as healthPlugin, f as ScheduleDefinition, g as schedulesPlugin, h as _default$8, m as SchedulesPluginOptions, p as ScheduleStats, v as HealthOptions, y as _default$3 } from "../types-DDD5RKTu.mjs";
|
|
6
|
+
import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-CMMTL3cj.mjs";
|
|
7
|
+
import { _ as CachingRule, a as MetricsCollector, c as metricsPlugin, d as _default$6, f as realtimePlugin, g as CachingOptions, h as ssePlugin, i as MetricEntry, l as ChangeOperation, m as _default$9, n as _default$10, o as MetricsOptions, p as SSEOptions, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as RealtimeOptions, v as _default$1, y as cachingPlugin } from "../versioning-DEs-_hFi.mjs";
|
|
8
8
|
import { t as TracingOptions } from "../tracing-Dro5eH6j.mjs";
|
|
9
9
|
import { PaginatedResult } from "@classytic/repo-core/pagination";
|
|
10
10
|
import { FastifyInstance, FastifyPluginAsync } from "fastify";
|
|
@@ -89,6 +89,91 @@ declare module "fastify" {
|
|
|
89
89
|
}
|
|
90
90
|
declare const _default$2: FastifyPluginAsync<GracefulShutdownOptions>;
|
|
91
91
|
//#endregion
|
|
92
|
+
//#region src/plugins/pressure.d.ts
|
|
93
|
+
/**
|
|
94
|
+
* One measurable source of load, normalised by whoever owns it.
|
|
95
|
+
*
|
|
96
|
+
* A throwing `read()` reports 0, never 1 — a broken thermometer is not a fire.
|
|
97
|
+
* Logged once per signal, not per sample.
|
|
98
|
+
*/
|
|
99
|
+
interface PressureSignal {
|
|
100
|
+
/** Stable identity — appears in snapshots and logs. */
|
|
101
|
+
readonly name: string;
|
|
102
|
+
/** Saturation in [0, 1]. Values outside the range are clamped. */
|
|
103
|
+
read(): number | Promise<number>;
|
|
104
|
+
}
|
|
105
|
+
/** `ok` → serve · `degraded` → serve, shed what is optional · `saturated` → refuse. */
|
|
106
|
+
type PressureState = "ok" | "degraded" | "saturated";
|
|
107
|
+
interface PressureThresholds {
|
|
108
|
+
/** Enter `degraded` at or above this. Default 0.8. */
|
|
109
|
+
degraded?: number;
|
|
110
|
+
/** Enter `saturated` at or above this. Default 0.95. */
|
|
111
|
+
saturated?: number;
|
|
112
|
+
}
|
|
113
|
+
interface PressureSnapshot {
|
|
114
|
+
readonly state: PressureState;
|
|
115
|
+
/** Highest signal — the one that decided the state. */
|
|
116
|
+
readonly worst: {
|
|
117
|
+
name: string;
|
|
118
|
+
value: number;
|
|
119
|
+
} | undefined;
|
|
120
|
+
readonly signals: Readonly<Record<string, number>>;
|
|
121
|
+
}
|
|
122
|
+
interface PressureOptions {
|
|
123
|
+
/** Extra signals beyond the built-in ELU reader. */
|
|
124
|
+
signals?: PressureSignal[];
|
|
125
|
+
thresholds?: PressureThresholds;
|
|
126
|
+
/** Sampling cadence in ms. Default 1000. */
|
|
127
|
+
intervalMs?: number;
|
|
128
|
+
/** Include the built-in event-loop-utilisation signal. Default true. */
|
|
129
|
+
eventLoopUtilization?: boolean;
|
|
130
|
+
/** Fired when the state CHANGES — not on every sample. */
|
|
131
|
+
onStateChange?: (next: PressureState, snapshot: PressureSnapshot) => void;
|
|
132
|
+
/**
|
|
133
|
+
* Refuse with 503 while `saturated`. Default OFF — arc cannot know which
|
|
134
|
+
* routes are sheddable, and refusing a checkout because a dashboard drained
|
|
135
|
+
* the pool is worse than serving it slowly.
|
|
136
|
+
*
|
|
137
|
+
* `exclude` matches `request.url` by prefix. Health routes are ALWAYS exempt:
|
|
138
|
+
* a 503 on `/_health/ready` reads as "process dead", not "process full".
|
|
139
|
+
*/
|
|
140
|
+
shed?: boolean | {
|
|
141
|
+
statusCode?: number;
|
|
142
|
+
retryAfterSeconds?: number;
|
|
143
|
+
exclude?: string[];
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
interface PressureApi {
|
|
147
|
+
state(): PressureState;
|
|
148
|
+
snapshot(): PressureSnapshot;
|
|
149
|
+
/** Register a signal after boot — for modules that resolve their source late. */
|
|
150
|
+
register(signal: PressureSignal): void;
|
|
151
|
+
/** True at `saturated`. The check a handler makes before admitting work. */
|
|
152
|
+
shouldShed(): boolean;
|
|
153
|
+
/**
|
|
154
|
+
* A readiness check for `healthPlugin({ checks })`. NOT auto-registered:
|
|
155
|
+
* flipping readiness pulls the instance from its load balancer — right in a
|
|
156
|
+
* fleet, a self-inflicted outage for a single instance. Unhealthy only at
|
|
157
|
+
* `saturated`; `degraded` still serves.
|
|
158
|
+
*/
|
|
159
|
+
readinessCheck(options?: {
|
|
160
|
+
name?: string;
|
|
161
|
+
critical?: boolean;
|
|
162
|
+
}): HealthCheck;
|
|
163
|
+
}
|
|
164
|
+
declare module "fastify" {
|
|
165
|
+
interface FastifyInstance {
|
|
166
|
+
pressure: PressureApi;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
declare const pressurePlugin: FastifyPluginAsync<PressureOptions>;
|
|
170
|
+
/**
|
|
171
|
+
* `fp()`-wrapped so `fastify.pressure` is visible to the whole app rather than
|
|
172
|
+
* trapped in this plugin's encapsulation context — the named export above is
|
|
173
|
+
* the raw plugin, matching every other arc plugin entry.
|
|
174
|
+
*/
|
|
175
|
+
declare const _default$5: FastifyPluginAsync<PressureOptions>;
|
|
176
|
+
//#endregion
|
|
92
177
|
//#region src/plugins/replyHelpers.d.ts
|
|
93
178
|
declare module "fastify" {
|
|
94
179
|
interface FastifyReply {
|
|
@@ -166,6 +251,6 @@ declare function createRequestIdGenerator(opts?: Pick<RequestIdOptions, "header"
|
|
|
166
251
|
headers: Record<string, string | string[] | undefined>;
|
|
167
252
|
}) => string;
|
|
168
253
|
declare const requestIdPlugin: FastifyPluginAsync<RequestIdOptions>;
|
|
169
|
-
declare const _default$
|
|
254
|
+
declare const _default$7: FastifyPluginAsync<RequestIdOptions>;
|
|
170
255
|
//#endregion
|
|
171
|
-
export { type ArcCore, type ArcCorePluginOptions, type ArcPlugin, type CachingOptions, type CachingRule, type ChangeOperation, type CreatePluginDefinition, type ErrorHandlerOptions, type ErrorMapper, type GracefulShutdownOptions, type HealthCheck, type HealthOptions, type MetricEntry, type MetricsCollector, type MetricsOptions, type PluginMeta, type PluginResourceResult, type RealtimeOptions, type RequestIdOptions, type SSEOptions, type ScheduleDefinition, type ScheduleStats, type SchedulesPluginOptions, type TracingOptions, type VersioningOptions, _default as arcCorePlugin, arcCorePlugin as arcCorePluginFn, _default$1 as cachingPlugin, cachingPlugin as cachingPluginFn, createPlugin, createRequestIdGenerator, defaultIsDuplicateKeyError, errorHandlerPlugin, errorHandlerPlugin as errorHandlerPluginFn, _default$2 as gracefulShutdownPlugin, gracefulShutdownPlugin as gracefulShutdownPluginFn, _default$3 as healthPlugin, healthPlugin as healthPluginFn, _default$4 as metricsPlugin, metricsPlugin as metricsPluginFn, _default$5 as realtimePlugin, realtimePlugin as realtimePluginFn, replyHelpersPlugin, _default$
|
|
256
|
+
export { type ArcCore, type ArcCorePluginOptions, type ArcPlugin, type CachingOptions, type CachingRule, type ChangeOperation, type CreatePluginDefinition, type ErrorHandlerOptions, type ErrorMapper, type GracefulShutdownOptions, type HealthCheck, type HealthOptions, type MetricEntry, type MetricsCollector, type MetricsOptions, type PluginMeta, type PluginResourceResult, type PressureApi, type PressureOptions, type PressureSignal, type PressureSnapshot, type PressureState, type PressureThresholds, type RealtimeOptions, type RequestIdOptions, type SSEOptions, type ScheduleDefinition, type ScheduleStats, type SchedulesPluginOptions, type TracingOptions, type VersioningOptions, _default as arcCorePlugin, arcCorePlugin as arcCorePluginFn, _default$1 as cachingPlugin, cachingPlugin as cachingPluginFn, createPlugin, createRequestIdGenerator, defaultIsDuplicateKeyError, errorHandlerPlugin, errorHandlerPlugin as errorHandlerPluginFn, _default$2 as gracefulShutdownPlugin, gracefulShutdownPlugin as gracefulShutdownPluginFn, _default$3 as healthPlugin, healthPlugin as healthPluginFn, _default$4 as metricsPlugin, metricsPlugin as metricsPluginFn, _default$5 as pressurePlugin, pressurePlugin as pressurePluginFn, _default$6 as realtimePlugin, realtimePlugin as realtimePluginFn, replyHelpersPlugin, _default$7 as requestIdPlugin, requestIdPlugin as requestIdPluginFn, sanitizeRequestId, _default$8 as schedulesPlugin, schedulesPlugin as schedulesPluginFn, _default$9 as ssePlugin, ssePlugin as ssePluginFn, _default$10 as versioningPlugin, versioningPlugin as versioningPluginFn };
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { p as MUTATION_OPERATIONS } from "../constants-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { t as
|
|
7
|
-
import { t as
|
|
8
|
-
import {
|
|
9
|
-
import { n as
|
|
10
|
-
import { n as
|
|
11
|
-
import { n as
|
|
12
|
-
import { n as
|
|
13
|
-
import { t as
|
|
14
|
-
import {
|
|
15
|
-
import { n as
|
|
16
|
-
import { n as
|
|
1
|
+
/*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { p as MUTATION_OPERATIONS } from "../constants-BhzLXCfN.mjs";
|
|
3
|
+
import { arcLog } from "../logger/index.mjs";
|
|
4
|
+
import { c as getOrgId } from "../types-GY4kATJb.mjs";
|
|
5
|
+
import { n as requestContext } from "../requestContext-DzOUGNdY.mjs";
|
|
6
|
+
import { t as hasEvents } from "../typeGuards-B-_jqaMi.mjs";
|
|
7
|
+
import { t as HookSystem } from "../HookSystem-LlPm3Anm.mjs";
|
|
8
|
+
import { t as ResourceRegistry } from "../ResourceRegistry-yuD1Ra53.mjs";
|
|
9
|
+
import { a as requestIdPlugin, i as createRequestIdGenerator, n as health_default, o as requestId_default, s as sanitizeRequestId, t as healthPlugin } from "../health-_Zs3R_Sb.mjs";
|
|
10
|
+
import { n as caching_default, t as cachingPlugin } from "../caching-cN5X9VEL.mjs";
|
|
11
|
+
import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-BbQ1nQdk.mjs";
|
|
12
|
+
import { n as metrics_default, t as metricsPlugin } from "../metrics-5LNPvL3P.mjs";
|
|
13
|
+
import { n as realtime_default, t as realtimePlugin } from "../realtime-Cfl2bVjj.mjs";
|
|
14
|
+
import { t as replyHelpersPlugin } from "../replyHelpers-2jfmMnnV.mjs";
|
|
15
|
+
import { n as schedules_default, t as schedulesPlugin } from "../schedules-BLpZLWGF.mjs";
|
|
16
|
+
import { n as sse_default, t as ssePlugin } from "../sse-DUIP1XH6.mjs";
|
|
17
|
+
import { n as versioning_default, t as versioningPlugin } from "../versioning-BbTs4pwM.mjs";
|
|
17
18
|
import fp from "fastify-plugin";
|
|
19
|
+
import { performance as performance$1 } from "node:perf_hooks";
|
|
18
20
|
//#region src/core/arcCorePlugin.ts
|
|
19
21
|
const arcCorePlugin = async (fastify, opts = {}) => {
|
|
20
22
|
const { emitEvents = true, hookSystem, registry } = opts;
|
|
@@ -205,4 +207,153 @@ var gracefulShutdown_default = fp(gracefulShutdownPlugin, {
|
|
|
205
207
|
fastify: "5.x"
|
|
206
208
|
});
|
|
207
209
|
//#endregion
|
|
208
|
-
|
|
210
|
+
//#region src/plugins/pressure.ts
|
|
211
|
+
/**
|
|
212
|
+
* Admission control — ONE place that decides "are we saturated?".
|
|
213
|
+
*
|
|
214
|
+
* Arc already sheds on event-loop lag (`@fastify/under-pressure`), but lag is
|
|
215
|
+
* LATE: by the time the loop is behind, the work causing it is already
|
|
216
|
+
* admitted. What actually saturates a backend — a drained pool, an undrained
|
|
217
|
+
* queue, an outbox falling behind — is invisible to it. Rate limiting is a
|
|
218
|
+
* different axis: it bounds request FREQUENCY, this bounds concurrent
|
|
219
|
+
* EXPENSIVE WORK.
|
|
220
|
+
*
|
|
221
|
+
* Signals are REGISTERED, not enumerated, because only ELU has a source arc
|
|
222
|
+
* can read today — no kit exposes pool stats, no queue exposes depth. Arc owns
|
|
223
|
+
* the DECISION; signals come from whoever can produce them.
|
|
224
|
+
*
|
|
225
|
+
* `read()` returns SATURATION in [0,1]. Each signal normalises itself: 90% of
|
|
226
|
+
* a pool is nearly fatal, 90% ELU is merely busy, and only the signal's author
|
|
227
|
+
* knows which.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* await app.register(pressurePlugin, {
|
|
232
|
+
* signals: [{ name: 'db-pool', read: () => pool.borrowed / pool.size }],
|
|
233
|
+
* shed: true,
|
|
234
|
+
* });
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
const log = arcLog("pressure");
|
|
238
|
+
/**
|
|
239
|
+
* Event-loop utilisation as saturation — already a [0,1] ratio, and measured
|
|
240
|
+
* ACROSS the interval rather than instantaneously: one lag reading is a spike,
|
|
241
|
+
* utilisation over a second is load.
|
|
242
|
+
*/
|
|
243
|
+
function eluSignal() {
|
|
244
|
+
let previous = performance$1.eventLoopUtilization();
|
|
245
|
+
return {
|
|
246
|
+
name: "event-loop",
|
|
247
|
+
read() {
|
|
248
|
+
const current = performance$1.eventLoopUtilization();
|
|
249
|
+
const delta = performance$1.eventLoopUtilization(current, previous);
|
|
250
|
+
previous = current;
|
|
251
|
+
return delta.utilization;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
const clamp = (n) => Number.isFinite(n) ? Math.min(1, Math.max(0, n)) : 0;
|
|
256
|
+
const pressurePlugin = async (fastify, options) => {
|
|
257
|
+
const degradedAt = options.thresholds?.degraded ?? .8;
|
|
258
|
+
const saturatedAt = options.thresholds?.saturated ?? .95;
|
|
259
|
+
if (degradedAt > saturatedAt) throw new Error(`pressurePlugin: thresholds.degraded (${degradedAt}) is above thresholds.saturated (${saturatedAt}) — 'saturated' would be unreachable and the app would never shed.`);
|
|
260
|
+
const signals = [...options.eventLoopUtilization === false ? [] : [eluSignal()], ...options.signals ?? []];
|
|
261
|
+
/** Signals that threw. Logged once each — a broken reader must not spam. */
|
|
262
|
+
const broken = /* @__PURE__ */ new Set();
|
|
263
|
+
let snapshot = {
|
|
264
|
+
state: "ok",
|
|
265
|
+
worst: void 0,
|
|
266
|
+
signals: {}
|
|
267
|
+
};
|
|
268
|
+
async function sample() {
|
|
269
|
+
const values = {};
|
|
270
|
+
let worst;
|
|
271
|
+
for (const signal of signals) {
|
|
272
|
+
let value = 0;
|
|
273
|
+
try {
|
|
274
|
+
value = clamp(await signal.read());
|
|
275
|
+
broken.delete(signal.name);
|
|
276
|
+
} catch (error) {
|
|
277
|
+
if (!broken.has(signal.name)) {
|
|
278
|
+
broken.add(signal.name);
|
|
279
|
+
log.warn("pressure signal failed to read; treating as 0", {
|
|
280
|
+
signal: signal.name,
|
|
281
|
+
error
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
values[signal.name] = value;
|
|
286
|
+
if (!worst || value > worst.value) worst = {
|
|
287
|
+
name: signal.name,
|
|
288
|
+
value
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
const peak = worst?.value ?? 0;
|
|
292
|
+
const next = peak >= saturatedAt ? "saturated" : peak >= degradedAt ? "degraded" : "ok";
|
|
293
|
+
const previous = snapshot.state;
|
|
294
|
+
snapshot = {
|
|
295
|
+
state: next,
|
|
296
|
+
worst,
|
|
297
|
+
signals: values
|
|
298
|
+
};
|
|
299
|
+
if (next !== previous) {
|
|
300
|
+
log.info("pressure state changed", {
|
|
301
|
+
from: previous,
|
|
302
|
+
to: next,
|
|
303
|
+
worst
|
|
304
|
+
});
|
|
305
|
+
options.onStateChange?.(next, snapshot);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
const timer = setInterval(() => {
|
|
309
|
+
sample();
|
|
310
|
+
}, options.intervalMs ?? 1e3);
|
|
311
|
+
timer.unref?.();
|
|
312
|
+
fastify.addHook("onClose", async () => clearInterval(timer));
|
|
313
|
+
fastify.decorate("pressure", {
|
|
314
|
+
state: () => snapshot.state,
|
|
315
|
+
snapshot: () => snapshot,
|
|
316
|
+
register: (signal) => {
|
|
317
|
+
signals.push(signal);
|
|
318
|
+
},
|
|
319
|
+
shouldShed: () => snapshot.state === "saturated",
|
|
320
|
+
readinessCheck: (checkOptions) => ({
|
|
321
|
+
name: checkOptions?.name ?? "pressure",
|
|
322
|
+
critical: checkOptions?.critical ?? true,
|
|
323
|
+
check: () => snapshot.state !== "saturated"
|
|
324
|
+
})
|
|
325
|
+
});
|
|
326
|
+
if (options.shed) {
|
|
327
|
+
const shedConfig = options.shed === true ? {} : options.shed;
|
|
328
|
+
const statusCode = shedConfig.statusCode ?? 503;
|
|
329
|
+
const retryAfter = shedConfig.retryAfterSeconds ?? 1;
|
|
330
|
+
const exempt = [
|
|
331
|
+
"/_health",
|
|
332
|
+
"/health",
|
|
333
|
+
...shedConfig.exclude ?? []
|
|
334
|
+
];
|
|
335
|
+
fastify.addHook("onRequest", async (request, reply) => {
|
|
336
|
+
if (snapshot.state !== "saturated") return;
|
|
337
|
+
const url = request.url;
|
|
338
|
+
if (exempt.some((prefix) => url.startsWith(prefix))) return;
|
|
339
|
+
reply.header("Retry-After", String(retryAfter));
|
|
340
|
+
return reply.code(statusCode).send({
|
|
341
|
+
code: "arc.unavailable",
|
|
342
|
+
message: "Server is at capacity — retry shortly.",
|
|
343
|
+
status: statusCode
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
await sample();
|
|
348
|
+
};
|
|
349
|
+
/**
|
|
350
|
+
* `fp()`-wrapped so `fastify.pressure` is visible to the whole app rather than
|
|
351
|
+
* trapped in this plugin's encapsulation context — the named export above is
|
|
352
|
+
* the raw plugin, matching every other arc plugin entry.
|
|
353
|
+
*/
|
|
354
|
+
var pressure_default = fp(pressurePlugin, {
|
|
355
|
+
name: "arc-pressure",
|
|
356
|
+
fastify: "5.x"
|
|
357
|
+
});
|
|
358
|
+
//#endregion
|
|
359
|
+
export { arcCorePlugin_default as arcCorePlugin, arcCorePlugin as arcCorePluginFn, caching_default as cachingPlugin, cachingPlugin as cachingPluginFn, createPlugin, createRequestIdGenerator, defaultIsDuplicateKeyError, errorHandlerPlugin, errorHandlerPlugin as errorHandlerPluginFn, gracefulShutdown_default as gracefulShutdownPlugin, gracefulShutdownPlugin as gracefulShutdownPluginFn, health_default as healthPlugin, healthPlugin as healthPluginFn, metrics_default as metricsPlugin, metricsPlugin as metricsPluginFn, pressure_default as pressurePlugin, pressurePlugin as pressurePluginFn, realtime_default as realtimePlugin, realtimePlugin as realtimePluginFn, replyHelpersPlugin, requestId_default as requestIdPlugin, requestIdPlugin as requestIdPluginFn, sanitizeRequestId, schedules_default as schedulesPlugin, schedulesPlugin as schedulesPluginFn, sse_default as ssePlugin, ssePlugin as ssePluginFn, versioning_default as versioningPlugin, versioningPlugin as versioningPluginFn };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as hasEvents } from "../typeGuards-
|
|
1
|
+
/*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as hasEvents } from "../typeGuards-B-_jqaMi.mjs";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/plugins/response-cache.ts
|
|
5
5
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
1
|
+
/*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/plugins/tracing.ts
|
|
@@ -59,7 +59,7 @@ try {
|
|
|
59
59
|
function createTracerProvider(options) {
|
|
60
60
|
if (!isAvailable || !NodeTracerProvider || !BatchSpanProcessor || !OTLPTraceExporter) return null;
|
|
61
61
|
const { serviceName = "@classytic/arc", serviceVersion, exporterUrl = "http://localhost:4318/v1/traces" } = options;
|
|
62
|
-
const resolvedVersion = serviceVersion ?? "2.
|
|
62
|
+
const resolvedVersion = serviceVersion ?? "2.35.0";
|
|
63
63
|
const exporter = new OTLPTraceExporter({ url: exporterUrl });
|
|
64
64
|
const provider = new NodeTracerProvider({ resource: { attributes: {
|
|
65
65
|
"service.name": serviceName,
|