@cqrs-ddd/pipeline 0.5.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/COMMERCIAL_LICENSE.txt +34 -0
- package/LICENSE +661 -0
- package/README.md +42 -0
- package/dist/behaviors/logging.behavior.d.ts +195 -0
- package/dist/behaviors/logging.behavior.d.ts.map +1 -0
- package/dist/behaviors/logging.behavior.js +206 -0
- package/dist/behaviors/logging.behavior.js.map +1 -0
- package/dist/constants/pipeline-context.constants.d.ts +34 -0
- package/dist/constants/pipeline-context.constants.d.ts.map +1 -0
- package/dist/constants/pipeline-context.constants.js +34 -0
- package/dist/constants/pipeline-context.constants.js.map +1 -0
- package/dist/create-pipeline.d.ts +122 -0
- package/dist/create-pipeline.d.ts.map +1 -0
- package/dist/create-pipeline.js +193 -0
- package/dist/create-pipeline.js.map +1 -0
- package/dist/entries.d.ts +13 -0
- package/dist/entries.d.ts.map +1 -0
- package/dist/entries.js +3 -0
- package/dist/entries.js.map +1 -0
- package/dist/errors/missing-partition.error.d.ts +27 -0
- package/dist/errors/missing-partition.error.d.ts.map +1 -0
- package/dist/errors/missing-partition.error.js +33 -0
- package/dist/errors/missing-partition.error.js.map +1 -0
- package/dist/errors/missing-pipeline-item.error.d.ts +8 -0
- package/dist/errors/missing-pipeline-item.error.d.ts.map +1 -0
- package/dist/errors/missing-pipeline-item.error.js +16 -0
- package/dist/errors/missing-pipeline-item.error.js.map +1 -0
- package/dist/handler-pipeline.d.ts +62 -0
- package/dist/handler-pipeline.d.ts.map +1 -0
- package/dist/handler-pipeline.js +74 -0
- package/dist/handler-pipeline.js.map +1 -0
- package/dist/helpers/behavior-entries.d.ts +34 -0
- package/dist/helpers/behavior-entries.d.ts.map +1 -0
- package/dist/helpers/behavior-entries.js +50 -0
- package/dist/helpers/behavior-entries.js.map +1 -0
- package/dist/helpers/behavior-id.d.ts +43 -0
- package/dist/helpers/behavior-id.d.ts.map +1 -0
- package/dist/helpers/behavior-id.js +38 -0
- package/dist/helpers/behavior-id.js.map +1 -0
- package/dist/helpers/logging.intent.d.ts +17 -0
- package/dist/helpers/logging.intent.d.ts.map +1 -0
- package/dist/helpers/logging.intent.js +18 -0
- package/dist/helpers/logging.intent.js.map +1 -0
- package/dist/helpers/postgres-json.d.ts +25 -0
- package/dist/helpers/postgres-json.d.ts.map +1 -0
- package/dist/helpers/postgres-json.js +35 -0
- package/dist/helpers/postgres-json.js.map +1 -0
- package/dist/helpers/replace-request.d.ts +19 -0
- package/dist/helpers/replace-request.d.ts.map +1 -0
- package/dist/helpers/replace-request.js +29 -0
- package/dist/helpers/replace-request.js.map +1 -0
- package/dist/helpers/tenant-partition.d.ts +38 -0
- package/dist/helpers/tenant-partition.d.ts.map +1 -0
- package/dist/helpers/tenant-partition.js +27 -0
- package/dist/helpers/tenant-partition.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/context-source.interface.d.ts +42 -0
- package/dist/interfaces/context-source.interface.d.ts.map +1 -0
- package/dist/interfaces/context-source.interface.js +3 -0
- package/dist/interfaces/context-source.interface.js.map +1 -0
- package/dist/interfaces/pipeline-behavior-contract.interface.d.ts +99 -0
- package/dist/interfaces/pipeline-behavior-contract.interface.d.ts.map +1 -0
- package/dist/interfaces/pipeline-behavior-contract.interface.js +22 -0
- package/dist/interfaces/pipeline-behavior-contract.interface.js.map +1 -0
- package/dist/interfaces/pipeline-handler-meta.interface.d.ts +15 -0
- package/dist/interfaces/pipeline-handler-meta.interface.d.ts.map +1 -0
- package/dist/interfaces/pipeline-handler-meta.interface.js +3 -0
- package/dist/interfaces/pipeline-handler-meta.interface.js.map +1 -0
- package/dist/interfaces/pipeline.behavior.interface.d.ts +38 -0
- package/dist/interfaces/pipeline.behavior.interface.d.ts.map +1 -0
- package/dist/interfaces/pipeline.behavior.interface.js +3 -0
- package/dist/interfaces/pipeline.behavior.interface.js.map +1 -0
- package/dist/interfaces/pipeline.context.interface.d.ts +69 -0
- package/dist/interfaces/pipeline.context.interface.d.ts.map +1 -0
- package/dist/interfaces/pipeline.context.interface.js +3 -0
- package/dist/interfaces/pipeline.context.interface.js.map +1 -0
- package/dist/logger.d.ts +45 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +64 -0
- package/dist/logger.js.map +1 -0
- package/dist/options/global-behaviors.options.d.ts +57 -0
- package/dist/options/global-behaviors.options.d.ts.map +1 -0
- package/dist/options/global-behaviors.options.js +3 -0
- package/dist/options/global-behaviors.options.js.map +1 -0
- package/dist/pipeline-items.d.ts +22 -0
- package/dist/pipeline-items.d.ts.map +1 -0
- package/dist/pipeline-items.js +34 -0
- package/dist/pipeline-items.js.map +1 -0
- package/dist/pipeline.context.d.ts +86 -0
- package/dist/pipeline.context.d.ts.map +1 -0
- package/dist/pipeline.context.js +109 -0
- package/dist/pipeline.context.js.map +1 -0
- package/dist/services/pipeline-contracts.d.ts +29 -0
- package/dist/services/pipeline-contracts.d.ts.map +1 -0
- package/dist/services/pipeline-contracts.js +102 -0
- package/dist/services/pipeline-contracts.js.map +1 -0
- package/dist/services/pipeline-plan.d.ts +49 -0
- package/dist/services/pipeline-plan.d.ts.map +1 -0
- package/dist/services/pipeline-plan.js +111 -0
- package/dist/services/pipeline-plan.js.map +1 -0
- package/dist/services/pipeline-runner.d.ts +26 -0
- package/dist/services/pipeline-runner.d.ts.map +1 -0
- package/dist/services/pipeline-runner.js +68 -0
- package/dist/services/pipeline-runner.js.map +1 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
import { LoggingBehavior } from './behaviors/logging.behavior.js';
|
|
3
|
+
import { behaviorEntryType, normalizeBehaviorEntries, } from './helpers/behavior-entries.js';
|
|
4
|
+
import { getBehaviorId } from './helpers/behavior-id.js';
|
|
5
|
+
import { PipelineConfigurationError, } from './interfaces/pipeline-behavior-contract.interface.js';
|
|
6
|
+
import { validateBehaviorContracts } from './services/pipeline-contracts.js';
|
|
7
|
+
import { compilePipelinePlan, toGlobalConfigs, } from './services/pipeline-plan.js';
|
|
8
|
+
import { createPipelineRunner, } from './services/pipeline-runner.js';
|
|
9
|
+
const KINDS = ['command', 'query', 'event'];
|
|
10
|
+
/**
|
|
11
|
+
* Brand by which a request tells a pipeline its kind, so a wrapped method needs no
|
|
12
|
+
* `kind` option; the request's class name then names the operation. `@cqrs-ddd/core`
|
|
13
|
+
* puts it on `BaseCommand`, `BaseQuery` and `DomainEvent`; any class can declare it.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* class GetPriceQuery {
|
|
18
|
+
* get [REQUEST_KIND]() {
|
|
19
|
+
* return 'query' as const;
|
|
20
|
+
* }
|
|
21
|
+
* constructor(readonly sku: string) {}
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export const REQUEST_KIND = Symbol.for('@cqrs-ddd/request-kind');
|
|
26
|
+
/**
|
|
27
|
+
* Creates a pipeline: behaviors that wrap plain functions and class methods with
|
|
28
|
+
* cross-cutting concerns, with no framework and no dependency-injection container.
|
|
29
|
+
*
|
|
30
|
+
* Global behaviors are constructed when the pipeline is created, so a behavior whose
|
|
31
|
+
* required dependency is missing fails here rather than at its first call.
|
|
32
|
+
*
|
|
33
|
+
* @throws TypeError on a malformed global entry or two instances of one behavior class.
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const pipeline = createPipeline({
|
|
37
|
+
* behaviors: [new CacheBehavior(buildCache({}))],
|
|
38
|
+
* globalBehaviors: { before: [logging({ requestResponseLogLevel: 'log' })] },
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* export const getPrice = pipeline.wrap(
|
|
42
|
+
* { name: 'getPrice', kind: 'query' },
|
|
43
|
+
* cache({ key }),
|
|
44
|
+
* )(async (sku: string) => prices.find(sku));
|
|
45
|
+
*
|
|
46
|
+
* class Prices {
|
|
47
|
+
* @pipeline.wrap({ kind: 'query' }, cache({ key }))
|
|
48
|
+
* async find(sku: string) {}
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export function createPipeline(options = {}) {
|
|
53
|
+
const { globalBehaviors, sources = {}, diagnostics = 'strict', logger = console, } = options;
|
|
54
|
+
const instances = new Map();
|
|
55
|
+
for (const behavior of options.behaviors ?? []) {
|
|
56
|
+
const type = behavior.constructor;
|
|
57
|
+
const id = getBehaviorId(type);
|
|
58
|
+
if (instances.has(id)) {
|
|
59
|
+
throw new TypeError(`createPipeline: two instances of ${type.name}; pass one per behavior class.`);
|
|
60
|
+
}
|
|
61
|
+
instances.set(id, behavior);
|
|
62
|
+
}
|
|
63
|
+
const instanceOf = (type) => {
|
|
64
|
+
const id = getBehaviorId(type);
|
|
65
|
+
let instance = instances.get(id);
|
|
66
|
+
if (!instance) {
|
|
67
|
+
instance = id === LOGGING_ID ? new LoggingBehavior(logger) : new type();
|
|
68
|
+
instances.set(id, instance);
|
|
69
|
+
}
|
|
70
|
+
return instance;
|
|
71
|
+
};
|
|
72
|
+
for (const config of toGlobalConfigs(globalBehaviors)) {
|
|
73
|
+
for (const entry of [...(config.before ?? []), ...(config.after ?? [])]) {
|
|
74
|
+
instanceOf(behaviorEntryType(entry, 'createPipeline globalBehaviors'));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function compile(handlerName, requestKind, declared, skip) {
|
|
78
|
+
const plan = compilePipelinePlan({
|
|
79
|
+
handlerName,
|
|
80
|
+
requestKind,
|
|
81
|
+
handlerBehaviorTypes: declared.types,
|
|
82
|
+
handlerOptions: declared.options,
|
|
83
|
+
skippedBehaviorTypes: skip
|
|
84
|
+
? normalizeBehaviorEntries(skip, 'pipeline.wrap skip', false).types
|
|
85
|
+
: undefined,
|
|
86
|
+
globalBehaviors,
|
|
87
|
+
});
|
|
88
|
+
const behaviors = plan.behaviorTypes.map(instanceOf);
|
|
89
|
+
if (diagnostics !== 'off') {
|
|
90
|
+
const found = [];
|
|
91
|
+
validateBehaviorContracts({
|
|
92
|
+
...plan,
|
|
93
|
+
handlerType: Object,
|
|
94
|
+
handlerName,
|
|
95
|
+
requestKind,
|
|
96
|
+
resolvedBehaviors: new Map(behaviors.map((b, i) => [i, b])),
|
|
97
|
+
diagnostics: found,
|
|
98
|
+
});
|
|
99
|
+
if (found.length > 0 && diagnostics === 'strict') {
|
|
100
|
+
throw new PipelineConfigurationError(found);
|
|
101
|
+
}
|
|
102
|
+
for (const d of found) {
|
|
103
|
+
logger.warn(`[Pipeline Diagnostic] '${d.handlerName}' with behavior '${d.behaviorName}': ${d.message}. Fix: ${d.fix}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return { plan, behaviors };
|
|
107
|
+
}
|
|
108
|
+
function wrap(...input) {
|
|
109
|
+
const [first] = input;
|
|
110
|
+
const hasOptions = typeof first === 'object' && first !== null && !Array.isArray(first);
|
|
111
|
+
const wrapOptions = (hasOptions ? first : {});
|
|
112
|
+
const entries = (hasOptions ? input.slice(1) : input);
|
|
113
|
+
if (wrapOptions.kind !== undefined && !KINDS.includes(wrapOptions.kind)) {
|
|
114
|
+
throw new TypeError(`pipeline.wrap: kind must be 'command', 'query' or 'event', received ${String(wrapOptions.kind)}.`);
|
|
115
|
+
}
|
|
116
|
+
const declared = normalizeBehaviorEntries(entries, 'pipeline.wrap');
|
|
117
|
+
function bind(fn, methodKey) {
|
|
118
|
+
const label = wrapOptions.name ?? methodKey;
|
|
119
|
+
if (label === undefined) {
|
|
120
|
+
throw new TypeError('pipeline.wrap: a plain function needs a `name`, which keys and logs use to tell operations apart.');
|
|
121
|
+
}
|
|
122
|
+
const handlerType = { [label]: class {
|
|
123
|
+
} }[label];
|
|
124
|
+
const runners = new Map();
|
|
125
|
+
const runnerFor = (kind) => {
|
|
126
|
+
let runner = runners.get(kind);
|
|
127
|
+
if (!runner) {
|
|
128
|
+
const { plan, behaviors } = compile(label, kind, declared, wrapOptions.skip);
|
|
129
|
+
const behaviorOptions = plan.mergedOptions.size > 0 ? plan.mergedOptions : undefined;
|
|
130
|
+
runner = createPipelineRunner(fn, (request, self) => {
|
|
131
|
+
const handlerName = wrapOptions.name ?? `${ownerName(self)}.${label}`;
|
|
132
|
+
return {
|
|
133
|
+
handlerType,
|
|
134
|
+
handlerName,
|
|
135
|
+
requestKind: kind,
|
|
136
|
+
behaviorOptions,
|
|
137
|
+
requestName: wrapOptions.name ??
|
|
138
|
+
(brandOf(request) ? undefined : handlerName),
|
|
139
|
+
};
|
|
140
|
+
}, behaviors, plan.hasPipeline, sources);
|
|
141
|
+
runners.set(kind, runner);
|
|
142
|
+
}
|
|
143
|
+
return runner;
|
|
144
|
+
};
|
|
145
|
+
if (wrapOptions.kind)
|
|
146
|
+
runnerFor(wrapOptions.kind);
|
|
147
|
+
return async function (...args) {
|
|
148
|
+
const request = args.length === 1 ? args[0] : args;
|
|
149
|
+
const kind = wrapOptions.kind ?? brandOf(request);
|
|
150
|
+
if (!kind) {
|
|
151
|
+
throw new TypeError(`${label}: declare its kind with pipeline.wrap({ kind }), or pass a request that carries REQUEST_KIND.`);
|
|
152
|
+
}
|
|
153
|
+
return runnerFor(kind)(this, request, args);
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return function apply(target, key, descriptor) {
|
|
157
|
+
if (key === undefined && typeof target === 'function') {
|
|
158
|
+
return bind(target);
|
|
159
|
+
}
|
|
160
|
+
if (isDecoratorContext(key)) {
|
|
161
|
+
if (key.kind !== 'method') {
|
|
162
|
+
throw new TypeError(`pipeline.wrap decorates methods, not a ${key.kind}.`);
|
|
163
|
+
}
|
|
164
|
+
return bind(target, String(key.name));
|
|
165
|
+
}
|
|
166
|
+
const property = descriptor;
|
|
167
|
+
if (typeof property?.value === 'function') {
|
|
168
|
+
property.value = bind(property.value, String(key));
|
|
169
|
+
return property;
|
|
170
|
+
}
|
|
171
|
+
throw new TypeError('pipeline.wrap(...) applies to a function or a method.');
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return { wrap };
|
|
175
|
+
}
|
|
176
|
+
const LOGGING_ID = getBehaviorId(LoggingBehavior);
|
|
177
|
+
function brandOf(request) {
|
|
178
|
+
if (typeof request !== 'object' || request === null)
|
|
179
|
+
return undefined;
|
|
180
|
+
const kind = request[REQUEST_KIND];
|
|
181
|
+
return KINDS.includes(kind)
|
|
182
|
+
? kind
|
|
183
|
+
: undefined;
|
|
184
|
+
}
|
|
185
|
+
function ownerName(self) {
|
|
186
|
+
if (typeof self === 'function')
|
|
187
|
+
return self.name;
|
|
188
|
+
return self?.constructor?.name ?? 'anonymous';
|
|
189
|
+
}
|
|
190
|
+
function isDecoratorContext(value) {
|
|
191
|
+
return typeof value === 'object' && value !== null && 'kind' in value;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=create-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-pipeline.js","sourceRoot":"","sources":["../src/create-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IPipelineBehavior } from './interfaces/pipeline.behavior.interface.js';
|
|
2
|
+
import type { Constructor } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* A tuple of a pipeline behavior class and its options.
|
|
5
|
+
*/
|
|
6
|
+
export type PipelineBehaviorTuple<TBehavior extends IPipelineBehavior = IPipelineBehavior, TOptions extends object = object> = [Constructor<TBehavior>, TOptions];
|
|
7
|
+
/**
|
|
8
|
+
* A pipeline behavior entry can be either:
|
|
9
|
+
* - A behavior class: `LoggingBehavior`
|
|
10
|
+
* - A tuple of behavior class and options: `[AuditBehavior, { action: 'user.create', severity: 'high' }]`
|
|
11
|
+
*/
|
|
12
|
+
export type PipelineBehaviorEntry<TBehavior extends IPipelineBehavior = IPipelineBehavior, TOptions extends object = object> = Constructor<TBehavior> | PipelineBehaviorTuple<TBehavior, TOptions>;
|
|
13
|
+
//# sourceMappingURL=entries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../src/entries.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,qBAAqB,CAC/B,SAAS,SAAS,iBAAiB,GAAG,iBAAiB,EACvD,QAAQ,SAAS,MAAM,GAAG,MAAM,IAC9B,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;AAEvC;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,CAC/B,SAAS,SAAS,iBAAiB,GAAG,iBAAiB,EACvD,QAAQ,SAAS,MAAM,GAAG,MAAM,IAC9B,WAAW,CAAC,SAAS,CAAC,GAAG,qBAAqB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC"}
|
package/dist/entries.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entries.js","sourceRoot":"","sources":["../src/entries.ts"],"names":[],"mappings":"AAAA,sEAAsE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raised when a partitioned key (cache, idempotency, rate limit) needs a
|
|
3
|
+
* dimension, such as the tenant or the principal, that could not be resolved.
|
|
4
|
+
* Omitting it instead would merge isolation domains: callers whose identity
|
|
5
|
+
* is unknown would share one key.
|
|
6
|
+
*
|
|
7
|
+
* Each package subclasses it with its own name and dimensions, such as
|
|
8
|
+
* `MissingCachePartitionError`.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* export class MissingCachePartitionError extends MissingPartitionError<'tenant' | 'principal'> {
|
|
13
|
+
* override readonly name = 'MissingCachePartitionError';
|
|
14
|
+
*
|
|
15
|
+
* constructor(requestName: string, dimension: 'tenant' | 'principal', remedy: string) {
|
|
16
|
+
* super('Cache', requestName, dimension, remedy);
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare abstract class MissingPartitionError<TDimension extends string = string> extends Error {
|
|
22
|
+
readonly requestName: string;
|
|
23
|
+
readonly dimension: TDimension;
|
|
24
|
+
readonly remedy: string;
|
|
25
|
+
protected constructor(keyKind: string, requestName: string, dimension: TDimension, remedy: string);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=missing-partition.error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missing-partition.error.d.ts","sourceRoot":"","sources":["../../src/errors/missing-partition.error.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,8BAAsB,qBAAqB,CACzC,UAAU,SAAS,MAAM,GAAG,MAAM,CAClC,SAAQ,KAAK;aAGK,WAAW,EAAE,MAAM;aACnB,SAAS,EAAE,UAAU;aACrB,MAAM,EAAE,MAAM;IAJhC,SAAS,aACP,OAAO,EAAE,MAAM,EACC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,UAAU,EACrB,MAAM,EAAE,MAAM,EAK/B;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
/**
|
|
3
|
+
* Raised when a partitioned key (cache, idempotency, rate limit) needs a
|
|
4
|
+
* dimension, such as the tenant or the principal, that could not be resolved.
|
|
5
|
+
* Omitting it instead would merge isolation domains: callers whose identity
|
|
6
|
+
* is unknown would share one key.
|
|
7
|
+
*
|
|
8
|
+
* Each package subclasses it with its own name and dimensions, such as
|
|
9
|
+
* `MissingCachePartitionError`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* export class MissingCachePartitionError extends MissingPartitionError<'tenant' | 'principal'> {
|
|
14
|
+
* override readonly name = 'MissingCachePartitionError';
|
|
15
|
+
*
|
|
16
|
+
* constructor(requestName: string, dimension: 'tenant' | 'principal', remedy: string) {
|
|
17
|
+
* super('Cache', requestName, dimension, remedy);
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export class MissingPartitionError extends Error {
|
|
23
|
+
requestName;
|
|
24
|
+
dimension;
|
|
25
|
+
remedy;
|
|
26
|
+
constructor(keyKind, requestName, dimension, remedy) {
|
|
27
|
+
super(`${keyKind} key for ${requestName} requires a ${dimension} partition, which could not be resolved. ${remedy}`);
|
|
28
|
+
this.requestName = requestName;
|
|
29
|
+
this.dimension = dimension;
|
|
30
|
+
this.remedy = remedy;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=missing-partition.error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missing-partition.error.js","sourceRoot":"","sources":["../../src/errors/missing-partition.error.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAgB,qBAEpB,SAAQ,KAAK;IAGK,WAAW;IACX,SAAS;IACT,MAAM;IAJxB,YACE,OAAe,EACC,WAAmB,EACnB,SAAqB,EACrB,MAAc;QAE9B,KAAK,CACH,GAAG,OAAO,YAAY,WAAW,eAAe,SAAS,4CAA4C,MAAM,EAAE,CAC9G,CAAC;2BANc,WAAW;yBACX,SAAS;sBACT,MAAM;IAKxB,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** A required context item is absent or contains undefined. */
|
|
2
|
+
export declare class MissingPipelineItemError extends Error {
|
|
3
|
+
readonly itemName: string;
|
|
4
|
+
readonly requestName: string;
|
|
5
|
+
readonly handlerName: string;
|
|
6
|
+
constructor(itemName: string, requestName: string, handlerName: string, customMessage?: string);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=missing-pipeline-item.error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missing-pipeline-item.error.d.ts","sourceRoot":"","sources":["../../src/errors/missing-pipeline-item.error.ts"],"names":[],"mappings":"AAEA,+DAA+D;AAC/D,qBAAa,wBAAyB,SAAQ,KAAK;IAE/C,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM;IAH9B,YACW,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EAC5B,aAAa,CAAC,EAAE,MAAM,EAOvB;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
/** A required context item is absent or contains undefined. */
|
|
3
|
+
export class MissingPipelineItemError extends Error {
|
|
4
|
+
itemName;
|
|
5
|
+
requestName;
|
|
6
|
+
handlerName;
|
|
7
|
+
constructor(itemName, requestName, handlerName, customMessage) {
|
|
8
|
+
super(`Missing pipeline item "${itemName}" for request "${requestName}" in handler "${handlerName}". Populate the item before reading it with requirePipelineItem.` +
|
|
9
|
+
(customMessage ? ` ${customMessage}` : ''));
|
|
10
|
+
this.itemName = itemName;
|
|
11
|
+
this.requestName = requestName;
|
|
12
|
+
this.handlerName = handlerName;
|
|
13
|
+
this.name = MissingPipelineItemError.name;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=missing-pipeline-item.error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missing-pipeline-item.error.js","sourceRoot":"","sources":["../../src/errors/missing-pipeline-item.error.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,+DAA+D;AAC/D,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IAEtC,QAAQ;IACR,WAAW;IACX,WAAW;IAHtB,YACW,QAAgB,EAChB,WAAmB,EACnB,WAAmB,EAC5B,aAAsB;QAEtB,KAAK,CACH,0BAA0B,QAAQ,kBAAkB,WAAW,iBAAiB,WAAW,kEAAkE;YAC3J,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAC7C,CAAC;wBARO,QAAQ;2BACR,WAAW;2BACX,WAAW;QAOpB,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC,IAAI,CAAC;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { PipelineBehaviorEntry } from './entries.js';
|
|
2
|
+
import type { BehaviorId } from './helpers/behavior-id.js';
|
|
3
|
+
import type { IPipelineBehavior } from './interfaces/pipeline.behavior.interface.js';
|
|
4
|
+
import type { Constructor } from './types.js';
|
|
5
|
+
/** A class, of a request or of a handler, whatever its constructor takes. */
|
|
6
|
+
export type AnyClass = abstract new (...args: any[]) => unknown;
|
|
7
|
+
/**
|
|
8
|
+
* A class decorator for the standard and the `experimentalDecorators` mode: it receives
|
|
9
|
+
* the class, and a context only in the standard mode.
|
|
10
|
+
*/
|
|
11
|
+
export type DualClassDecorator = (target: AnyClass, context?: ClassDecoratorContext) => void;
|
|
12
|
+
/** The pipeline a handler class declares with `@UsePipeline` and `@SkipPipeline`. */
|
|
13
|
+
export interface HandlerPipeline {
|
|
14
|
+
readonly types: Constructor<IPipelineBehavior>[];
|
|
15
|
+
readonly options: Map<BehaviorId, Record<string, unknown>>;
|
|
16
|
+
readonly skipped: Constructor<IPipelineBehavior>[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Declares the behaviors that run around a handler, outermost first: behavior classes or
|
|
20
|
+
* `[Behavior, options]` tuples such as `cache({ key })`. The global behaviors wrap these;
|
|
21
|
+
* a behavior declared in both runs once, at its global position, with these options
|
|
22
|
+
* merged over the global ones. The handler runtime reads the declaration with
|
|
23
|
+
* {@link pipelineOf}.
|
|
24
|
+
*
|
|
25
|
+
* @throws TypeError on a malformed entry.
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* @CommandHandler(CreateUserCommand)
|
|
29
|
+
* @UsePipeline(idempotent({ keyFactory }), audit({ action: 'user.create' }))
|
|
30
|
+
* class CreateUserHandler implements ICommandHandler<CreateUserCommand> {
|
|
31
|
+
* async execute(command: CreateUserCommand) {}
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function UsePipeline(...entries: PipelineBehaviorEntry[]): DualClassDecorator;
|
|
36
|
+
/**
|
|
37
|
+
* Opts a handler out of global behaviors. Repeated decorators add up.
|
|
38
|
+
*
|
|
39
|
+
* @throws TypeError when an argument is not a behavior class.
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* @QueryHandler(HealthQuery)
|
|
43
|
+
* @SkipPipeline(LoggingBehavior, TraceBehavior)
|
|
44
|
+
* class HealthHandler implements IQueryHandler<HealthQuery> {
|
|
45
|
+
* async execute() {
|
|
46
|
+
* return 'ok';
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function SkipPipeline(...behaviors: Constructor<IPipelineBehavior>[]): DualClassDecorator;
|
|
52
|
+
/**
|
|
53
|
+
* The pipeline a handler class declares; empty when it declares none. A subclass
|
|
54
|
+
* inherits its parent's declaration until it declares its own.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* pipelineOf(CreateUserHandler).types; // [IdempotencyBehavior, AuditBehavior]
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function pipelineOf(handler: AnyClass): HandlerPipeline;
|
|
62
|
+
//# sourceMappingURL=handler-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-pipeline.d.ts","sourceRoot":"","sources":["../src/handler-pipeline.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C,6EAA6E;AAE7E,MAAM,MAAM,QAAQ,GAAG,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC;AAEhE;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAC/B,MAAM,EAAE,QAAQ,EAChB,OAAO,CAAC,EAAE,qBAAqB,KAC5B,IAAI,CAAC;AAEV,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACjD,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC;CACpD;AAUD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CACzB,GAAG,OAAO,EAAE,qBAAqB,EAAE,GAClC,kBAAkB,CASpB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,GAAG,SAAS,EAAE,WAAW,CAAC,iBAAiB,CAAC,EAAE,GAC7C,kBAAkB,CAepB;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,QAAQ,GAAG,eAAe,CAO7D"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
import { normalizeBehaviorEntries } from './helpers/behavior-entries.js';
|
|
3
|
+
const PIPELINE = Symbol.for('@cqrs-ddd/pipeline:handler-pipeline');
|
|
4
|
+
const SKIPPED = Symbol.for('@cqrs-ddd/pipeline:skipped');
|
|
5
|
+
function define(target, key, value) {
|
|
6
|
+
Object.defineProperty(target, key, { value, configurable: true });
|
|
7
|
+
}
|
|
8
|
+
function read(target, key) {
|
|
9
|
+
return target[key];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Declares the behaviors that run around a handler, outermost first: behavior classes or
|
|
13
|
+
* `[Behavior, options]` tuples such as `cache({ key })`. The global behaviors wrap these;
|
|
14
|
+
* a behavior declared in both runs once, at its global position, with these options
|
|
15
|
+
* merged over the global ones. The handler runtime reads the declaration with
|
|
16
|
+
* {@link pipelineOf}.
|
|
17
|
+
*
|
|
18
|
+
* @throws TypeError on a malformed entry.
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* @CommandHandler(CreateUserCommand)
|
|
22
|
+
* @UsePipeline(idempotent({ keyFactory }), audit({ action: 'user.create' }))
|
|
23
|
+
* class CreateUserHandler implements ICommandHandler<CreateUserCommand> {
|
|
24
|
+
* async execute(command: CreateUserCommand) {}
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function UsePipeline(...entries) {
|
|
29
|
+
return (target, context) => {
|
|
30
|
+
const name = String(context?.name ?? target.name);
|
|
31
|
+
const { types, options } = normalizeBehaviorEntries(entries, `@UsePipeline on ${name}`);
|
|
32
|
+
define(target, PIPELINE, { types, options });
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Opts a handler out of global behaviors. Repeated decorators add up.
|
|
37
|
+
*
|
|
38
|
+
* @throws TypeError when an argument is not a behavior class.
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* @QueryHandler(HealthQuery)
|
|
42
|
+
* @SkipPipeline(LoggingBehavior, TraceBehavior)
|
|
43
|
+
* class HealthHandler implements IQueryHandler<HealthQuery> {
|
|
44
|
+
* async execute() {
|
|
45
|
+
* return 'ok';
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export function SkipPipeline(...behaviors) {
|
|
51
|
+
return (target, context) => {
|
|
52
|
+
const name = String(context?.name ?? target.name);
|
|
53
|
+
const existing = read(target, SKIPPED) ?? [];
|
|
54
|
+
define(target, SKIPPED, normalizeBehaviorEntries([...existing, ...behaviors], `@SkipPipeline on ${name}`, false).types);
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The pipeline a handler class declares; empty when it declares none. A subclass
|
|
59
|
+
* inherits its parent's declaration until it declares its own.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* pipelineOf(CreateUserHandler).types; // [IdempotencyBehavior, AuditBehavior]
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export function pipelineOf(handler) {
|
|
67
|
+
const declared = read(handler, PIPELINE);
|
|
68
|
+
return {
|
|
69
|
+
types: declared?.types ?? [],
|
|
70
|
+
options: declared?.options ?? new Map(),
|
|
71
|
+
skipped: read(handler, SKIPPED) ?? [],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=handler-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-pipeline.js","sourceRoot":"","sources":["../src/handler-pipeline.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAGtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAKzE,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACnE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;AAsBzD,SAAS,MAAM,CAAC,MAAgB,EAAE,GAAW,EAAE,KAAc;IAC3D,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,IAAI,CAAI,MAAgB,EAAE,GAAW;IAC5C,OAAQ,MAAmD,CAAC,GAAG,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,WAAW,CACzB,GAAG,OAAgC;IAEnC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;QACzB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,wBAAwB,CACjD,OAAO,EACP,mBAAmB,IAAI,EAAE,CAC1B,CAAC;QACF,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAG,SAA2C;IAE9C,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;QACzB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,QAAQ,GACZ,IAAI,CAAmC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QAChE,MAAM,CACJ,MAAM,EACN,OAAO,EACP,wBAAwB,CACtB,CAAC,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC,EAC3B,oBAAoB,IAAI,EAAE,EAC1B,KAAK,CACN,CAAC,KAAK,CACR,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,OAAiB;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAmC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3E,OAAO;QACL,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC5B,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,IAAI,GAAG,EAAE;QACvC,OAAO,EAAE,IAAI,CAAmC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;KACxE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { IPipelineBehavior } from '../interfaces/pipeline.behavior.interface.js';
|
|
2
|
+
import type { Constructor } from '../types.js';
|
|
3
|
+
import { type BehaviorId } from './behavior-id.js';
|
|
4
|
+
/** Validates a declaration before its plan is compiled. */
|
|
5
|
+
export declare function behaviorEntryType(entry: unknown, location: string, allowTuple?: boolean): Constructor<IPipelineBehavior>;
|
|
6
|
+
/**
|
|
7
|
+
* Accumulators shared across several calls, so one identity is deduplicated
|
|
8
|
+
* across every chain position and every matching global configuration.
|
|
9
|
+
*/
|
|
10
|
+
export interface BehaviorEntryAccumulators {
|
|
11
|
+
/** Identities already placed. The first occurrence fixes chain position. */
|
|
12
|
+
seen: Set<BehaviorId>;
|
|
13
|
+
/** Options by identity. A later tuple supplies the effective options. */
|
|
14
|
+
options: Map<BehaviorId, Record<string, unknown>>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* First identity fixes placement; the last tuple supplies options. Bare repeats
|
|
18
|
+
* preserve options.
|
|
19
|
+
*
|
|
20
|
+
* Pass `accumulators` to apply that rule across multiple entry lists — global
|
|
21
|
+
* `before` and `after` share one set so a behavior declared in both runs once,
|
|
22
|
+
* at its first position, without the bare repeat erasing tuple options.
|
|
23
|
+
*
|
|
24
|
+
* @param entries - Raw declarations, each a behavior class or `[Class, options]`.
|
|
25
|
+
* @param location - Human-readable declaration site, used in thrown messages.
|
|
26
|
+
* @param allowTuple - Whether `[Class, options]` is accepted (`@SkipPipeline` takes classes only).
|
|
27
|
+
* @param accumulators - Shared dedup state; a fresh pair is used when omitted.
|
|
28
|
+
* @returns Types to include, in first-seen order, plus the options map.
|
|
29
|
+
*/
|
|
30
|
+
export declare function normalizeBehaviorEntries(entries: readonly unknown[], location: string, allowTuple?: boolean, accumulators?: BehaviorEntryAccumulators): {
|
|
31
|
+
types: Constructor<IPipelineBehavior>[];
|
|
32
|
+
options: Map<BehaviorId, Record<string, unknown>>;
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=behavior-entries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavior-entries.d.ts","sourceRoot":"","sources":["../../src/helpers/behavior-entries.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,KAAK,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAElE,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,UAAO,GAChB,WAAW,CAAC,iBAAiB,CAAC,CAuBhC;AAED;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,4EAA4E;IAC5E,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACtB,yEAAyE;IACzE,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,UAAO,EACjB,YAAY,CAAC,EAAE,yBAAyB,GACvC;IACD,KAAK,EAAE,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACxC,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACnD,CAoBA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
import { getBehaviorId } from './behavior-id.js';
|
|
3
|
+
/** Validates a declaration before its plan is compiled. */
|
|
4
|
+
export function behaviorEntryType(entry, location, allowTuple = true) {
|
|
5
|
+
const tuple = Array.isArray(entry);
|
|
6
|
+
const candidate = tuple && allowTuple ? entry[0] : entry;
|
|
7
|
+
if (typeof candidate !== 'function' ||
|
|
8
|
+
!candidate.prototype ||
|
|
9
|
+
(tuple && entry.length !== 2)) {
|
|
10
|
+
throw new TypeError(`${location}: expected a behavior class${allowTuple ? ' or a [BehaviorClass, options] tuple' : ''}. Check for undefined references caused by circular imports.`);
|
|
11
|
+
}
|
|
12
|
+
if (tuple &&
|
|
13
|
+
(entry[1] === null ||
|
|
14
|
+
typeof entry[1] !== 'object' ||
|
|
15
|
+
Array.isArray(entry[1]))) {
|
|
16
|
+
throw new TypeError(`${location}: options for ${candidate.name} must be an object.`);
|
|
17
|
+
}
|
|
18
|
+
return candidate;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* First identity fixes placement; the last tuple supplies options. Bare repeats
|
|
22
|
+
* preserve options.
|
|
23
|
+
*
|
|
24
|
+
* Pass `accumulators` to apply that rule across multiple entry lists — global
|
|
25
|
+
* `before` and `after` share one set so a behavior declared in both runs once,
|
|
26
|
+
* at its first position, without the bare repeat erasing tuple options.
|
|
27
|
+
*
|
|
28
|
+
* @param entries - Raw declarations, each a behavior class or `[Class, options]`.
|
|
29
|
+
* @param location - Human-readable declaration site, used in thrown messages.
|
|
30
|
+
* @param allowTuple - Whether `[Class, options]` is accepted (`@SkipPipeline` takes classes only).
|
|
31
|
+
* @param accumulators - Shared dedup state; a fresh pair is used when omitted.
|
|
32
|
+
* @returns Types to include, in first-seen order, plus the options map.
|
|
33
|
+
*/
|
|
34
|
+
export function normalizeBehaviorEntries(entries, location, allowTuple = true, accumulators) {
|
|
35
|
+
const types = [];
|
|
36
|
+
const options = accumulators?.options ?? new Map();
|
|
37
|
+
const seen = accumulators?.seen ?? new Set();
|
|
38
|
+
entries.forEach((entry, index) => {
|
|
39
|
+
const type = behaviorEntryType(entry, `${location}, entry ${index}`, allowTuple);
|
|
40
|
+
const id = getBehaviorId(type);
|
|
41
|
+
if (Array.isArray(entry))
|
|
42
|
+
options.set(id, entry[1]);
|
|
43
|
+
if (!seen.has(id)) {
|
|
44
|
+
seen.add(id);
|
|
45
|
+
types.push(type);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return { types, options };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=behavior-entries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavior-entries.js","sourceRoot":"","sources":["../../src/helpers/behavior-entries.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAItE,OAAO,EAAmB,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAElE,2DAA2D;AAC3D,MAAM,UAAU,iBAAiB,CAC/B,KAAc,EACd,QAAgB,EAChB,UAAU,GAAG,IAAI;IAEjB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACzD,IACE,OAAO,SAAS,KAAK,UAAU;QAC/B,CAAC,SAAS,CAAC,SAAS;QACpB,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,EAC7B,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,GAAG,QAAQ,8BAA8B,UAAU,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC,EAAE,8DAA8D,CAChK,CAAC;IACJ,CAAC;IACD,IACE,KAAK;QACL,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;YAChB,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ;YAC5B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAC1B,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,GAAG,QAAQ,iBAAiB,SAAS,CAAC,IAAI,qBAAqB,CAChE,CAAC;IACJ,CAAC;IACD,OAAO,SAA2C,CAAC;AACrD,CAAC;AAaD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAA2B,EAC3B,QAAgB,EAChB,UAAU,GAAG,IAAI,EACjB,YAAwC;IAKxC,MAAM,KAAK,GAAqC,EAAE,CAAC;IACnD,MAAM,OAAO,GACX,YAAY,EAAE,OAAO,IAAI,IAAI,GAAG,EAAuC,CAAC;IAC1E,MAAM,IAAI,GAAG,YAAY,EAAE,IAAI,IAAI,IAAI,GAAG,EAAc,CAAC;IACzD,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,iBAAiB,CAC5B,KAAK,EACL,GAAG,QAAQ,WAAW,KAAK,EAAE,EAC7B,UAAU,CACX,CAAC;QACF,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAA4B,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { IPipelineBehavior } from '../interfaces/pipeline.behavior.interface.js';
|
|
2
|
+
import type { Constructor } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Optional static property on a behavior class that provides a stable,
|
|
5
|
+
* unique identity for deduplication when global and handler behaviors overlap.
|
|
6
|
+
*
|
|
7
|
+
* Use this to recognize one behavior across multiple loaded copies of its package:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* export class LoggingBehavior implements IPipelineBehavior {
|
|
11
|
+
* static readonly [PIPELINE_BEHAVIOR_ID] = 'my-package:LoggingBehavior';
|
|
12
|
+
* }
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* When absent, the constructor reference is used as the fallback identity.
|
|
16
|
+
*/
|
|
17
|
+
export declare const PIPELINE_BEHAVIOR_ID: unique symbol;
|
|
18
|
+
/**
|
|
19
|
+
* Identity of a behavior for deduplication and option lookup.
|
|
20
|
+
*
|
|
21
|
+
* Either the constructor itself — the default, and exact — or the string a class
|
|
22
|
+
* opted into through {@link PIPELINE_BEHAVIOR_ID}.
|
|
23
|
+
*/
|
|
24
|
+
export type BehaviorId = string | Constructor<IPipelineBehavior>;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the identity used to deduplicate a behavior and resolve its options.
|
|
27
|
+
*
|
|
28
|
+
* By default the constructor reference is the identity. A behavior that must be
|
|
29
|
+
* recognized across multiple loaded copies of the same package can opt into a
|
|
30
|
+
* stable string identity through {@link PIPELINE_BEHAVIOR_ID}.
|
|
31
|
+
*
|
|
32
|
+
* @param cls - Behavior class whose identity should be resolved.
|
|
33
|
+
* @returns The constructor reference or the behavior's explicit stable id.
|
|
34
|
+
*
|
|
35
|
+
* @example Stable identity across duplicated package copies
|
|
36
|
+
* ```ts
|
|
37
|
+
* export class LoggingBehavior implements IPipelineBehavior {
|
|
38
|
+
* static readonly [PIPELINE_BEHAVIOR_ID] = 'my-package:LoggingBehavior';
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function getBehaviorId(cls: Constructor<IPipelineBehavior>): BehaviorId;
|
|
43
|
+
//# sourceMappingURL=behavior-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavior-id.d.ts","sourceRoot":"","sources":["../../src/helpers/behavior-id.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,eAEhC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAAC;AAEjE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,CAAC,iBAAiB,CAAC,GAAG,UAAU,CAE7E"}
|