@xeplr/workflow-engine 3.1.0 → 3.2.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/README.md +4 -0
- package/lib/flows.js +38 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,6 +105,10 @@ host gives workflow is the boundary.
|
|
|
105
105
|
first match wins (`@xeplr/expression-handler`); a blank condition is the
|
|
106
106
|
catch-all; targets are a `stepKey`, `end_success` or `end_failed`. No match
|
|
107
107
|
and no catch-all **fails the run**.
|
|
108
|
+
- **Screens hand over to screens**: a flow's run view carries `previous` — what
|
|
109
|
+
every screen submitted earlier in the run, keyed by screen key, the saved row
|
|
110
|
+
as `values.id` (`lib/flows.js` `previousOf`). Read-only, built from the step
|
|
111
|
+
runs; nothing new is stored, and nothing is checked between screens.
|
|
108
112
|
- **Letting a function decide**: a transition `{ decide: 'routeByAmount', targets?: [...] }`
|
|
109
113
|
asks a function the app registered with `@xeplr/actions` under `event: 'decide'`
|
|
110
114
|
where to go. It is called with `{ output, values (= output), params, item, trigger,
|
package/lib/flows.js
CHANGED
|
@@ -597,7 +597,9 @@ function runView(run, steps, stepRuns) {
|
|
|
597
597
|
// the resolved input is kept (workflowRunner patches `input` as it parks)
|
|
598
598
|
// — the step row holds the tokens, and a browser has nothing to resolve
|
|
599
599
|
// them with.
|
|
600
|
-
given: {}
|
|
600
|
+
given: {},
|
|
601
|
+
// WHAT THE SCREENS BEFORE THIS ONE SAVED, by screen key — see previousOf.
|
|
602
|
+
previous: {}
|
|
601
603
|
};
|
|
602
604
|
if (!waiting) {
|
|
603
605
|
if (run.status === 'failed' && run.error) view.error = run.error;
|
|
@@ -614,9 +616,43 @@ function runView(run, steps, stepRuns) {
|
|
|
614
616
|
if (sr.stepKey !== waiting.stepKey) return;
|
|
615
617
|
Object.assign(view.values, sr.output || {});
|
|
616
618
|
});
|
|
619
|
+
view.previous = previousOf(steps, stepRuns, waiting);
|
|
617
620
|
return view;
|
|
618
621
|
}
|
|
619
622
|
|
|
623
|
+
/**
|
|
624
|
+
* THE HAND-OVER BETWEEN SCREENS — what every screen submitted earlier in this
|
|
625
|
+
* run, keyed by the SCREEN's key:
|
|
626
|
+
*
|
|
627
|
+
* { department_edit: { values: { id: "6f2a…", name: "Finance", … } } }
|
|
628
|
+
*
|
|
629
|
+
* A field on the next screen fills itself from it with a default of
|
|
630
|
+
* `{previous.department_edit.values.name}` (@xeplr/ui-factory). By screen and
|
|
631
|
+
* not by step, because the binding lives ON the screen, and a screen is the
|
|
632
|
+
* same form in every flow that shows it. `id` is the row that screen saved —
|
|
633
|
+
* part of the values, as it is of the row.
|
|
634
|
+
*
|
|
635
|
+
* Nothing is checked: a screen not reached on this run's branch is simply
|
|
636
|
+
* absent, and a binding to it comes out empty. A screen shown twice (a loop)
|
|
637
|
+
* hands over its latest. The step being shown now is not its own "previous".
|
|
638
|
+
*/
|
|
639
|
+
function previousOf(steps, stepRuns, waiting) {
|
|
640
|
+
var screenOf = {};
|
|
641
|
+
steps.forEach(function(st) {
|
|
642
|
+
if (st.actionName === SCREEN_ACTION && st.values && st.values.screen) screenOf[st.stepKey] = st.values.screen;
|
|
643
|
+
});
|
|
644
|
+
var out = {};
|
|
645
|
+
stepRuns.forEach(function(sr) {
|
|
646
|
+
if (sr.status !== 'success' || (waiting && sr.id === waiting.id)) return;
|
|
647
|
+
var screen = screenOf[sr.stepKey];
|
|
648
|
+
if (!screen) return;
|
|
649
|
+
var values = Object.assign({}, sr.output || {});
|
|
650
|
+
if (values.recordId !== undefined) { values.id = values.recordId; delete values.recordId; }
|
|
651
|
+
out[screen] = { values: values };
|
|
652
|
+
});
|
|
653
|
+
return out;
|
|
654
|
+
}
|
|
655
|
+
|
|
620
656
|
async function stepRunsOf(runId) {
|
|
621
657
|
return db.model('WorkflowStepRun').query().where({ runId: runId }).orderBy('recordCreatedDate', 'asc');
|
|
622
658
|
}
|
|
@@ -937,6 +973,7 @@ module.exports = {
|
|
|
937
973
|
fail: fail,
|
|
938
974
|
END_TARGETS: END_TARGETS,
|
|
939
975
|
conditionToWhen: conditionToWhen,
|
|
976
|
+
previousOf: previousOf,
|
|
940
977
|
toStepRows: toStepRows,
|
|
941
978
|
validateFlow: validateFlow,
|
|
942
979
|
runView: runView,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xeplr/workflow-engine",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "The free workflow engine: runs, actions as steps, branching, waits, and triggers — manual, API, a schedule, a job finishing. No HTTP: @xeplr/workflow-api puts the routes on top.",
|
|
6
6
|
"keywords": [
|