effectable 0.1.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/LICENSE +21 -0
- package/README.md +157 -0
- package/build/LICENSE +21 -0
- package/build/bootstrap/bootstrap.d.ts +32 -0
- package/build/bootstrap/bootstrap.d.ts.map +1 -0
- package/build/bootstrap/bootstrap.js +179 -0
- package/build/bootstrap/bootstrap.js.map +1 -0
- package/build/bootstrap/index.d.ts +9 -0
- package/build/bootstrap/index.d.ts.map +1 -0
- package/build/bootstrap/index.js +14 -0
- package/build/bootstrap/index.js.map +1 -0
- package/build/bootstrap/types.d.ts +105 -0
- package/build/bootstrap/types.d.ts.map +1 -0
- package/build/bootstrap/types.js +26 -0
- package/build/bootstrap/types.js.map +1 -0
- package/build/component/Component.d.ts +126 -0
- package/build/component/Component.d.ts.map +1 -0
- package/build/component/Component.js +123 -0
- package/build/component/Component.js.map +1 -0
- package/build/component/GraphRuntime.d.ts +457 -0
- package/build/component/GraphRuntime.d.ts.map +1 -0
- package/build/component/GraphRuntime.js +1168 -0
- package/build/component/GraphRuntime.js.map +1 -0
- package/build/component/constants.d.ts +1 -0
- package/build/component/constants.d.ts.map +1 -0
- package/build/component/constants.js +2 -0
- package/build/component/constants.js.map +1 -0
- package/build/component/context.d.ts +199 -0
- package/build/component/context.d.ts.map +1 -0
- package/build/component/context.js +262 -0
- package/build/component/context.js.map +1 -0
- package/build/component/graphRuntime.constants.d.ts +13 -0
- package/build/component/graphRuntime.constants.d.ts.map +1 -0
- package/build/component/graphRuntime.constants.js +15 -0
- package/build/component/graphRuntime.constants.js.map +1 -0
- package/build/component/h.d.ts +48 -0
- package/build/component/h.d.ts.map +1 -0
- package/build/component/h.js +72 -0
- package/build/component/h.js.map +1 -0
- package/build/component/index.d.ts +19 -0
- package/build/component/index.d.ts.map +1 -0
- package/build/component/index.js +39 -0
- package/build/component/index.js.map +1 -0
- package/build/component/lifecycle.d.ts +179 -0
- package/build/component/lifecycle.d.ts.map +1 -0
- package/build/component/lifecycle.js +367 -0
- package/build/component/lifecycle.js.map +1 -0
- package/build/component/refs.d.ts +105 -0
- package/build/component/refs.d.ts.map +1 -0
- package/build/component/refs.js +128 -0
- package/build/component/refs.js.map +1 -0
- package/build/component/types.d.ts +169 -0
- package/build/component/types.d.ts.map +1 -0
- package/build/component/types.js +40 -0
- package/build/component/types.js.map +1 -0
- package/build/connect/connect.d.ts +31 -0
- package/build/connect/connect.d.ts.map +1 -0
- package/build/connect/connect.js +500 -0
- package/build/connect/connect.js.map +1 -0
- package/build/connect/index.d.ts +8 -0
- package/build/connect/index.d.ts.map +1 -0
- package/build/connect/index.js +11 -0
- package/build/connect/index.js.map +1 -0
- package/build/connect/types.d.ts +90 -0
- package/build/connect/types.d.ts.map +1 -0
- package/build/connect/types.js +8 -0
- package/build/connect/types.js.map +1 -0
- package/build/index.d.ts +26 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +60 -0
- package/build/index.js.map +1 -0
- package/build/runtime/BusDecorators.d.ts +113 -0
- package/build/runtime/BusDecorators.d.ts.map +1 -0
- package/build/runtime/BusDecorators.js +302 -0
- package/build/runtime/BusDecorators.js.map +1 -0
- package/build/runtime/CommandBus.d.ts +43 -0
- package/build/runtime/CommandBus.d.ts.map +1 -0
- package/build/runtime/CommandBus.js +65 -0
- package/build/runtime/CommandBus.js.map +1 -0
- package/build/runtime/EventBus.d.ts +50 -0
- package/build/runtime/EventBus.d.ts.map +1 -0
- package/build/runtime/EventBus.js +90 -0
- package/build/runtime/EventBus.js.map +1 -0
- package/build/runtime/HandleRegistry.d.ts +143 -0
- package/build/runtime/HandleRegistry.d.ts.map +1 -0
- package/build/runtime/HandleRegistry.js +244 -0
- package/build/runtime/HandleRegistry.js.map +1 -0
- package/build/runtime/QueryBus.d.ts +43 -0
- package/build/runtime/QueryBus.d.ts.map +1 -0
- package/build/runtime/QueryBus.js +65 -0
- package/build/runtime/QueryBus.js.map +1 -0
- package/build/runtime/index.d.ts +13 -0
- package/build/runtime/index.d.ts.map +1 -0
- package/build/runtime/index.js +32 -0
- package/build/runtime/index.js.map +1 -0
- package/build/runtime/types.d.ts +79 -0
- package/build/runtime/types.d.ts.map +1 -0
- package/build/runtime/types.js +8 -0
- package/build/runtime/types.js.map +1 -0
- package/build/store/createStore.d.ts +36 -0
- package/build/store/createStore.d.ts.map +1 -0
- package/build/store/createStore.js +131 -0
- package/build/store/createStore.js.map +1 -0
- package/build/store/index.d.ts +14 -0
- package/build/store/index.d.ts.map +1 -0
- package/build/store/index.js +39 -0
- package/build/store/index.js.map +1 -0
- package/build/store/middleware.d.ts +38 -0
- package/build/store/middleware.d.ts.map +1 -0
- package/build/store/middleware.js +99 -0
- package/build/store/middleware.js.map +1 -0
- package/build/store/selector.d.ts +62 -0
- package/build/store/selector.d.ts.map +1 -0
- package/build/store/selector.js +226 -0
- package/build/store/selector.js.map +1 -0
- package/build/store/semanticStateTree.d.ts +91 -0
- package/build/store/semanticStateTree.d.ts.map +1 -0
- package/build/store/semanticStateTree.js +263 -0
- package/build/store/semanticStateTree.js.map +1 -0
- package/build/store/types.d.ts +259 -0
- package/build/store/types.d.ts.map +1 -0
- package/build/store/types.js +28 -0
- package/build/store/types.js.map +1 -0
- package/package.json +109 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight event bus implementation.
|
|
3
|
+
*
|
|
4
|
+
* @module Effectable/runtime/EventBus
|
|
5
|
+
*/
|
|
6
|
+
import type { EventHandler, RuntimeEvent } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Event bus with per-type and global subscriptions.
|
|
9
|
+
*/
|
|
10
|
+
export declare class EventBus<TEvent extends RuntimeEvent = RuntimeEvent> {
|
|
11
|
+
private readonly handlersByType;
|
|
12
|
+
private readonly anyHandlers;
|
|
13
|
+
/**
|
|
14
|
+
* Publishes an event to all matching subscribers.
|
|
15
|
+
*
|
|
16
|
+
* @param {TEvent} event - runtime event
|
|
17
|
+
* @returns {void}
|
|
18
|
+
*/
|
|
19
|
+
publish(event: TEvent): void;
|
|
20
|
+
/**
|
|
21
|
+
* Subscribes a handler to the given event type only.
|
|
22
|
+
*
|
|
23
|
+
* @param {TEvent['type']} eventType - event type
|
|
24
|
+
* @param {EventHandler<TEvent>} handler - event handler
|
|
25
|
+
* @returns {() => void} unsubscribe function
|
|
26
|
+
*/
|
|
27
|
+
subscribe(eventType: TEvent['type'], handler: EventHandler<TEvent>): () => void;
|
|
28
|
+
/**
|
|
29
|
+
* Subscribes a handler to all events on the bus.
|
|
30
|
+
*
|
|
31
|
+
* @param {EventHandler<TEvent>} handler - event handler
|
|
32
|
+
* @returns {() => void} unsubscribe function
|
|
33
|
+
*/
|
|
34
|
+
subscribeAll(handler: EventHandler<TEvent>): () => void;
|
|
35
|
+
/**
|
|
36
|
+
* Unsubscribes a handler from a specific event type.
|
|
37
|
+
*
|
|
38
|
+
* @param {TEvent['type']} eventType - event type
|
|
39
|
+
* @param {EventHandler<TEvent>} handler - event handler
|
|
40
|
+
* @returns {void}
|
|
41
|
+
*/
|
|
42
|
+
unsubscribe(eventType: TEvent['type'], handler: EventHandler<TEvent>): void;
|
|
43
|
+
/**
|
|
44
|
+
* Clears all subscriptions.
|
|
45
|
+
*
|
|
46
|
+
* @returns {void}
|
|
47
|
+
*/
|
|
48
|
+
clear(): void;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=EventBus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventBus.d.ts","sourceRoot":"","sources":["../../src/runtime/EventBus.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D;;GAEG;AACH,qBAAa,QAAQ,CAAC,MAAM,SAAS,YAAY,GAAG,YAAY;IAC9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgD;IAC/E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAE/D;;;;;OAKG;IACI,OAAO,CAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAapC;;;;;;OAMG;IACI,SAAS,CACd,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EACzB,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,GAC5B,MAAM,IAAI;IAcb;;;;;OAKG;IACI,YAAY,CAAE,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI;IAO/D;;;;;;OAMG;IACI,WAAW,CAChB,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EACzB,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,GAC5B,IAAI;IAYP;;;;OAIG;IACI,KAAK,IAAK,IAAI;CAItB"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Lightweight event bus implementation.
|
|
4
|
+
*
|
|
5
|
+
* @module Effectable/runtime/EventBus
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.EventBus = void 0;
|
|
9
|
+
/**
|
|
10
|
+
* Event bus with per-type and global subscriptions.
|
|
11
|
+
*/
|
|
12
|
+
class EventBus {
|
|
13
|
+
handlersByType = new Map();
|
|
14
|
+
anyHandlers = new Set();
|
|
15
|
+
/**
|
|
16
|
+
* Publishes an event to all matching subscribers.
|
|
17
|
+
*
|
|
18
|
+
* @param {TEvent} event - runtime event
|
|
19
|
+
* @returns {void}
|
|
20
|
+
*/
|
|
21
|
+
publish(event) {
|
|
22
|
+
const typedHandlers = this.handlersByType.get(event.type);
|
|
23
|
+
if (typeof typedHandlers !== 'undefined') {
|
|
24
|
+
for (const handler of typedHandlers) {
|
|
25
|
+
handler(event);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
for (const handler of this.anyHandlers) {
|
|
29
|
+
handler(event);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Subscribes a handler to the given event type only.
|
|
34
|
+
*
|
|
35
|
+
* @param {TEvent['type']} eventType - event type
|
|
36
|
+
* @param {EventHandler<TEvent>} handler - event handler
|
|
37
|
+
* @returns {() => void} unsubscribe function
|
|
38
|
+
*/
|
|
39
|
+
subscribe(eventType, handler) {
|
|
40
|
+
const current = this.handlersByType.get(eventType);
|
|
41
|
+
const handlers = typeof current === 'undefined'
|
|
42
|
+
? new Set()
|
|
43
|
+
: current;
|
|
44
|
+
handlers.add(handler);
|
|
45
|
+
this.handlersByType.set(eventType, handlers);
|
|
46
|
+
return () => {
|
|
47
|
+
this.unsubscribe(eventType, handler);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Subscribes a handler to all events on the bus.
|
|
52
|
+
*
|
|
53
|
+
* @param {EventHandler<TEvent>} handler - event handler
|
|
54
|
+
* @returns {() => void} unsubscribe function
|
|
55
|
+
*/
|
|
56
|
+
subscribeAll(handler) {
|
|
57
|
+
this.anyHandlers.add(handler);
|
|
58
|
+
return () => {
|
|
59
|
+
this.anyHandlers.delete(handler);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Unsubscribes a handler from a specific event type.
|
|
64
|
+
*
|
|
65
|
+
* @param {TEvent['type']} eventType - event type
|
|
66
|
+
* @param {EventHandler<TEvent>} handler - event handler
|
|
67
|
+
* @returns {void}
|
|
68
|
+
*/
|
|
69
|
+
unsubscribe(eventType, handler) {
|
|
70
|
+
const handlers = this.handlersByType.get(eventType);
|
|
71
|
+
if (typeof handlers === 'undefined') {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
handlers.delete(handler);
|
|
75
|
+
if (handlers.size === 0) {
|
|
76
|
+
this.handlersByType.delete(eventType);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Clears all subscriptions.
|
|
81
|
+
*
|
|
82
|
+
* @returns {void}
|
|
83
|
+
*/
|
|
84
|
+
clear() {
|
|
85
|
+
this.handlersByType.clear();
|
|
86
|
+
this.anyHandlers.clear();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.EventBus = EventBus;
|
|
90
|
+
//# sourceMappingURL=EventBus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventBus.js","sourceRoot":"","sources":["../../src/runtime/EventBus.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAIH;;GAEG;AACH,MAAa,QAAQ;IACF,cAAc,GAAG,IAAI,GAAG,EAAqC,CAAC;IAC9D,WAAW,GAAG,IAAI,GAAG,EAAwB,CAAC;IAE/D;;;;;OAKG;IACI,OAAO,CAAE,KAAa;QAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,OAAO,aAAa,KAAK,WAAW,EAAE,CAAC;YACzC,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;gBACpC,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACvC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,SAAS,CACd,SAAyB,EACzB,OAA6B;QAE7B,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,OAAO,OAAO,KAAK,WAAW;YAC7C,CAAC,CAAC,IAAI,GAAG,EAAwB;YACjC,CAAC,CAAC,OAAO,CAAC;QAEZ,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAE7C,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACI,YAAY,CAAE,OAA6B;QAChD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACI,WAAW,CAChB,SAAyB,EACzB,OAA6B;QAE7B,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpD,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzB,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,KAAK;QACV,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACF;AA3FD,4BA2FC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry of imperative handle objects.
|
|
3
|
+
*
|
|
4
|
+
* `HandleRegistry` is a small runtime registry that stores and retrieves
|
|
5
|
+
* "imperative handles" (objects with methods) keyed by a string.
|
|
6
|
+
*
|
|
7
|
+
* In application code this idea is used for bridge mechanics:
|
|
8
|
+
* 1) a runtime-host/internal service creates a handle (for example with `runUname()` / `getSnapshot()`),
|
|
9
|
+
* 2) that handle is registered in `HandleRegistry` under a `handleKey`,
|
|
10
|
+
* 3) command/query handlers obtain the handle via `resolve()` and call its methods.
|
|
11
|
+
*
|
|
12
|
+
* Thanks to this, domain handlers do not depend on how the runtime-host lifecycle is structured:
|
|
13
|
+
* they only operate on `key -> handle -> method`.
|
|
14
|
+
*
|
|
15
|
+
* @module Effectable/runtime/HandleRegistry
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const handleRegistry = new HandleRegistry();
|
|
19
|
+
*
|
|
20
|
+
* // runtime-host created an imperative handle and registered it
|
|
21
|
+
* const disposer = handleRegistry.register('domain:instance1:handle', myHandle);
|
|
22
|
+
*
|
|
23
|
+
* // query-handler resolves the handle by key and returns a snapshot
|
|
24
|
+
* const handle = handleRegistry.resolve<typeof myHandle>('domain:instance1:handle');
|
|
25
|
+
* const snapshot = handle.getSnapshot();
|
|
26
|
+
*
|
|
27
|
+
* // on shutdown the runtime-host must unregister
|
|
28
|
+
* disposer();
|
|
29
|
+
*/
|
|
30
|
+
import 'reflect-metadata';
|
|
31
|
+
export type HandleRefKeyFactory<TInstance = unknown> = string | ((instance: TInstance) => string);
|
|
32
|
+
/**
|
|
33
|
+
* Decorator that sets a handle key (or key factory) for an instance.
|
|
34
|
+
*
|
|
35
|
+
* Used together with `HandleRegistry.autoRegister(instance)`:
|
|
36
|
+
* - the decorator stores key metadata
|
|
37
|
+
* - `autoRegister()` fills the ref object (on the field marked with `@UseRef()`)
|
|
38
|
+
* with methods marked with `@UseImperativeHandle()`
|
|
39
|
+
*/
|
|
40
|
+
export declare function forwardRef<TInstance = unknown>(keyOrFactory: HandleRefKeyFactory<TInstance>): ClassDecorator;
|
|
41
|
+
/**
|
|
42
|
+
* Method decorator that includes a method in the imperative handle.
|
|
43
|
+
*
|
|
44
|
+
* Together with `@forwardRef(...)` and the `@UseRef()` property decorator, it lets you build a handle
|
|
45
|
+
* without manually calling `handleRegistry.register(handleKey, { ... })`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function UseImperativeHandle(): MethodDecorator;
|
|
48
|
+
/**
|
|
49
|
+
* Property decorator that marks the field where the runtime host should place a ref object.
|
|
50
|
+
*
|
|
51
|
+
* That ref object is then filled with methods marked with `@UseImperativeHandle()`.
|
|
52
|
+
*/
|
|
53
|
+
export declare function UseRef(): PropertyDecorator;
|
|
54
|
+
/**
|
|
55
|
+
* Handle registry keyed by string.
|
|
56
|
+
*/
|
|
57
|
+
export declare class HandleRegistry {
|
|
58
|
+
private readonly handles;
|
|
59
|
+
private buildRefHandle;
|
|
60
|
+
private resolveHandleKey;
|
|
61
|
+
/**
|
|
62
|
+
* Automatically registers an imperative handle for the given instance.
|
|
63
|
+
*
|
|
64
|
+
* `instance` must be annotated with:
|
|
65
|
+
* - `@UseRef(...)` on the class (sets the handle key)
|
|
66
|
+
* - `@UseImperativeHandle()` on methods (defines the handle surface)
|
|
67
|
+
*
|
|
68
|
+
* @param {unknown} instance - instance from which the handle is built
|
|
69
|
+
* @returns {() => void} disposer that unregisters the handle
|
|
70
|
+
*/
|
|
71
|
+
autoRegister(instance: unknown): () => void;
|
|
72
|
+
/**
|
|
73
|
+
* Registers a handle and returns a disposer that unregisters it.
|
|
74
|
+
*
|
|
75
|
+
* Prefer keeping the disposer and calling it from the component's `onUnmount()`,
|
|
76
|
+
* so stale handles are not left after the runtime instance stops.
|
|
77
|
+
*
|
|
78
|
+
* @param {string} key - handle key
|
|
79
|
+
* @param {THandle} handle - imperative API object
|
|
80
|
+
* @returns {() => void} unregister function
|
|
81
|
+
*/
|
|
82
|
+
register<THandle>(key: string, handle: THandle): () => void;
|
|
83
|
+
/**
|
|
84
|
+
* Removes a handle by key.
|
|
85
|
+
*
|
|
86
|
+
* Usually called either directly in "manual lifecycle" scenarios,
|
|
87
|
+
* or indirectly via the disposer returned from `register()`.
|
|
88
|
+
*
|
|
89
|
+
* @param {string} key - handle key
|
|
90
|
+
* @returns {void}
|
|
91
|
+
*/
|
|
92
|
+
unregister(key: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Returns a handle by key if it is registered.
|
|
95
|
+
*
|
|
96
|
+
* If the handle is not found, returns `undefined` — without throwing.
|
|
97
|
+
*
|
|
98
|
+
* @param {string} key - handle key
|
|
99
|
+
* @returns {THandle | undefined} found handle
|
|
100
|
+
*/
|
|
101
|
+
get<THandle>(key: string): THandle | undefined;
|
|
102
|
+
/**
|
|
103
|
+
* Returns a handle by key or throws.
|
|
104
|
+
*
|
|
105
|
+
* This is the strict method: suitable for command/query handlers
|
|
106
|
+
* when a missing handle means a business-logic error
|
|
107
|
+
* (for example, a request arrived for an instance that has already stopped).
|
|
108
|
+
*
|
|
109
|
+
* @param {string} key - handle key
|
|
110
|
+
* @returns {THandle} found handle
|
|
111
|
+
* @throws {Error} if the handle is not registered
|
|
112
|
+
*/
|
|
113
|
+
resolve<THandle>(key: string): THandle;
|
|
114
|
+
/**
|
|
115
|
+
* Checks whether a handle exists for the key.
|
|
116
|
+
*
|
|
117
|
+
* Useful for diagnostics and "soft" scenarios
|
|
118
|
+
* when you want to avoid exceptions and take an alternate path.
|
|
119
|
+
*
|
|
120
|
+
* @param {string} key - handle key
|
|
121
|
+
* @returns {boolean} true if the handle is registered
|
|
122
|
+
*/
|
|
123
|
+
has(key: string): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Returns the list of registered keys.
|
|
126
|
+
*
|
|
127
|
+
* Suitable for debugging runtime instances (for example, to see
|
|
128
|
+
* which handles are currently active).
|
|
129
|
+
*
|
|
130
|
+
* @returns {string[]} list of keys
|
|
131
|
+
*/
|
|
132
|
+
keys(): string[];
|
|
133
|
+
/**
|
|
134
|
+
* Fully clears the registry.
|
|
135
|
+
*
|
|
136
|
+
* Use on full system/subsystem shutdown,
|
|
137
|
+
* when all previously registered imperative handles are considered obsolete.
|
|
138
|
+
*
|
|
139
|
+
* @returns {void}
|
|
140
|
+
*/
|
|
141
|
+
clear(): void;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=HandleRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HandleRegistry.d.ts","sourceRoot":"","sources":["../../src/runtime/HandleRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,kBAAkB,CAAC;AAM1B,MAAM,MAAM,mBAAmB,CAAC,SAAS,GAAG,OAAO,IAC/C,MAAM,GACN,CAAC,CAAC,QAAQ,EAAE,SAAS,KAAK,MAAM,CAAC,CAAC;AAEtC;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,SAAS,GAAG,OAAO,EAC5C,YAAY,EAAE,mBAAmB,CAAC,SAAS,CAAC,GAC3C,cAAc,CAIhB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAK,eAAe,CAmBtD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,IAAK,iBAAiB,CAS3C;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IAEtD,OAAO,CAAC,cAAc;IA2CtB,OAAO,CAAC,gBAAgB;IAwBxB;;;;;;;;;OASG;IACI,YAAY,CAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,IAAI;IAMnD;;;;;;;;;OASG;IACI,QAAQ,CAAC,OAAO,EAAG,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI;IAOnE;;;;;;;;OAQG;IACI,UAAU,CAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAIrC;;;;;;;OAOG;IACI,GAAG,CAAC,OAAO,EAAG,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAItD;;;;;;;;;;OAUG;IACI,OAAO,CAAC,OAAO,EAAG,GAAG,EAAE,MAAM,GAAG,OAAO;IAQ9C;;;;;;;;OAQG;IACI,GAAG,CAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAIjC;;;;;;;OAOG;IACI,IAAI,IAAK,MAAM,EAAE;IAIxB;;;;;;;OAOG;IACI,KAAK,IAAK,IAAI;CAGtB"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Registry of imperative handle objects.
|
|
4
|
+
*
|
|
5
|
+
* `HandleRegistry` is a small runtime registry that stores and retrieves
|
|
6
|
+
* "imperative handles" (objects with methods) keyed by a string.
|
|
7
|
+
*
|
|
8
|
+
* In application code this idea is used for bridge mechanics:
|
|
9
|
+
* 1) a runtime-host/internal service creates a handle (for example with `runUname()` / `getSnapshot()`),
|
|
10
|
+
* 2) that handle is registered in `HandleRegistry` under a `handleKey`,
|
|
11
|
+
* 3) command/query handlers obtain the handle via `resolve()` and call its methods.
|
|
12
|
+
*
|
|
13
|
+
* Thanks to this, domain handlers do not depend on how the runtime-host lifecycle is structured:
|
|
14
|
+
* they only operate on `key -> handle -> method`.
|
|
15
|
+
*
|
|
16
|
+
* @module Effectable/runtime/HandleRegistry
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const handleRegistry = new HandleRegistry();
|
|
20
|
+
*
|
|
21
|
+
* // runtime-host created an imperative handle and registered it
|
|
22
|
+
* const disposer = handleRegistry.register('domain:instance1:handle', myHandle);
|
|
23
|
+
*
|
|
24
|
+
* // query-handler resolves the handle by key and returns a snapshot
|
|
25
|
+
* const handle = handleRegistry.resolve<typeof myHandle>('domain:instance1:handle');
|
|
26
|
+
* const snapshot = handle.getSnapshot();
|
|
27
|
+
*
|
|
28
|
+
* // on shutdown the runtime-host must unregister
|
|
29
|
+
* disposer();
|
|
30
|
+
*/
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.HandleRegistry = void 0;
|
|
33
|
+
exports.forwardRef = forwardRef;
|
|
34
|
+
exports.UseImperativeHandle = UseImperativeHandle;
|
|
35
|
+
exports.UseRef = UseRef;
|
|
36
|
+
require("reflect-metadata");
|
|
37
|
+
const USE_REF_METADATA_KEY = 'effectable:HandleRegistry:UseRef';
|
|
38
|
+
const USE_REF_PROPERTY_METADATA_KEY = 'effectable:HandleRegistry:UseRefProperty';
|
|
39
|
+
const USE_IMPERATIVE_HANDLE_METADATA_KEY = 'effectable:HandleRegistry:UseImperativeHandle';
|
|
40
|
+
/**
|
|
41
|
+
* Decorator that sets a handle key (or key factory) for an instance.
|
|
42
|
+
*
|
|
43
|
+
* Used together with `HandleRegistry.autoRegister(instance)`:
|
|
44
|
+
* - the decorator stores key metadata
|
|
45
|
+
* - `autoRegister()` fills the ref object (on the field marked with `@UseRef()`)
|
|
46
|
+
* with methods marked with `@UseImperativeHandle()`
|
|
47
|
+
*/
|
|
48
|
+
function forwardRef(keyOrFactory) {
|
|
49
|
+
return (target) => {
|
|
50
|
+
Reflect.defineMetadata(USE_REF_METADATA_KEY, keyOrFactory, target);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Method decorator that includes a method in the imperative handle.
|
|
55
|
+
*
|
|
56
|
+
* Together with `@forwardRef(...)` and the `@UseRef()` property decorator, it lets you build a handle
|
|
57
|
+
* without manually calling `handleRegistry.register(handleKey, { ... })`.
|
|
58
|
+
*/
|
|
59
|
+
function UseImperativeHandle() {
|
|
60
|
+
return (target, propertyKey) => {
|
|
61
|
+
if (typeof propertyKey === 'undefined') {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const ctor = target.constructor;
|
|
65
|
+
const current = Reflect.getMetadata(USE_IMPERATIVE_HANDLE_METADATA_KEY, ctor);
|
|
66
|
+
const next = typeof current === 'undefined'
|
|
67
|
+
? new Set()
|
|
68
|
+
: new Set(current);
|
|
69
|
+
next.add(String(propertyKey));
|
|
70
|
+
Reflect.defineMetadata(USE_IMPERATIVE_HANDLE_METADATA_KEY, next, ctor);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Property decorator that marks the field where the runtime host should place a ref object.
|
|
75
|
+
*
|
|
76
|
+
* That ref object is then filled with methods marked with `@UseImperativeHandle()`.
|
|
77
|
+
*/
|
|
78
|
+
function UseRef() {
|
|
79
|
+
return (target, propertyKey) => {
|
|
80
|
+
if (typeof propertyKey === 'undefined') {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const ctor = target.constructor;
|
|
84
|
+
Reflect.defineMetadata(USE_REF_PROPERTY_METADATA_KEY, propertyKey, ctor);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Handle registry keyed by string.
|
|
89
|
+
*/
|
|
90
|
+
class HandleRegistry {
|
|
91
|
+
handles = new Map();
|
|
92
|
+
buildRefHandle(instance) {
|
|
93
|
+
const ctor = instance !== null && typeof instance === 'object'
|
|
94
|
+
? instance.constructor
|
|
95
|
+
: null;
|
|
96
|
+
if (typeof ctor !== 'function') {
|
|
97
|
+
throw new Error('HandleRegistry.autoRegister: invalid instance');
|
|
98
|
+
}
|
|
99
|
+
const refPropertyKey = Reflect.getMetadata(USE_REF_PROPERTY_METADATA_KEY, ctor);
|
|
100
|
+
if (typeof refPropertyKey === 'undefined') {
|
|
101
|
+
throw new Error('HandleRegistry.autoRegister: missing ref property metadata (@UseRef)');
|
|
102
|
+
}
|
|
103
|
+
const ref = instance[refPropertyKey];
|
|
104
|
+
if (typeof ref !== 'object' || ref === null) {
|
|
105
|
+
throw new Error('HandleRegistry.autoRegister: ref property is not an object');
|
|
106
|
+
}
|
|
107
|
+
const methodNames = Reflect.getMetadata(USE_IMPERATIVE_HANDLE_METADATA_KEY, ctor);
|
|
108
|
+
if (typeof methodNames === 'undefined' || methodNames.size === 0) {
|
|
109
|
+
throw new Error('HandleRegistry.autoRegister: no @UseImperativeHandle methods');
|
|
110
|
+
}
|
|
111
|
+
for (const methodName of methodNames) {
|
|
112
|
+
const fn = instance[methodName];
|
|
113
|
+
if (typeof fn !== 'function') {
|
|
114
|
+
throw new Error(`HandleRegistry.autoRegister: method is not a function: ${methodName}`);
|
|
115
|
+
}
|
|
116
|
+
ref[methodName] = fn.bind(instance);
|
|
117
|
+
}
|
|
118
|
+
return ref;
|
|
119
|
+
}
|
|
120
|
+
resolveHandleKey(instance) {
|
|
121
|
+
const ctor = instance !== null && typeof instance === 'object'
|
|
122
|
+
? instance.constructor
|
|
123
|
+
: null;
|
|
124
|
+
if (typeof ctor !== 'function') {
|
|
125
|
+
throw new Error('HandleRegistry.autoRegister: invalid instance');
|
|
126
|
+
}
|
|
127
|
+
const keyOrFactory = Reflect.getMetadata(USE_REF_METADATA_KEY, ctor);
|
|
128
|
+
if (typeof keyOrFactory === 'undefined') {
|
|
129
|
+
throw new Error('HandleRegistry.autoRegister: missing @UseRef metadata');
|
|
130
|
+
}
|
|
131
|
+
if (typeof keyOrFactory === 'string') {
|
|
132
|
+
return keyOrFactory;
|
|
133
|
+
}
|
|
134
|
+
return keyOrFactory(instance);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Automatically registers an imperative handle for the given instance.
|
|
138
|
+
*
|
|
139
|
+
* `instance` must be annotated with:
|
|
140
|
+
* - `@UseRef(...)` on the class (sets the handle key)
|
|
141
|
+
* - `@UseImperativeHandle()` on methods (defines the handle surface)
|
|
142
|
+
*
|
|
143
|
+
* @param {unknown} instance - instance from which the handle is built
|
|
144
|
+
* @returns {() => void} disposer that unregisters the handle
|
|
145
|
+
*/
|
|
146
|
+
autoRegister(instance) {
|
|
147
|
+
const key = this.resolveHandleKey(instance);
|
|
148
|
+
const handle = this.buildRefHandle(instance);
|
|
149
|
+
return this.register(key, handle);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Registers a handle and returns a disposer that unregisters it.
|
|
153
|
+
*
|
|
154
|
+
* Prefer keeping the disposer and calling it from the component's `onUnmount()`,
|
|
155
|
+
* so stale handles are not left after the runtime instance stops.
|
|
156
|
+
*
|
|
157
|
+
* @param {string} key - handle key
|
|
158
|
+
* @param {THandle} handle - imperative API object
|
|
159
|
+
* @returns {() => void} unregister function
|
|
160
|
+
*/
|
|
161
|
+
register(key, handle) {
|
|
162
|
+
this.handles.set(key, handle);
|
|
163
|
+
return () => {
|
|
164
|
+
this.unregister(key);
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Removes a handle by key.
|
|
169
|
+
*
|
|
170
|
+
* Usually called either directly in "manual lifecycle" scenarios,
|
|
171
|
+
* or indirectly via the disposer returned from `register()`.
|
|
172
|
+
*
|
|
173
|
+
* @param {string} key - handle key
|
|
174
|
+
* @returns {void}
|
|
175
|
+
*/
|
|
176
|
+
unregister(key) {
|
|
177
|
+
this.handles.delete(key);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Returns a handle by key if it is registered.
|
|
181
|
+
*
|
|
182
|
+
* If the handle is not found, returns `undefined` — without throwing.
|
|
183
|
+
*
|
|
184
|
+
* @param {string} key - handle key
|
|
185
|
+
* @returns {THandle | undefined} found handle
|
|
186
|
+
*/
|
|
187
|
+
get(key) {
|
|
188
|
+
return this.handles.get(key);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Returns a handle by key or throws.
|
|
192
|
+
*
|
|
193
|
+
* This is the strict method: suitable for command/query handlers
|
|
194
|
+
* when a missing handle means a business-logic error
|
|
195
|
+
* (for example, a request arrived for an instance that has already stopped).
|
|
196
|
+
*
|
|
197
|
+
* @param {string} key - handle key
|
|
198
|
+
* @returns {THandle} found handle
|
|
199
|
+
* @throws {Error} if the handle is not registered
|
|
200
|
+
*/
|
|
201
|
+
resolve(key) {
|
|
202
|
+
const handle = this.get(key);
|
|
203
|
+
if (typeof handle === 'undefined') {
|
|
204
|
+
throw new Error(`Handle is not registered: ${key}`);
|
|
205
|
+
}
|
|
206
|
+
return handle;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Checks whether a handle exists for the key.
|
|
210
|
+
*
|
|
211
|
+
* Useful for diagnostics and "soft" scenarios
|
|
212
|
+
* when you want to avoid exceptions and take an alternate path.
|
|
213
|
+
*
|
|
214
|
+
* @param {string} key - handle key
|
|
215
|
+
* @returns {boolean} true if the handle is registered
|
|
216
|
+
*/
|
|
217
|
+
has(key) {
|
|
218
|
+
return this.handles.has(key);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Returns the list of registered keys.
|
|
222
|
+
*
|
|
223
|
+
* Suitable for debugging runtime instances (for example, to see
|
|
224
|
+
* which handles are currently active).
|
|
225
|
+
*
|
|
226
|
+
* @returns {string[]} list of keys
|
|
227
|
+
*/
|
|
228
|
+
keys() {
|
|
229
|
+
return Array.from(this.handles.keys());
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Fully clears the registry.
|
|
233
|
+
*
|
|
234
|
+
* Use on full system/subsystem shutdown,
|
|
235
|
+
* when all previously registered imperative handles are considered obsolete.
|
|
236
|
+
*
|
|
237
|
+
* @returns {void}
|
|
238
|
+
*/
|
|
239
|
+
clear() {
|
|
240
|
+
this.handles.clear();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
exports.HandleRegistry = HandleRegistry;
|
|
244
|
+
//# sourceMappingURL=HandleRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HandleRegistry.js","sourceRoot":"","sources":["../../src/runtime/HandleRegistry.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;;AAoBH,gCAMC;AAQD,kDAmBC;AAOD,wBASC;AAnED,4BAA0B;AAE1B,MAAM,oBAAoB,GAAG,kCAAkC,CAAC;AAChE,MAAM,6BAA6B,GAAG,0CAA0C,CAAC;AACjF,MAAM,kCAAkC,GAAG,+CAA+C,CAAC;AAM3F;;;;;;;GAOG;AACH,SAAgB,UAAU,CACxB,YAA4C;IAE5C,OAAO,CAAC,MAAM,EAAE,EAAE;QAChB,OAAO,CAAC,cAAc,CAAC,oBAAoB,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;IACrE,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB;IACjC,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;QAC7B,IAAI,OAAO,WAAW,KAAK,WAAW,EAAE,CAAC;YACvC,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;QAChC,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CACjC,kCAAkC,EAClC,IAAI,CACsB,CAAC;QAE7B,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,WAAW;YACzC,CAAC,CAAC,IAAI,GAAG,EAAU;YACnB,CAAC,CAAC,IAAI,GAAG,CAAS,OAAO,CAAC,CAAC;QAE7B,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;QAC9B,OAAO,CAAC,cAAc,CAAC,kCAAkC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACzE,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,MAAM;IACpB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;QAC7B,IAAI,OAAO,WAAW,KAAK,WAAW,EAAE,CAAC;YACvC,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;QAChC,OAAO,CAAC,cAAc,CAAC,6BAA6B,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IAC3E,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAa,cAAc;IACR,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;IAE9C,cAAc,CAAE,QAAiB;QACvC,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ;YAC5D,CAAC,CAAE,QAAsC,CAAC,WAAW;YACrD,CAAC,CAAC,IAAI,CAAC;QACT,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,cAAc,GAAG,OAAO,CAAC,WAAW,CACxC,6BAA6B,EAC7B,IAAI,CACiB,CAAC;QAExB,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;QAC1F,CAAC;QAED,MAAM,GAAG,GAAI,QAAoC,CAAC,cAAc,CAAC,CAAC;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CACrC,kCAAkC,EAClC,IAAI,CACsB,CAAC;QAE7B,IAAI,OAAO,WAAW,KAAK,WAAW,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAClF,CAAC;QAED,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,MAAM,EAAE,GAAI,QAAoC,CAAC,UAAU,CAAC,CAAC;YAC7D,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,0DAA0D,UAAU,EAAE,CAAC,CAAC;YAC1F,CAAC;YAEA,GAA+B,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnE,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,gBAAgB,CAAE,QAAiB;QACzC,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ;YAC5D,CAAC,CAAE,QAAsC,CAAC,WAAW;YACrD,CAAC,CAAC,IAAI,CAAC;QACT,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CACtC,oBAAoB,EACpB,IAAI,CACuC,CAAC;QAE9C,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QAED,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACrC,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED;;;;;;;;;OASG;IACI,YAAY,CAAE,QAAiB;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAED;;;;;;;;;OASG;IACI,QAAQ,CAAW,GAAW,EAAE,MAAe;QACpD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACI,UAAU,CAAE,GAAW;QAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED;;;;;;;OAOG;IACI,GAAG,CAAW,GAAW;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAwB,CAAC;IACtD,CAAC;IAED;;;;;;;;;;OAUG;IACI,OAAO,CAAW,GAAW;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAU,GAAG,CAAC,CAAC;QACtC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;OAQG;IACI,GAAG,CAAE,GAAW;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;;;OAOG;IACI,IAAI;QACT,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;;OAOG;IACI,KAAK;QACV,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF;AAvLD,wCAuLC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight query bus implementation.
|
|
3
|
+
*
|
|
4
|
+
* @module Effectable/runtime/QueryBus
|
|
5
|
+
*/
|
|
6
|
+
import type { QueryHandler, RuntimeQuery } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Query bus with a single handler per query type.
|
|
9
|
+
*/
|
|
10
|
+
export declare class QueryBus<TQuery extends RuntimeQuery = RuntimeQuery> {
|
|
11
|
+
private readonly handlers;
|
|
12
|
+
/**
|
|
13
|
+
* Registers a query handler.
|
|
14
|
+
*
|
|
15
|
+
* @param {TQuery['type']} queryType - query type
|
|
16
|
+
* @param {QueryHandler<TQuery, TResult>} handler - query handler
|
|
17
|
+
* @returns {() => void} unregister function
|
|
18
|
+
* @throws {Error} if a handler is already registered
|
|
19
|
+
*/
|
|
20
|
+
register<TResult>(queryType: TQuery['type'], handler: QueryHandler<TQuery, TResult>): () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Executes a query through the registered handler.
|
|
23
|
+
*
|
|
24
|
+
* @param {TQuery} query - query
|
|
25
|
+
* @returns {Promise<TResult>} query execution result
|
|
26
|
+
* @throws {Error} if no handler is found
|
|
27
|
+
*/
|
|
28
|
+
execute<TResult>(query: TQuery): Promise<TResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Unregisters a query handler.
|
|
31
|
+
*
|
|
32
|
+
* @param {TQuery['type']} queryType - query type
|
|
33
|
+
* @returns {void}
|
|
34
|
+
*/
|
|
35
|
+
unregister(queryType: TQuery['type']): void;
|
|
36
|
+
/**
|
|
37
|
+
* Clears all registered handlers.
|
|
38
|
+
*
|
|
39
|
+
* @returns {void}
|
|
40
|
+
*/
|
|
41
|
+
clear(): void;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=QueryBus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryBus.d.ts","sourceRoot":"","sources":["../../src/runtime/QueryBus.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D;;GAEG;AACH,qBAAa,QAAQ,CAAC,MAAM,SAAS,YAAY,GAAG,YAAY;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoD;IAE7E;;;;;;;OAOG;IACI,QAAQ,CAAC,OAAO,EACrB,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EACzB,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,GACrC,MAAM,IAAI;IAWb;;;;;;OAMG;IACU,OAAO,CAAC,OAAO,EAAG,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU/D;;;;;OAKG;IACI,UAAU,CAAE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI;IAInD;;;;OAIG;IACI,KAAK,IAAK,IAAI;CAGtB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Lightweight query bus implementation.
|
|
4
|
+
*
|
|
5
|
+
* @module Effectable/runtime/QueryBus
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.QueryBus = void 0;
|
|
9
|
+
/**
|
|
10
|
+
* Query bus with a single handler per query type.
|
|
11
|
+
*/
|
|
12
|
+
class QueryBus {
|
|
13
|
+
handlers = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Registers a query handler.
|
|
16
|
+
*
|
|
17
|
+
* @param {TQuery['type']} queryType - query type
|
|
18
|
+
* @param {QueryHandler<TQuery, TResult>} handler - query handler
|
|
19
|
+
* @returns {() => void} unregister function
|
|
20
|
+
* @throws {Error} if a handler is already registered
|
|
21
|
+
*/
|
|
22
|
+
register(queryType, handler) {
|
|
23
|
+
if (this.handlers.has(queryType)) {
|
|
24
|
+
throw new Error(`Query handler is already registered: ${queryType}`);
|
|
25
|
+
}
|
|
26
|
+
this.handlers.set(queryType, handler);
|
|
27
|
+
return () => {
|
|
28
|
+
this.unregister(queryType);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Executes a query through the registered handler.
|
|
33
|
+
*
|
|
34
|
+
* @param {TQuery} query - query
|
|
35
|
+
* @returns {Promise<TResult>} query execution result
|
|
36
|
+
* @throws {Error} if no handler is found
|
|
37
|
+
*/
|
|
38
|
+
async execute(query) {
|
|
39
|
+
const handler = this.handlers.get(query.type);
|
|
40
|
+
if (typeof handler === 'undefined') {
|
|
41
|
+
throw new Error(`Query handler is not registered: ${query.type}`);
|
|
42
|
+
}
|
|
43
|
+
const result = await handler(query);
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Unregisters a query handler.
|
|
48
|
+
*
|
|
49
|
+
* @param {TQuery['type']} queryType - query type
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
52
|
+
unregister(queryType) {
|
|
53
|
+
this.handlers.delete(queryType);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Clears all registered handlers.
|
|
57
|
+
*
|
|
58
|
+
* @returns {void}
|
|
59
|
+
*/
|
|
60
|
+
clear() {
|
|
61
|
+
this.handlers.clear();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.QueryBus = QueryBus;
|
|
65
|
+
//# sourceMappingURL=QueryBus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryBus.js","sourceRoot":"","sources":["../../src/runtime/QueryBus.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAIH;;GAEG;AACH,MAAa,QAAQ;IACF,QAAQ,GAAG,IAAI,GAAG,EAAyC,CAAC;IAE7E;;;;;;;OAOG;IACI,QAAQ,CACb,SAAyB,EACzB,OAAsC;QAEtC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,wCAAwC,SAAS,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAwC,CAAC,CAAC;QACvE,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,OAAO,CAAW,KAAa;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;QACpC,OAAO,MAAiB,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACI,UAAU,CAAE,SAAyB;QAC1C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACI,KAAK;QACV,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACF;AA5DD,4BA4DC"}
|