@zmdb/app 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 +674 -0
- package/README.md +27 -0
- package/dist/application.d.ts +45 -0
- package/dist/application.d.ts.map +1 -0
- package/dist/application.js +186 -0
- package/dist/application.js.map +1 -0
- package/dist/commands/index.d.ts +31 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +338 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/cqrs/index.d.ts +47 -0
- package/dist/cqrs/index.d.ts.map +1 -0
- package/dist/cqrs/index.js +76 -0
- package/dist/cqrs/index.js.map +1 -0
- package/dist/data/index.d.ts +12 -0
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/index.js +25 -0
- package/dist/data/index.js.map +1 -0
- package/dist/di/index.d.ts +44 -0
- package/dist/di/index.d.ts.map +1 -0
- package/dist/di/index.js +136 -0
- package/dist/di/index.js.map +1 -0
- package/dist/events/index.d.ts +46 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +181 -0
- package/dist/events/index.js.map +1 -0
- package/dist/health/index.d.ts +35 -0
- package/dist/health/index.d.ts.map +1 -0
- package/dist/health/index.js +14 -0
- package/dist/health/index.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle.d.ts +21 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +52 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/messaging/index.d.ts +176 -0
- package/dist/messaging/index.d.ts.map +1 -0
- package/dist/messaging/index.js +442 -0
- package/dist/messaging/index.js.map +1 -0
- package/dist/messaging/transport-kit.d.ts +22 -0
- package/dist/messaging/transport-kit.d.ts.map +1 -0
- package/dist/messaging/transport-kit.js +174 -0
- package/dist/messaging/transport-kit.js.map +1 -0
- package/dist/modules/index.d.ts +52 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/modules/index.js +351 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/lifecycle-instances.d.ts +4 -0
- package/dist/modules/lifecycle-instances.d.ts.map +1 -0
- package/dist/modules/lifecycle-instances.js +19 -0
- package/dist/modules/lifecycle-instances.js.map +1 -0
- package/dist/modules/runtime.d.ts +18 -0
- package/dist/modules/runtime.d.ts.map +1 -0
- package/dist/modules/runtime.js +8 -0
- package/dist/modules/runtime.js.map +1 -0
- package/dist/observability/index.d.ts +27 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +145 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/propagation.d.ts +10 -0
- package/dist/observability/propagation.d.ts.map +1 -0
- package/dist/observability/propagation.js +96 -0
- package/dist/observability/propagation.js.map +1 -0
- package/dist/observability/types.d.ts +66 -0
- package/dist/observability/types.d.ts.map +1 -0
- package/dist/observability/types.js +10 -0
- package/dist/observability/types.js.map +1 -0
- package/dist/polyfill.d.ts +2 -0
- package/dist/polyfill.d.ts.map +1 -0
- package/dist/polyfill.js +21 -0
- package/dist/polyfill.js.map +1 -0
- package/dist/state/fixtures.d.ts +10 -0
- package/dist/state/fixtures.d.ts.map +1 -0
- package/dist/state/fixtures.js +14 -0
- package/dist/state/fixtures.js.map +1 -0
- package/dist/state/index.d.ts +26 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +37 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state-transitions.d.ts +57 -0
- package/dist/state-transitions.d.ts.map +1 -0
- package/dist/state-transitions.js +31 -0
- package/dist/state-transitions.js.map +1 -0
- package/package.json +99 -0
- package/src/application.ts +243 -0
- package/src/commands/index.ts +447 -0
- package/src/cqrs/index.ts +124 -0
- package/src/data/index.ts +33 -0
- package/src/di/index.ts +179 -0
- package/src/events/index.ts +248 -0
- package/src/health/index.ts +54 -0
- package/src/index.ts +68 -0
- package/src/lifecycle.ts +62 -0
- package/src/messaging/index.ts +668 -0
- package/src/messaging/transport-kit.ts +234 -0
- package/src/modules/index.ts +476 -0
- package/src/modules/lifecycle-instances.ts +23 -0
- package/src/modules/runtime.ts +26 -0
- package/src/observability/index.ts +204 -0
- package/src/observability/propagation.ts +107 -0
- package/src/observability/types.ts +68 -0
- package/src/polyfill.ts +24 -0
- package/src/state/fixtures.ts +20 -0
- package/src/state/index.ts +57 -0
- package/src/state-transitions.ts +150 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type TransactionContext } from '@zmdb/orm/transactions';
|
|
2
|
+
/** A command name mapped to its input and result types. */
|
|
3
|
+
export interface CommandMap {
|
|
4
|
+
readonly [command: string]: {
|
|
5
|
+
readonly input: unknown;
|
|
6
|
+
readonly result: unknown;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
/** The caller-facing command object: one method per command name. */
|
|
10
|
+
export type CommandBus<M extends CommandMap> = {
|
|
11
|
+
readonly [K in keyof M]: (input: M[K]['input']) => Promise<M[K]['result']>;
|
|
12
|
+
};
|
|
13
|
+
/** The complete application-owned handler object. */
|
|
14
|
+
export type CommandHandlers<M extends CommandMap> = {
|
|
15
|
+
readonly [K in keyof M]: (input: M[K]['input'], ctx: CommandRun) => Promise<M[K]['result']>;
|
|
16
|
+
};
|
|
17
|
+
/** Context supplied to one command handler. */
|
|
18
|
+
export interface CommandRun {
|
|
19
|
+
readonly command: string;
|
|
20
|
+
readonly tx: TransactionContext | undefined;
|
|
21
|
+
}
|
|
22
|
+
/** Observation emitted after one command settles. */
|
|
23
|
+
export type CommandOutcome = {
|
|
24
|
+
readonly command: string;
|
|
25
|
+
readonly ok: true;
|
|
26
|
+
readonly ms: number;
|
|
27
|
+
} | {
|
|
28
|
+
readonly command: string;
|
|
29
|
+
readonly ok: false;
|
|
30
|
+
readonly ms: number;
|
|
31
|
+
readonly error: unknown;
|
|
32
|
+
};
|
|
33
|
+
/** The fixed command pipeline. Validation is deliberately total. */
|
|
34
|
+
export interface CommandBusOptions<M extends CommandMap> {
|
|
35
|
+
readonly validate: {
|
|
36
|
+
readonly [K in keyof M]: (raw: unknown) => M[K]['input'];
|
|
37
|
+
};
|
|
38
|
+
readonly authorise?: <K extends keyof M & string>(command: K, input: M[K]['input']) => Promise<void>;
|
|
39
|
+
readonly onCommand?: (run: CommandOutcome) => void;
|
|
40
|
+
readonly transaction?: (fn: (tx: TransactionContext) => Promise<unknown>) => Promise<unknown>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build an app-owned command bus from a complete, compile-time-checked handler
|
|
44
|
+
* map. There is no registry, discovery pass, decorator, or global singleton.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createCommandBus<M extends CommandMap>(handlers: CommandHandlers<M>, options: CommandBusOptions<M>): CommandBus<M>;
|
|
47
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cqrs/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,2DAA2D;AAC3D,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;CACnF;AAED,qEAAqE;AACrE,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,UAAU,IAAI;IAC7C,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;CAC3E,CAAC;AAEF,qDAAqD;AACrD,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,UAAU,IAAI;IAClD,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;CAC5F,CAAC;AAEF,+CAA+C;AAC/C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAC7C;AAED,qDAAqD;AACrD,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnG,oEAAoE;AACpE,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,UAAU;IACrD,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;KAAE,CAAC;IAChF,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrG,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IACnD,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,kBAAkB,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/F;AA+DD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,UAAU,EACnD,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,EAC5B,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC5B,UAAU,CAAC,CAAC,CAAC,CAcf"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// @zmdb/app — typed command bus (epic #591, spec ./SPEC.md).
|
|
2
|
+
// The mapped caller surface is built once from a complete handler map. Every
|
|
3
|
+
// command crosses the same validation, authorisation, transaction, and outcome
|
|
4
|
+
// observation boundary.
|
|
5
|
+
import {} from '@zmdb/orm/transactions';
|
|
6
|
+
function callable(record, key, kind) {
|
|
7
|
+
const value = Reflect.get(record, key);
|
|
8
|
+
if (typeof value !== 'function') {
|
|
9
|
+
throw new Error(`@zmdb/app: command "${key}" has no callable ${kind}`);
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
function observe(observer, outcome) {
|
|
14
|
+
if (observer === undefined) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
observer(outcome);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// Observation cannot replace either a successful result or the original
|
|
22
|
+
// command failure.
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function commandMethod(command, handler, validator, options) {
|
|
26
|
+
return async (raw) => {
|
|
27
|
+
const started = options.onCommand === undefined ? undefined : globalThis.performance.now();
|
|
28
|
+
try {
|
|
29
|
+
const input = Reflect.apply(validator, undefined, [raw]);
|
|
30
|
+
if (options.authorise !== undefined) {
|
|
31
|
+
await Reflect.apply(options.authorise, undefined, [command, input]);
|
|
32
|
+
}
|
|
33
|
+
const invoke = async (tx) => Reflect.apply(handler, undefined, [input, { command, tx }]);
|
|
34
|
+
const result = options.transaction === undefined ? await invoke(undefined) : await options.transaction(tx => invoke(tx));
|
|
35
|
+
if (started !== undefined) {
|
|
36
|
+
observe(options.onCommand, {
|
|
37
|
+
command,
|
|
38
|
+
ok: true,
|
|
39
|
+
ms: globalThis.performance.now() - started,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (started !== undefined) {
|
|
46
|
+
observe(options.onCommand, {
|
|
47
|
+
command,
|
|
48
|
+
ok: false,
|
|
49
|
+
ms: globalThis.performance.now() - started,
|
|
50
|
+
error,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build an app-owned command bus from a complete, compile-time-checked handler
|
|
59
|
+
* map. There is no registry, discovery pass, decorator, or global singleton.
|
|
60
|
+
*/
|
|
61
|
+
export function createCommandBus(handlers, options) {
|
|
62
|
+
// boundary: Object.create(null) supplies the empty runtime carrier. The
|
|
63
|
+
// mapped input types prove the handler and validator key sets are complete,
|
|
64
|
+
// and the loop installs one method for every own command before returning.
|
|
65
|
+
const bus = Object.create(null);
|
|
66
|
+
for (const command of Object.keys(handlers)) {
|
|
67
|
+
const handler = callable(handlers, command, 'handler');
|
|
68
|
+
const validator = callable(options.validate, command, 'validator');
|
|
69
|
+
const installed = Reflect.set(bus, command, commandMethod(command, handler, validator, options));
|
|
70
|
+
if (!installed) {
|
|
71
|
+
throw new Error(`@zmdb/app: could not install command "${command}"`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return bus;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cqrs/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type BaseRepository, type LoaderScope } from '@zmdb/orm';
|
|
2
|
+
import { type DeclaredTable } from '@zmdb/schema';
|
|
3
|
+
import { type Token } from '../di/index.js';
|
|
4
|
+
/** Data access shared within one request, never across requests. */
|
|
5
|
+
export interface RequestData {
|
|
6
|
+
readonly loaders: LoaderScope;
|
|
7
|
+
}
|
|
8
|
+
/** Allocate a loader scope only when the request first uses data loading. */
|
|
9
|
+
export declare function createRequestData(): RequestData;
|
|
10
|
+
/** A typed repository token shared by HTTP, jobs and command applications. */
|
|
11
|
+
export declare function repositoryToken<T extends DeclaredTable>(name: string): Token<BaseRepository<T>>;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AACrF,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEzD,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B;AAgBD,6EAA6E;AAC7E,wBAAgB,iBAAiB,IAAI,WAAW,CAE/C;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,CAAC,SAAS,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAE/F"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createLoaderScope } from '@zmdb/orm';
|
|
2
|
+
import {} from '@zmdb/schema';
|
|
3
|
+
import { createToken } from '../di/index.js';
|
|
4
|
+
const loadersByRequest = new WeakMap();
|
|
5
|
+
const loadersProperty = {
|
|
6
|
+
configurable: true,
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get() {
|
|
9
|
+
let loaders = loadersByRequest.get(this);
|
|
10
|
+
if (loaders === undefined) {
|
|
11
|
+
loaders = createLoaderScope();
|
|
12
|
+
loadersByRequest.set(this, loaders);
|
|
13
|
+
}
|
|
14
|
+
return loaders;
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
/** Allocate a loader scope only when the request first uses data loading. */
|
|
18
|
+
export function createRequestData() {
|
|
19
|
+
return Object.defineProperty({}, 'loaders', loadersProperty);
|
|
20
|
+
}
|
|
21
|
+
/** A typed repository token shared by HTTP, jobs and command applications. */
|
|
22
|
+
export function repositoryToken(name) {
|
|
23
|
+
return createToken(name);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAyC,MAAM,WAAW,CAAC;AACrF,OAAO,EAAsB,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,WAAW,EAAc,MAAM,gBAAgB,CAAC;AAOzD,MAAM,gBAAgB,GAAG,IAAI,OAAO,EAA4B,CAAC;AACjE,MAAM,eAAe,GAAuB;IAC1C,YAAY,EAAE,IAAI;IAClB,UAAU,EAAE,IAAI;IAChB,GAAG;QACD,IAAI,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,GAAG,iBAAiB,EAAE,CAAC;YAC9B,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC;AAEF,6EAA6E;AAC7E,MAAM,UAAU,iBAAiB;IAC/B,OAAO,MAAM,CAAC,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,eAAe,CAAgB,CAAC;AAC9E,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,eAAe,CAA0B,IAAY;IACnE,OAAO,WAAW,CAAoB,IAAI,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import '../polyfill.js';
|
|
2
|
+
export interface Token<T> {
|
|
3
|
+
readonly description: string;
|
|
4
|
+
readonly __type?: T;
|
|
5
|
+
}
|
|
6
|
+
/** Create a unique injection token carrying its instance type. */
|
|
7
|
+
export declare function createToken<T>(description: string): Token<T>;
|
|
8
|
+
/** Thrown by `Container.resolve` when a token was never registered. */
|
|
9
|
+
export declare class UnresolvedTokenError extends Error {
|
|
10
|
+
constructor(description: string);
|
|
11
|
+
}
|
|
12
|
+
/** Read the field-injection declarations recorded on a class. */
|
|
13
|
+
export declare function injectionsOf(ctor: abstract new (...args: never[]) => unknown): readonly {
|
|
14
|
+
readonly field: string | symbol;
|
|
15
|
+
readonly token: Token<unknown>;
|
|
16
|
+
}[];
|
|
17
|
+
/**
|
|
18
|
+
* Field decorator: resolve `token` from the container that is building this
|
|
19
|
+
* instance. The field's declared type must be assignable from the token type,
|
|
20
|
+
* so a mismatch is a compile error and no `as` is needed.
|
|
21
|
+
*/
|
|
22
|
+
export declare function Inject<T>(token: Token<T>): (_value: undefined, context: ClassFieldDecoratorContext<unknown, T>) => (initial: T) => T;
|
|
23
|
+
/** A class constructor the container can build. */
|
|
24
|
+
export type Constructor<T> = new () => T;
|
|
25
|
+
/** Provider scope: a singleton is resolved once and cached; transient re-runs. */
|
|
26
|
+
export type Scope = 'singleton' | 'transient';
|
|
27
|
+
/** The explicit, opt-in DI registry. Resolution is O(1) by token identity. */
|
|
28
|
+
export declare class Container {
|
|
29
|
+
#private;
|
|
30
|
+
/** Bind a token to an instance. The instance type is constrained to T. */
|
|
31
|
+
register<T>(token: Token<T>, instance: T): void;
|
|
32
|
+
/** Bind a token to a factory with a scope (default singleton). */
|
|
33
|
+
registerFactory<T>(token: Token<T>, factory: (c: Container) => T, scope?: Scope): void;
|
|
34
|
+
/** True if the token is registered (as a value or a factory). */
|
|
35
|
+
has<T>(token: Token<T>): boolean;
|
|
36
|
+
/** Resolve a token to its instance, or throw UnresolvedTokenError. */
|
|
37
|
+
resolve<T>(token: Token<T>): T;
|
|
38
|
+
/**
|
|
39
|
+
* Construct `Ctor` with its `@Inject`ed fields satisfied from this container.
|
|
40
|
+
* Resolution happens here (once), then is cached on the instance.
|
|
41
|
+
*/
|
|
42
|
+
build<T>(Ctor: Constructor<T>): T;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/di/index.ts"],"names":[],"mappings":"AAMA,OAAO,gBAAgB,CAAC;AAIxB,MAAM,WAAW,KAAK,CAAC,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;CACrB;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAE5D;AAED,uEAAuE;AACvE,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,WAAW,EAAE,MAAM,EAG9B;CACF;AAsBD,iEAAiE;AACjE,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GAC/C,SAAS;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;CAAE,EAAE,CAMhF;AAoBD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,YACd,SAAS,WAAW,0BAA0B,CAAC,OAAO,EAAE,CAAC,CAAC,KAAG,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAuBxG;AAED,mDAAmD;AACnD,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC;AAEzC,kFAAkF;AAClF,MAAM,MAAM,KAAK,GAAG,WAAW,GAAG,WAAW,CAAC;AAE9C,8EAA8E;AAC9E,qBAAa,SAAS;;IAQpB,0EAA0E;IAC1E,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAE9C;IAED,kEAAkE;IAClE,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,CAAC,EAAE,KAAK,GAAE,KAAmB,GAAG,IAAI,CAElG;IAED,iEAAiE;IACjE,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAE/B;IAED,sEAAsE;IACtE,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAa7B;IAED;;;OAGG;IACH,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAEhC;CACF"}
|
package/dist/di/index.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// @zmdb/app — compile-time dependency injection (epic #262, spec ./SPEC.md).
|
|
2
|
+
// Container + @Inject field decorator. No emitDecoratorMetadata, no reflection,
|
|
3
|
+
// no `as` on the consumer surface. Resolution happens at build (class-init) time.
|
|
4
|
+
// Install Symbol.metadata (used by field decorators) before any decorated class
|
|
5
|
+
// in a consumer module is evaluated.
|
|
6
|
+
import '../polyfill.js';
|
|
7
|
+
/** Create a unique injection token carrying its instance type. */
|
|
8
|
+
export function createToken(description) {
|
|
9
|
+
return { description };
|
|
10
|
+
}
|
|
11
|
+
/** Thrown by `Container.resolve` when a token was never registered. */
|
|
12
|
+
export class UnresolvedTokenError extends Error {
|
|
13
|
+
constructor(description) {
|
|
14
|
+
super(`@zmdb/app: no provider registered for token "${description}"`);
|
|
15
|
+
this.name = 'UnresolvedTokenError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const INJECTIONS = Symbol('zmdb.web.di.injections');
|
|
19
|
+
// boundary: our @Inject decorator is the only writer of the INJECTIONS slot, so
|
|
20
|
+
// viewing the metadata record through DiMetadata is sound (no call-site `as`).
|
|
21
|
+
function diView(metadata) {
|
|
22
|
+
return metadata;
|
|
23
|
+
}
|
|
24
|
+
/** Read the field-injection declarations recorded on a class. */
|
|
25
|
+
export function injectionsOf(ctor) {
|
|
26
|
+
const metadata = ctor[Symbol.metadata];
|
|
27
|
+
if (metadata === undefined || metadata === null) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
return diView(metadata)[INJECTIONS] ?? [];
|
|
31
|
+
}
|
|
32
|
+
// The container whose `build` is currently running. Field initializers read it
|
|
33
|
+
// to resolve their token. Set for the duration of `build` and cleared in a
|
|
34
|
+
// `finally`, so there is no persistent global request-time state.
|
|
35
|
+
let currentContainer;
|
|
36
|
+
// Run `fn` with `container` set as the active (building) container, restoring the
|
|
37
|
+
// previous one afterward. Keeps the swap out of `Container.build` so the method
|
|
38
|
+
// body never aliases `this` to a variable.
|
|
39
|
+
function withActiveContainer(container, fn) {
|
|
40
|
+
const previous = currentContainer;
|
|
41
|
+
currentContainer = container;
|
|
42
|
+
try {
|
|
43
|
+
return fn();
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
currentContainer = previous;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Field decorator: resolve `token` from the container that is building this
|
|
51
|
+
* instance. The field's declared type must be assignable from the token type,
|
|
52
|
+
* so a mismatch is a compile error and no `as` is needed.
|
|
53
|
+
*/
|
|
54
|
+
export function Inject(token) {
|
|
55
|
+
return function (_value, context) {
|
|
56
|
+
const view = diView(context.metadata);
|
|
57
|
+
const request = { field: context.name, token };
|
|
58
|
+
// A subclass's metadata record is created with the base's as its prototype, so
|
|
59
|
+
// `view[INJECTIONS]` on a subclass reads the base's array and pushing into it
|
|
60
|
+
// files the subclass's field under the base class. Copy what is inherited on
|
|
61
|
+
// the first own write, then push, so a reader sees base fields then own.
|
|
62
|
+
const own = Object.hasOwn(context.metadata, INJECTIONS) ? view[INJECTIONS] : undefined;
|
|
63
|
+
if (own === undefined) {
|
|
64
|
+
view[INJECTIONS] = [...(view[INJECTIONS] ?? []), request];
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
own.push(request);
|
|
68
|
+
}
|
|
69
|
+
// The initializer runs during construction; resolve from the active build.
|
|
70
|
+
return function () {
|
|
71
|
+
if (currentContainer === undefined) {
|
|
72
|
+
throw new Error(`@zmdb/app: @Inject field "${String(context.name)}" was initialized outside container.build(...)`);
|
|
73
|
+
}
|
|
74
|
+
return currentContainer.resolve(token);
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** The explicit, opt-in DI registry. Resolution is O(1) by token identity. */
|
|
79
|
+
export class Container {
|
|
80
|
+
// Keyed by token identity. Values are the registered instances; each key's
|
|
81
|
+
// value type is guaranteed by `register`'s typed signature.
|
|
82
|
+
#bindings = new Map();
|
|
83
|
+
// Factory providers: token → { factory, scope }. Singleton factories cache
|
|
84
|
+
// their first result back into #bindings.
|
|
85
|
+
#factories = new Map();
|
|
86
|
+
/** Bind a token to an instance. The instance type is constrained to T. */
|
|
87
|
+
register(token, instance) {
|
|
88
|
+
this.#bindings.set(token, instance);
|
|
89
|
+
}
|
|
90
|
+
/** Bind a token to a factory with a scope (default singleton). */
|
|
91
|
+
registerFactory(token, factory, scope = 'singleton') {
|
|
92
|
+
this.#factories.set(token, { factory, scope });
|
|
93
|
+
}
|
|
94
|
+
/** True if the token is registered (as a value or a factory). */
|
|
95
|
+
has(token) {
|
|
96
|
+
return this.#bindings.has(token) || this.#factories.has(token);
|
|
97
|
+
}
|
|
98
|
+
/** Resolve a token to its instance, or throw UnresolvedTokenError. */
|
|
99
|
+
resolve(token) {
|
|
100
|
+
if (this.#bindings.has(token)) {
|
|
101
|
+
return readBinding(this.#bindings, token);
|
|
102
|
+
}
|
|
103
|
+
const provider = this.#factories.get(token);
|
|
104
|
+
if (provider !== undefined) {
|
|
105
|
+
const value = provider.factory(this);
|
|
106
|
+
if (provider.scope === 'singleton') {
|
|
107
|
+
this.#bindings.set(token, value);
|
|
108
|
+
}
|
|
109
|
+
return narrowFactoryValue(value);
|
|
110
|
+
}
|
|
111
|
+
throw new UnresolvedTokenError(token.description);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Construct `Ctor` with its `@Inject`ed fields satisfied from this container.
|
|
115
|
+
* Resolution happens here (once), then is cached on the instance.
|
|
116
|
+
*/
|
|
117
|
+
build(Ctor) {
|
|
118
|
+
return withActiveContainer(this, () => new Ctor());
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// boundary: `register<T>` is the only writer and stores exactly the token's T
|
|
122
|
+
// under that token key, so reading it back as T is sound. This is the single
|
|
123
|
+
// enumerated boundary cast in the DI module (ARCHITECTURE.md §2.1) — a
|
|
124
|
+
// heterogeneous token→instance Map cannot prove its value type structurally, so
|
|
125
|
+
// the assertion is isolated here with the soundness argument, and never appears
|
|
126
|
+
// at a call site or on the consumer surface.
|
|
127
|
+
function readBinding(bindings, token) {
|
|
128
|
+
return bindings.get(token);
|
|
129
|
+
}
|
|
130
|
+
// boundary: a factory registered under Token<T> via registerFactory returns T by
|
|
131
|
+
// construction; widening its `unknown` result to T is sound. Same enumerated DI
|
|
132
|
+
// boundary as readBinding (ARCHITECTURE.md §2.1); never on the consumer surface.
|
|
133
|
+
function narrowFactoryValue(value) {
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/di/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import '../polyfill.js';
|
|
2
|
+
import { type OutboxWriter } from '@zmdb/orm/outbox';
|
|
3
|
+
import { type TransactionContext } from '@zmdb/orm/transactions';
|
|
4
|
+
/** An application-owned map from event names to payload types. */
|
|
5
|
+
export interface EventMap {
|
|
6
|
+
readonly [event: string]: unknown;
|
|
7
|
+
}
|
|
8
|
+
/** One validator or handler failure observed while dispatching an event. */
|
|
9
|
+
export interface EventFailure {
|
|
10
|
+
readonly event: string;
|
|
11
|
+
readonly handler: string;
|
|
12
|
+
readonly error: unknown;
|
|
13
|
+
}
|
|
14
|
+
/** The settled result of an awaited in-process emission. */
|
|
15
|
+
export interface EmitReport {
|
|
16
|
+
readonly delivered: number;
|
|
17
|
+
readonly failures: readonly EventFailure[];
|
|
18
|
+
}
|
|
19
|
+
/** Construction options for one app-owned event registry. */
|
|
20
|
+
export interface EventsOptions<M extends EventMap> {
|
|
21
|
+
readonly onError: (failure: EventFailure) => void;
|
|
22
|
+
readonly validate?: {
|
|
23
|
+
readonly [K in keyof M]?: (raw: unknown) => M[K];
|
|
24
|
+
};
|
|
25
|
+
readonly outbox?: (tx: TransactionContext) => OutboxWriter;
|
|
26
|
+
}
|
|
27
|
+
/** Typed in-process dispatch plus an explicit transactional outbox crossing. */
|
|
28
|
+
export interface Events<M extends EventMap> {
|
|
29
|
+
emit<K extends keyof M & string>(event: K, payload: M[K]): void;
|
|
30
|
+
emitAndWait<K extends keyof M & string>(event: K, payload: M[K]): Promise<EmitReport>;
|
|
31
|
+
on<K extends keyof M & string>(event: K, handler: (payload: M[K]) => void | Promise<void>): () => void;
|
|
32
|
+
bind(instance: object): () => void;
|
|
33
|
+
emitInTransaction<K extends keyof M & string>(tx: TransactionContext, event: K, payload: M[K]): Promise<string>;
|
|
34
|
+
}
|
|
35
|
+
/** A handler declaration recorded by `@OnEvent`. */
|
|
36
|
+
export interface ResolvedEventHandler {
|
|
37
|
+
readonly event: string;
|
|
38
|
+
readonly handlerName: string;
|
|
39
|
+
}
|
|
40
|
+
/** Stage-3 method decorator recording an application-event binding. */
|
|
41
|
+
export declare function OnEvent(event: string): (_target: Function, context: ClassMethodDecoratorContext) => void;
|
|
42
|
+
/** Read the bindings declared by a class. Nothing scans or constructs it. */
|
|
43
|
+
export declare function getEventHandlers(cls: abstract new (...args: never[]) => unknown): readonly ResolvedEventHandler[];
|
|
44
|
+
/** Build one isolated event registry for an application. */
|
|
45
|
+
export declare function createEvents<M extends EventMap>(options: EventsOptions<M>): Events<M>;
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAKA,OAAO,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,kEAAkE;AAClE,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CACnC;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,4DAA4D;AAC5D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;CAC5C;AAED,6DAA6D;AAC7D,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,QAAQ;IAC/C,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;KAAE,CAAC;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,kBAAkB,KAAK,YAAY,CAAC;CAC5D;AAED,gFAAgF;AAChF,MAAM,WAAW,MAAM,CAAC,CAAC,SAAS,QAAQ;IACxC,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAChE,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtF,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC;IACvG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;IACnC,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACjH;AAED,oDAAoD;AACpD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAmBD,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,aACT,QAAQ,WAAW,2BAA2B,KAAG,IAAI,CAWhF;AAUD,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GAAG,SAAS,oBAAoB,EAAE,CAEjH;AAqCD,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,CAAC,SAAS,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAqHrF"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// @zmdb/app — typed, app-owned application events (epic #591, spec ./SPEC.md).
|
|
2
|
+
// Handlers are registered explicitly, run concurrently, and report failures
|
|
3
|
+
// without letting one handler stop another. Durable emission crosses through
|
|
4
|
+
// the caller's transaction and the repository outbox.
|
|
5
|
+
import '../polyfill.js';
|
|
6
|
+
import {} from '@zmdb/orm/outbox';
|
|
7
|
+
import {} from '@zmdb/orm/transactions';
|
|
8
|
+
const EVENT_HANDLERS = Symbol('zmdb.web.events.handlers');
|
|
9
|
+
// boundary: @OnEvent is the only writer of the EVENT_HANDLERS slot, so this
|
|
10
|
+
// typed view of decorator metadata is sound (ARCHITECTURE.md §2.1).
|
|
11
|
+
function eventMetadata(metadata) {
|
|
12
|
+
return metadata;
|
|
13
|
+
}
|
|
14
|
+
/** Stage-3 method decorator recording an application-event binding. */
|
|
15
|
+
export function OnEvent(event) {
|
|
16
|
+
return function (_target, context) {
|
|
17
|
+
const handlerName = typeof context.name === 'string' ? context.name : context.name.toString();
|
|
18
|
+
const view = eventMetadata(context.metadata);
|
|
19
|
+
const own = Object.hasOwn(context.metadata, EVENT_HANDLERS) ? view[EVENT_HANDLERS] : undefined;
|
|
20
|
+
const binding = { event, handlerName };
|
|
21
|
+
if (own === undefined) {
|
|
22
|
+
view[EVENT_HANDLERS] = [...(view[EVENT_HANDLERS] ?? []), binding];
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
own.push(binding);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function handlersDeclaredBy(cls) {
|
|
30
|
+
const metadata = cls[Symbol.metadata];
|
|
31
|
+
if (metadata === undefined || metadata === null) {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
return eventMetadata(metadata)[EVENT_HANDLERS] ?? [];
|
|
35
|
+
}
|
|
36
|
+
/** Read the bindings declared by a class. Nothing scans or constructs it. */
|
|
37
|
+
export function getEventHandlers(cls) {
|
|
38
|
+
return handlersDeclaredBy(cls);
|
|
39
|
+
}
|
|
40
|
+
function storedHandler(handler, name = handler.name || '<anonymous>') {
|
|
41
|
+
return {
|
|
42
|
+
name,
|
|
43
|
+
async invoke(payload) {
|
|
44
|
+
// The public `on(event, handler)` signature ties P to the same event key
|
|
45
|
+
// used by the registry; Reflect.apply is the erased runtime crossing.
|
|
46
|
+
await Reflect.apply(handler, undefined, [payload]);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function boundHandler(instance, declaration) {
|
|
51
|
+
const value = Reflect.get(instance, declaration.handlerName);
|
|
52
|
+
if (typeof value !== 'function') {
|
|
53
|
+
throw new Error(`@zmdb/app: @OnEvent handler "${declaration.handlerName}" is not a callable instance method`);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
name: declaration.handlerName,
|
|
57
|
+
async invoke(payload) {
|
|
58
|
+
await Reflect.apply(value, instance, [payload]);
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function invoke(handler, payload) {
|
|
63
|
+
try {
|
|
64
|
+
return Promise.resolve(handler.invoke(payload));
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return Promise.reject(error);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Build one isolated event registry for an application. */
|
|
71
|
+
export function createEvents(options) {
|
|
72
|
+
const handlers = new Map();
|
|
73
|
+
const report = (failure) => {
|
|
74
|
+
try {
|
|
75
|
+
options.onError(failure);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// The error sink is the terminal reporting boundary. Its own exception
|
|
79
|
+
// must not turn a fire-and-forget emission into an unhandled rejection.
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const register = (event, handler) => {
|
|
83
|
+
const registrations = handlers.get(event);
|
|
84
|
+
if (registrations === undefined) {
|
|
85
|
+
handlers.set(event, [handler]);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
registrations.push(handler);
|
|
89
|
+
}
|
|
90
|
+
let active = true;
|
|
91
|
+
return () => {
|
|
92
|
+
if (!active) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
active = false;
|
|
96
|
+
const current = handlers.get(event);
|
|
97
|
+
if (current === undefined) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const index = current.indexOf(handler);
|
|
101
|
+
if (index >= 0) {
|
|
102
|
+
current.splice(index, 1);
|
|
103
|
+
}
|
|
104
|
+
if (current.length === 0) {
|
|
105
|
+
handlers.delete(event);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
const dispatch = async (event, payload) => {
|
|
110
|
+
let checked = payload;
|
|
111
|
+
try {
|
|
112
|
+
const validator = options.validate?.[event];
|
|
113
|
+
if (validator !== undefined) {
|
|
114
|
+
checked = validator(payload);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
const failure = { event, handler: 'validate', error };
|
|
119
|
+
report(failure);
|
|
120
|
+
return { delivered: 0, failures: [failure] };
|
|
121
|
+
}
|
|
122
|
+
const registrations = [...(handlers.get(event) ?? [])];
|
|
123
|
+
const settled = await Promise.allSettled(registrations.map(handler => invoke(handler, checked)));
|
|
124
|
+
const failures = [];
|
|
125
|
+
let delivered = 0;
|
|
126
|
+
for (let index = 0; index < settled.length; index += 1) {
|
|
127
|
+
const outcome = settled[index];
|
|
128
|
+
const registration = registrations[index];
|
|
129
|
+
if (outcome?.status === 'fulfilled') {
|
|
130
|
+
delivered += 1;
|
|
131
|
+
}
|
|
132
|
+
else if (outcome !== undefined && registration !== undefined) {
|
|
133
|
+
const failure = {
|
|
134
|
+
event,
|
|
135
|
+
handler: registration.name,
|
|
136
|
+
error: outcome.reason,
|
|
137
|
+
};
|
|
138
|
+
failures.push(failure);
|
|
139
|
+
report(failure);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return { delivered, failures };
|
|
143
|
+
};
|
|
144
|
+
return {
|
|
145
|
+
emit(event, payload) {
|
|
146
|
+
void dispatch(event, payload).catch(error => {
|
|
147
|
+
report({ event, handler: '<dispatch>', error });
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
emitAndWait: dispatch,
|
|
151
|
+
on(event, handler) {
|
|
152
|
+
return register(event, storedHandler(handler));
|
|
153
|
+
},
|
|
154
|
+
bind(instance) {
|
|
155
|
+
const ctor = instance.constructor;
|
|
156
|
+
const declarations = typeof ctor === 'function' ? handlersDeclaredBy(ctor) : [];
|
|
157
|
+
const disposers = declarations.map(declaration => register(declaration.event, boundHandler(instance, declaration)));
|
|
158
|
+
let active = true;
|
|
159
|
+
return () => {
|
|
160
|
+
if (!active) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
active = false;
|
|
164
|
+
for (const dispose of disposers) {
|
|
165
|
+
dispose();
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
},
|
|
169
|
+
async emitInTransaction(tx, event, payload) {
|
|
170
|
+
if (options.outbox === undefined) {
|
|
171
|
+
throw new Error('@zmdb/app: emitInTransaction requires an outbox writer');
|
|
172
|
+
}
|
|
173
|
+
const encoded = JSON.stringify(payload);
|
|
174
|
+
if (encoded === undefined) {
|
|
175
|
+
throw new Error('@zmdb/app: event payload is not JSON-serializable');
|
|
176
|
+
}
|
|
177
|
+
return options.outbox(tx).write(event, encoded);
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=index.js.map
|