@fluojs/cqrs 1.0.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/LICENSE +21 -0
- package/README.ko.md +153 -0
- package/README.md +153 -0
- package/dist/buses/command-bus.d.ts +29 -0
- package/dist/buses/command-bus.d.ts.map +1 -0
- package/dist/buses/command-bus.js +122 -0
- package/dist/buses/event-bus.d.ts +49 -0
- package/dist/buses/event-bus.d.ts.map +1 -0
- package/dist/buses/event-bus.js +165 -0
- package/dist/buses/query-bus.d.ts +29 -0
- package/dist/buses/query-bus.d.ts.map +1 -0
- package/dist/buses/query-bus.js +122 -0
- package/dist/buses/saga-bus.d.ts +46 -0
- package/dist/buses/saga-bus.d.ts.map +1 -0
- package/dist/buses/saga-bus.js +225 -0
- package/dist/decorators.d.ts +48 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +127 -0
- package/dist/discovery.d.ts +27 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +84 -0
- package/dist/errors.d.ts +65 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +99 -0
- package/dist/event-clone.d.ts +10 -0
- package/dist/event-clone.d.ts.map +1 -0
- package/dist/event-clone.js +15 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/metadata.d.ts +87 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +235 -0
- package/dist/module.d.ts +30 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +74 -0
- package/dist/status.d.ts +17 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +69 -0
- package/dist/tokens.d.ts +9 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +6 -0
- package/dist/types.d.ts +161 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { metadataSymbol } from '@fluojs/core/internal';
|
|
2
|
+
import { commandHandlerMetadataSymbol, eventHandlerMetadataSymbol, queryHandlerMetadataSymbol, sagaMetadataSymbol } from './metadata.js';
|
|
3
|
+
function getStandardMetadataBag(metadata) {
|
|
4
|
+
void metadataSymbol;
|
|
5
|
+
if (typeof metadata !== 'object' || metadata === null) {
|
|
6
|
+
throw new Error('Decorator metadata is unavailable. Ensure standard decorators are enabled.');
|
|
7
|
+
}
|
|
8
|
+
return metadata;
|
|
9
|
+
}
|
|
10
|
+
function defineStandardCommandHandlerMetadata(metadata, handlerMetadata) {
|
|
11
|
+
const bag = getStandardMetadataBag(metadata);
|
|
12
|
+
bag[commandHandlerMetadataSymbol] = {
|
|
13
|
+
commandType: handlerMetadata.commandType
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function defineStandardQueryHandlerMetadata(metadata, handlerMetadata) {
|
|
17
|
+
const bag = getStandardMetadataBag(metadata);
|
|
18
|
+
bag[queryHandlerMetadataSymbol] = {
|
|
19
|
+
queryType: handlerMetadata.queryType
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function defineStandardEventHandlerMetadata(metadata, handlerMetadata) {
|
|
23
|
+
const bag = getStandardMetadataBag(metadata);
|
|
24
|
+
bag[eventHandlerMetadataSymbol] = {
|
|
25
|
+
eventType: handlerMetadata.eventType
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function defineStandardSagaMetadata(metadata, sagaMetadata) {
|
|
29
|
+
const bag = getStandardMetadataBag(metadata);
|
|
30
|
+
bag[sagaMetadataSymbol] = {
|
|
31
|
+
eventTypes: [...sagaMetadata.eventTypes]
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function normalizeSagaEventTypes(eventTypeOrTypes) {
|
|
35
|
+
const eventTypes = Array.isArray(eventTypeOrTypes) ? eventTypeOrTypes : [eventTypeOrTypes];
|
|
36
|
+
const uniqueEventTypes = Array.from(new Set(eventTypes));
|
|
37
|
+
if (uniqueEventTypes.length === 0) {
|
|
38
|
+
throw new Error('@Saga() requires at least one event type.');
|
|
39
|
+
}
|
|
40
|
+
for (const eventType of uniqueEventTypes) {
|
|
41
|
+
if (typeof eventType !== 'function') {
|
|
42
|
+
throw new Error('@Saga() event types must be class constructors.');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return uniqueEventTypes;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Associates a singleton provider class with one command type.
|
|
50
|
+
*
|
|
51
|
+
* @param commandType Command constructor handled by the decorated class.
|
|
52
|
+
* @returns A class decorator that stores command-handler metadata for discovery.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* import { CommandHandler, type ICommandHandler } from '@fluojs/cqrs';
|
|
57
|
+
*
|
|
58
|
+
* class CreateUserCommand {
|
|
59
|
+
* constructor(public readonly name: string) {}
|
|
60
|
+
* }
|
|
61
|
+
*
|
|
62
|
+
* @CommandHandler(CreateUserCommand)
|
|
63
|
+
* export class CreateUserHandler implements ICommandHandler<CreateUserCommand, string> {
|
|
64
|
+
* async execute(command: CreateUserCommand) {
|
|
65
|
+
* return command.name;
|
|
66
|
+
* }
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export function CommandHandler(commandType) {
|
|
71
|
+
const decorator = (_value, context) => {
|
|
72
|
+
const metadata = {
|
|
73
|
+
commandType
|
|
74
|
+
};
|
|
75
|
+
defineStandardCommandHandlerMetadata(context.metadata, metadata);
|
|
76
|
+
};
|
|
77
|
+
return decorator;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Associates a singleton provider class with one query type.
|
|
82
|
+
*
|
|
83
|
+
* @param queryType Query constructor handled by the decorated class.
|
|
84
|
+
* @returns A class decorator that stores query-handler metadata for discovery.
|
|
85
|
+
*/
|
|
86
|
+
export function QueryHandler(queryType) {
|
|
87
|
+
const decorator = (_value, context) => {
|
|
88
|
+
const metadata = {
|
|
89
|
+
queryType
|
|
90
|
+
};
|
|
91
|
+
defineStandardQueryHandlerMetadata(context.metadata, metadata);
|
|
92
|
+
};
|
|
93
|
+
return decorator;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Associates a singleton provider class with one event type.
|
|
98
|
+
*
|
|
99
|
+
* @param eventType Event constructor handled by the decorated class.
|
|
100
|
+
* @returns A class decorator that stores event-handler metadata for discovery.
|
|
101
|
+
*/
|
|
102
|
+
export function EventHandler(eventType) {
|
|
103
|
+
const decorator = (_value, context) => {
|
|
104
|
+
const metadata = {
|
|
105
|
+
eventType
|
|
106
|
+
};
|
|
107
|
+
defineStandardEventHandlerMetadata(context.metadata, metadata);
|
|
108
|
+
};
|
|
109
|
+
return decorator;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Marks a singleton provider class as a saga listener for one or more event types.
|
|
114
|
+
*
|
|
115
|
+
* @param eventTypeOrTypes One event constructor or a list of constructors that should trigger the saga.
|
|
116
|
+
* @returns A class decorator that stores saga metadata for discovery.
|
|
117
|
+
*/
|
|
118
|
+
export function Saga(eventTypeOrTypes) {
|
|
119
|
+
const eventTypes = normalizeSagaEventTypes(eventTypeOrTypes);
|
|
120
|
+
const decorator = (_value, context) => {
|
|
121
|
+
const metadata = {
|
|
122
|
+
eventTypes
|
|
123
|
+
};
|
|
124
|
+
defineStandardSagaMetadata(context.metadata, metadata);
|
|
125
|
+
};
|
|
126
|
+
return decorator;
|
|
127
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type Token } from '@fluojs/core';
|
|
2
|
+
import type { Container } from '@fluojs/di';
|
|
3
|
+
import type { ApplicationLogger, CompiledModule } from '@fluojs/runtime';
|
|
4
|
+
export interface DiscoveryCandidate {
|
|
5
|
+
moduleName: string;
|
|
6
|
+
scope: 'request' | 'singleton' | 'transient';
|
|
7
|
+
targetType: Function;
|
|
8
|
+
token: Token;
|
|
9
|
+
}
|
|
10
|
+
export declare function createDuplicateHandlerMessage(kind: 'command' | 'query' | 'event', messageType: Function, first: {
|
|
11
|
+
moduleName: string;
|
|
12
|
+
targetType: Function;
|
|
13
|
+
}, second: {
|
|
14
|
+
moduleName: string;
|
|
15
|
+
targetType: Function;
|
|
16
|
+
}): string;
|
|
17
|
+
export declare abstract class CqrsBusBase {
|
|
18
|
+
protected readonly runtimeContainer: Container;
|
|
19
|
+
protected readonly compiledModules: readonly CompiledModule[];
|
|
20
|
+
protected readonly logger: ApplicationLogger;
|
|
21
|
+
protected readonly handlerInstances: Map<Token, Promise<unknown>>;
|
|
22
|
+
constructor(runtimeContainer: Container, compiledModules: readonly CompiledModule[], logger: ApplicationLogger);
|
|
23
|
+
protected discoveryCandidates(): DiscoveryCandidate[];
|
|
24
|
+
protected preloadHandlerInstance(token: Token): Promise<void>;
|
|
25
|
+
protected resolveHandlerInstance(token: Token): Promise<unknown>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,WAAW,CAAC;IAC7C,UAAU,EAAE,QAAQ,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;CACd;AAkBD,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,EACnC,WAAW,EAAE,QAAQ,EACrB,KAAK,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,QAAQ,CAAA;CAAE,EACnD,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,QAAQ,CAAA;CAAE,GACnD,MAAM,CAER;AAED,8BAAsB,WAAW;IAI7B,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,SAAS;IAC9C,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,SAAS,cAAc,EAAE;IAC7D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB;IAL9C,SAAS,CAAC,QAAQ,CAAC,gBAAgB,+BAAsC;gBAGpD,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,MAAM,EAAE,iBAAiB;IAG9C,SAAS,CAAC,mBAAmB,IAAI,kBAAkB,EAAE;cAsCrC,sBAAsB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;cAgBnD,sBAAsB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;CAiBvE"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { getClassDiMetadata } from '@fluojs/core/internal';
|
|
2
|
+
function scopeFromProvider(provider) {
|
|
3
|
+
if (typeof provider === 'function') {
|
|
4
|
+
return getClassDiMetadata(provider)?.scope ?? 'singleton';
|
|
5
|
+
}
|
|
6
|
+
if ('useClass' in provider) {
|
|
7
|
+
return provider.scope ?? getClassDiMetadata(provider.useClass)?.scope ?? 'singleton';
|
|
8
|
+
}
|
|
9
|
+
return 'scope' in provider ? provider.scope ?? 'singleton' : 'singleton';
|
|
10
|
+
}
|
|
11
|
+
function isClassProvider(provider) {
|
|
12
|
+
return typeof provider === 'object' && provider !== null && 'useClass' in provider;
|
|
13
|
+
}
|
|
14
|
+
export function createDuplicateHandlerMessage(kind, messageType, first, second) {
|
|
15
|
+
return `Duplicate ${kind} handler for ${messageType.name} was discovered in ${first.moduleName}.${first.targetType.name} and ${second.moduleName}.${second.targetType.name}.`;
|
|
16
|
+
}
|
|
17
|
+
export class CqrsBusBase {
|
|
18
|
+
handlerInstances = new Map();
|
|
19
|
+
constructor(runtimeContainer, compiledModules, logger) {
|
|
20
|
+
this.runtimeContainer = runtimeContainer;
|
|
21
|
+
this.compiledModules = compiledModules;
|
|
22
|
+
this.logger = logger;
|
|
23
|
+
}
|
|
24
|
+
discoveryCandidates() {
|
|
25
|
+
const candidates = [];
|
|
26
|
+
for (const compiledModule of this.compiledModules) {
|
|
27
|
+
for (const provider of compiledModule.definition.providers ?? []) {
|
|
28
|
+
if (typeof provider === 'function') {
|
|
29
|
+
candidates.push({
|
|
30
|
+
moduleName: compiledModule.type.name,
|
|
31
|
+
scope: scopeFromProvider(provider),
|
|
32
|
+
targetType: provider,
|
|
33
|
+
token: provider
|
|
34
|
+
});
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (isClassProvider(provider)) {
|
|
38
|
+
candidates.push({
|
|
39
|
+
moduleName: compiledModule.type.name,
|
|
40
|
+
scope: scopeFromProvider(provider),
|
|
41
|
+
targetType: provider.useClass,
|
|
42
|
+
token: provider.provide
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
for (const controller of compiledModule.definition.controllers ?? []) {
|
|
47
|
+
candidates.push({
|
|
48
|
+
moduleName: compiledModule.type.name,
|
|
49
|
+
scope: scopeFromProvider(controller),
|
|
50
|
+
targetType: controller,
|
|
51
|
+
token: controller
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return candidates;
|
|
56
|
+
}
|
|
57
|
+
async preloadHandlerInstance(token) {
|
|
58
|
+
if (this.handlerInstances.has(token)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const resolving = this.runtimeContainer.resolve(token);
|
|
62
|
+
this.handlerInstances.set(token, resolving);
|
|
63
|
+
try {
|
|
64
|
+
await resolving;
|
|
65
|
+
} catch (error) {
|
|
66
|
+
this.handlerInstances.delete(token);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async resolveHandlerInstance(token) {
|
|
71
|
+
const cached = this.handlerInstances.get(token);
|
|
72
|
+
if (cached) {
|
|
73
|
+
return await cached;
|
|
74
|
+
}
|
|
75
|
+
const resolving = this.runtimeContainer.resolve(token);
|
|
76
|
+
this.handlerInstances.set(token, resolving);
|
|
77
|
+
try {
|
|
78
|
+
return await resolving;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
this.handlerInstances.delete(token);
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { FluoError } from '@fluojs/core';
|
|
2
|
+
/** Raised when the command bus cannot find a handler for the requested command type. */
|
|
3
|
+
export declare class CommandHandlerNotFoundException extends FluoError {
|
|
4
|
+
/**
|
|
5
|
+
* Creates a missing-command-handler error.
|
|
6
|
+
*
|
|
7
|
+
* @param message Human-readable failure description.
|
|
8
|
+
*/
|
|
9
|
+
constructor(message: string);
|
|
10
|
+
}
|
|
11
|
+
/** Raised when two different singleton providers claim the same command type. */
|
|
12
|
+
export declare class DuplicateCommandHandlerError extends FluoError {
|
|
13
|
+
/**
|
|
14
|
+
* Creates a duplicate-command-handler error.
|
|
15
|
+
*
|
|
16
|
+
* @param message Human-readable failure description.
|
|
17
|
+
*/
|
|
18
|
+
constructor(message: string);
|
|
19
|
+
}
|
|
20
|
+
/** Raised when the query bus cannot find a handler for the requested query type. */
|
|
21
|
+
export declare class QueryHandlerNotFoundException extends FluoError {
|
|
22
|
+
/**
|
|
23
|
+
* Creates a missing-query-handler error.
|
|
24
|
+
*
|
|
25
|
+
* @param message Human-readable failure description.
|
|
26
|
+
*/
|
|
27
|
+
constructor(message: string);
|
|
28
|
+
}
|
|
29
|
+
/** Raised when two different singleton providers claim the same query type. */
|
|
30
|
+
export declare class DuplicateQueryHandlerError extends FluoError {
|
|
31
|
+
/**
|
|
32
|
+
* Creates a duplicate-query-handler error.
|
|
33
|
+
*
|
|
34
|
+
* @param message Human-readable failure description.
|
|
35
|
+
*/
|
|
36
|
+
constructor(message: string);
|
|
37
|
+
}
|
|
38
|
+
/** Raised when conflicting event-handler registrations break the CQRS discovery contract. */
|
|
39
|
+
export declare class DuplicateEventHandlerError extends FluoError {
|
|
40
|
+
/**
|
|
41
|
+
* Creates a duplicate-event-handler error.
|
|
42
|
+
*
|
|
43
|
+
* @param message Human-readable failure description.
|
|
44
|
+
*/
|
|
45
|
+
constructor(message: string);
|
|
46
|
+
}
|
|
47
|
+
/** Raised when a saga throws a non-Fluo error while handling an event. */
|
|
48
|
+
export declare class SagaExecutionError extends FluoError {
|
|
49
|
+
/**
|
|
50
|
+
* Creates a saga-execution error.
|
|
51
|
+
*
|
|
52
|
+
* @param message Human-readable failure description.
|
|
53
|
+
*/
|
|
54
|
+
constructor(message: string);
|
|
55
|
+
}
|
|
56
|
+
/** Raised when saga orchestration re-enters an unsafe in-process topology. */
|
|
57
|
+
export declare class SagaTopologyError extends FluoError {
|
|
58
|
+
/**
|
|
59
|
+
* Creates a saga-topology guard error.
|
|
60
|
+
*
|
|
61
|
+
* @param message Human-readable failure description.
|
|
62
|
+
*/
|
|
63
|
+
constructor(message: string);
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,wFAAwF;AACxF,qBAAa,+BAAgC,SAAQ,SAAS;IAC5D;;;;OAIG;gBACS,OAAO,EAAE,MAAM;CAG5B;AAED,iFAAiF;AACjF,qBAAa,4BAA6B,SAAQ,SAAS;IACzD;;;;OAIG;gBACS,OAAO,EAAE,MAAM;CAG5B;AAED,oFAAoF;AACpF,qBAAa,6BAA8B,SAAQ,SAAS;IAC1D;;;;OAIG;gBACS,OAAO,EAAE,MAAM;CAG5B;AAED,+EAA+E;AAC/E,qBAAa,0BAA2B,SAAQ,SAAS;IACvD;;;;OAIG;gBACS,OAAO,EAAE,MAAM;CAG5B;AAED,6FAA6F;AAC7F,qBAAa,0BAA2B,SAAQ,SAAS;IACvD;;;;OAIG;gBACS,OAAO,EAAE,MAAM;CAG5B;AAED,0EAA0E;AAC1E,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C;;;;OAIG;gBACS,OAAO,EAAE,MAAM;CAG5B;AAED,8EAA8E;AAC9E,qBAAa,iBAAkB,SAAQ,SAAS;IAC9C;;;;OAIG;gBACS,OAAO,EAAE,MAAM;CAG5B"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { FluoError } from '@fluojs/core';
|
|
2
|
+
|
|
3
|
+
/** Raised when the command bus cannot find a handler for the requested command type. */
|
|
4
|
+
export class CommandHandlerNotFoundException extends FluoError {
|
|
5
|
+
/**
|
|
6
|
+
* Creates a missing-command-handler error.
|
|
7
|
+
*
|
|
8
|
+
* @param message Human-readable failure description.
|
|
9
|
+
*/
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message, {
|
|
12
|
+
code: 'CQRS_COMMAND_HANDLER_NOT_FOUND'
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Raised when two different singleton providers claim the same command type. */
|
|
18
|
+
export class DuplicateCommandHandlerError extends FluoError {
|
|
19
|
+
/**
|
|
20
|
+
* Creates a duplicate-command-handler error.
|
|
21
|
+
*
|
|
22
|
+
* @param message Human-readable failure description.
|
|
23
|
+
*/
|
|
24
|
+
constructor(message) {
|
|
25
|
+
super(message, {
|
|
26
|
+
code: 'CQRS_DUPLICATE_COMMAND_HANDLER'
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Raised when the query bus cannot find a handler for the requested query type. */
|
|
32
|
+
export class QueryHandlerNotFoundException extends FluoError {
|
|
33
|
+
/**
|
|
34
|
+
* Creates a missing-query-handler error.
|
|
35
|
+
*
|
|
36
|
+
* @param message Human-readable failure description.
|
|
37
|
+
*/
|
|
38
|
+
constructor(message) {
|
|
39
|
+
super(message, {
|
|
40
|
+
code: 'CQRS_QUERY_HANDLER_NOT_FOUND'
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Raised when two different singleton providers claim the same query type. */
|
|
46
|
+
export class DuplicateQueryHandlerError extends FluoError {
|
|
47
|
+
/**
|
|
48
|
+
* Creates a duplicate-query-handler error.
|
|
49
|
+
*
|
|
50
|
+
* @param message Human-readable failure description.
|
|
51
|
+
*/
|
|
52
|
+
constructor(message) {
|
|
53
|
+
super(message, {
|
|
54
|
+
code: 'CQRS_DUPLICATE_QUERY_HANDLER'
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Raised when conflicting event-handler registrations break the CQRS discovery contract. */
|
|
60
|
+
export class DuplicateEventHandlerError extends FluoError {
|
|
61
|
+
/**
|
|
62
|
+
* Creates a duplicate-event-handler error.
|
|
63
|
+
*
|
|
64
|
+
* @param message Human-readable failure description.
|
|
65
|
+
*/
|
|
66
|
+
constructor(message) {
|
|
67
|
+
super(message, {
|
|
68
|
+
code: 'CQRS_DUPLICATE_EVENT_HANDLER'
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Raised when a saga throws a non-Fluo error while handling an event. */
|
|
74
|
+
export class SagaExecutionError extends FluoError {
|
|
75
|
+
/**
|
|
76
|
+
* Creates a saga-execution error.
|
|
77
|
+
*
|
|
78
|
+
* @param message Human-readable failure description.
|
|
79
|
+
*/
|
|
80
|
+
constructor(message) {
|
|
81
|
+
super(message, {
|
|
82
|
+
code: 'CQRS_SAGA_EXECUTION_FAILED'
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Raised when saga orchestration re-enters an unsafe in-process topology. */
|
|
88
|
+
export class SagaTopologyError extends FluoError {
|
|
89
|
+
/**
|
|
90
|
+
* Creates a saga-topology guard error.
|
|
91
|
+
*
|
|
92
|
+
* @param message Human-readable failure description.
|
|
93
|
+
*/
|
|
94
|
+
constructor(message) {
|
|
95
|
+
super(message, {
|
|
96
|
+
code: 'CQRS_SAGA_UNSAFE_TOPOLOGY'
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CqrsEventType, IEvent } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an isolated event instance by cloning the source payload before rehydrating the event prototype.
|
|
4
|
+
*
|
|
5
|
+
* @param eventType Event class whose prototype should back the isolated event.
|
|
6
|
+
* @param source Source payload to clone and assign onto the event instance.
|
|
7
|
+
* @returns A detached event instance with the requested event prototype.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createIsolatedEvent<TEvent extends IEvent>(eventType: CqrsEventType<TEvent>, source: unknown): TEvent;
|
|
10
|
+
//# sourceMappingURL=event-clone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-clone.d.ts","sourceRoot":"","sources":["../src/event-clone.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAQpH"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { cloneWithFallback } from '@fluojs/core/internal';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an isolated event instance by cloning the source payload before rehydrating the event prototype.
|
|
4
|
+
*
|
|
5
|
+
* @param eventType Event class whose prototype should back the isolated event.
|
|
6
|
+
* @param source Source payload to clone and assign onto the event instance.
|
|
7
|
+
* @returns A detached event instance with the requested event prototype.
|
|
8
|
+
*/
|
|
9
|
+
export function createIsolatedEvent(eventType, source) {
|
|
10
|
+
const clonedPayload = cloneWithFallback(source);
|
|
11
|
+
if (typeof clonedPayload !== 'object' || clonedPayload === null) {
|
|
12
|
+
return clonedPayload;
|
|
13
|
+
}
|
|
14
|
+
return Object.assign(Object.create(eventType.prototype), clonedPayload);
|
|
15
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { CommandHandler, EventHandler, QueryHandler, Saga } from './decorators.js';
|
|
2
|
+
export { DuplicateCommandHandlerError, DuplicateEventHandlerError, DuplicateQueryHandlerError, CommandHandlerNotFoundException, QueryHandlerNotFoundException, SagaExecutionError, SagaTopologyError, } from './errors.js';
|
|
3
|
+
export { commandHandlerMetadataSymbol, defineCommandHandlerMetadata, defineEventHandlerMetadata, defineQueryHandlerMetadata, eventHandlerMetadataSymbol, getCommandHandlerMetadata, getCommandHandlerMetadataEntry, getEventHandlerMetadata, getQueryHandlerMetadata, getQueryHandlerMetadataEntry, queryHandlerMetadataSymbol, defineSagaMetadata, getSagaMetadata, sagaMetadataSymbol, } from './metadata.js';
|
|
4
|
+
export { CqrsModule, type CqrsModuleOptions } from './module.js';
|
|
5
|
+
export * from './status.js';
|
|
6
|
+
export { CommandBusLifecycleService } from './buses/command-bus.js';
|
|
7
|
+
export { CqrsEventBusService } from './buses/event-bus.js';
|
|
8
|
+
export { QueryBusLifecycleService } from './buses/query-bus.js';
|
|
9
|
+
export { COMMAND_BUS, EVENT_BUS, QUERY_BUS } from './tokens.js';
|
|
10
|
+
export type { CommandBus, CommandHandlerClass, CommandHandlerDescriptor, CommandHandlerMetadata, CommandType, CqrsEventBus, CqrsEventType, EventHandlerDescriptor, EventHandlerClass, EventHandlerMetadata, ICommand, ICommandHandler, IEvent, IEventHandler, IQuery, IQueryHandler, ISaga, QueryBus, QueryHandlerClass, QueryHandlerDescriptor, QueryHandlerMetadata, QueryType, SagaClass, SagaDescriptor, SagaMetadata, } from './types.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,+BAA+B,EAC/B,6BAA6B,EAC7B,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,0BAA0B,EAC1B,yBAAyB,EACzB,8BAA8B,EAC9B,uBAAuB,EACvB,uBAAuB,EACvB,4BAA4B,EAC5B,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACjE,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,EACtB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,QAAQ,EACR,eAAe,EACf,MAAM,EACN,aAAa,EACb,MAAM,EACN,aAAa,EACb,KAAK,EACL,QAAQ,EACR,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,SAAS,EACT,SAAS,EACT,cAAc,EACd,YAAY,GACb,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { CommandHandler, EventHandler, QueryHandler, Saga } from './decorators.js';
|
|
2
|
+
export { DuplicateCommandHandlerError, DuplicateEventHandlerError, DuplicateQueryHandlerError, CommandHandlerNotFoundException, QueryHandlerNotFoundException, SagaExecutionError, SagaTopologyError } from './errors.js';
|
|
3
|
+
export { commandHandlerMetadataSymbol, defineCommandHandlerMetadata, defineEventHandlerMetadata, defineQueryHandlerMetadata, eventHandlerMetadataSymbol, getCommandHandlerMetadata, getCommandHandlerMetadataEntry, getEventHandlerMetadata, getQueryHandlerMetadata, getQueryHandlerMetadataEntry, queryHandlerMetadataSymbol, defineSagaMetadata, getSagaMetadata, sagaMetadataSymbol } from './metadata.js';
|
|
4
|
+
export { CqrsModule } from './module.js';
|
|
5
|
+
export * from './status.js';
|
|
6
|
+
export { CommandBusLifecycleService } from './buses/command-bus.js';
|
|
7
|
+
export { CqrsEventBusService } from './buses/event-bus.js';
|
|
8
|
+
export { QueryBusLifecycleService } from './buses/query-bus.js';
|
|
9
|
+
export { COMMAND_BUS, EVENT_BUS, QUERY_BUS } from './tokens.js';
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type MetadataPropertyKey } from '@fluojs/core';
|
|
2
|
+
import type { CommandHandlerMetadata, EventHandlerMetadata, QueryHandlerMetadata, SagaMetadata } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Stores command-handler metadata on a class for compatibility with manual metadata registration.
|
|
5
|
+
*
|
|
6
|
+
* @param target Handler class constructor receiving the metadata.
|
|
7
|
+
* @param metadata Command-handler metadata to store.
|
|
8
|
+
*/
|
|
9
|
+
export declare function defineCommandHandlerMetadata(target: Function, metadata: CommandHandlerMetadata): void;
|
|
10
|
+
/**
|
|
11
|
+
* Reads command-handler metadata from either the compatibility store or standard decorator metadata.
|
|
12
|
+
*
|
|
13
|
+
* @param target Handler class constructor to inspect.
|
|
14
|
+
* @returns The resolved command-handler metadata, if present.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getCommandHandlerMetadata(target: Function): CommandHandlerMetadata | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Stores query-handler metadata on a class for compatibility with manual metadata registration.
|
|
19
|
+
*
|
|
20
|
+
* @param target Handler class constructor receiving the metadata.
|
|
21
|
+
* @param metadata Query-handler metadata to store.
|
|
22
|
+
*/
|
|
23
|
+
export declare function defineQueryHandlerMetadata(target: Function, metadata: QueryHandlerMetadata): void;
|
|
24
|
+
/**
|
|
25
|
+
* Reads query-handler metadata from either the compatibility store or standard decorator metadata.
|
|
26
|
+
*
|
|
27
|
+
* @param target Handler class constructor to inspect.
|
|
28
|
+
* @returns The resolved query-handler metadata, if present.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getQueryHandlerMetadata(target: Function): QueryHandlerMetadata | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Stores event-handler metadata on a class for compatibility with manual metadata registration.
|
|
33
|
+
*
|
|
34
|
+
* @param target Handler class constructor receiving the metadata.
|
|
35
|
+
* @param metadata Event-handler metadata to store.
|
|
36
|
+
*/
|
|
37
|
+
export declare function defineEventHandlerMetadata(target: Function, metadata: EventHandlerMetadata): void;
|
|
38
|
+
/**
|
|
39
|
+
* Reads event-handler metadata from either the compatibility store or standard decorator metadata.
|
|
40
|
+
*
|
|
41
|
+
* @param target Handler class constructor to inspect.
|
|
42
|
+
* @returns The resolved event-handler metadata, if present.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getEventHandlerMetadata(target: Function): EventHandlerMetadata | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Stores saga metadata on a class for compatibility with manual metadata registration.
|
|
47
|
+
*
|
|
48
|
+
* @param target Saga class constructor receiving the metadata.
|
|
49
|
+
* @param metadata Saga metadata to store.
|
|
50
|
+
*/
|
|
51
|
+
export declare function defineSagaMetadata(target: Function, metadata: SagaMetadata): void;
|
|
52
|
+
/**
|
|
53
|
+
* Reads saga metadata from either the compatibility store or standard decorator metadata.
|
|
54
|
+
*
|
|
55
|
+
* @param target Saga class constructor to inspect.
|
|
56
|
+
* @returns The resolved saga metadata, if present.
|
|
57
|
+
*/
|
|
58
|
+
export declare function getSagaMetadata(target: Function): SagaMetadata | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Returns the normalized command-handler metadata entry used by public-surface tests and tooling.
|
|
61
|
+
*
|
|
62
|
+
* @param target Handler instance or prototype whose constructor should be inspected.
|
|
63
|
+
* @returns The command-handler metadata entry for the canonical `execute` method, if present.
|
|
64
|
+
*/
|
|
65
|
+
export declare function getCommandHandlerMetadataEntry(target: object): {
|
|
66
|
+
metadata: CommandHandlerMetadata;
|
|
67
|
+
propertyKey: MetadataPropertyKey;
|
|
68
|
+
} | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Returns the normalized query-handler metadata entry used by public-surface tests and tooling.
|
|
71
|
+
*
|
|
72
|
+
* @param target Handler instance or prototype whose constructor should be inspected.
|
|
73
|
+
* @returns The query-handler metadata entry for the canonical `execute` method, if present.
|
|
74
|
+
*/
|
|
75
|
+
export declare function getQueryHandlerMetadataEntry(target: object): {
|
|
76
|
+
metadata: QueryHandlerMetadata;
|
|
77
|
+
propertyKey: MetadataPropertyKey;
|
|
78
|
+
} | undefined;
|
|
79
|
+
/** Standard decorator metadata key used to store command-handler metadata. */
|
|
80
|
+
export declare const commandHandlerMetadataSymbol: symbol;
|
|
81
|
+
/** Standard decorator metadata key used to store query-handler metadata. */
|
|
82
|
+
export declare const queryHandlerMetadataSymbol: symbol;
|
|
83
|
+
/** Standard decorator metadata key used to store event-handler metadata. */
|
|
84
|
+
export declare const eventHandlerMetadataSymbol: symbol;
|
|
85
|
+
/** Standard decorator metadata key used to store saga metadata. */
|
|
86
|
+
export declare const sagaMetadataSymbol: symbol;
|
|
87
|
+
//# sourceMappingURL=metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGxD,OAAO,KAAK,EACV,sBAAsB,EAGtB,oBAAoB,EACpB,oBAAoB,EAEpB,YAAY,EACb,MAAM,YAAY,CAAC;AA+GpB;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,sBAAsB,GAAG,IAAI,CAErG;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,QAAQ,GAAG,sBAAsB,GAAG,SAAS,CAS9F;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAEjG;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,QAAQ,GAAG,oBAAoB,GAAG,SAAS,CAS1F;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAEjG;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,QAAQ,GAAG,oBAAoB,GAAG,SAAS,CAS1F;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAEjF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,YAAY,GAAG,SAAS,CAS1E;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,MAAM,GACb;IAAE,QAAQ,EAAE,sBAAsB,CAAC;IAAC,WAAW,EAAE,mBAAmB,CAAA;CAAE,GAAG,SAAS,CAiBpF;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,GACb;IAAE,QAAQ,EAAE,oBAAoB,CAAC;IAAC,WAAW,EAAE,mBAAmB,CAAA;CAAE,GAAG,SAAS,CAiBlF;AAED,8EAA8E;AAC9E,eAAO,MAAM,4BAA4B,QAAoC,CAAC;AAC9E,4EAA4E;AAC5E,eAAO,MAAM,0BAA0B,QAAkC,CAAC;AAC1E,4EAA4E;AAC5E,eAAO,MAAM,0BAA0B,QAAkC,CAAC;AAC1E,mEAAmE;AACnE,eAAO,MAAM,kBAAkB,QAA0B,CAAC"}
|