@beehexa/hexasync-template-worker-flow 2608.20.18 → 2608.20.32
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/flow.d.ts +163 -0
- package/dist/flow.d.ts.map +1 -0
- package/dist/flow.js +251 -0
- package/dist/flow.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/render.d.ts +25 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +157 -0
- package/dist/render.js.map +1 -0
- package/dist/routeGraph.d.ts +41 -0
- package/dist/routeGraph.d.ts.map +1 -0
- package/dist/routeGraph.js +214 -0
- package/dist/routeGraph.js.map +1 -0
- package/dist/routes.d.ts +71 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +155 -0
- package/dist/routes.js.map +1 -0
- package/dist/stages.d.ts +112 -0
- package/dist/stages.d.ts.map +1 -0
- package/dist/stages.js +178 -0
- package/dist/stages.js.map +1 -0
- package/package.json +2 -2
package/dist/flow.d.ts
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { type StageEdge, type StageDefinition, type WorkerCollection, type PullerKind } from './stages.js';
|
|
2
|
+
/** Where a node came from in the authored source. Every field optional: an absent location is not a guessed one. */
|
|
3
|
+
export interface NodeLocation {
|
|
4
|
+
/** The authored file, as the caller identifies files — a URI here, a path there. Never parsed by this package. */
|
|
5
|
+
readonly file?: string;
|
|
6
|
+
/** Zero-based, end-exclusive, in the caller's own coordinate system. */
|
|
7
|
+
readonly range?: {
|
|
8
|
+
readonly start: {
|
|
9
|
+
readonly line: number;
|
|
10
|
+
readonly character: number;
|
|
11
|
+
};
|
|
12
|
+
readonly end: {
|
|
13
|
+
readonly line: number;
|
|
14
|
+
readonly character: number;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
/** The authored text, so a consumer can quote the node without re-reading the file. */
|
|
18
|
+
readonly sourceText?: string;
|
|
19
|
+
}
|
|
20
|
+
/** What the caller is asked to locate. Enough to find the node without knowing this package's internals. */
|
|
21
|
+
export interface LocateRequest {
|
|
22
|
+
readonly collection: WorkerCollection;
|
|
23
|
+
readonly stage: string;
|
|
24
|
+
/** Absent for a synthesised node, which has no line of its own. */
|
|
25
|
+
readonly stepKey?: string;
|
|
26
|
+
readonly address: string;
|
|
27
|
+
/**
|
|
28
|
+
* For a SYNTHESISED node: the key of the step that produced it, and the path that reaches it (Jazz, 2026-08-17).
|
|
29
|
+
*
|
|
30
|
+
* ⛔ The junction's `locate` call passed neither, while `Junction.owner` and `Junction.path` sat in the same loop —
|
|
31
|
+
* so the only thing a locator could do with a diamond was decline, and the extension's did, on the stated grounds
|
|
32
|
+
* that the owner's own line *"would be a plausible-looking lie"*. It would be; the BRANCH's line is not, and the
|
|
33
|
+
* path is what identifies it. Reported as *"clicking the diamond should let me focus on the actual IF"*.
|
|
34
|
+
*
|
|
35
|
+
* `path` is relative to the step — `['data','if']`, `['next','then','if']`, `['next','expression']` — and its last
|
|
36
|
+
* segment may be SYNTHETIC (`expression`, `unknown`, `cycle`, `switch`): those name what the junction is, not a key
|
|
37
|
+
* the document holds. A locator resolves the longest authored prefix, which is why the whole path is handed over
|
|
38
|
+
* rather than a pre-trimmed one: only the reader of the file knows which segments it can see.
|
|
39
|
+
*/
|
|
40
|
+
readonly ownerStepKey?: string;
|
|
41
|
+
readonly path?: readonly string[];
|
|
42
|
+
}
|
|
43
|
+
/** One node in the flow — a step, or a decision synthesised from a step's branch. */
|
|
44
|
+
export interface FlowNode extends NodeLocation {
|
|
45
|
+
/** The AD-33 canonical address. Stable across any edit that renames nothing. */
|
|
46
|
+
readonly address: string;
|
|
47
|
+
/** `worker` on every node, deliberately — Story 4.2 AC-4 exists so no consumer merges the two domains. */
|
|
48
|
+
readonly runtime: 'worker';
|
|
49
|
+
readonly stage: string;
|
|
50
|
+
/** The step's declared type, when it declares one. 34 of 5,820 authored steps do not. */
|
|
51
|
+
readonly type?: string;
|
|
52
|
+
/**
|
|
53
|
+
* The step's human name, where it declares one.
|
|
54
|
+
*
|
|
55
|
+
* ⛔ Never captured, and **all three** baselines draw it: the CLI report emits
|
|
56
|
+
* `pushSteps_GET_SALES_RETURN_DETAIL["Get Sales Return Detail"]`, the extension
|
|
57
|
+
* `n0{"GET_SALES_RETURN_DETAIL<br/>Get Sales Return Detail"}`. Story 4.3 defended dropping it by citing
|
|
58
|
+
* `SHOW_CREATE_PROFILE_ERROR["Couldn't Start Profile Creation"]` — a FRONTEND node, which shows a name, so the
|
|
59
|
+
* evidence argued against the behaviour it was used to defend. Story 4.6 could not have reproduced its own baseline.
|
|
60
|
+
*/
|
|
61
|
+
readonly name?: string;
|
|
62
|
+
/**
|
|
63
|
+
* An ENTRY step (`rootStep`, or `root`).
|
|
64
|
+
*
|
|
65
|
+
* For the renderer rather than for routing: a stage arrow must leave a terminal and land on an ENTRY, which is how
|
|
66
|
+
* dashboard chooses its target. Without this the renderer could only guess "first in document order" — the fourth
|
|
67
|
+
* stage geometry the Story 4.3 review found.
|
|
68
|
+
*/
|
|
69
|
+
readonly isEntry?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* A branch point, drawn as a diamond.
|
|
72
|
+
*
|
|
73
|
+
* ⚠️ True on a SYNTHESISED node only (Story 4.1 review, HIGH-3). It used to be true on a branching step as well,
|
|
74
|
+
* so a renderer keyed on it drew two diamonds per branch. The baseline draws the step as a rectangle and the
|
|
75
|
+
* junction beside it, and that is what the arms leave.
|
|
76
|
+
*/
|
|
77
|
+
readonly decides: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* What a renderer writes inside a synthesised node: the condition text, the expression, or the unresolved target.
|
|
80
|
+
*
|
|
81
|
+
* Added by the review: without it, even the one junction the first version created could not carry the baseline's
|
|
82
|
+
* label (`cond.if`, or the expression verbatim), and the only candidate carrier was the unimplemented `locate`
|
|
83
|
+
* seam.
|
|
84
|
+
*/
|
|
85
|
+
readonly label?: string;
|
|
86
|
+
/** For a synthesised node, which kind it is — so a renderer picks a shape without parsing the label. */
|
|
87
|
+
readonly junction?: 'if' | 'expression' | 'unknown';
|
|
88
|
+
/** For a step node, its authored key. Absent on a synthesised node, which has no key of its own. */
|
|
89
|
+
readonly stepKey?: string;
|
|
90
|
+
/** For a synthesised node, the address of the step that produced it. */
|
|
91
|
+
readonly owner?: string;
|
|
92
|
+
}
|
|
93
|
+
/** The whole model for one component. */
|
|
94
|
+
export interface WorkerFlow {
|
|
95
|
+
readonly address: string;
|
|
96
|
+
readonly collection: WorkerCollection;
|
|
97
|
+
/** Reported, never used to choose the stage list. */
|
|
98
|
+
readonly pullerKind?: PullerKind;
|
|
99
|
+
readonly stages: readonly StageDefinition[];
|
|
100
|
+
readonly stageEdges: readonly StageEdge[];
|
|
101
|
+
/** Keyed by address, so a click resolves in one lookup. */
|
|
102
|
+
readonly nodes: readonly FlowNode[];
|
|
103
|
+
/** Edges between nodes, with both ends as ADDRESSES. Every end is indexed in `nodes`. */
|
|
104
|
+
readonly edges: readonly FlowEdgeAddressed[];
|
|
105
|
+
/**
|
|
106
|
+
* Step keys declared more than once in one stage, and therefore dropped.
|
|
107
|
+
*
|
|
108
|
+
* Present only when it happened, so a consumer that does not care reads nothing — but reported rather than
|
|
109
|
+
* swallowed: one corpus file does this, and a graph that is quietly smaller than the document is its own defect.
|
|
110
|
+
*/
|
|
111
|
+
readonly duplicateStepKeys?: readonly {
|
|
112
|
+
readonly stage: string;
|
|
113
|
+
readonly key: string;
|
|
114
|
+
}[];
|
|
115
|
+
}
|
|
116
|
+
/** A route edge with both ends addressed, and its unresolved cases preserved. */
|
|
117
|
+
export interface FlowEdgeAddressed {
|
|
118
|
+
readonly from: string;
|
|
119
|
+
/**
|
|
120
|
+
* Always present.
|
|
121
|
+
*
|
|
122
|
+
* ⚠️ This was optional, left over from before junctions existed: a dead end used to be an edge with no `to` and a
|
|
123
|
+
* `raw` string. Since the route graph absorbs every unresolved route into an `unknown` junction, both ends are always
|
|
124
|
+
* real nodes — the loop that builds these skips an edge it cannot address at all. A renderer could not consume the
|
|
125
|
+
* optional form without inventing a node for the missing end.
|
|
126
|
+
*/
|
|
127
|
+
readonly to: string;
|
|
128
|
+
readonly label?: string;
|
|
129
|
+
readonly stage: string;
|
|
130
|
+
}
|
|
131
|
+
export interface WorkerFlowInput {
|
|
132
|
+
readonly collection: WorkerCollection;
|
|
133
|
+
/** The parsed component, authored form. */
|
|
134
|
+
readonly component: Record<string, unknown>;
|
|
135
|
+
/** Its `id`, authored — AD-33 keeps the token rather than a composed GUID. */
|
|
136
|
+
readonly componentId?: unknown;
|
|
137
|
+
/** Supplies file/range/sourceText for a node, or nothing. */
|
|
138
|
+
readonly locate?: (request: LocateRequest) => NodeLocation | undefined;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* ⛔ `branchOf` was DELETED here (Story 4.1 review, MEDIUM-2).
|
|
142
|
+
*
|
|
143
|
+
* It decided independently of `routeEdges` what "branches" means, and the two disagreed: an `IF` whose `data`
|
|
144
|
+
* carried only `{ expression }` was meant to route through its `next` while `branchOf` synthesised a diamond anyway —
|
|
145
|
+
* an orphan node asserting a decision the document does not make. Two functions owning one concept, with only one of
|
|
146
|
+
* them the authority.
|
|
147
|
+
*
|
|
148
|
+
* ⚠️ **Correction (Story 4.7 review).** The route graph did NOT in fact route that case through `next` — it drew the
|
|
149
|
+
* diamond and dropped the `next` edge, orphaning its target, so this paragraph described the intent rather than the
|
|
150
|
+
* behaviour for two stories. `routeGraph.ts` now has the fallback its flat twin `routes.ts` always had. Deleting
|
|
151
|
+
* `branchOf` was still the right call; the claim about what survived it was just untrue until now.
|
|
152
|
+
*
|
|
153
|
+
* `routeGraph` is now that single authority: it decides where a junction belongs *while* placing the edge that
|
|
154
|
+
* reaches it, so a junction cannot exist without an arrow into it and an arrow cannot bypass one.
|
|
155
|
+
*/
|
|
156
|
+
/**
|
|
157
|
+
* The flow model and the node index for one component.
|
|
158
|
+
*
|
|
159
|
+
* One entry point, one route graph. Nodes and edges are both derived from that graph before returning, so neither
|
|
160
|
+
* can contain something the other does not know about — see the note on "one pass" above.
|
|
161
|
+
*/
|
|
162
|
+
export declare function workerFlow(input: WorkerFlowInput): WorkerFlow;
|
|
163
|
+
//# sourceMappingURL=flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../src/flow.ts"],"names":[],"mappings":"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"}
|
package/dist/flow.js
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A worker component's flow and its node index, from ONE pass — Story 4.1 AC-3 and AC-4.
|
|
3
|
+
*
|
|
4
|
+
* ### Why one pass is an acceptance criterion rather than an optimisation
|
|
5
|
+
*
|
|
6
|
+
* AC-3: *"the diagram and the node index come from one pass"*. Two passes are how a synthesised node ends up in one
|
|
7
|
+
* and not the other — drawn but unaddressable, or addressable but undrawn. Either way a click resolves to nothing,
|
|
8
|
+
* and the failure is invisible until someone clicks. So `workerFlow` returns nodes and edges together and there is
|
|
9
|
+
* no second entry point that produces only one of them.
|
|
10
|
+
*
|
|
11
|
+
* ### Every node is addressed by AD-33, including the synthesised ones
|
|
12
|
+
*
|
|
13
|
+
* A step node is `<component>:<stage>:key_<stepKey>`. A **decision** node is the branch's own path —
|
|
14
|
+
* `<step>:next:if` or `<step>:data:if` — which is what makes it stable: the diamond keeps that address however many
|
|
15
|
+
* steps are added around it. The three previous schemes all numbered it (`_D_<n>`, `_IF_<n>`), so inserting a step
|
|
16
|
+
* above renumbered a node that nothing had renamed.
|
|
17
|
+
*
|
|
18
|
+
* A synthesised node carries `owner`, the address of the step that produced it, so a click on the diamond resolves
|
|
19
|
+
* to a real line in a real file (AC-3's *"the node reports the step that produced it"*).
|
|
20
|
+
*
|
|
21
|
+
* ### Source location arrives as DATA (AD-3)
|
|
22
|
+
*
|
|
23
|
+
* `file`, `range` and `sourceText` are supplied by a `locate` callback rather than read here. This package is core:
|
|
24
|
+
* it cannot open a file, and the extension bundles it into a host with no filesystem at all. Story 4.1 records that
|
|
25
|
+
* this half exists nowhere yet for a worker step — the only source-range machinery in any repo is dashboard's
|
|
26
|
+
* *frontend* path — so the seam is defined here and the producer is an adapter's job. A node whose location the
|
|
27
|
+
* caller cannot supply simply has none, which is the honest answer rather than a guessed line number.
|
|
28
|
+
*/
|
|
29
|
+
import { keySegment, identitySegment, nodeAddress, normalizeComponentKey, } from '@beehexa/hexasync-template-model';
|
|
30
|
+
import { stagesPresent, stageEdges, pullerKindOf, } from './stages.js';
|
|
31
|
+
import { routeGraph, junctionAddress } from './routeGraph.js';
|
|
32
|
+
/**
|
|
33
|
+
* A boolean flag as authored — `true`, or the string a JSON-served profile may carry.
|
|
34
|
+
*
|
|
35
|
+
* Deliberately narrow: only the exact strings `'true'`/`'TRUE'` (any case, trimmed) count. `'1'`, `'yes'` and the like
|
|
36
|
+
* are NOT accepted, because widening a flag reader is how `'false'`-adjacent values start meaning true somewhere down
|
|
37
|
+
* the line — and no corpus or UI has ever written them for this field.
|
|
38
|
+
*/
|
|
39
|
+
function isTruthyFlag(value) {
|
|
40
|
+
return (value === true ||
|
|
41
|
+
(typeof value === 'string' && value.trim().toLowerCase() === 'true'));
|
|
42
|
+
}
|
|
43
|
+
/** A step's own `key`/`name`/`type`, read defensively: a document is untrusted input. */
|
|
44
|
+
function stepOf(raw) {
|
|
45
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
46
|
+
return undefined;
|
|
47
|
+
const step = raw;
|
|
48
|
+
const key = typeof step.key === 'string' ? step.key : undefined;
|
|
49
|
+
if (key === undefined || key === '')
|
|
50
|
+
return undefined;
|
|
51
|
+
/**
|
|
52
|
+
* A step the composer DELETES is not in the flow (Story 4.1 review, HIGH-2).
|
|
53
|
+
*
|
|
54
|
+
* `!CHECK_EXISTS_ITEMS` is the corpus's one such key — `001-projects/continental-cosmetics/…/QuickBooksCategoryPusher.override.yaml`.
|
|
55
|
+
* AD-33 rule 6 stops the `!` reaching an address, and this used to be the whole treatment: the node was still
|
|
56
|
+
* created, and `identitySegment` refusing the segment silently re-addressed it onto its PARENT STAGE. Three
|
|
57
|
+
* consequences, all real: `addressMatches` then made every sibling step a descendant of the phantom, so clicking
|
|
58
|
+
* it selected the entire stage; the node reported a raw `stepKey` no composed document contains, disagreeing with
|
|
59
|
+
* its own normalised address; and two removed steps in one stage collapsed onto one byte-identical address.
|
|
60
|
+
*
|
|
61
|
+
* Rule 6 was adopted so an address is never minted for a node the composer deletes. Skipping the step is the only
|
|
62
|
+
* reading of that which also declines to mint the NODE.
|
|
63
|
+
*/
|
|
64
|
+
if (normalizeComponentKey(key)?.removes === true)
|
|
65
|
+
return undefined;
|
|
66
|
+
const type = typeof step.displayType === 'string'
|
|
67
|
+
? step.displayType
|
|
68
|
+
: typeof step.type === 'string'
|
|
69
|
+
? step.type
|
|
70
|
+
: undefined;
|
|
71
|
+
const name = typeof step.name === 'string' && step.name.trim() !== ''
|
|
72
|
+
? step.name.trim()
|
|
73
|
+
: undefined;
|
|
74
|
+
// `rootStep` is the worker spelling; `root` is the frontend's. Both accepted, since a document may use either.
|
|
75
|
+
//
|
|
76
|
+
// The STRING `'true'` counts. A YAML corpus writes a bare `rootStep: true` (5,060 of 5,060 occurrences), so a
|
|
77
|
+
// boolean-only test looks complete when read against the templates — but a profile served to a UI as JSON can carry
|
|
78
|
+
// the quoted form, and `dashboard-v2` types the field as `rootStep?: string` and tested `String(s.rootStep) ===
|
|
79
|
+
// 'true'` in the emitter this package replaced. A coercion like that is written because the strict test failed.
|
|
80
|
+
// Missing it does not error: entry detection just silently picks the first declared step, so an inter-stage arrow
|
|
81
|
+
// lands on the wrong node and the diagram still looks plausible.
|
|
82
|
+
const isEntry = isTruthyFlag(step.rootStep) || isTruthyFlag(step.root);
|
|
83
|
+
return {
|
|
84
|
+
key,
|
|
85
|
+
...(step.next !== undefined ? { next: step.next } : {}),
|
|
86
|
+
...(type !== undefined ? { stepType: type, type } : {}),
|
|
87
|
+
...(step.data !== undefined ? { data: step.data } : {}),
|
|
88
|
+
...(step.onError !== undefined ? { onError: step.onError } : {}),
|
|
89
|
+
/**
|
|
90
|
+
* `fromStep`, from the step or from its `data` — an Exception step is authored both ways.
|
|
91
|
+
*
|
|
92
|
+
* `data.fromStep` is the RUNTIME's own spelling: `ErrorExecutor` reads `$.data.fromStep` first and falls back to
|
|
93
|
+
* `$.fromStep`, and every `StepIteratorTests` fixture writes it under `data`. The report's `toFlowStep` accepted
|
|
94
|
+
* both; this read only the top level, so an Exception step authored the runtime's way lost its `|"Exception"|`
|
|
95
|
+
* back-edge entirely (Story 4.6 review, L1).
|
|
96
|
+
*/
|
|
97
|
+
...(typeof step.fromStep === 'string'
|
|
98
|
+
? { fromStep: step.fromStep }
|
|
99
|
+
: typeof step.data?.fromStep ===
|
|
100
|
+
'string'
|
|
101
|
+
? { fromStep: step.data.fromStep }
|
|
102
|
+
: {}),
|
|
103
|
+
...(name !== undefined ? { name } : {}),
|
|
104
|
+
...(isEntry ? { isEntry: true } : {}),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* ⛔ `branchOf` was DELETED here (Story 4.1 review, MEDIUM-2).
|
|
109
|
+
*
|
|
110
|
+
* It decided independently of `routeEdges` what "branches" means, and the two disagreed: an `IF` whose `data`
|
|
111
|
+
* carried only `{ expression }` was meant to route through its `next` while `branchOf` synthesised a diamond anyway —
|
|
112
|
+
* an orphan node asserting a decision the document does not make. Two functions owning one concept, with only one of
|
|
113
|
+
* them the authority.
|
|
114
|
+
*
|
|
115
|
+
* ⚠️ **Correction (Story 4.7 review).** The route graph did NOT in fact route that case through `next` — it drew the
|
|
116
|
+
* diamond and dropped the `next` edge, orphaning its target, so this paragraph described the intent rather than the
|
|
117
|
+
* behaviour for two stories. `routeGraph.ts` now has the fallback its flat twin `routes.ts` always had. Deleting
|
|
118
|
+
* `branchOf` was still the right call; the claim about what survived it was just untrue until now.
|
|
119
|
+
*
|
|
120
|
+
* `routeGraph` is now that single authority: it decides where a junction belongs *while* placing the edge that
|
|
121
|
+
* reaches it, so a junction cannot exist without an arrow into it and an arrow cannot bypass one.
|
|
122
|
+
*/
|
|
123
|
+
/**
|
|
124
|
+
* The flow model and the node index for one component.
|
|
125
|
+
*
|
|
126
|
+
* One entry point, one route graph. Nodes and edges are both derived from that graph before returning, so neither
|
|
127
|
+
* can contain something the other does not know about — see the note on "one pass" above.
|
|
128
|
+
*/
|
|
129
|
+
export function workerFlow(input) {
|
|
130
|
+
const { collection, component, componentId, locate } = input;
|
|
131
|
+
const base = nodeAddress([
|
|
132
|
+
keySegment(collection),
|
|
133
|
+
identitySegment(componentId, 'id'),
|
|
134
|
+
]);
|
|
135
|
+
const stages = stagesPresent(collection, component);
|
|
136
|
+
const nodes = [];
|
|
137
|
+
const edges = [];
|
|
138
|
+
const duplicates = [];
|
|
139
|
+
for (const stage of stages) {
|
|
140
|
+
const raw = component[stage.key];
|
|
141
|
+
const parsed = raw.map(stepOf).filter((s) => s !== undefined);
|
|
142
|
+
/**
|
|
143
|
+
* Steps are DE-DUPLICATED by key, and the duplicates are dropped (Story 4.1 review, HIGH-1).
|
|
144
|
+
*
|
|
145
|
+
* One corpus pusher — `001-projects/ru9/rubaby/partials/Pusher-SapoOmniOrder.yaml` — declares `key: CREATE`
|
|
146
|
+
* twice in one `pushSteps`, and it survives composition. Addressing both produced two nodes with ONE address,
|
|
147
|
+
* the second step's route attributed to the first node, and `addressForRenderedId` returning `undefined` — a
|
|
148
|
+
* click resolving to nothing, which is the failure this model's own docblock calls invisible until someone
|
|
149
|
+
* clicks.
|
|
150
|
+
*
|
|
151
|
+
* Dropped rather than disambiguated with a counter: a counter is what AD-33 exists to remove, and the runtime
|
|
152
|
+
* itself cannot address the second `CREATE` either — `next: CREATE` names the first. Reported so the caller can
|
|
153
|
+
* surface it, because a silently smaller graph is its own defect.
|
|
154
|
+
*/
|
|
155
|
+
const steps = [];
|
|
156
|
+
for (const step of parsed) {
|
|
157
|
+
if (steps.some((s) => s.key === step.key)) {
|
|
158
|
+
duplicates.push({ stage: stage.key, key: String(step.key) });
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
steps.push(step);
|
|
162
|
+
}
|
|
163
|
+
/** Each step's address, and the map every edge end is resolved through. */
|
|
164
|
+
const addressOf = new Map();
|
|
165
|
+
for (const step of steps) {
|
|
166
|
+
addressOf.set(step.key, nodeAddress([
|
|
167
|
+
keySegment(base),
|
|
168
|
+
keySegment(stage.key),
|
|
169
|
+
identitySegment(step.key, 'key'),
|
|
170
|
+
]));
|
|
171
|
+
}
|
|
172
|
+
const graph = routeGraph(steps);
|
|
173
|
+
const junctionOf = new Map();
|
|
174
|
+
for (const step of steps) {
|
|
175
|
+
const address = addressOf.get(step.key);
|
|
176
|
+
nodes.push({
|
|
177
|
+
address,
|
|
178
|
+
runtime: 'worker',
|
|
179
|
+
stage: stage.key,
|
|
180
|
+
...(step.type !== undefined ? { type: step.type } : {}),
|
|
181
|
+
...(step.name !== undefined ? { name: step.name } : {}),
|
|
182
|
+
...(step.isEntry === true ? { isEntry: true } : {}),
|
|
183
|
+
// A step is never itself the diamond — see `decides`.
|
|
184
|
+
decides: false,
|
|
185
|
+
stepKey: step.key,
|
|
186
|
+
...(locate?.({
|
|
187
|
+
collection,
|
|
188
|
+
stage: stage.key,
|
|
189
|
+
stepKey: step.key,
|
|
190
|
+
address,
|
|
191
|
+
}) ?? {}),
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
for (const point of graph.junctions) {
|
|
195
|
+
const owner = addressOf.get(point.owner);
|
|
196
|
+
if (owner === undefined)
|
|
197
|
+
continue;
|
|
198
|
+
const address = junctionAddress(owner, point.path);
|
|
199
|
+
junctionOf.set(`${point.owner} ${point.path.join(' ')}`, address);
|
|
200
|
+
nodes.push({
|
|
201
|
+
address,
|
|
202
|
+
runtime: 'worker',
|
|
203
|
+
stage: stage.key,
|
|
204
|
+
decides: point.kind !== 'unknown',
|
|
205
|
+
label: point.label,
|
|
206
|
+
junction: point.kind,
|
|
207
|
+
owner,
|
|
208
|
+
...(locate?.({
|
|
209
|
+
collection,
|
|
210
|
+
stage: stage.key,
|
|
211
|
+
address,
|
|
212
|
+
// The step KEY, not its address: a locator reads a document, and the document names steps by key. It has the
|
|
213
|
+
// address too (in `address`'s own prefix) and needs no help deriving it.
|
|
214
|
+
ownerStepKey: point.owner,
|
|
215
|
+
path: point.path,
|
|
216
|
+
}) ?? {}),
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/** An edge end, as an address. */
|
|
220
|
+
const endAddress = (end) => end.kind === 'step'
|
|
221
|
+
? addressOf.get(end.key)
|
|
222
|
+
: junctionOf.get(`${end.owner} ${end.path.join(' ')}`);
|
|
223
|
+
for (const edge of graph.edges) {
|
|
224
|
+
const from = endAddress(edge.from);
|
|
225
|
+
const to = endAddress(edge.to);
|
|
226
|
+
// Both ends are always indexed by construction; the guard keeps a dropped duplicate from producing a
|
|
227
|
+
// half-addressed edge rather than none.
|
|
228
|
+
if (from === undefined || to === undefined)
|
|
229
|
+
continue;
|
|
230
|
+
edges.push({
|
|
231
|
+
from,
|
|
232
|
+
to,
|
|
233
|
+
...(edge.label !== undefined ? { label: edge.label } : {}),
|
|
234
|
+
stage: stage.key,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
address: base,
|
|
240
|
+
collection,
|
|
241
|
+
...(collection === 'pullers'
|
|
242
|
+
? { pullerKind: pullerKindOf(component) }
|
|
243
|
+
: {}),
|
|
244
|
+
stages,
|
|
245
|
+
stageEdges: stageEdges(collection, component),
|
|
246
|
+
nodes,
|
|
247
|
+
edges,
|
|
248
|
+
...(duplicates.length > 0 ? { duplicateStepKeys: duplicates } : {}),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=flow.js.map
|
package/dist/flow.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow.js","sourceRoot":"","sources":["../src/flow.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The flow model for a worker component — one computation, every consumer (FR-15, FR-17, NFR-1).
|
|
3
|
+
*
|
|
4
|
+
* Three implementations answered *"what is this component's flow?"* independently: the CLI's report renderer, the
|
|
5
|
+
* VS Code extension's preview, and dashboard-v2's diagram. That is the defect Epic 4 exists to remove, and
|
|
6
|
+
* `golden-flows/` is the pre-migration measurement taken so each difference becomes a deliberate verdict rather
|
|
7
|
+
* than a surprise.
|
|
8
|
+
*
|
|
9
|
+
* ⛔ **CORE (AD-3)**: no filesystem, no `vscode`, no Node builtin. The extension bundles this into a web-worker host
|
|
10
|
+
* where none of them exist, so an authored file and location arrive as data.
|
|
11
|
+
*
|
|
12
|
+
* ⚠️ `check:web-bundle` is that rule's gate **in the extension's repo, not in this one** (Story 4.1 review, L1):
|
|
13
|
+
* Task 1 called it "a gate" and no such script exists here. What holds the rule up on this side is
|
|
14
|
+
* `lint:boundaries` (which classifies this package `core` from `package.json`'s `hexasync.layer`, itself now guarded
|
|
15
|
+
* by `apps/cli/src/__tests__/packageLayer.spec.ts`) plus the one-dependency manifest. The bundle check runs when the
|
|
16
|
+
* extension consumes this in Story 4.5.
|
|
17
|
+
*/
|
|
18
|
+
export { WORKER_STAGES, stagesPresent, stageEdges, pullerKindOf, type StagePhase, type StageDefinition, type WorkerCollection, type PullerKind, type StageEdge, } from './stages.js';
|
|
19
|
+
export { routeEdges, quotedKeys, looksLikeExpression, type RoutableStep, type RouteEdge, } from './routes.js';
|
|
20
|
+
export { workerFlow, type WorkerFlow, type WorkerFlowInput, type FlowNode, type FlowEdgeAddressed, type NodeLocation, type LocateRequest, } from './flow.js';
|
|
21
|
+
export { routeGraph, junctionAddress, type RouteGraph, type Junction, type JunctionKind, type GraphEdge, type EdgeEnd, } from './routeGraph.js';
|
|
22
|
+
export { renderMermaid, renderMarkdown } from './render.js';
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EACL,aAAa,EACb,aAAa,EACb,UAAU,EACV,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,SAAS,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,UAAU,EACV,UAAU,EACV,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,UAAU,EACV,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,aAAa,GACnB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,UAAU,EACV,eAAe,EACf,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,OAAO,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The flow model for a worker component — one computation, every consumer (FR-15, FR-17, NFR-1).
|
|
3
|
+
*
|
|
4
|
+
* Three implementations answered *"what is this component's flow?"* independently: the CLI's report renderer, the
|
|
5
|
+
* VS Code extension's preview, and dashboard-v2's diagram. That is the defect Epic 4 exists to remove, and
|
|
6
|
+
* `golden-flows/` is the pre-migration measurement taken so each difference becomes a deliberate verdict rather
|
|
7
|
+
* than a surprise.
|
|
8
|
+
*
|
|
9
|
+
* ⛔ **CORE (AD-3)**: no filesystem, no `vscode`, no Node builtin. The extension bundles this into a web-worker host
|
|
10
|
+
* where none of them exist, so an authored file and location arrive as data.
|
|
11
|
+
*
|
|
12
|
+
* ⚠️ `check:web-bundle` is that rule's gate **in the extension's repo, not in this one** (Story 4.1 review, L1):
|
|
13
|
+
* Task 1 called it "a gate" and no such script exists here. What holds the rule up on this side is
|
|
14
|
+
* `lint:boundaries` (which classifies this package `core` from `package.json`'s `hexasync.layer`, itself now guarded
|
|
15
|
+
* by `apps/cli/src/__tests__/packageLayer.spec.ts`) plus the one-dependency manifest. The bundle check runs when the
|
|
16
|
+
* extension consumes this in Story 4.5.
|
|
17
|
+
*/
|
|
18
|
+
export { WORKER_STAGES, stagesPresent, stageEdges, pullerKindOf, } from './stages.js';
|
|
19
|
+
export { routeEdges, quotedKeys, looksLikeExpression, } from './routes.js';
|
|
20
|
+
export { workerFlow, } from './flow.js';
|
|
21
|
+
export { routeGraph, junctionAddress, } from './routeGraph.js';
|
|
22
|
+
export { renderMermaid, renderMarkdown } from './render.js';
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EACL,aAAa,EACb,aAAa,EACb,UAAU,EACV,YAAY,GAMb,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,UAAU,EACV,UAAU,EACV,mBAAmB,GAGpB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,UAAU,GAOX,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,UAAU,EACV,eAAe,GAMhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `renderMermaid` / `renderMarkdown` for a worker flow — Story 4.3, `PACKAGE-CONTRACT.md` §5.
|
|
3
|
+
*
|
|
4
|
+
* Thin by design. The emission rules live in `hexasync-template-model`'s `flowRender`, because AD-21 forbids the two
|
|
5
|
+
* flow packages importing each other and the shared half has to live somewhere neither owns. This file's whole job is
|
|
6
|
+
* to say what a WORKER node looks like: which shape it takes, what its label reads, and how stages become subgraphs.
|
|
7
|
+
*/
|
|
8
|
+
import { type RenderOptions } from '@beehexa/hexasync-template-model';
|
|
9
|
+
import type { WorkerFlow } from './flow.js';
|
|
10
|
+
export declare function renderMermaid(flow: WorkerFlow, opts?: RenderOptions): string;
|
|
11
|
+
/**
|
|
12
|
+
* Markdown for one component — `(flow, opts)`, matching the frontend twin and `PACKAGE-CONTRACT.md` §5.
|
|
13
|
+
*
|
|
14
|
+
* ⛔ This took `(flow, title, opts)` (Story 4.3 review, MEDIUM-1). §5 declares `renderMarkdown(model, opts?)`
|
|
15
|
+
* *"exported from both flow packages"*, so a caller written to the contract passed the options object into the `title`
|
|
16
|
+
* slot and it reached `escapeLabel`: **`TypeError: value.replace is not a function`**. TypeScript caught it for TS
|
|
17
|
+
* consumers; JS consumers and the "one renderer set, callable uniformly" premise did not.
|
|
18
|
+
*
|
|
19
|
+
* The title now comes from the model, which has everything needed: the collection and the component's authored id. A
|
|
20
|
+
* caller wanting its own wording passes `title`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function renderMarkdown(flow: WorkerFlow, opts?: RenderOptions & {
|
|
23
|
+
readonly title?: string;
|
|
24
|
+
}): string;
|
|
25
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAmI5C,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,IAAI,GAAE,aAAkB,GACvB,MAAM,CAMR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,UAAU,EAChB,IAAI,GAAE,aAAa,GAAG;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GACrD,MAAM,CAQR"}
|