@atscript/moost-wf 0.1.68 → 0.1.69
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/README.md +1 -1
- package/dist/index.d.mts +40 -28
- package/dist/index.mjs +32 -59
- package/package.json +18 -18
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ Part of the [atscript-ui](https://github.com/moostjs/atscript-ui) monorepo.
|
|
|
17
17
|
- Workflow decorators that wrap Moost handlers and expose them as `@atscript/vue-wf`-compatible endpoints
|
|
18
18
|
- Interceptors that serialize / deserialize workflow state across HTTP requests
|
|
19
19
|
- `@AsWfState` storage abstraction with a default `@atscript/db`-backed implementation
|
|
20
|
-
- Unified `WfFinished` envelope + helpers (`
|
|
20
|
+
- Unified `WfFinished` envelope + helpers (`finishWf(opts)`, `abortWf(reason, opts)`) for terminal-screen UX. See [Finish Screens](https://ui.atscript.dev/workflows/finish-screens).
|
|
21
21
|
|
|
22
22
|
## Install
|
|
23
23
|
|
package/dist/index.d.mts
CHANGED
|
@@ -124,7 +124,6 @@ interface TFormActions {
|
|
|
124
124
|
declare function extractPassContext(type: TAtscriptAnnotatedType, wfContext: Record<string, unknown>): Record<string, unknown>;
|
|
125
125
|
/**
|
|
126
126
|
* Read declared action names from `@ui.form.action` and `@wf.action.withData` annotations.
|
|
127
|
-
* Also reads legacy `@ui.altAction` as a stateless action fallback.
|
|
128
127
|
* Results are cached per type identity.
|
|
129
128
|
*/
|
|
130
129
|
declare function getFormActions(type: TAtscriptAnnotatedType): TFormActions;
|
|
@@ -179,7 +178,7 @@ interface WfFinished<TData = unknown> {
|
|
|
179
178
|
finished: true;
|
|
180
179
|
data?: TData;
|
|
181
180
|
message?: WfMessage;
|
|
182
|
-
|
|
181
|
+
next?: WfNext;
|
|
183
182
|
aborted?: boolean;
|
|
184
183
|
reason?: string;
|
|
185
184
|
}
|
|
@@ -187,11 +186,11 @@ interface WfMessage {
|
|
|
187
186
|
level: "info" | "success" | "warn" | "error";
|
|
188
187
|
text: string;
|
|
189
188
|
}
|
|
190
|
-
type
|
|
191
|
-
|
|
189
|
+
type WfNext = {
|
|
190
|
+
trigger: "immediate";
|
|
192
191
|
action: WfAction;
|
|
193
192
|
} | {
|
|
194
|
-
|
|
193
|
+
trigger: "auto";
|
|
195
194
|
timeoutMs: number;
|
|
196
195
|
action: WfAction;
|
|
197
196
|
skipButton?: {
|
|
@@ -199,7 +198,7 @@ type WfFinishedEnd = {
|
|
|
199
198
|
behavior?: "now" | "cancel";
|
|
200
199
|
};
|
|
201
200
|
} | {
|
|
202
|
-
|
|
201
|
+
trigger: "manual";
|
|
203
202
|
primary?: WfButton;
|
|
204
203
|
options?: WfButton[];
|
|
205
204
|
};
|
|
@@ -218,28 +217,41 @@ type WfAction = {
|
|
|
218
217
|
};
|
|
219
218
|
/** Type-guard for the unified envelope. */
|
|
220
219
|
declare function isWfFinished(v: unknown): v is WfFinished;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
/** Present → `mode: 'auto'` with countdown; absent → `mode: 'immediate'`. */
|
|
228
|
-
autoMs?: number;
|
|
229
|
-
/** Only honored when `autoMs` is set — adds a "skip / cancel" button. */
|
|
230
|
-
skipLabel?: string;
|
|
231
|
-
}
|
|
232
|
-
declare function finishWfWithRedirect(target: string, opts?: RedirectOpts): void;
|
|
233
|
-
interface ChoiceOpts {
|
|
234
|
-
data?: unknown;
|
|
220
|
+
/**
|
|
221
|
+
* Options bag shared by `finishWf` and `abortWf`. Every field is optional
|
|
222
|
+
* — pick whichever envelope properties the terminal screen needs.
|
|
223
|
+
*/
|
|
224
|
+
interface FinishWfOpts<T = unknown> {
|
|
225
|
+
data?: T;
|
|
235
226
|
message?: WfMessage;
|
|
236
|
-
|
|
237
|
-
options?: WfButton[];
|
|
227
|
+
next?: WfNext;
|
|
238
228
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
})
|
|
229
|
+
/**
|
|
230
|
+
* Build a `WfFinished` envelope and hand it to wooks. All envelope
|
|
231
|
+
* properties are optional; pass `data`, `message`, and/or `next`:
|
|
232
|
+
*
|
|
233
|
+
* finishWf({ data: { id: 42 } });
|
|
234
|
+
* finishWf({ message: { level: "success", text: "Saved." } });
|
|
235
|
+
* finishWf({
|
|
236
|
+
* next: {
|
|
237
|
+
* trigger: "auto",
|
|
238
|
+
* timeoutMs: 3000,
|
|
239
|
+
* action: { type: "redirect", target: "/home" },
|
|
240
|
+
* },
|
|
241
|
+
* });
|
|
242
|
+
*/
|
|
243
|
+
declare function finishWf<T = unknown>(opts?: FinishWfOpts<T>): void;
|
|
244
|
+
/**
|
|
245
|
+
* Build an aborted `WfFinished` envelope (`aborted: true` + `reason`) and
|
|
246
|
+
* hand it to wooks. The same options as `finishWf` are accepted — an
|
|
247
|
+
* aborted flow may still carry partial `data`, a `message`, or a `next`
|
|
248
|
+
* action that lets the user navigate away.
|
|
249
|
+
*
|
|
250
|
+
* abortWf("user-cancelled");
|
|
251
|
+
* abortWf("rate-limited", {
|
|
252
|
+
* message: { level: "warn", text: "Try again later." },
|
|
253
|
+
* });
|
|
254
|
+
*/
|
|
255
|
+
declare function abortWf(reason: string, opts?: FinishWfOpts): void;
|
|
244
256
|
//#endregion
|
|
245
|
-
export { AltAction, type
|
|
257
|
+
export { AltAction, type FinishWfOpts, FormInput, FormInputRequired, type TFormInput, type WfAction, type WfButton, type WfFinished, type WfMessage, type WfNext, abortWf, createAsHttpOutlet, extractPassContext, finishWf, formInputInterceptor, getFormActions, handleAsOutletRequest, isWfFinished, serializeFormSchema, useFormInput, useWfAction };
|
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,6 @@ import { useWfFinished } from "@wooksjs/event-wf";
|
|
|
7
7
|
const WF_CONTEXT_PASS = "wf.context.pass";
|
|
8
8
|
const UI_FORM_ACTION = "ui.form.action";
|
|
9
9
|
const WF_ACTION_WITH_DATA = "wf.action.withData";
|
|
10
|
-
const UI_ALT_ACTION = "ui.altAction";
|
|
11
10
|
const formActionsCache = /* @__PURE__ */ new WeakMap();
|
|
12
11
|
/**
|
|
13
12
|
* Extract whitelisted context keys from workflow state.
|
|
@@ -22,7 +21,6 @@ function extractPassContext(type, wfContext) {
|
|
|
22
21
|
}
|
|
23
22
|
/**
|
|
24
23
|
* Read declared action names from `@ui.form.action` and `@wf.action.withData` annotations.
|
|
25
|
-
* Also reads legacy `@ui.altAction` as a stateless action fallback.
|
|
26
24
|
* Results are cached per type identity.
|
|
27
25
|
*/
|
|
28
26
|
function getFormActions(type) {
|
|
@@ -50,8 +48,6 @@ function getFormActions(type) {
|
|
|
50
48
|
actionsWithData.push(wfAction);
|
|
51
49
|
continue;
|
|
52
50
|
}
|
|
53
|
-
const altAction = fieldType.metadata.get(UI_ALT_ACTION);
|
|
54
|
-
if (altAction) actions.push(typeof altAction === "string" ? altAction : altAction.id);
|
|
55
51
|
}
|
|
56
52
|
const result = {
|
|
57
53
|
actions,
|
|
@@ -419,67 +415,44 @@ function setEnvelope(envelope) {
|
|
|
419
415
|
value: envelope
|
|
420
416
|
});
|
|
421
417
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
}
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
function finishWfWithRedirect(target, opts = {}) {
|
|
442
|
-
const action = {
|
|
443
|
-
type: "redirect",
|
|
444
|
-
target,
|
|
445
|
-
reason: opts.reason
|
|
446
|
-
};
|
|
447
|
-
const end = opts.autoMs ? {
|
|
448
|
-
mode: "auto",
|
|
449
|
-
timeoutMs: opts.autoMs,
|
|
450
|
-
action,
|
|
451
|
-
skipButton: opts.skipLabel ? { label: opts.skipLabel } : void 0
|
|
452
|
-
} : {
|
|
453
|
-
mode: "immediate",
|
|
454
|
-
action
|
|
455
|
-
};
|
|
456
|
-
finishWf({
|
|
457
|
-
finished: true,
|
|
458
|
-
message: opts.message,
|
|
459
|
-
end
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
function finishWfWithChoice(opts) {
|
|
463
|
-
if (!opts.primary && (!opts.options || opts.options.length === 0)) throw new Error("finishWfWithChoice() requires at least a primary button or one option.");
|
|
464
|
-
finishWf({
|
|
418
|
+
/**
|
|
419
|
+
* Build a `WfFinished` envelope and hand it to wooks. All envelope
|
|
420
|
+
* properties are optional; pass `data`, `message`, and/or `next`:
|
|
421
|
+
*
|
|
422
|
+
* finishWf({ data: { id: 42 } });
|
|
423
|
+
* finishWf({ message: { level: "success", text: "Saved." } });
|
|
424
|
+
* finishWf({
|
|
425
|
+
* next: {
|
|
426
|
+
* trigger: "auto",
|
|
427
|
+
* timeoutMs: 3000,
|
|
428
|
+
* action: { type: "redirect", target: "/home" },
|
|
429
|
+
* },
|
|
430
|
+
* });
|
|
431
|
+
*/
|
|
432
|
+
function finishWf(opts) {
|
|
433
|
+
setEnvelope({
|
|
465
434
|
finished: true,
|
|
466
|
-
|
|
467
|
-
message: opts.message,
|
|
468
|
-
end: {
|
|
469
|
-
mode: "manual",
|
|
470
|
-
primary: opts.primary,
|
|
471
|
-
options: opts.options
|
|
472
|
-
}
|
|
435
|
+
...opts
|
|
473
436
|
});
|
|
474
437
|
}
|
|
475
|
-
|
|
476
|
-
|
|
438
|
+
/**
|
|
439
|
+
* Build an aborted `WfFinished` envelope (`aborted: true` + `reason`) and
|
|
440
|
+
* hand it to wooks. The same options as `finishWf` are accepted — an
|
|
441
|
+
* aborted flow may still carry partial `data`, a `message`, or a `next`
|
|
442
|
+
* action that lets the user navigate away.
|
|
443
|
+
*
|
|
444
|
+
* abortWf("user-cancelled");
|
|
445
|
+
* abortWf("rate-limited", {
|
|
446
|
+
* message: { level: "warn", text: "Try again later." },
|
|
447
|
+
* });
|
|
448
|
+
*/
|
|
449
|
+
function abortWf(reason, opts) {
|
|
450
|
+
setEnvelope({
|
|
477
451
|
finished: true,
|
|
478
452
|
aborted: true,
|
|
479
453
|
reason,
|
|
480
|
-
|
|
481
|
-
end: opts.end
|
|
454
|
+
...opts
|
|
482
455
|
});
|
|
483
456
|
}
|
|
484
457
|
//#endregion
|
|
485
|
-
export { AltAction, FormInput, FormInputRequired, createAsHttpOutlet, extractPassContext, finishWf,
|
|
458
|
+
export { AltAction, FormInput, FormInputRequired, abortWf, createAsHttpOutlet, extractPassContext, finishWf, formInputInterceptor, getFormActions, handleAsOutletRequest, isWfFinished, serializeFormSchema, useFormInput, useWfAction };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/moost-wf",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.69",
|
|
4
4
|
"description": "Workflow form integration for moost — decorators, interceptors, and serialization driven by atscript type metadata",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"atscript",
|
|
@@ -51,26 +51,26 @@
|
|
|
51
51
|
"access": "public"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@atscript/core": "^0.1.
|
|
55
|
-
"@atscript/db": "^0.1.
|
|
56
|
-
"@atscript/db-sqlite": "^0.1.
|
|
57
|
-
"@atscript/typescript": "^0.1.
|
|
58
|
-
"@moostjs/event-wf": "^0.6.
|
|
54
|
+
"@atscript/core": "^0.1.58",
|
|
55
|
+
"@atscript/db": "^0.1.82",
|
|
56
|
+
"@atscript/db-sqlite": "^0.1.82",
|
|
57
|
+
"@atscript/typescript": "^0.1.58",
|
|
58
|
+
"@moostjs/event-wf": "^0.6.14",
|
|
59
59
|
"@prostojs/wf": "^0.1.1",
|
|
60
|
-
"@wooksjs/event-core": "^0.7.
|
|
61
|
-
"@wooksjs/event-wf": "^0.7.
|
|
62
|
-
"moost": "^0.6.
|
|
63
|
-
"unplugin-atscript": "^0.1.
|
|
64
|
-
"vitest": "npm:@voidzero-dev/vite-plus-test@
|
|
65
|
-
"@atscript/ui": "^0.1.
|
|
60
|
+
"@wooksjs/event-core": "^0.7.13",
|
|
61
|
+
"@wooksjs/event-wf": "^0.7.13",
|
|
62
|
+
"moost": "^0.6.14",
|
|
63
|
+
"unplugin-atscript": "^0.1.58",
|
|
64
|
+
"vitest": "npm:@voidzero-dev/vite-plus-test@0.1.14",
|
|
65
|
+
"@atscript/ui": "^0.1.69"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
|
-
"@atscript/core": "^0.1.
|
|
69
|
-
"@atscript/typescript": "^0.1.
|
|
70
|
-
"@moostjs/event-wf": "^0.6.
|
|
71
|
-
"@wooksjs/event-core": "^0.7.
|
|
72
|
-
"@wooksjs/event-wf": "^0.7.
|
|
73
|
-
"moost": "^0.6.
|
|
68
|
+
"@atscript/core": "^0.1.58",
|
|
69
|
+
"@atscript/typescript": "^0.1.58",
|
|
70
|
+
"@moostjs/event-wf": "^0.6.14",
|
|
71
|
+
"@wooksjs/event-core": "^0.7.13",
|
|
72
|
+
"@wooksjs/event-wf": "^0.7.13",
|
|
73
|
+
"moost": "^0.6.14"
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
76
|
"build": "vp pack",
|