@capixjs/core 0.1.0-alpha.8 → 0.1.0-beta.1
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/capability.d.ts +34 -14
- package/dist/capability.d.ts.map +1 -1
- package/dist/capability.js +14 -1
- package/dist/capability.js.map +1 -1
- package/dist/enhancers.d.ts +26 -10
- package/dist/enhancers.d.ts.map +1 -1
- package/dist/enhancers.js +13 -53
- package/dist/enhancers.js.map +1 -1
- package/dist/event-bus.d.ts.map +1 -1
- package/dist/event-bus.js +11 -2
- package/dist/event-bus.js.map +1 -1
- package/dist/execution-engine.d.ts +23 -0
- package/dist/execution-engine.d.ts.map +1 -1
- package/dist/execution-engine.js +28 -1
- package/dist/execution-engine.js.map +1 -1
- package/dist/http-shutdown.d.ts +21 -0
- package/dist/http-shutdown.d.ts.map +1 -0
- package/dist/http-shutdown.js +35 -0
- package/dist/http-shutdown.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +7 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +7 -1
- package/dist/server.js.map +1 -1
- package/dist/stores.d.ts +53 -0
- package/dist/stores.d.ts.map +1 -0
- package/dist/stores.js +80 -0
- package/dist/stores.js.map +1 -0
- package/package.json +14 -3
package/dist/capability.d.ts
CHANGED
|
@@ -2,32 +2,52 @@
|
|
|
2
2
|
* capability.ts — the core capability primitive
|
|
3
3
|
* Depends on: errors.ts, context.ts, guards.ts, zod
|
|
4
4
|
*/
|
|
5
|
-
import type {
|
|
5
|
+
import type { ZodType, output as ZodOutput } from 'zod';
|
|
6
6
|
import type { BaseContext } from './context.js';
|
|
7
7
|
import type { AnyGuard, AnyInputGuard, InputGuard, NarrowContext } from './guards.js';
|
|
8
8
|
declare const CAPABILITY_BRAND: unique symbol;
|
|
9
9
|
export type Intent = 'query' | 'mutation' | 'update' | 'replace' | 'delete';
|
|
10
|
+
/**
|
|
11
|
+
* Resolves a capability's effective intent: an intent passed explicitly to
|
|
12
|
+
* `capability()` wins; otherwise it is inferred from the capability's key
|
|
13
|
+
* name in the group tree (`getUser` → query, `deleteUser` → delete).
|
|
14
|
+
*
|
|
15
|
+
* This is the rule every transport uses — REST for route methods, MCP for
|
|
16
|
+
* tool annotations, GraphQL for query/mutation placement. Transport authors
|
|
17
|
+
* should call this instead of reading `intent` directly, so explicit and
|
|
18
|
+
* inferred intents behave identically across transports.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveIntent(cap: AnyCapability, key: string): Intent;
|
|
10
21
|
/** Infers capability intent from its key name in the parent group. */
|
|
11
22
|
export declare function inferIntent(key: string): Intent;
|
|
12
23
|
export type Enhancer = <TInput, TOutput, TContext extends BaseContext>(cap: Capability<TInput, TOutput, TContext>) => Capability<TInput, TOutput, TContext>;
|
|
13
24
|
export type Resolver<TInput, TOutput, TContext extends BaseContext> = (input: TInput, ctx: TContext) => TOutput | Promise<TOutput>;
|
|
14
25
|
export type Capability<TInput, TOutput, TContext extends BaseContext> = {
|
|
26
|
+
/** @internal Brand field — use {@link isCapability} instead of reading this. */
|
|
15
27
|
readonly _capix: true;
|
|
16
28
|
readonly [CAPABILITY_BRAND]: true;
|
|
17
29
|
readonly name: string;
|
|
30
|
+
/** @internal Phantom type field for inference — never set at runtime. Use {@link InferInput}. */
|
|
18
31
|
readonly _input: TInput;
|
|
32
|
+
/** @internal Phantom type field for inference — never set at runtime. Use {@link InferOutput}. */
|
|
19
33
|
readonly _output: TOutput;
|
|
34
|
+
/** @internal Phantom type field for inference — never set at runtime. Use {@link InferContext}. */
|
|
20
35
|
readonly _context: TContext;
|
|
21
|
-
readonly inputSchema:
|
|
22
|
-
readonly outputSchema:
|
|
36
|
+
readonly inputSchema: ZodType | null;
|
|
37
|
+
readonly outputSchema: ZodType | null;
|
|
23
38
|
readonly guards: ReadonlyArray<AnyGuard>;
|
|
24
39
|
readonly inputGuards: ReadonlyArray<AnyInputGuard>;
|
|
40
|
+
/**
|
|
41
|
+
* The intent passed to capability(), or 'mutation' when defaulted.
|
|
42
|
+
* Transports should use {@link resolveIntent} rather than reading this —
|
|
43
|
+
* it applies key-name inference when no explicit intent was given.
|
|
44
|
+
*/
|
|
25
45
|
readonly intent: Intent;
|
|
26
|
-
/** True when intent was explicitly passed to capability()
|
|
46
|
+
/** @internal True when intent was explicitly passed to capability(). Use {@link resolveIntent}. */
|
|
27
47
|
readonly _intentExplicit: boolean;
|
|
28
48
|
/**
|
|
29
|
-
* Set by compileRegistry when inputSchema is a z.object({}) with no
|
|
30
|
-
*
|
|
49
|
+
* @internal Set by compileRegistry when inputSchema is a z.object({}) with no
|
|
50
|
+
* keys — the execution engine skips input validation entirely.
|
|
31
51
|
*/
|
|
32
52
|
readonly _skipValidation: boolean;
|
|
33
53
|
/**
|
|
@@ -55,9 +75,9 @@ export type Capability<TInput, TOutput, TContext extends BaseContext> = {
|
|
|
55
75
|
*/
|
|
56
76
|
resolve: (input: TInput, ctx: BaseContext) => Promise<TOutput>;
|
|
57
77
|
/**
|
|
58
|
-
* Raw resolver — no guards.
|
|
59
|
-
*
|
|
60
|
-
* Do not call
|
|
78
|
+
* Raw resolver — no guards. Extension-author API: enhancers wrap this to
|
|
79
|
+
* avoid re-running guards, and the execution engine calls it after running
|
|
80
|
+
* guards itself. Do not call from application code — use resolve() instead.
|
|
61
81
|
*/
|
|
62
82
|
_resolverOnly: (input: TInput, ctx: TContext) => Promise<TOutput>;
|
|
63
83
|
/**
|
|
@@ -78,7 +98,7 @@ export type Capability<TInput, TOutput, TContext extends BaseContext> = {
|
|
|
78
98
|
*/
|
|
79
99
|
inputGuard(g: InputGuard<TInput, TContext>): Capability<TInput, TOutput, TContext>;
|
|
80
100
|
enhance(e: Enhancer): Capability<TInput, TOutput, TContext>;
|
|
81
|
-
output<O>(schema:
|
|
101
|
+
output<O>(schema: ZodType<O>): Capability<TInput, O, TContext>;
|
|
82
102
|
};
|
|
83
103
|
export type AnyCapability = Capability<any, any, any>;
|
|
84
104
|
/**
|
|
@@ -116,9 +136,9 @@ export declare function capability<TOutput, TContext extends BaseContext = BaseC
|
|
|
116
136
|
/** No-input capability with explicit intent. */
|
|
117
137
|
export declare function capability<TOutput, TContext extends BaseContext = BaseContext>(resolver: (input: undefined, ctx: TContext) => TOutput | Promise<TOutput>, intent: Intent): Capability<undefined, TOutput, TContext>;
|
|
118
138
|
/** With typed input schema. */
|
|
119
|
-
export declare function capability<TSchema extends
|
|
139
|
+
export declare function capability<TSchema extends ZodType, TOutput, TContext extends BaseContext = BaseContext>(schema: TSchema, resolver: Resolver<ZodOutput<TSchema>, TOutput, TContext>): Capability<ZodOutput<TSchema>, TOutput, TContext>;
|
|
120
140
|
/** With typed input schema and explicit intent. */
|
|
121
|
-
export declare function capability<TSchema extends
|
|
141
|
+
export declare function capability<TSchema extends ZodType, TOutput, TContext extends BaseContext = BaseContext>(schema: TSchema, resolver: Resolver<ZodOutput<TSchema>, TOutput, TContext>, intent: Intent): Capability<ZodOutput<TSchema>, TOutput, TContext>;
|
|
122
142
|
/** Extract the validated input type from a Capability. */
|
|
123
143
|
export type InferInput<TCap extends AnyCapability> = TCap['_input'];
|
|
124
144
|
/** Extract the resolved output type from a Capability. */
|
|
@@ -140,8 +160,8 @@ export declare function compileRegistry(tree: GroupTree, prefix?: string): Capab
|
|
|
140
160
|
export type ScopedCapabilityFactory<TContext extends BaseContext> = {
|
|
141
161
|
<TOutput>(resolver: (input: undefined, ctx: TContext) => TOutput | Promise<TOutput>): Capability<undefined, TOutput, TContext>;
|
|
142
162
|
<TOutput>(resolver: (input: undefined, ctx: TContext) => TOutput | Promise<TOutput>, intent: Intent): Capability<undefined, TOutput, TContext>;
|
|
143
|
-
<TSchema extends
|
|
144
|
-
<TSchema extends
|
|
163
|
+
<TSchema extends ZodType, TOutput>(schema: TSchema, resolver: Resolver<ZodOutput<TSchema>, TOutput, TContext>): Capability<ZodOutput<TSchema>, TOutput, TContext>;
|
|
164
|
+
<TSchema extends ZodType, TOutput>(schema: TSchema, resolver: Resolver<ZodOutput<TSchema>, TOutput, TContext>, intent: Intent): Capability<ZodOutput<TSchema>, TOutput, TContext>;
|
|
145
165
|
};
|
|
146
166
|
export declare namespace capability {
|
|
147
167
|
/**
|
package/dist/capability.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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"}
|
package/dist/capability.js
CHANGED
|
@@ -9,6 +9,19 @@ const MUTATION_PREFIXES = ['create', 'add', 'new'];
|
|
|
9
9
|
const UPDATE_PREFIXES = ['update', 'edit', 'patch', 'modify'];
|
|
10
10
|
const REPLACE_PREFIXES = ['replace', 'set', 'put'];
|
|
11
11
|
const DELETE_PREFIXES = ['delete', 'remove', 'destroy', 'cancel'];
|
|
12
|
+
/**
|
|
13
|
+
* Resolves a capability's effective intent: an intent passed explicitly to
|
|
14
|
+
* `capability()` wins; otherwise it is inferred from the capability's key
|
|
15
|
+
* name in the group tree (`getUser` → query, `deleteUser` → delete).
|
|
16
|
+
*
|
|
17
|
+
* This is the rule every transport uses — REST for route methods, MCP for
|
|
18
|
+
* tool annotations, GraphQL for query/mutation placement. Transport authors
|
|
19
|
+
* should call this instead of reading `intent` directly, so explicit and
|
|
20
|
+
* inferred intents behave identically across transports.
|
|
21
|
+
*/
|
|
22
|
+
export function resolveIntent(cap, key) {
|
|
23
|
+
return cap._intentExplicit ? cap.intent : inferIntent(key);
|
|
24
|
+
}
|
|
12
25
|
/** Infers capability intent from its key name in the parent group. */
|
|
13
26
|
export function inferIntent(key) {
|
|
14
27
|
const lower = key.toLowerCase();
|
|
@@ -134,7 +147,7 @@ export function capability(...args) {
|
|
|
134
147
|
const [first, second, thirdArg] = args;
|
|
135
148
|
const isZodSchema = first !== null &&
|
|
136
149
|
typeof first === 'object' &&
|
|
137
|
-
'_def' in first;
|
|
150
|
+
('_zod' in first || '_def' in first);
|
|
138
151
|
if (!isZodSchema) {
|
|
139
152
|
// No-schema overloads: capability(resolver) | capability(resolver, intent)
|
|
140
153
|
const explicitIntent = typeof second === 'string' ? second : undefined;
|
package/dist/capability.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;AAQxD,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAU,CAAC;AACzI,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAC5D,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAU,CAAC;AACvE,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAC5D,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAC;AAE3E,sEAAsE;AACtE,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,OAAO,CAAC;IAC1C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,iBAAiB,EAAE,CAAC;QAClC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,UAAU,CAAC;IAC7C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;QAChC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,QAAQ,CAAC;IAC3C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,SAAS,CAAC;IAC5C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;QAChC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,QAAQ,CAAC;IAC3C,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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"}
|
package/dist/enhancers.d.ts
CHANGED
|
@@ -3,14 +3,16 @@
|
|
|
3
3
|
* Depends on: capability.ts
|
|
4
4
|
*/
|
|
5
5
|
import type { Enhancer } from './capability.js';
|
|
6
|
+
import type { CacheStore, RateLimitStore } from './stores.js';
|
|
6
7
|
/** Pass-through for type inference. */
|
|
7
8
|
export declare function defineEnhancer(fn: Enhancer): Enhancer;
|
|
8
9
|
/** Logs capability name, duration, and outcome. Falls back to console if ctx has no logger. */
|
|
9
10
|
export declare const withLogging: Enhancer;
|
|
10
11
|
export type CacheOptions = {
|
|
11
12
|
/**
|
|
12
|
-
* Maximum number of cached entries
|
|
13
|
-
* when the limit is reached.
|
|
13
|
+
* Maximum number of cached entries in the default in-memory store.
|
|
14
|
+
* Least-recently-used entries are evicted when the limit is reached.
|
|
15
|
+
* Default: 1_000. Ignored when a custom `store` is provided.
|
|
14
16
|
*/
|
|
15
17
|
readonly maxSize?: number;
|
|
16
18
|
/**
|
|
@@ -25,8 +27,15 @@ export type CacheOptions = {
|
|
|
25
27
|
* withCache(30, { keyFn: (input, ctx) => `${(ctx as AppContext).user?.id}:${JSON.stringify(input)}` })
|
|
26
28
|
*/
|
|
27
29
|
readonly keyFn?: (input: unknown, ctx: unknown) => string;
|
|
30
|
+
/**
|
|
31
|
+
* Cache backend. Defaults to an in-memory LRU, which is per-process — behind
|
|
32
|
+
* a load balancer each instance caches independently. Use a shared store
|
|
33
|
+
* (e.g. redisCacheStore from @capixjs/store-redis) for multi-instance
|
|
34
|
+
* deployments.
|
|
35
|
+
*/
|
|
36
|
+
readonly store?: CacheStore;
|
|
28
37
|
};
|
|
29
|
-
/**
|
|
38
|
+
/** Caches resolver results. Key = capabilityName:keyFn(input, ctx). TTL in seconds. */
|
|
30
39
|
export declare function withCache(ttlSeconds: number, options?: CacheOptions): Enhancer;
|
|
31
40
|
/** Rejects if the resolver exceeds the given milliseconds. */
|
|
32
41
|
export declare function withTimeout(ms: number): Enhancer;
|
|
@@ -49,16 +58,23 @@ export type RateLimitOptions = {
|
|
|
49
58
|
*/
|
|
50
59
|
readonly keyFn?: (input: unknown, ctx: unknown) => string;
|
|
51
60
|
/**
|
|
52
|
-
* Maximum number of distinct keys tracked
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
61
|
+
* Maximum number of distinct keys tracked by the default in-memory store.
|
|
62
|
+
* Default: 10_000. When exceeded, keys with no activity in the current
|
|
63
|
+
* window are swept; if every key is still active, the oldest-tracked keys
|
|
64
|
+
* are evicted (their rate-limit state resets). This bounds memory when
|
|
65
|
+
* keyFn has unbounded cardinality (per-user, per-IP).
|
|
66
|
+
* Ignored when a custom `store` is provided.
|
|
58
67
|
*/
|
|
59
68
|
readonly maxKeys?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Rate-limit backend. Defaults to an in-memory sliding window, which is
|
|
71
|
+
* per-process — N instances behind a load balancer enforce N times the
|
|
72
|
+
* intended limit. Use a shared store (e.g. redisRateLimitStore from
|
|
73
|
+
* @capixjs/store-redis) for multi-instance deployments.
|
|
74
|
+
*/
|
|
75
|
+
readonly store?: RateLimitStore;
|
|
60
76
|
};
|
|
61
|
-
/**
|
|
77
|
+
/** Rate limiter. Throws 429 with retryAfter meta when the limit is exceeded. */
|
|
62
78
|
export declare function withRateLimit(options: RateLimitOptions): Enhancer;
|
|
63
79
|
export type RollbackFn = () => unknown;
|
|
64
80
|
/**
|
package/dist/enhancers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enhancers.d.ts","sourceRoot":"","sources":["../src/enhancers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,iBAAiB,CAAC;AAI/D,uCAAuC;AACvC,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,GAAG,QAAQ,CAErD;AAED,+FAA+F;AAC/F,eAAO,MAAM,WAAW,EAiBjB,QAAQ,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG;IACzB
|
|
1
|
+
{"version":3,"file":"enhancers.d.ts","sourceRoot":"","sources":["../src/enhancers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,iBAAiB,CAAC;AAI/D,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9D,uCAAuC;AACvC,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,GAAG,QAAQ,CAErD;AAED,+FAA+F;AAC/F,eAAO,MAAM,WAAW,EAiBjB,QAAQ,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG;IACzB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IAC1D;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;CAC7B,CAAC;AAEF,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,QAAQ,CAkBlF;AAED,8DAA8D;AAC9D,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,CAqBhD;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,SAAM,GAAG,QAAQ,CAoBtE;AAMD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IAC1D;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,QAAQ,CAwBjE;AAMD,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC;AAEvC;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG;IAChC,QAAQ,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,UAAU,KAAK,IAAI,CAAC;CAC/C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,YAAY,EAsBlB,QAAQ,CAAC;AAMhB,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC7D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7E;AAED,8CAA8C;AAC9C,eAAO,MAAM,uBAAuB,EAAE,gBAOrC,CAAC;AAEF,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,SAAS,EAAE,gBAAgB,GAAG,QAAQ,CAkBjE;AAMD,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;AAMF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,qBAAqB,GAAG,QAAQ,CA+C3E"}
|
package/dist/enhancers.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { defineError, isFrameworkError } from './errors.js';
|
|
6
6
|
import { defaultErrors } from './errors.js';
|
|
7
|
+
import { createMemoryCacheStore, createMemoryRateLimitStore } from './stores.js';
|
|
7
8
|
/** Pass-through for type inference. */
|
|
8
9
|
export function defineEnhancer(fn) {
|
|
9
10
|
return fn;
|
|
@@ -27,33 +28,19 @@ export const withLogging = defineEnhancer((cap) => ({
|
|
|
27
28
|
}
|
|
28
29
|
},
|
|
29
30
|
}));
|
|
30
|
-
/**
|
|
31
|
+
/** Caches resolver results. Key = capabilityName:keyFn(input, ctx). TTL in seconds. */
|
|
31
32
|
export function withCache(ttlSeconds, options = {}) {
|
|
32
|
-
const maxSize = options.maxSize ?? 1_000;
|
|
33
33
|
const keyFn = options.keyFn;
|
|
34
|
-
const store =
|
|
34
|
+
const store = options.store ?? createMemoryCacheStore(options.maxSize !== undefined ? { maxSize: options.maxSize } : {});
|
|
35
35
|
return defineEnhancer((cap) => ({
|
|
36
36
|
...cap,
|
|
37
37
|
resolve: async (input, ctx) => {
|
|
38
38
|
const key = `${cap.name}:${keyFn ? keyFn(input, ctx) : JSON.stringify(input)}`;
|
|
39
|
-
const cached = store.get(key);
|
|
40
|
-
if (cached !== undefined)
|
|
41
|
-
|
|
42
|
-
// Refresh recency for LRU ordering
|
|
43
|
-
store.delete(key);
|
|
44
|
-
store.set(key, cached);
|
|
45
|
-
return cached.value;
|
|
46
|
-
}
|
|
47
|
-
store.delete(key); // expired — don't let dead entries occupy capacity
|
|
48
|
-
}
|
|
39
|
+
const cached = await store.get(key);
|
|
40
|
+
if (cached !== undefined)
|
|
41
|
+
return cached;
|
|
49
42
|
const result = await cap._resolverOnly(input, ctx);
|
|
50
|
-
|
|
51
|
-
// Evict least-recently-used (first key in Map insertion order)
|
|
52
|
-
const oldest = store.keys().next().value;
|
|
53
|
-
if (oldest !== undefined)
|
|
54
|
-
store.delete(oldest);
|
|
55
|
-
}
|
|
56
|
-
store.set(key, { value: result, expiresAt: Date.now() + ttlSeconds * 1000 });
|
|
43
|
+
await store.set(key, result, ttlSeconds * 1000);
|
|
57
44
|
return result;
|
|
58
45
|
},
|
|
59
46
|
}));
|
|
@@ -101,50 +88,23 @@ export function withRetry(maxAttempts, delayMs = 100) {
|
|
|
101
88
|
},
|
|
102
89
|
}));
|
|
103
90
|
}
|
|
104
|
-
/**
|
|
91
|
+
/** Rate limiter. Throws 429 with retryAfter meta when the limit is exceeded. */
|
|
105
92
|
export function withRateLimit(options) {
|
|
106
93
|
const { limit, windowMs, keyFn } = options;
|
|
107
|
-
const
|
|
108
|
-
const store = new Map();
|
|
109
|
-
function evictStale(now) {
|
|
110
|
-
const cutoff = now - windowMs;
|
|
111
|
-
for (const [k, ts] of store) {
|
|
112
|
-
const last = ts[ts.length - 1];
|
|
113
|
-
if (last === undefined || last <= cutoff)
|
|
114
|
-
store.delete(k);
|
|
115
|
-
}
|
|
116
|
-
// Every key still active — hard-cap by evicting oldest-tracked keys
|
|
117
|
-
if (store.size > maxKeys) {
|
|
118
|
-
for (const k of store.keys()) {
|
|
119
|
-
store.delete(k);
|
|
120
|
-
if (store.size <= maxKeys)
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
94
|
+
const store = options.store ?? createMemoryRateLimitStore(options.maxKeys !== undefined ? { maxKeys: options.maxKeys } : {});
|
|
125
95
|
return defineEnhancer((cap) => ({
|
|
126
96
|
...cap,
|
|
127
97
|
resolve: async (input, ctx) => {
|
|
128
98
|
const key = keyFn ? keyFn(input, ctx) : cap.name;
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
evictStale(now);
|
|
133
|
-
let timestamps = store.get(key) ?? [];
|
|
134
|
-
timestamps = timestamps.filter((t) => t > windowStart);
|
|
135
|
-
if (timestamps.length >= limit) {
|
|
136
|
-
// Find the oldest timestamp in the window — client can retry after it expires
|
|
137
|
-
const oldestInWindow = timestamps[0] ?? now;
|
|
138
|
-
const resetAt = oldestInWindow + windowMs;
|
|
139
|
-
const retryAfter = Math.ceil((resetAt - now) / 1000);
|
|
99
|
+
const decision = await store.hit(key, limit, windowMs);
|
|
100
|
+
if (!decision.allowed) {
|
|
101
|
+
const resetAt = Date.now() + decision.retryAfterMs;
|
|
140
102
|
throw defaultErrors.TooManyRequests({
|
|
141
|
-
retryAfter,
|
|
103
|
+
retryAfter: Math.ceil(decision.retryAfterMs / 1000),
|
|
142
104
|
resetAt: new Date(resetAt).toISOString(),
|
|
143
105
|
limit,
|
|
144
106
|
});
|
|
145
107
|
}
|
|
146
|
-
timestamps.push(now);
|
|
147
|
-
store.set(key, timestamps);
|
|
148
108
|
return cap._resolverOnly(input, ctx);
|
|
149
109
|
},
|
|
150
110
|
}));
|
package/dist/enhancers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enhancers.js","sourceRoot":"","sources":["../src/enhancers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"enhancers.js","sourceRoot":"","sources":["../src/enhancers.ts"],"names":[],"mappings":"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"}
|
package/dist/event-bus.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,MAAM,MAAM,gBAAgB,CAAC,KAAK,GAAG,OAAO,IAAI;IAC9C,wEAAwE;IACxE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,QAAQ,CAAC,OAAO,SAAS,QAAQ,IAAI;IAC/C,kEAAkE;IAClE,OAAO,CAAC,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAE5E,SAAS,EAAE;QACT;;;;;;;;;;;;;;;;;;;WAmBG;QACH,CAAC,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,EAC/B,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EACnC,OAAO,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GACrC,MAAM,IAAI,CAAC;QACd;;;;;WAKG;QACH,CAAC,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,EAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EACnC,OAAO,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GACrC,MAAM,IAAI,CAAC;KACf,CAAC;IAEF,uEAAuE;IACvE,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvC,uFAAuF;IACvF,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACrF,CAAC;AAOF,wBAAgB,cAAc,CAAC,OAAO,SAAS,QAAQ,KAAK,QAAQ,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,MAAM,MAAM,gBAAgB,CAAC,KAAK,GAAG,OAAO,IAAI;IAC9C,wEAAwE;IACxE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,QAAQ,CAAC,OAAO,SAAS,QAAQ,IAAI;IAC/C,kEAAkE;IAClE,OAAO,CAAC,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAE5E,SAAS,EAAE;QACT;;;;;;;;;;;;;;;;;;;WAmBG;QACH,CAAC,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,EAC/B,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EACnC,OAAO,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GACrC,MAAM,IAAI,CAAC;QACd;;;;;WAKG;QACH,CAAC,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,EAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EACnC,OAAO,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GACrC,MAAM,IAAI,CAAC;KACf,CAAC;IAEF,uEAAuE;IACvE,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvC,uFAAuF;IACvF,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACrF,CAAC;AAOF,wBAAgB,cAAc,CAAC,OAAO,SAAS,QAAQ,KAAK,QAAQ,CAAC,OAAO,CAAC,CAgE5E"}
|
package/dist/event-bus.js
CHANGED
|
@@ -26,8 +26,17 @@ export function createEventBus() {
|
|
|
26
26
|
if (!eventListeners)
|
|
27
27
|
return;
|
|
28
28
|
for (const sub of eventListeners.values()) {
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
// Isolate subscribers: a throwing handler (or filter) must not abort
|
|
30
|
+
// delivery to the remaining subscribers, and must never propagate into
|
|
31
|
+
// the publisher — a resolver that emits after a successful mutation
|
|
32
|
+
// would otherwise turn into a 500 after the write already committed.
|
|
33
|
+
try {
|
|
34
|
+
if (!sub.filter || sub.filter(data)) {
|
|
35
|
+
sub.handler(data);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
console.error(`[capix] Event subscriber for '${event}' threw:`, err);
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
},
|
package/dist/event-bus.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiEH,MAAM,UAAU,cAAc;IAC5B,0CAA0C;IAC1C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAqC,CAAC;IAE/D,SAAS,aAAa,CACpB,QAAyB,EACzB,KAAa,EACb,OAAgC,EAChC,MAAgD;QAEhD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAC3D,SAAS,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACzD,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,CAAC,KAAa,EAAE,IAAa;YAClC,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC5C,IAAI,CAAC,cAAc;gBAAE,OAAO;YAC5B,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1C,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiEH,MAAM,UAAU,cAAc;IAC5B,0CAA0C;IAC1C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAqC,CAAC;IAE/D,SAAS,aAAa,CACpB,QAAyB,EACzB,KAAa,EACb,OAAgC,EAChC,MAAgD;QAEhD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAC3D,SAAS,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACzD,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,CAAC,KAAa,EAAE,IAAa;YAClC,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC5C,IAAI,CAAC,cAAc;gBAAE,OAAO;YAC5B,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1C,qEAAqE;gBACrE,uEAAuE;gBACvE,oEAAoE;gBACpE,qEAAqE;gBACrE,IAAI,CAAC;oBACH,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;wBACpC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBACpB,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,KAAK,UAAU,EAAE,GAAG,CAAC,CAAC;gBACvE,CAAC;YACH,CAAC;QACH,CAAC;QAED,SAAS,CACP,eAAuB,EACvB,cAAkD,EAClD,gBAAwE,EACxE,YAAwC;YAExC,IAAI,OAAO,cAAc,KAAK,UAAU,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,gBAAyD,CAAC;gBACvE,OAAO,aAAa,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAChF,CAAC;YACD,OAAO,aAAa,CAClB,eAAe,EACf,cAAc,EACd,gBAA2C,EAC3C,YAAY,EAAE,MAAM,CACrB,CAAC;QACJ,CAAC;QAED,cAAc,CAAC,QAAgB;YAC7B,KAAK,MAAM,cAAc,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;gBAChD,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,WAAW,CAAC,QAAgB,EAAE,KAAa;YACzC,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QACtD,CAAC;KAC8B,CAAC;AACpC,CAAC"}
|
|
@@ -26,10 +26,33 @@ export type CapabilityResponse = {
|
|
|
26
26
|
readonly error: SerializedError;
|
|
27
27
|
};
|
|
28
28
|
export type InvokeFn = (req: CapabilityRequest) => Promise<CapabilityResponse>;
|
|
29
|
+
/**
|
|
30
|
+
* Lifecycle hooks observing every capability invocation on every transport.
|
|
31
|
+
*
|
|
32
|
+
* Hooks receive the same CapabilityRequest object across the request's
|
|
33
|
+
* lifecycle — key a WeakMap on it to correlate onRequest with the outcome
|
|
34
|
+
* (e.g. to close a tracing span). Hook errors are caught and logged; they
|
|
35
|
+
* never affect the request.
|
|
36
|
+
*/
|
|
37
|
+
export type LifecycleHooks = {
|
|
38
|
+
/** Fires when a request enters the engine, before lookup and validation. */
|
|
39
|
+
readonly onRequest?: (req: CapabilityRequest) => void;
|
|
40
|
+
/** Fires after a successful resolve. */
|
|
41
|
+
readonly onResponse?: (req: CapabilityRequest, info: {
|
|
42
|
+
durationMs: number;
|
|
43
|
+
data: unknown;
|
|
44
|
+
}) => void;
|
|
45
|
+
/** Fires on any failure: unknown capability, guard rejection, validation, resolver throw. */
|
|
46
|
+
readonly onError?: (req: CapabilityRequest, info: {
|
|
47
|
+
durationMs: number;
|
|
48
|
+
error: SerializedError;
|
|
49
|
+
}) => void;
|
|
50
|
+
};
|
|
29
51
|
export type ExecutionEngineOptions = {
|
|
30
52
|
readonly registry: CapabilityRegistry;
|
|
31
53
|
readonly buildContext: ContextBuilder;
|
|
32
54
|
readonly isDevelopment?: boolean;
|
|
55
|
+
readonly hooks?: LifecycleHooks;
|
|
33
56
|
};
|
|
34
57
|
/**
|
|
35
58
|
* Creates the invoke function that runs the full capability pipeline:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-engine.d.ts","sourceRoot":"","sources":["../src/execution-engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAe,cAAc,EAAc,MAAM,cAAc,CAAC;AAI5E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC7C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;CAAE,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAE/E,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"execution-engine.d.ts","sourceRoot":"","sources":["../src/execution-engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAe,cAAc,EAAc,MAAM,cAAc,CAAC;AAI5E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC7C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;CAAE,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAE/E;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACtD,wCAAwC;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACpG,6FAA6F;IAC7F,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,eAAe,CAAA;KAAE,KAAK,IAAI,CAAC;CAC3G,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AA8BF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,QAAQ,CAyM/E"}
|
package/dist/execution-engine.js
CHANGED
|
@@ -35,7 +35,7 @@ function toErrorResponse(err, isDevelopment) {
|
|
|
35
35
|
*/
|
|
36
36
|
export function createExecutionEngine(options) {
|
|
37
37
|
const { registry, buildContext, isDevelopment = false } = options;
|
|
38
|
-
|
|
38
|
+
const invoke = async function invoke(req) {
|
|
39
39
|
// 1. Look up capability
|
|
40
40
|
const cap = registry.get(req.capability);
|
|
41
41
|
if (!cap) {
|
|
@@ -206,5 +206,32 @@ export function createExecutionEngine(options) {
|
|
|
206
206
|
}
|
|
207
207
|
return { ok: true, data: output };
|
|
208
208
|
};
|
|
209
|
+
const hooks = options.hooks;
|
|
210
|
+
if (hooks === undefined)
|
|
211
|
+
return invoke;
|
|
212
|
+
// Hook errors are isolated: observability must never fail a request.
|
|
213
|
+
const fire = (fn, name) => {
|
|
214
|
+
if (fn === undefined)
|
|
215
|
+
return;
|
|
216
|
+
try {
|
|
217
|
+
fn();
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
console.error(`[capix] Lifecycle hook '${name}' threw:`, err);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
return async function invokeWithHooks(req) {
|
|
224
|
+
const start = Date.now();
|
|
225
|
+
fire(hooks.onRequest && (() => hooks.onRequest(req)), 'onRequest');
|
|
226
|
+
const response = await invoke(req);
|
|
227
|
+
const durationMs = Date.now() - start;
|
|
228
|
+
if (response.ok) {
|
|
229
|
+
fire(hooks.onResponse && (() => hooks.onResponse(req, { durationMs, data: response.data })), 'onResponse');
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
fire(hooks.onError && (() => hooks.onError(req, { durationMs, error: response.error })), 'onError');
|
|
233
|
+
}
|
|
234
|
+
return response;
|
|
235
|
+
};
|
|
209
236
|
}
|
|
210
237
|
//# sourceMappingURL=execution-engine.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-engine.js","sourceRoot":"","sources":["../src/execution-engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"execution-engine.js","sourceRoot":"","sources":["../src/execution-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* http-shutdown.ts — graceful HTTP server close shared by the HTTP transports.
|
|
3
|
+
*
|
|
4
|
+
* `server.close()` alone is not a shutdown: it stops accepting connections but
|
|
5
|
+
* waits forever for keep-alive sockets, and gives in-flight requests unlimited
|
|
6
|
+
* time. This helper implements the standard drain sequence.
|
|
7
|
+
*/
|
|
8
|
+
import type * as http from 'node:http';
|
|
9
|
+
/**
|
|
10
|
+
* Gracefully closes an HTTP server:
|
|
11
|
+
*
|
|
12
|
+
* 1. stop accepting new connections
|
|
13
|
+
* 2. drop idle keep-alive sockets immediately (they hold nothing in flight)
|
|
14
|
+
* 3. give in-flight requests `drainMs` to finish
|
|
15
|
+
* 4. force-close whatever is still open
|
|
16
|
+
*
|
|
17
|
+
* Resolves when the server has fully closed. Extension-author API — custom
|
|
18
|
+
* HTTP transports should use this in `unmount()`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function closeHttpServerGracefully(server: http.Server, drainMs: number): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=http-shutdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-shutdown.d.ts","sourceRoot":"","sources":["../src/http-shutdown.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAEvC;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe7F"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* http-shutdown.ts — graceful HTTP server close shared by the HTTP transports.
|
|
3
|
+
*
|
|
4
|
+
* `server.close()` alone is not a shutdown: it stops accepting connections but
|
|
5
|
+
* waits forever for keep-alive sockets, and gives in-flight requests unlimited
|
|
6
|
+
* time. This helper implements the standard drain sequence.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Gracefully closes an HTTP server:
|
|
10
|
+
*
|
|
11
|
+
* 1. stop accepting new connections
|
|
12
|
+
* 2. drop idle keep-alive sockets immediately (they hold nothing in flight)
|
|
13
|
+
* 3. give in-flight requests `drainMs` to finish
|
|
14
|
+
* 4. force-close whatever is still open
|
|
15
|
+
*
|
|
16
|
+
* Resolves when the server has fully closed. Extension-author API — custom
|
|
17
|
+
* HTTP transports should use this in `unmount()`.
|
|
18
|
+
*/
|
|
19
|
+
export function closeHttpServerGracefully(server, drainMs) {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
// unref: an armed drain timer must not keep the process alive on its own
|
|
22
|
+
const timer = setTimeout(() => server.closeAllConnections(), drainMs);
|
|
23
|
+
timer.unref();
|
|
24
|
+
server.close((err) => {
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
if (err)
|
|
27
|
+
reject(err);
|
|
28
|
+
else
|
|
29
|
+
resolve();
|
|
30
|
+
});
|
|
31
|
+
// Idle keep-alive connections would otherwise block close() indefinitely
|
|
32
|
+
server.closeIdleConnections();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=http-shutdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-shutdown.js","sourceRoot":"","sources":["../src/http-shutdown.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAmB,EAAE,OAAe;IAC5E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,yEAAyE;QACzE,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,EAAE,EAAE,OAAO,CAAC,CAAC;QACtE,KAAK,CAAC,KAAK,EAAE,CAAC;QAEd,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACnB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,GAAG;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;gBAChB,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,yEAAyE;QACzE,MAAM,CAAC,oBAAoB,EAAE,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,12 +7,15 @@ export { defineContext, getHeader } from './context.js';
|
|
|
7
7
|
export type { RawRequest, BaseContext, ContextBuilder } from './context.js';
|
|
8
8
|
export { defineGuard, defineGuardFor, runGuards, defineInputGuard, runInputGuards } from './guards.js';
|
|
9
9
|
export type { Guard, NarrowingGuard, AnyGuard, NarrowContext, InputGuard, AnyInputGuard } from './guards.js';
|
|
10
|
-
export { capability, isCapability, compileRegistry, inferIntent } from './capability.js';
|
|
10
|
+
export { capability, isCapability, compileRegistry, inferIntent, resolveIntent } from './capability.js';
|
|
11
11
|
export type { Intent, Enhancer, Resolver, Capability, AnyCapability, CapabilityRegistry, GroupTree, InferInput, InferOutput, InferContext, ScopedCapabilityFactory, } from './capability.js';
|
|
12
12
|
export { defineEnhancer, withLogging, withCache, withTimeout, withRetry, withRateLimit, withRollback, withMetrics, withCircuitBreaker, consoleMetricsCollector, } from './enhancers.js';
|
|
13
13
|
export type { CacheOptions, RateLimitOptions, MetricsCollector, CircuitBreakerOptions, RollbackFn, WithRollback, } from './enhancers.js';
|
|
14
14
|
export { createExecutionEngine } from './execution-engine.js';
|
|
15
|
-
export
|
|
15
|
+
export { closeHttpServerGracefully } from './http-shutdown.js';
|
|
16
|
+
export { createMemoryCacheStore, createMemoryRateLimitStore } from './stores.js';
|
|
17
|
+
export type { CacheStore, RateLimitStore, RateLimitResult, MemoryCacheStoreOptions, MemoryRateLimitStoreOptions, } from './stores.js';
|
|
18
|
+
export type { CapabilityRequest, CapabilityResponse, SerializedError, InvokeFn, ExecutionEngineOptions, LifecycleHooks, } from './execution-engine.js';
|
|
16
19
|
export { definePlugin, mergePlugins } from './plugin.js';
|
|
17
20
|
export type { Plugin, MergedPlugins } from './plugin.js';
|
|
18
21
|
export { createServer, defineConfig } from './server.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3E,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG5E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACvG,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG7G,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3E,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG5E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACvG,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG7G,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACxG,YAAY,EACV,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,SAAS,EACT,UAAU,EACV,WAAW,EACX,YAAY,EACZ,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,cAAc,EACd,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,aAAa,EACb,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,UAAU,EACV,YAAY,GACb,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAG/D,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACjF,YAAY,EACV,UAAU,EACV,cAAc,EACd,eAAe,EACf,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,sBAAsB,EACtB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzD,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzD,YAAY,EAAE,SAAS,EAAE,yBAAyB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG5G,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,11 +8,14 @@ export { defineContext, getHeader } from './context.js';
|
|
|
8
8
|
// Guards
|
|
9
9
|
export { defineGuard, defineGuardFor, runGuards, defineInputGuard, runInputGuards } from './guards.js';
|
|
10
10
|
// Capability
|
|
11
|
-
export { capability, isCapability, compileRegistry, inferIntent } from './capability.js';
|
|
11
|
+
export { capability, isCapability, compileRegistry, inferIntent, resolveIntent } from './capability.js';
|
|
12
12
|
// Enhancers
|
|
13
13
|
export { defineEnhancer, withLogging, withCache, withTimeout, withRetry, withRateLimit, withRollback, withMetrics, withCircuitBreaker, consoleMetricsCollector, } from './enhancers.js';
|
|
14
14
|
// Execution engine
|
|
15
15
|
export { createExecutionEngine } from './execution-engine.js';
|
|
16
|
+
export { closeHttpServerGracefully } from './http-shutdown.js';
|
|
17
|
+
// Stores (pluggable backends for withCache / withRateLimit)
|
|
18
|
+
export { createMemoryCacheStore, createMemoryRateLimitStore } from './stores.js';
|
|
16
19
|
// Plugin
|
|
17
20
|
export { definePlugin, mergePlugins } from './plugin.js';
|
|
18
21
|
// Server
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG3E,UAAU;AACV,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGxD,SAAS;AACT,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGvG,aAAa;AACb,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG3E,UAAU;AACV,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGxD,SAAS;AACT,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGvG,aAAa;AACb,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAexG,YAAY;AACZ,OAAO,EACL,cAAc,EACd,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,aAAa,EACb,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAUxB,mBAAmB;AACnB,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,4DAA4D;AAC5D,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAiBjF,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGzD,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGzD,YAAY;AACZ,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/server.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { AnyCapability, CapabilityRegistry, GroupTree } from './capability.js';
|
|
6
6
|
import type { ContextBuilder } from './context.js';
|
|
7
|
-
import type { InvokeFn } from './execution-engine.js';
|
|
7
|
+
import type { InvokeFn, LifecycleHooks } from './execution-engine.js';
|
|
8
8
|
import type { Plugin } from './plugin.js';
|
|
9
9
|
export type MountOptions = {
|
|
10
10
|
readonly registry: CapabilityRegistry;
|
|
@@ -33,6 +33,12 @@ export type ServerConfig = {
|
|
|
33
33
|
readonly transports: Transport[];
|
|
34
34
|
readonly plugins?: Plugin[];
|
|
35
35
|
readonly isDevelopment?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Lifecycle hooks observing every capability invocation on every transport
|
|
38
|
+
* — the integration point for tracing, metrics, and error reporting.
|
|
39
|
+
* See the observability guide for OpenTelemetry and Sentry recipes.
|
|
40
|
+
*/
|
|
41
|
+
readonly hooks?: LifecycleHooks;
|
|
36
42
|
};
|
|
37
43
|
export type Server = {
|
|
38
44
|
start(): Promise<void>;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;CAC3B,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG,SAAS,GAAG;IAClD,iFAAiF;IACjF,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAChF,QAAQ,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAuFzD;AAED,8CAA8C;AAC9C,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAE/D"}
|
package/dist/server.js
CHANGED
|
@@ -53,6 +53,7 @@ export function createServer(config) {
|
|
|
53
53
|
registry: serverRegistry,
|
|
54
54
|
buildContext: wrappedContext,
|
|
55
55
|
isDevelopment: config.isDevelopment ?? process.env['NODE_ENV'] !== 'production',
|
|
56
|
+
...(config.hooks !== undefined ? { hooks: config.hooks } : {}),
|
|
56
57
|
});
|
|
57
58
|
const isDev = config.isDevelopment ?? process.env['NODE_ENV'] !== 'production';
|
|
58
59
|
return {
|
|
@@ -79,7 +80,12 @@ export function createServer(config) {
|
|
|
79
80
|
// Plugin additional capabilities are always merged in
|
|
80
81
|
const tree = { ...caps, ...additionalCapabilities };
|
|
81
82
|
const registry = compileRegistry(tree);
|
|
82
|
-
const invoke = createExecutionEngine({
|
|
83
|
+
const invoke = createExecutionEngine({
|
|
84
|
+
registry,
|
|
85
|
+
buildContext: wrappedContext,
|
|
86
|
+
isDevelopment: isDev,
|
|
87
|
+
...(config.hooks !== undefined ? { hooks: config.hooks } : {}),
|
|
88
|
+
});
|
|
83
89
|
await transport.mount(invoke, { registry, invoke });
|
|
84
90
|
}
|
|
85
91
|
},
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/stores.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stores.ts — pluggable backends for withCache and withRateLimit.
|
|
3
|
+
*
|
|
4
|
+
* The in-memory implementations below are the defaults and are correct for a
|
|
5
|
+
* single process. Behind a load balancer they silently diverge: each instance
|
|
6
|
+
* keeps its own cache and its own rate-limit counters (N instances = N times
|
|
7
|
+
* the intended limit). For multi-instance deployments plug in a shared
|
|
8
|
+
* backend — see @capixjs/store-redis.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Pluggable cache backend for {@link withCache}.
|
|
12
|
+
* Implementations own expiry and capacity policy.
|
|
13
|
+
*/
|
|
14
|
+
export type CacheStore = {
|
|
15
|
+
/** Returns the cached value, or undefined when missing or expired. */
|
|
16
|
+
get(key: string): unknown | undefined | Promise<unknown | undefined>;
|
|
17
|
+
/** Stores a value for ttlMs milliseconds. */
|
|
18
|
+
set(key: string, value: unknown, ttlMs: number): void | Promise<void>;
|
|
19
|
+
};
|
|
20
|
+
export type MemoryCacheStoreOptions = {
|
|
21
|
+
/** Maximum number of entries; least-recently-used are evicted. Default: 1_000. */
|
|
22
|
+
readonly maxSize?: number;
|
|
23
|
+
};
|
|
24
|
+
/** In-memory LRU cache store — the withCache default. Single-process only. */
|
|
25
|
+
export declare function createMemoryCacheStore(options?: MemoryCacheStoreOptions): CacheStore;
|
|
26
|
+
export type RateLimitResult = {
|
|
27
|
+
readonly allowed: true;
|
|
28
|
+
} | {
|
|
29
|
+
readonly allowed: false;
|
|
30
|
+
readonly retryAfterMs: number;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Pluggable rate-limit backend for {@link withRateLimit}.
|
|
34
|
+
*
|
|
35
|
+
* `hit` records an attempt and decides in one call; implementations must make
|
|
36
|
+
* that atomic per key (a check-then-set race would admit bursts over the
|
|
37
|
+
* limit). Window semantics belong to the store: the in-memory default uses a
|
|
38
|
+
* sliding window, the Redis adapter a fixed window.
|
|
39
|
+
*/
|
|
40
|
+
export type RateLimitStore = {
|
|
41
|
+
hit(key: string, limit: number, windowMs: number): RateLimitResult | Promise<RateLimitResult>;
|
|
42
|
+
};
|
|
43
|
+
export type MemoryRateLimitStoreOptions = {
|
|
44
|
+
/**
|
|
45
|
+
* Maximum number of distinct keys tracked. Default: 10_000.
|
|
46
|
+
* When exceeded, keys with no activity in the current window are swept;
|
|
47
|
+
* if every key is still active, the oldest-tracked keys are evicted.
|
|
48
|
+
*/
|
|
49
|
+
readonly maxKeys?: number;
|
|
50
|
+
};
|
|
51
|
+
/** In-memory sliding-window rate-limit store — the withRateLimit default. Single-process only. */
|
|
52
|
+
export declare function createMemoryRateLimitStore(options?: MemoryRateLimitStoreOptions): RateLimitStore;
|
|
53
|
+
//# sourceMappingURL=stores.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,sEAAsE;IACtE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IACrE,6CAA6C;IAC7C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,UAAU,CA4BxF;AAMD,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC/F,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,kGAAkG;AAClG,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,2BAAgC,GAAG,cAAc,CAyCpG"}
|
package/dist/stores.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stores.ts — pluggable backends for withCache and withRateLimit.
|
|
3
|
+
*
|
|
4
|
+
* The in-memory implementations below are the defaults and are correct for a
|
|
5
|
+
* single process. Behind a load balancer they silently diverge: each instance
|
|
6
|
+
* keeps its own cache and its own rate-limit counters (N instances = N times
|
|
7
|
+
* the intended limit). For multi-instance deployments plug in a shared
|
|
8
|
+
* backend — see @capixjs/store-redis.
|
|
9
|
+
*/
|
|
10
|
+
/** In-memory LRU cache store — the withCache default. Single-process only. */
|
|
11
|
+
export function createMemoryCacheStore(options = {}) {
|
|
12
|
+
const maxSize = options.maxSize ?? 1_000;
|
|
13
|
+
const entries = new Map();
|
|
14
|
+
return {
|
|
15
|
+
get(key) {
|
|
16
|
+
const cached = entries.get(key);
|
|
17
|
+
if (cached === undefined)
|
|
18
|
+
return undefined;
|
|
19
|
+
if (cached.expiresAt <= Date.now()) {
|
|
20
|
+
entries.delete(key); // expired — don't let dead entries occupy capacity
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
// Refresh recency for LRU ordering
|
|
24
|
+
entries.delete(key);
|
|
25
|
+
entries.set(key, cached);
|
|
26
|
+
return cached.value;
|
|
27
|
+
},
|
|
28
|
+
set(key, value, ttlMs) {
|
|
29
|
+
if (entries.size >= maxSize && !entries.has(key)) {
|
|
30
|
+
// Evict least-recently-used (first key in Map insertion order)
|
|
31
|
+
const oldest = entries.keys().next().value;
|
|
32
|
+
if (oldest !== undefined)
|
|
33
|
+
entries.delete(oldest);
|
|
34
|
+
}
|
|
35
|
+
entries.delete(key);
|
|
36
|
+
entries.set(key, { value, expiresAt: Date.now() + ttlMs });
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** In-memory sliding-window rate-limit store — the withRateLimit default. Single-process only. */
|
|
41
|
+
export function createMemoryRateLimitStore(options = {}) {
|
|
42
|
+
const maxKeys = options.maxKeys ?? 10_000;
|
|
43
|
+
const buckets = new Map();
|
|
44
|
+
function evictStale(now, windowMs) {
|
|
45
|
+
const cutoff = now - windowMs;
|
|
46
|
+
for (const [k, ts] of buckets) {
|
|
47
|
+
const last = ts[ts.length - 1];
|
|
48
|
+
if (last === undefined || last <= cutoff)
|
|
49
|
+
buckets.delete(k);
|
|
50
|
+
}
|
|
51
|
+
// Every key still active — hard-cap by evicting oldest-tracked keys
|
|
52
|
+
if (buckets.size > maxKeys) {
|
|
53
|
+
for (const k of buckets.keys()) {
|
|
54
|
+
buckets.delete(k);
|
|
55
|
+
if (buckets.size <= maxKeys)
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
hit(key, limit, windowMs) {
|
|
62
|
+
const now = Date.now();
|
|
63
|
+
const windowStart = now - windowMs;
|
|
64
|
+
if (buckets.size > maxKeys)
|
|
65
|
+
evictStale(now, windowMs);
|
|
66
|
+
let timestamps = buckets.get(key) ?? [];
|
|
67
|
+
timestamps = timestamps.filter((t) => t > windowStart);
|
|
68
|
+
if (timestamps.length >= limit) {
|
|
69
|
+
// Oldest timestamp in the window determines when a slot frees up
|
|
70
|
+
const oldestInWindow = timestamps[0] ?? now;
|
|
71
|
+
buckets.set(key, timestamps);
|
|
72
|
+
return { allowed: false, retryAfterMs: oldestInWindow + windowMs - now };
|
|
73
|
+
}
|
|
74
|
+
timestamps.push(now);
|
|
75
|
+
buckets.set(key, timestamps);
|
|
76
|
+
return { allowed: true };
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=stores.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stores.js","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capixjs/core",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
4
|
"description": "Capability-based Node.js server framework — core",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/milanito/capix.git",
|
|
9
|
+
"directory": "packages/core"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/milanito/capix#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/milanito/capix/issues"
|
|
14
|
+
},
|
|
6
15
|
"type": "module",
|
|
7
16
|
"main": "./dist/index.js",
|
|
8
17
|
"types": "./dist/index.d.ts",
|
|
@@ -32,16 +41,18 @@
|
|
|
32
41
|
"node": ">=20"
|
|
33
42
|
},
|
|
34
43
|
"dependencies": {
|
|
35
|
-
"zod": "^
|
|
44
|
+
"zod": "^4.0.0"
|
|
36
45
|
},
|
|
37
46
|
"devDependencies": {
|
|
38
47
|
"@types/node": "^20.0.0",
|
|
39
48
|
"typescript": "^5.5.0",
|
|
40
|
-
"vitest": "^1.6.0"
|
|
49
|
+
"vitest": "^1.6.0",
|
|
50
|
+
"@vitest/coverage-v8": "^1.6.1"
|
|
41
51
|
},
|
|
42
52
|
"scripts": {
|
|
43
53
|
"build": "tsc",
|
|
44
54
|
"test": "vitest run",
|
|
55
|
+
"test:coverage": "vitest run --coverage",
|
|
45
56
|
"typecheck": "tsc --noEmit"
|
|
46
57
|
}
|
|
47
58
|
}
|