nucleus-core-ts 0.10.124 → 0.10.126
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/.build-ok +1 -1
- package/dist/fe/components/VerificationFlowPage/components/VerificationFlowPage.js +23 -39
- package/dist/fe/components/VerificationFlowPage/stepOrder.d.ts +30 -0
- package/dist/fe/components/VerificationFlowPage/stepOrder.js +62 -0
- package/dist/index.js +1 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
package/dist/.build-ok
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.10.
|
|
1
|
+
0.10.126
|
|
@@ -6,6 +6,7 @@ import { useEffect, useEffectEvent, useRef, useState } from 'react';
|
|
|
6
6
|
import { cn } from '../../../utils/cn';
|
|
7
7
|
import { newId } from '../../../utils/newId';
|
|
8
8
|
import { DEFAULT_VERIFICATION_FLOW_LABELS, setActiveLabels } from '../labels';
|
|
9
|
+
import { assignStepOrders } from '../stepOrder';
|
|
9
10
|
import { useVerificationFlowStore } from '../store';
|
|
10
11
|
import { getVerificationFlowTheme } from '../theme';
|
|
11
12
|
import { setActiveTheme } from '../theme/store';
|
|
@@ -177,43 +178,26 @@ function buildSavePayload(flowId, entityName, flowName, flowDescription, trigger
|
|
|
177
178
|
label: String(e.label || ''),
|
|
178
179
|
animated: true
|
|
179
180
|
}));
|
|
180
|
-
|
|
181
|
+
/*
|
|
182
|
+
* `step_order` comes from the DRAWING, through one shared pure function.
|
|
183
|
+
*
|
|
184
|
+
* This used to be an inline walk whose seed list and neighbour order
|
|
185
|
+
* followed whatever order the nodes and edges arrived in — heap order, for a
|
|
186
|
+
* flow loaded from the database. Re-saving a flow without touching it could
|
|
187
|
+
* therefore renumber its steps and hand the first decision to a different
|
|
188
|
+
* reviewer. `assignStepOrders` is deterministic and has a test that fails
|
|
189
|
+
* without it; `getFlow` returns ordered rows so both layers agree.
|
|
190
|
+
*/ const stepNodeIds = new Set(nodes.filter((n)=>{
|
|
181
191
|
const d = n.data;
|
|
182
192
|
return (d.nodeType || n.type) === 'step';
|
|
183
193
|
}).map((n)=>n.id));
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
for (const t of adjacency[fromId] || []){
|
|
192
|
-
if (visited.has(t)) continue;
|
|
193
|
-
visited.add(t);
|
|
194
|
-
if (stepNodeIds.has(t)) result.push(t);
|
|
195
|
-
else result.push(...findNextSteps(t, visited));
|
|
196
|
-
}
|
|
197
|
-
return result;
|
|
198
|
-
};
|
|
199
|
-
const stepGraph = {};
|
|
200
|
-
const incomingSteps = new Set();
|
|
201
|
-
for (const sid of stepNodeIds){
|
|
202
|
-
stepGraph[sid] = findNextSteps(sid);
|
|
203
|
-
for (const next of stepGraph[sid])incomingSteps.add(next);
|
|
204
|
-
}
|
|
205
|
-
const stepOrderMap = {};
|
|
206
|
-
const queue = [
|
|
207
|
-
...stepNodeIds
|
|
208
|
-
].filter((id)=>!incomingSteps.has(id));
|
|
209
|
-
let order = 1;
|
|
210
|
-
while(queue.length > 0){
|
|
211
|
-
const current = queue.shift();
|
|
212
|
-
if (!current) break;
|
|
213
|
-
if (stepOrderMap[current] !== undefined) continue;
|
|
214
|
-
stepOrderMap[current] = order++;
|
|
215
|
-
for (const next of stepGraph[current] || [])queue.push(next);
|
|
216
|
-
}
|
|
194
|
+
const stepOrderMap = assignStepOrders({
|
|
195
|
+
stepNodeIds,
|
|
196
|
+
edges: flowEdges.map((e)=>({
|
|
197
|
+
source: e.source_node_id,
|
|
198
|
+
target: e.target_node_id
|
|
199
|
+
}))
|
|
200
|
+
});
|
|
217
201
|
const steps = nodes.map((n)=>{
|
|
218
202
|
const d = n.data;
|
|
219
203
|
const nodeType = String(d.nodeType || n.type);
|
|
@@ -819,14 +803,14 @@ export function VerificationFlowPage({ entityName, title, subtitle, flowListActi
|
|
|
819
803
|
value: "update",
|
|
820
804
|
children: say.triggerOnUpdate
|
|
821
805
|
}),
|
|
822
|
-
/*#__PURE__*/ _jsx("option", {
|
|
823
|
-
value: "delete",
|
|
824
|
-
children: say.triggerOnDelete
|
|
825
|
-
}),
|
|
826
806
|
/*#__PURE__*/ _jsx("option", {
|
|
827
807
|
value: "manual",
|
|
828
808
|
children: say.triggerOnManual
|
|
829
|
-
})
|
|
809
|
+
}),
|
|
810
|
+
flowTriggerOn === 'delete' ? /*#__PURE__*/ _jsx("option", {
|
|
811
|
+
value: "delete",
|
|
812
|
+
children: say.triggerOnDelete
|
|
813
|
+
}) : null
|
|
830
814
|
]
|
|
831
815
|
})
|
|
832
816
|
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which step comes first, second, third — derived from the DRAWING alone.
|
|
3
|
+
*
|
|
4
|
+
* The editor does not store a step's position; it re-derives it from the graph
|
|
5
|
+
* on every save. That derivation used to depend on the order the nodes and
|
|
6
|
+
* edges happened to arrive in, and for a flow loaded from the database that is
|
|
7
|
+
* heap order, which changes after updates. So opening a saved flow and pressing
|
|
8
|
+
* save without touching anything could renumber the steps — a different
|
|
9
|
+
* reviewer asked first, on a chain whose entire purpose is who is asked when.
|
|
10
|
+
*
|
|
11
|
+
* Extracted as a pure function so that property can be tested without a
|
|
12
|
+
* renderer: the same graph must always produce the same numbering, whatever
|
|
13
|
+
* order its nodes and edges are handed over in.
|
|
14
|
+
*
|
|
15
|
+
* Steps are numbered breadth-first from the steps nothing points at. A
|
|
16
|
+
* non-step node (a verifier, a notification) is walked THROUGH, so a step
|
|
17
|
+
* wired to the next one via an intermediate node still counts as adjacent.
|
|
18
|
+
* Ties — several roots, several next steps — are broken by node id, which is
|
|
19
|
+
* arbitrary but stable, and that is the whole point.
|
|
20
|
+
*/
|
|
21
|
+
export type StepOrderGraph = {
|
|
22
|
+
/** Every node, with the ids of the step nodes among them. */
|
|
23
|
+
stepNodeIds: Iterable<string>;
|
|
24
|
+
/** Directed edges, source → target. */
|
|
25
|
+
edges: Array<{
|
|
26
|
+
source: string;
|
|
27
|
+
target: string;
|
|
28
|
+
}>;
|
|
29
|
+
};
|
|
30
|
+
export declare function assignStepOrders(graph: StepOrderGraph): Record<string, number>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which step comes first, second, third — derived from the DRAWING alone.
|
|
3
|
+
*
|
|
4
|
+
* The editor does not store a step's position; it re-derives it from the graph
|
|
5
|
+
* on every save. That derivation used to depend on the order the nodes and
|
|
6
|
+
* edges happened to arrive in, and for a flow loaded from the database that is
|
|
7
|
+
* heap order, which changes after updates. So opening a saved flow and pressing
|
|
8
|
+
* save without touching anything could renumber the steps — a different
|
|
9
|
+
* reviewer asked first, on a chain whose entire purpose is who is asked when.
|
|
10
|
+
*
|
|
11
|
+
* Extracted as a pure function so that property can be tested without a
|
|
12
|
+
* renderer: the same graph must always produce the same numbering, whatever
|
|
13
|
+
* order its nodes and edges are handed over in.
|
|
14
|
+
*
|
|
15
|
+
* Steps are numbered breadth-first from the steps nothing points at. A
|
|
16
|
+
* non-step node (a verifier, a notification) is walked THROUGH, so a step
|
|
17
|
+
* wired to the next one via an intermediate node still counts as adjacent.
|
|
18
|
+
* Ties — several roots, several next steps — are broken by node id, which is
|
|
19
|
+
* arbitrary but stable, and that is the whole point.
|
|
20
|
+
*/ export function assignStepOrders(graph) {
|
|
21
|
+
const stepIds = new Set(graph.stepNodeIds);
|
|
22
|
+
const adjacency = {};
|
|
23
|
+
for (const e of graph.edges){
|
|
24
|
+
if (!adjacency[e.source]) adjacency[e.source] = [];
|
|
25
|
+
adjacency[e.source]?.push(e.target);
|
|
26
|
+
}
|
|
27
|
+
const nextSteps = (fromId, visited = new Set())=>{
|
|
28
|
+
const result = [];
|
|
29
|
+
for (const t of [
|
|
30
|
+
...adjacency[fromId] || []
|
|
31
|
+
].sort()){
|
|
32
|
+
if (visited.has(t)) continue;
|
|
33
|
+
visited.add(t);
|
|
34
|
+
if (stepIds.has(t)) result.push(t);
|
|
35
|
+
else result.push(...nextSteps(t, visited));
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
const stepGraph = {};
|
|
40
|
+
const hasIncoming = new Set();
|
|
41
|
+
// Sorted so `stepGraph`'s own construction does not depend on set insertion
|
|
42
|
+
// order either.
|
|
43
|
+
for (const sid of [
|
|
44
|
+
...stepIds
|
|
45
|
+
].sort()){
|
|
46
|
+
stepGraph[sid] = nextSteps(sid);
|
|
47
|
+
for (const n of stepGraph[sid])hasIncoming.add(n);
|
|
48
|
+
}
|
|
49
|
+
const order = {};
|
|
50
|
+
const queue = [
|
|
51
|
+
...stepIds
|
|
52
|
+
].filter((id)=>!hasIncoming.has(id)).sort();
|
|
53
|
+
let next = 1;
|
|
54
|
+
while(queue.length > 0){
|
|
55
|
+
const current = queue.shift();
|
|
56
|
+
if (!current) break;
|
|
57
|
+
if (order[current] !== undefined) continue;
|
|
58
|
+
order[current] = next++;
|
|
59
|
+
for (const n of stepGraph[current] || [])queue.push(n);
|
|
60
|
+
}
|
|
61
|
+
return order;
|
|
62
|
+
}
|