@decaf-ts/ui-decorators 0.18.0 → 0.19.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/dist/ui-decorators.cjs +1 -1
- package/lib/cjs/graph/constants.cjs +28 -1
- package/lib/cjs/graph/constants.cjs.map +1 -1
- package/lib/cjs/index.cjs +3 -3
- package/lib/cjs/user-requests/UserRequestHandler.cjs +190 -0
- package/lib/cjs/user-requests/UserRequestHandler.cjs.map +1 -0
- package/lib/cjs/user-requests/constants.cjs +22 -0
- package/lib/cjs/user-requests/constants.cjs.map +1 -0
- package/lib/cjs/user-requests/decorators.cjs +41 -0
- package/lib/cjs/user-requests/decorators.cjs.map +1 -0
- package/lib/cjs/user-requests/errors.cjs +26 -0
- package/lib/cjs/user-requests/errors.cjs.map +1 -0
- package/lib/cjs/user-requests/index.cjs +33 -0
- package/lib/cjs/user-requests/index.cjs.map +1 -0
- package/lib/cjs/user-requests/types.cjs +4 -0
- package/lib/cjs/user-requests/types.cjs.map +1 -0
- package/lib/esm/graph/constants.js +26 -0
- package/lib/esm/graph/constants.js.map +1 -1
- package/lib/esm/index.js +3 -3
- package/lib/esm/user-requests/UserRequestHandler.js +185 -0
- package/lib/esm/user-requests/UserRequestHandler.js.map +1 -0
- package/lib/esm/user-requests/constants.js +18 -0
- package/lib/esm/user-requests/constants.js.map +1 -0
- package/lib/esm/user-requests/decorators.js +37 -0
- package/lib/esm/user-requests/decorators.js.map +1 -0
- package/lib/esm/user-requests/errors.js +21 -0
- package/lib/esm/user-requests/errors.js.map +1 -0
- package/lib/esm/user-requests/index.js +16 -0
- package/lib/esm/user-requests/index.js.map +1 -0
- package/lib/esm/user-requests/types.js +8 -0
- package/lib/esm/user-requests/types.js.map +1 -0
- package/lib/types/graph/constants.d.cts +66 -0
- package/lib/types/graph/constants.d.mts +66 -0
- package/lib/types/index.d.cts +3 -3
- package/lib/types/index.d.mts +3 -3
- package/lib/types/user-requests/UserRequestHandler.d.cts +117 -0
- package/lib/types/user-requests/UserRequestHandler.d.mts +117 -0
- package/lib/types/user-requests/constants.d.cts +17 -0
- package/lib/types/user-requests/constants.d.mts +17 -0
- package/lib/types/user-requests/decorators.d.cts +22 -0
- package/lib/types/user-requests/decorators.d.mts +22 -0
- package/lib/types/user-requests/errors.d.cts +18 -0
- package/lib/types/user-requests/errors.d.mts +18 -0
- package/lib/types/user-requests/index.d.cts +15 -0
- package/lib/types/user-requests/index.d.mts +15 -0
- package/lib/types/user-requests/types.d.cts +36 -0
- package/lib/types/user-requests/types.d.mts +36 -0
- package/package.json +22 -4
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ui-decorators/user-requests/UserRequestHandler
|
|
3
|
+
* @summary Service-based base class for user request handlers.
|
|
4
|
+
* @description No Angular or DOM imports — safe for pure-Node (backend) bundles.
|
|
5
|
+
*
|
|
6
|
+
* Handlers extend `Service`, receive a rendering-engine facade as a
|
|
7
|
+
* `protected readonly` property and implement `handle`, either returning the
|
|
8
|
+
* resolved value or throwing (a `CancelledError` when the user cancels
|
|
9
|
+
* mid-request). Lookup and dispatch are static: `@userRequest(reference)`
|
|
10
|
+
* records the class as metadata and `UserRequestHandler.getHandler(reference)`
|
|
11
|
+
* / `UserRequestHandler.handle(request, renderingEngine)` resolve and run it,
|
|
12
|
+
* so no process-wide registry instance is needed.
|
|
13
|
+
*/
|
|
14
|
+
import { Service, } from "@decaf-ts/core";
|
|
15
|
+
import { Metadata } from "@decaf-ts/decoration";
|
|
16
|
+
import { InternalError } from "@decaf-ts/db-decorators";
|
|
17
|
+
import { USER_REQUEST_KEY } from "./constants.js";
|
|
18
|
+
import { CancelledError } from "./errors.js";
|
|
19
|
+
/**
|
|
20
|
+
* @description Abstract base class for user request handlers.
|
|
21
|
+
*
|
|
22
|
+
* Handler methods follow the core `Service` golden rules: `handle` (and the
|
|
23
|
+
* lifecycle helpers `getInput`/`cancel`) accept rest contextual args
|
|
24
|
+
* (`...args: ContextualArgs<C>`) and obtain their `{ log, ctx, ctxArgs }` via
|
|
25
|
+
* `this.logCtx([request, ...args], this.handle, true)` — entry and resolution
|
|
26
|
+
* via `log.info`, transitions via `log.verbose`, payload details via
|
|
27
|
+
* `log.debug` and failures/cancellations via `log.error`. A `CancelledError`
|
|
28
|
+
* is thrown when the user cancels mid-request. `handle` is the one async
|
|
29
|
+
* method handlers override, returning the resolved value or throwing.
|
|
30
|
+
* @summary Service-based base class implementing the user request lifecycle.
|
|
31
|
+
* @template T The resolved payload type the handler returns.
|
|
32
|
+
* @template C The decaf context the service runs under.
|
|
33
|
+
*/
|
|
34
|
+
export class UserRequestHandler extends Service {
|
|
35
|
+
/**
|
|
36
|
+
* @description Creates a handler bound to the given rendering-engine facade.
|
|
37
|
+
* The facade is the only external dependency: no context/resolver
|
|
38
|
+
* indirection.
|
|
39
|
+
* @param {RenderingFacade} renderingEngine The rendering-engine surface the
|
|
40
|
+
* handler drives (modal, toast, spinner and router).
|
|
41
|
+
*/
|
|
42
|
+
constructor(renderingEngine) {
|
|
43
|
+
super();
|
|
44
|
+
this.renderingEngine = renderingEngine;
|
|
45
|
+
this.cancelled = false;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @description Resolves the handler class registered for the given request
|
|
49
|
+
* reference via `Metadata`. Handlers are recorded by the `@userRequest`
|
|
50
|
+
* decorator under `USER_REQUEST_KEY`.
|
|
51
|
+
* @param {string} reference The request id/type the handler is registered
|
|
52
|
+
* for.
|
|
53
|
+
* @return {.Constructor<UserRequestHandler> | undefined}
|
|
54
|
+
* The registered handler constructor, or `undefined` when unknown.
|
|
55
|
+
*/
|
|
56
|
+
static getHandler(reference) {
|
|
57
|
+
return Metadata.get(USER_REQUEST_KEY, reference);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* @description Reads the `@userRequest` metadata recorded on a handler class
|
|
61
|
+
* via `Metadata`.
|
|
62
|
+
* @param {object} target The handler class to inspect.
|
|
63
|
+
* @return {UserRequestHandlerMetadata | undefined} The recorded metadata
|
|
64
|
+
* `{ reference }`, or `undefined` when the class is not decorated.
|
|
65
|
+
*/
|
|
66
|
+
static getMetadata(target) {
|
|
67
|
+
return Metadata.get(target, USER_REQUEST_KEY);
|
|
68
|
+
}
|
|
69
|
+
static async handle(request, renderingEngine) {
|
|
70
|
+
const id = request.type || request.id;
|
|
71
|
+
const Handler = UserRequestHandler.getHandler(id);
|
|
72
|
+
if (!Handler)
|
|
73
|
+
throw new InternalError(`No user request handler registered for "${id}"`);
|
|
74
|
+
const instance = new Handler(renderingEngine);
|
|
75
|
+
const ctx = await instance.context("user-request", {});
|
|
76
|
+
return instance.handle(request, ctx);
|
|
77
|
+
}
|
|
78
|
+
async getInput(request, ...args) {
|
|
79
|
+
const { log } = await this.logCtx([request, ...args], this.getInput, true);
|
|
80
|
+
const component = { props: { request } };
|
|
81
|
+
log.info(`Requesting input for user request "${request.type || request.id}"`);
|
|
82
|
+
const modal = await this.renderingEngine.getModal(component);
|
|
83
|
+
this.currentModal = modal;
|
|
84
|
+
if (this.cancelled) {
|
|
85
|
+
this.currentModal = undefined;
|
|
86
|
+
await modal.cancel();
|
|
87
|
+
log.error(`User request "${request.type || request.id}" was cancelled`);
|
|
88
|
+
throw new CancelledError(`User request "${request.type || request.id}" was cancelled`);
|
|
89
|
+
}
|
|
90
|
+
return this.awaitDismissal(request, modal);
|
|
91
|
+
}
|
|
92
|
+
awaitDismissal(request, modal) {
|
|
93
|
+
return new Promise((resolve, reject) => {
|
|
94
|
+
this.submitted = resolve;
|
|
95
|
+
this.dismissed = reject;
|
|
96
|
+
const confirm = modal.confirm.bind(modal);
|
|
97
|
+
const cancel = modal.cancel.bind(modal);
|
|
98
|
+
modal.confirm = async (event) => {
|
|
99
|
+
try {
|
|
100
|
+
await confirm(event);
|
|
101
|
+
this.currentModal = undefined;
|
|
102
|
+
const data = (event?.data ?? event);
|
|
103
|
+
resolve(data);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
// A facade confirms with an error payload (e.g. a `ValidationError`
|
|
107
|
+
// from an invalid form submission) by throwing it out of `confirm`;
|
|
108
|
+
// reject the pending request with that decaf error instead of
|
|
109
|
+
// leaving it hanging.
|
|
110
|
+
this.currentModal = undefined;
|
|
111
|
+
reject(error);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
modal.cancel = async () => {
|
|
115
|
+
await cancel();
|
|
116
|
+
this.currentModal = undefined;
|
|
117
|
+
reject(new CancelledError(`User request "${request.type || request.id}" was cancelled`));
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async cancel(...args) {
|
|
122
|
+
const { log } = await this.logCtx(args, this.cancel, true);
|
|
123
|
+
log.info("Cancelling active user request");
|
|
124
|
+
this.cancelled = true;
|
|
125
|
+
const modal = this.currentModal;
|
|
126
|
+
this.currentModal = undefined;
|
|
127
|
+
if (this.dismissed) {
|
|
128
|
+
log.verbose("Rejecting pending user request with CancelledError");
|
|
129
|
+
this.dismissed(new CancelledError("User request was cancelled"));
|
|
130
|
+
this.dismissed = undefined;
|
|
131
|
+
this.submitted = undefined;
|
|
132
|
+
}
|
|
133
|
+
if (modal) {
|
|
134
|
+
log.debug("Dismissing the active user request modal");
|
|
135
|
+
await modal.cancel();
|
|
136
|
+
}
|
|
137
|
+
log.error("User request cancelled");
|
|
138
|
+
}
|
|
139
|
+
logCtx(args, operation, allowCreate = false, overrides) {
|
|
140
|
+
const base = super.logCtx(args, operation, allowCreate, overrides);
|
|
141
|
+
if (base instanceof Promise) {
|
|
142
|
+
return (async () => this.wrapLogContext(await base))();
|
|
143
|
+
}
|
|
144
|
+
return this.wrapLogContext(base);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* @description Decorates the base contextual surface with the rendering
|
|
148
|
+
* engine methods exposed as `modal`/`toast`/`spinner`/`router` bound getters.
|
|
149
|
+
* @return {UserRequestLogContext<C, ARGS>} The decorated contextual surface.
|
|
150
|
+
* @template C The decaf context the service runs under.
|
|
151
|
+
* @template ARGS The contextual argument tuple passed to the call.
|
|
152
|
+
*/
|
|
153
|
+
wrapLogContext(base) {
|
|
154
|
+
const engine = this.renderingEngine;
|
|
155
|
+
const result = {
|
|
156
|
+
log: base.log,
|
|
157
|
+
ctx: base.ctx,
|
|
158
|
+
ctxArgs: base.ctxArgs,
|
|
159
|
+
};
|
|
160
|
+
Object.defineProperties(result, {
|
|
161
|
+
modal: {
|
|
162
|
+
get: () => engine.getModal.bind(engine),
|
|
163
|
+
enumerable: true,
|
|
164
|
+
configurable: true,
|
|
165
|
+
},
|
|
166
|
+
toast: {
|
|
167
|
+
get: () => engine.getToast.bind(engine),
|
|
168
|
+
enumerable: true,
|
|
169
|
+
configurable: true,
|
|
170
|
+
},
|
|
171
|
+
spinner: {
|
|
172
|
+
get: () => engine.getSpinner.bind(engine),
|
|
173
|
+
enumerable: true,
|
|
174
|
+
configurable: true,
|
|
175
|
+
},
|
|
176
|
+
router: {
|
|
177
|
+
get: () => engine.router.bind(engine),
|
|
178
|
+
enumerable: true,
|
|
179
|
+
configurable: true,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=UserRequestHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserRequestHandler.js","sourceRoot":"","sources":["../../../src/user-requests/UserRequestHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ui-decorators/user-requests/constants
|
|
3
|
+
* @summary Metadata keys for the User Request Resolution Engine.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @description Metadata key under which user request handlers are registered
|
|
7
|
+
* and resolved.
|
|
8
|
+
* @summary The `@userRequest(reference)` decorator stores both the handler
|
|
9
|
+
* reference and the decorating metadata under this key, and
|
|
10
|
+
* `UserRequestHandler.getHandler` / `UserRequestHandler.getMetadata` read it
|
|
11
|
+
* back. The key is scoped to the User Request Resolution Engine to avoid
|
|
12
|
+
* colliding with other reflection metadata.
|
|
13
|
+
* @const USER_REQUEST_KEY
|
|
14
|
+
* @type {string}
|
|
15
|
+
* @readonly
|
|
16
|
+
*/
|
|
17
|
+
export const USER_REQUEST_KEY = "user-requests.handler";
|
|
18
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/user-requests/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ui-decorators/user-requests/decorators
|
|
3
|
+
* @summary `@userRequest(reference)` class decorator.
|
|
4
|
+
* @description No Angular or DOM imports — safe for pure-Node (backend)
|
|
5
|
+
* bundles. Registration is metadata-based: the decorator records the handler
|
|
6
|
+
* class under `USER_REQUEST_KEY` and the static `UserRequestHandler` methods
|
|
7
|
+
* resolve and dispatch it, so no process-wide registry is involved.
|
|
8
|
+
*/
|
|
9
|
+
import { Decoration, metadata, Metadata, } from "@decaf-ts/decoration";
|
|
10
|
+
import { USER_REQUEST_KEY } from "./constants.js";
|
|
11
|
+
/**
|
|
12
|
+
* @description Registers a handler class for the given request id/type.
|
|
13
|
+
*
|
|
14
|
+
* Mirrors `core/src/migrations/decorators.ts`:
|
|
15
|
+
* `Decoration.for(KEY).define({ decorator, args }).apply()` plus
|
|
16
|
+
* `Metadata.set(USER_REQUEST_KEY, reference, original)` so the class is
|
|
17
|
+
* retrievable by id via metadata — `UserRequestHandler.getHandler(reference)`
|
|
18
|
+
* reads it back and `UserRequestHandler.handle(request, renderingEngine)`
|
|
19
|
+
* dispatches it — and a class-level `metadata(...)` payload for
|
|
20
|
+
* introspection (`UserRequestHandler.getMetadata(target)`).
|
|
21
|
+
* @param {string} reference The request id/type the handler is registered for.
|
|
22
|
+
* @return {ClassDecorator} The class decorator to apply.
|
|
23
|
+
*/
|
|
24
|
+
export function userRequest(reference) {
|
|
25
|
+
function innerUserRequest(ref) {
|
|
26
|
+
return function userRequestDecorator(target) {
|
|
27
|
+
const constructor = target;
|
|
28
|
+
const meta = { reference: ref };
|
|
29
|
+
Metadata.set(USER_REQUEST_KEY, ref, constructor);
|
|
30
|
+
return metadata(USER_REQUEST_KEY, meta)(constructor);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return Decoration.for(USER_REQUEST_KEY)
|
|
34
|
+
.define({ decorator: innerUserRequest, args: [reference] })
|
|
35
|
+
.apply();
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=decorators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../../src/user-requests/decorators.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,UAAU,EACV,QAAQ,EACR,QAAQ,GACT,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,uBAAoB;AAG/C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,SAAiB;IAC3C,SAAS,gBAAgB,CAAC,GAAW;QACnC,OAAO,SAAS,oBAAoB,CAAC,MAAc;YACjD,MAAM,WAAW,GAAG,MAAqB,CAAC;YAC1C,MAAM,IAAI,GAA+B,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;YAC5D,QAAQ,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;YACjD,OAAO,QAAQ,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC;QACvD,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC;SACpC,MAAM,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;SAC1D,KAAK,EAAoB,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ui-decorators/user-requests/errors
|
|
3
|
+
* @summary Decaf error hierarchy for the User Request Resolution Engine.
|
|
4
|
+
*/
|
|
5
|
+
import { InternalError } from "@decaf-ts/db-decorators";
|
|
6
|
+
/**
|
|
7
|
+
* @description Error thrown when the user cancels a user request mid-resolution.
|
|
8
|
+
* Follows the decaf error hierarchy: never a raw `Error`. Compatible with the
|
|
9
|
+
* validation error signaling used by `@devcerts/decaf` UI facades.
|
|
10
|
+
* @summary Error thrown when a user request is cancelled.
|
|
11
|
+
*/
|
|
12
|
+
export class CancelledError extends InternalError {
|
|
13
|
+
/**
|
|
14
|
+
* @param {string | Error | unknown} msg The cancellation message.
|
|
15
|
+
* @return {CancelledError} A new `CancelledError`.
|
|
16
|
+
*/
|
|
17
|
+
constructor(msg = "User request cancelled") {
|
|
18
|
+
super(msg, CancelledError.name, 400);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/user-requests/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD;;;;;GAKG;AACH,MAAM,OAAO,cAAe,SAAQ,aAAa;IAC/C;;;OAGG;IACH,YAAY,MAAgC,wBAAwB;QAClE,KAAK,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ui-decorators/user-requests
|
|
3
|
+
* @summary Backend binding surface for the User Request Resolution Engine.
|
|
4
|
+
* @description Framework-agnostic core of the engine: no Angular or DOM
|
|
5
|
+
* imports, safe for pure-Node (backend) bundles. Handlers are registered via
|
|
6
|
+
* `@userRequest(reference)` (metadata) and resolved/dispatched through the
|
|
7
|
+
* static `UserRequestHandler` methods; example handlers and rendering-engine
|
|
8
|
+
* mocks live only in the test tree, never under `src`. Frontend bindings live
|
|
9
|
+
* in `for-angular`.
|
|
10
|
+
*/
|
|
11
|
+
export * from "./constants.js";
|
|
12
|
+
export * from "./errors.js";
|
|
13
|
+
export * from "./types.js";
|
|
14
|
+
export * from "./UserRequestHandler.js";
|
|
15
|
+
export * from "./decorators.js";
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/user-requests/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,+BAA4B;AAC5B,4BAAyB;AACzB,2BAAwB;AACxB,wCAAqC;AACrC,gCAA6B"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ui-decorators/user-requests/types
|
|
3
|
+
* @summary Framework-agnostic contracts for the User Request Resolution Engine.
|
|
4
|
+
* @description No Angular or DOM imports are allowed here so the `user-requests`
|
|
5
|
+
* entry point stays consumable from pure-Node (backend) bundles.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/user-requests/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -37,6 +37,11 @@ export type GraphNodeMetadata = {
|
|
|
37
37
|
* (the one-vs-all toggle). See {@link GraphPortGroupMetadata}.
|
|
38
38
|
*/
|
|
39
39
|
portGroups?: GraphPortGroupMetadata[];
|
|
40
|
+
/**
|
|
41
|
+
* Node I/O inspection hints (DECAF-48 §4.6) — viewer mode and which ports
|
|
42
|
+
* map to the inputs/outputs panes. Frontend-safe metadata only.
|
|
43
|
+
*/
|
|
44
|
+
inspection?: GraphNodeIoMetadata;
|
|
40
45
|
};
|
|
41
46
|
export type GraphWorkflowNodeMetadata = {
|
|
42
47
|
id: string;
|
|
@@ -45,7 +50,68 @@ export type GraphWorkflowNodeMetadata = {
|
|
|
45
50
|
description?: string;
|
|
46
51
|
node?: unknown;
|
|
47
52
|
metadata?: Record<string, unknown>;
|
|
53
|
+
/**
|
|
54
|
+
* Node I/O inspection hints for this workflow instance (DECAF-48 §4.6).
|
|
55
|
+
* Frontend-safe metadata only.
|
|
56
|
+
*/
|
|
57
|
+
inspection?: GraphNodeIoMetadata;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* A view-mode choice for the reusable I/O viewer (DECAF-48 §4.6 / Req-9).
|
|
61
|
+
* One shared component renders both the inputs and outputs panes.
|
|
62
|
+
*/
|
|
63
|
+
export type GraphNodeIoViewMode = "json" | "table" | "raw";
|
|
64
|
+
/**
|
|
65
|
+
* Node I/O inspection metadata (DECAF-48 §4.6) — hints the workflow canvas
|
|
66
|
+
* uses to open the inline split view for an already-ran node. Framework
|
|
67
|
+
* neutral, frontend-safe, no engine/runtime dependency (DECAF-24 §4).
|
|
68
|
+
*/
|
|
69
|
+
export type GraphNodeIoMetadata = {
|
|
70
|
+
/** Default view mode for the reusable viewer. Defaults to "json". */
|
|
71
|
+
view?: GraphNodeIoViewMode;
|
|
72
|
+
/** Port property names shown in the right-side inputs pane. */
|
|
73
|
+
inputPorts?: string[];
|
|
74
|
+
/** Port property names shown in the left-side outputs pane. */
|
|
75
|
+
outputPorts?: string[];
|
|
76
|
+
/** Whether the node exposes editable config (opens the edit modal instead). */
|
|
77
|
+
editable?: boolean;
|
|
78
|
+
/** Free-form extension points. */
|
|
79
|
+
metadata?: Record<string, unknown>;
|
|
48
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* Visual treatment for a node/edge execution state (DECAF-48 §4.4). Maps a
|
|
83
|
+
* {@link GraphVisualState} value to the faded glow / fade-after-fail overlay
|
|
84
|
+
* colours used by the canvas renderer.
|
|
85
|
+
*/
|
|
86
|
+
export type GraphVisualStyle = {
|
|
87
|
+
/** Visual state string as defined by the shared `GraphVisualState` values (e.g. `"running"`, `"blocked"`). */
|
|
88
|
+
state: string;
|
|
89
|
+
/** Glow/border colour for the live run-feedback overlay. */
|
|
90
|
+
glow?: string;
|
|
91
|
+
/** Level of fade for unexecuted/disabled rendering (0..1). */
|
|
92
|
+
opacity?: number;
|
|
93
|
+
/** Optional fill colour when the node is in this state. */
|
|
94
|
+
color?: string;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* The default visual-state → overlay mapping contract (DECAF-48 §4.4):
|
|
98
|
+
* running=faded green, blocked=yellow, errored=red; succeeded keeps the
|
|
99
|
+
* node's own accent; unexecuted-after-failure fades/disabled. This is the
|
|
100
|
+
* shared, framework-neutral source of truth that supersedes the DECAF-32
|
|
101
|
+
* §21.9 running colour for the live run-feedback overlay (§4.5).
|
|
102
|
+
*/
|
|
103
|
+
export declare const GRAPH_VISUAL_STATE_STYLES: {
|
|
104
|
+
[state: string]: Omit<GraphVisualStyle, "state">;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Resolves the visual style overlay for a node/edge execution state, falling
|
|
108
|
+
* back to a neutral default when the state is unknown or unregistered.
|
|
109
|
+
*
|
|
110
|
+
* @param state - The visual state string (as defined by the shared
|
|
111
|
+
* `GraphVisualState` values, e.g. `"running"`, `"blocked"`).
|
|
112
|
+
* @returns The style overlay for the given state.
|
|
113
|
+
*/
|
|
114
|
+
export declare function graphVisualStyleOf(state: string): Omit<GraphVisualStyle, "state">;
|
|
49
115
|
export type GraphWorkflowRelationMetadata = {
|
|
50
116
|
source: string | unknown;
|
|
51
117
|
sourcePort?: string;
|
|
@@ -37,6 +37,11 @@ export type GraphNodeMetadata = {
|
|
|
37
37
|
* (the one-vs-all toggle). See {@link GraphPortGroupMetadata}.
|
|
38
38
|
*/
|
|
39
39
|
portGroups?: GraphPortGroupMetadata[];
|
|
40
|
+
/**
|
|
41
|
+
* Node I/O inspection hints (DECAF-48 §4.6) — viewer mode and which ports
|
|
42
|
+
* map to the inputs/outputs panes. Frontend-safe metadata only.
|
|
43
|
+
*/
|
|
44
|
+
inspection?: GraphNodeIoMetadata;
|
|
40
45
|
};
|
|
41
46
|
export type GraphWorkflowNodeMetadata = {
|
|
42
47
|
id: string;
|
|
@@ -45,7 +50,68 @@ export type GraphWorkflowNodeMetadata = {
|
|
|
45
50
|
description?: string;
|
|
46
51
|
node?: unknown;
|
|
47
52
|
metadata?: Record<string, unknown>;
|
|
53
|
+
/**
|
|
54
|
+
* Node I/O inspection hints for this workflow instance (DECAF-48 §4.6).
|
|
55
|
+
* Frontend-safe metadata only.
|
|
56
|
+
*/
|
|
57
|
+
inspection?: GraphNodeIoMetadata;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* A view-mode choice for the reusable I/O viewer (DECAF-48 §4.6 / Req-9).
|
|
61
|
+
* One shared component renders both the inputs and outputs panes.
|
|
62
|
+
*/
|
|
63
|
+
export type GraphNodeIoViewMode = "json" | "table" | "raw";
|
|
64
|
+
/**
|
|
65
|
+
* Node I/O inspection metadata (DECAF-48 §4.6) — hints the workflow canvas
|
|
66
|
+
* uses to open the inline split view for an already-ran node. Framework
|
|
67
|
+
* neutral, frontend-safe, no engine/runtime dependency (DECAF-24 §4).
|
|
68
|
+
*/
|
|
69
|
+
export type GraphNodeIoMetadata = {
|
|
70
|
+
/** Default view mode for the reusable viewer. Defaults to "json". */
|
|
71
|
+
view?: GraphNodeIoViewMode;
|
|
72
|
+
/** Port property names shown in the right-side inputs pane. */
|
|
73
|
+
inputPorts?: string[];
|
|
74
|
+
/** Port property names shown in the left-side outputs pane. */
|
|
75
|
+
outputPorts?: string[];
|
|
76
|
+
/** Whether the node exposes editable config (opens the edit modal instead). */
|
|
77
|
+
editable?: boolean;
|
|
78
|
+
/** Free-form extension points. */
|
|
79
|
+
metadata?: Record<string, unknown>;
|
|
48
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* Visual treatment for a node/edge execution state (DECAF-48 §4.4). Maps a
|
|
83
|
+
* {@link GraphVisualState} value to the faded glow / fade-after-fail overlay
|
|
84
|
+
* colours used by the canvas renderer.
|
|
85
|
+
*/
|
|
86
|
+
export type GraphVisualStyle = {
|
|
87
|
+
/** Visual state string as defined by the shared `GraphVisualState` values (e.g. `"running"`, `"blocked"`). */
|
|
88
|
+
state: string;
|
|
89
|
+
/** Glow/border colour for the live run-feedback overlay. */
|
|
90
|
+
glow?: string;
|
|
91
|
+
/** Level of fade for unexecuted/disabled rendering (0..1). */
|
|
92
|
+
opacity?: number;
|
|
93
|
+
/** Optional fill colour when the node is in this state. */
|
|
94
|
+
color?: string;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* The default visual-state → overlay mapping contract (DECAF-48 §4.4):
|
|
98
|
+
* running=faded green, blocked=yellow, errored=red; succeeded keeps the
|
|
99
|
+
* node's own accent; unexecuted-after-failure fades/disabled. This is the
|
|
100
|
+
* shared, framework-neutral source of truth that supersedes the DECAF-32
|
|
101
|
+
* §21.9 running colour for the live run-feedback overlay (§4.5).
|
|
102
|
+
*/
|
|
103
|
+
export declare const GRAPH_VISUAL_STATE_STYLES: {
|
|
104
|
+
[state: string]: Omit<GraphVisualStyle, "state">;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Resolves the visual style overlay for a node/edge execution state, falling
|
|
108
|
+
* back to a neutral default when the state is unknown or unregistered.
|
|
109
|
+
*
|
|
110
|
+
* @param state - The visual state string (as defined by the shared
|
|
111
|
+
* `GraphVisualState` values, e.g. `"running"`, `"blocked"`).
|
|
112
|
+
* @returns The style overlay for the given state.
|
|
113
|
+
*/
|
|
114
|
+
export declare function graphVisualStyleOf(state: string): Omit<GraphVisualStyle, "state">;
|
|
49
115
|
export type GraphWorkflowRelationMetadata = {
|
|
50
116
|
source: string | unknown;
|
|
51
117
|
sourcePort?: string;
|
package/lib/types/index.d.cts
CHANGED
|
@@ -15,19 +15,19 @@ export * from "./ui/index.d.cts";
|
|
|
15
15
|
* @const VERSION
|
|
16
16
|
* @memberOf module:ui-decorators
|
|
17
17
|
*/
|
|
18
|
-
export declare const VERSION = "0.
|
|
18
|
+
export declare const VERSION = "0.18.0";
|
|
19
19
|
/**
|
|
20
20
|
* @description Represents the current commit hash of the module build.
|
|
21
21
|
* @summary Stores the current git commit hash for the package. The build replaces
|
|
22
22
|
* the placeholder with the actual commit hash at publish time.
|
|
23
23
|
* @const COMMIT
|
|
24
24
|
*/
|
|
25
|
-
export declare const COMMIT = "
|
|
25
|
+
export declare const COMMIT = "23dcb33";
|
|
26
26
|
/**
|
|
27
27
|
* @description Represents the full version string of the module.
|
|
28
28
|
* @summary Stores the semver version and commit hash for the package.
|
|
29
29
|
* The build replaces the placeholder with the actual `<version>-<commit>` value at publish time.
|
|
30
30
|
* @const FULL_VERSION
|
|
31
31
|
*/
|
|
32
|
-
export declare const FULL_VERSION = "0.
|
|
32
|
+
export declare const FULL_VERSION = "0.18.0-23dcb33";
|
|
33
33
|
export declare const PACKAGE_NAME = "@decaf-ts/ui-decorators";
|
package/lib/types/index.d.mts
CHANGED
|
@@ -15,19 +15,19 @@ export * from "./ui/index.d.mts";
|
|
|
15
15
|
* @const VERSION
|
|
16
16
|
* @memberOf module:ui-decorators
|
|
17
17
|
*/
|
|
18
|
-
export declare const VERSION = "0.
|
|
18
|
+
export declare const VERSION = "0.18.0";
|
|
19
19
|
/**
|
|
20
20
|
* @description Represents the current commit hash of the module build.
|
|
21
21
|
* @summary Stores the current git commit hash for the package. The build replaces
|
|
22
22
|
* the placeholder with the actual commit hash at publish time.
|
|
23
23
|
* @const COMMIT
|
|
24
24
|
*/
|
|
25
|
-
export declare const COMMIT = "
|
|
25
|
+
export declare const COMMIT = "23dcb33";
|
|
26
26
|
/**
|
|
27
27
|
* @description Represents the full version string of the module.
|
|
28
28
|
* @summary Stores the semver version and commit hash for the package.
|
|
29
29
|
* The build replaces the placeholder with the actual `<version>-<commit>` value at publish time.
|
|
30
30
|
* @const FULL_VERSION
|
|
31
31
|
*/
|
|
32
|
-
export declare const FULL_VERSION = "0.
|
|
32
|
+
export declare const FULL_VERSION = "0.18.0-23dcb33";
|
|
33
33
|
export declare const PACKAGE_NAME = "@decaf-ts/ui-decorators";
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ui-decorators/user-requests/UserRequestHandler
|
|
3
|
+
* @summary Service-based base class for user request handlers.
|
|
4
|
+
* @description No Angular or DOM imports — safe for pure-Node (backend) bundles.
|
|
5
|
+
*
|
|
6
|
+
* Handlers extend `Service`, receive a rendering-engine facade as a
|
|
7
|
+
* `protected readonly` property and implement `handle`, either returning the
|
|
8
|
+
* resolved value or throwing (a `CancelledError` when the user cancels
|
|
9
|
+
* mid-request). Lookup and dispatch are static: `@userRequest(reference)`
|
|
10
|
+
* records the class as metadata and `UserRequestHandler.getHandler(reference)`
|
|
11
|
+
* / `UserRequestHandler.handle(request, renderingEngine)` resolve and run it,
|
|
12
|
+
* so no process-wide registry instance is needed.
|
|
13
|
+
*/
|
|
14
|
+
import { Context, ContextFlags, ContextualArgs, FlagsOf, LoggerOf, MaybeContextualArg, MethodOrOperation, Service } from "@decaf-ts/core";
|
|
15
|
+
import { Constructor } from "@decaf-ts/decoration";
|
|
16
|
+
import type { RenderingFacade, UserRequest, UserRequestHandlerMetadata } from "./types.d.cts";
|
|
17
|
+
/**
|
|
18
|
+
* @description Result of `UserRequestHandler.logCtx(...)`. Extends the
|
|
19
|
+
* standard `{ log, ctx, ctxArgs }` surface with the exact `RenderingEngine`
|
|
20
|
+
* methods a handler needs (`modal`/`toast`/`spinner`/`router`) wrapping the
|
|
21
|
+
* rendering engine handed to the handler constructor. The keys mirror the
|
|
22
|
+
* underlying engine methods without a `get` prefix, and no duplicated
|
|
23
|
+
* `UserRequest*` rendering types are introduced.
|
|
24
|
+
* @summary Contextual surface returned by `UserRequestHandler.logCtx(*, *, true)`.
|
|
25
|
+
* @template C The decaf context the handler service runs under.
|
|
26
|
+
* @template ARGS The contextual argument tuple passed to the call.
|
|
27
|
+
*/
|
|
28
|
+
export interface UserRequestLogContext<C extends Context<ContextFlags<any>> = Context<ContextFlags<any>>, ARGS extends any[] = any[]> {
|
|
29
|
+
log: LoggerOf<C>;
|
|
30
|
+
ctx: C;
|
|
31
|
+
ctxArgs: ContextualArgs<C, ARGS>;
|
|
32
|
+
readonly modal: RenderingFacade["getModal"];
|
|
33
|
+
readonly toast: RenderingFacade["getToast"];
|
|
34
|
+
readonly spinner: RenderingFacade["getSpinner"];
|
|
35
|
+
readonly router: RenderingFacade["router"];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* @description Abstract base class for user request handlers.
|
|
39
|
+
*
|
|
40
|
+
* Handler methods follow the core `Service` golden rules: `handle` (and the
|
|
41
|
+
* lifecycle helpers `getInput`/`cancel`) accept rest contextual args
|
|
42
|
+
* (`...args: ContextualArgs<C>`) and obtain their `{ log, ctx, ctxArgs }` via
|
|
43
|
+
* `this.logCtx([request, ...args], this.handle, true)` — entry and resolution
|
|
44
|
+
* via `log.info`, transitions via `log.verbose`, payload details via
|
|
45
|
+
* `log.debug` and failures/cancellations via `log.error`. A `CancelledError`
|
|
46
|
+
* is thrown when the user cancels mid-request. `handle` is the one async
|
|
47
|
+
* method handlers override, returning the resolved value or throwing.
|
|
48
|
+
* @summary Service-based base class implementing the user request lifecycle.
|
|
49
|
+
* @template T The resolved payload type the handler returns.
|
|
50
|
+
* @template C The decaf context the service runs under.
|
|
51
|
+
*/
|
|
52
|
+
export declare abstract class UserRequestHandler<T = unknown, C extends Context<ContextFlags<any>> = Context<ContextFlags<any>>> extends Service<C> {
|
|
53
|
+
protected readonly renderingEngine: RenderingFacade;
|
|
54
|
+
private currentModal?;
|
|
55
|
+
private cancelled;
|
|
56
|
+
private submitted?;
|
|
57
|
+
private dismissed?;
|
|
58
|
+
/**
|
|
59
|
+
* @description Creates a handler bound to the given rendering-engine facade.
|
|
60
|
+
* The facade is the only external dependency: no context/resolver
|
|
61
|
+
* indirection.
|
|
62
|
+
* @param {RenderingFacade} renderingEngine The rendering-engine surface the
|
|
63
|
+
* handler drives (modal, toast, spinner and router).
|
|
64
|
+
*/
|
|
65
|
+
protected constructor(renderingEngine: RenderingFacade);
|
|
66
|
+
/**
|
|
67
|
+
* @description Resolves the handler class registered for the given request
|
|
68
|
+
* reference via `Metadata`. Handlers are recorded by the `@userRequest`
|
|
69
|
+
* decorator under `USER_REQUEST_KEY`.
|
|
70
|
+
* @param {string} reference The request id/type the handler is registered
|
|
71
|
+
* for.
|
|
72
|
+
* @return {.Constructor<UserRequestHandler> | undefined}
|
|
73
|
+
* The registered handler constructor, or `undefined` when unknown.
|
|
74
|
+
*/
|
|
75
|
+
static getHandler(reference: string): Constructor<UserRequestHandler> | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* @description Reads the `@userRequest` metadata recorded on a handler class
|
|
78
|
+
* via `Metadata`.
|
|
79
|
+
* @param {object} target The handler class to inspect.
|
|
80
|
+
* @return {UserRequestHandlerMetadata | undefined} The recorded metadata
|
|
81
|
+
* `{ reference }`, or `undefined` when the class is not decorated.
|
|
82
|
+
*/
|
|
83
|
+
static getMetadata(target: object): UserRequestHandlerMetadata | undefined;
|
|
84
|
+
static handle<T = unknown>(request: UserRequest<T>, renderingEngine: RenderingFacade): Promise<T>;
|
|
85
|
+
protected getInput(request: UserRequest<T>, ...args: ContextualArgs<C>): Promise<T>;
|
|
86
|
+
private awaitDismissal;
|
|
87
|
+
cancel(...args: ContextualArgs<C> | []): Promise<void>;
|
|
88
|
+
abstract handle(request: UserRequest<T>, ...args: ContextualArgs<C>): Promise<T>;
|
|
89
|
+
/**
|
|
90
|
+
* @description Logging + rendering-engine methods for a call. Mirrors the
|
|
91
|
+
* `Service` `logCtx` contract and exposes `modal`/`toast`/`spinner`/`router`
|
|
92
|
+
* getters wrapping the rendering engine.
|
|
93
|
+
* @param {MaybeContextualArg<C, ARGS>} args Contextual args (context at the
|
|
94
|
+
* end, or pre-args plus context).
|
|
95
|
+
* @param {METHOD} operation The operation the context is created for.
|
|
96
|
+
* @param {boolean} allowCreate Whether a context is created when none is
|
|
97
|
+
* provided.
|
|
98
|
+
* @param {Partial<FlagsOf<CONTEXT>>} overrides Optional flag overrides.
|
|
99
|
+
* @return {UserRequestLogContext<C, ARGS> | Promise<UserRequestLogContext<C, ARGS>>}
|
|
100
|
+
* The contextual surface (or a promise of it when `allowCreate` is true).
|
|
101
|
+
* @template C The decaf context the service runs under.
|
|
102
|
+
* @template ARGS The contextual argument tuple passed to the call.
|
|
103
|
+
* @template CONTEXT The context type to promote to when creating one.
|
|
104
|
+
* @template METHOD The operation the context is created for.
|
|
105
|
+
*/
|
|
106
|
+
protected logCtx<ARGS extends any[] = any[], METHOD extends MethodOrOperation = MethodOrOperation>(args: MaybeContextualArg<C, ARGS>, operation: METHOD): UserRequestLogContext<C, ARGS>;
|
|
107
|
+
protected logCtx<CONTEXT extends Context<any> = C, ARGS extends any[] = any[], METHOD extends MethodOrOperation = MethodOrOperation>(args: MaybeContextualArg<CONTEXT, ARGS>, operation: METHOD, allowCreate: false, overrides?: Partial<FlagsOf<CONTEXT>>): UserRequestLogContext<C, ARGS>;
|
|
108
|
+
protected logCtx<CONTEXT extends Context<any> = C, ARGS extends any[] = any[], METHOD extends MethodOrOperation = MethodOrOperation>(args: MaybeContextualArg<CONTEXT, ARGS>, operation: METHOD, allowCreate: true, overrides?: Partial<FlagsOf<CONTEXT>>): Promise<UserRequestLogContext<C, ARGS>>;
|
|
109
|
+
/**
|
|
110
|
+
* @description Decorates the base contextual surface with the rendering
|
|
111
|
+
* engine methods exposed as `modal`/`toast`/`spinner`/`router` bound getters.
|
|
112
|
+
* @return {UserRequestLogContext<C, ARGS>} The decorated contextual surface.
|
|
113
|
+
* @template C The decaf context the service runs under.
|
|
114
|
+
* @template ARGS The contextual argument tuple passed to the call.
|
|
115
|
+
*/
|
|
116
|
+
private wrapLogContext;
|
|
117
|
+
}
|