@almadar/core 10.129.0 → 11.0.1
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/behavior-package.d.ts +49 -11
- package/dist/behavior-package.js +1 -1
- package/dist/{orbital-CkFdDS9f.d.ts → builders-BdgbY7Th.d.ts} +5828 -6917
- package/dist/builders.d.ts +6 -6
- package/dist/builders.js +7 -6
- package/dist/{bus-CcbB__oo.d.ts → bus-C0hFDNFR.d.ts} +262 -354
- package/dist/chunk-347APWFM.js +286 -0
- package/dist/chunk-347APWFM.js.map +1 -0
- package/dist/chunk-5WQ3U7NJ.js +2363 -0
- package/dist/chunk-5WQ3U7NJ.js.map +1 -0
- package/dist/chunk-5YTPYMPZ.js +99 -0
- package/dist/chunk-5YTPYMPZ.js.map +1 -0
- package/dist/chunk-66Q5VX2F.js +3810 -0
- package/dist/chunk-66Q5VX2F.js.map +1 -0
- package/dist/chunk-7GHJU5WI.js +39 -0
- package/dist/chunk-7GHJU5WI.js.map +1 -0
- package/dist/chunk-B4MNHGBP.js +8 -0
- package/dist/chunk-B4MNHGBP.js.map +1 -0
- package/dist/chunk-E4T2MQAV.js +24 -0
- package/dist/chunk-E4T2MQAV.js.map +1 -0
- package/dist/chunk-ENOCKYGA.js +412 -0
- package/dist/chunk-ENOCKYGA.js.map +1 -0
- package/dist/chunk-FGT5OS2Y.js +918 -0
- package/dist/chunk-FGT5OS2Y.js.map +1 -0
- package/dist/chunk-GF7KCLNR.js +3284 -0
- package/dist/chunk-GF7KCLNR.js.map +1 -0
- package/dist/chunk-PNGFWLHD.js +1567 -0
- package/dist/chunk-PNGFWLHD.js.map +1 -0
- package/dist/{chunk-X4SC7FGF.js → chunk-RGACZEYC.js} +99 -96
- package/dist/chunk-RGACZEYC.js.map +1 -0
- package/dist/{chunk-RYPVOI6H.js → chunk-SNZYN7UA.js} +2541 -433
- package/dist/{chunk-RYPVOI6H.js.map → chunk-SNZYN7UA.js.map} +1 -1
- package/dist/{chunk-KDMV222Q.js → chunk-TDNQT3M3.js} +304 -373
- package/dist/chunk-TDNQT3M3.js.map +1 -0
- package/dist/chunk-VG7BRFUD.js +152 -0
- package/dist/chunk-VG7BRFUD.js.map +1 -0
- package/dist/chunk-Z7BI7DE7.js +1293 -0
- package/dist/chunk-Z7BI7DE7.js.map +1 -0
- package/dist/{domain-Dz3jP-UM.d.ts → domain-Cpmja5ak.d.ts} +55 -55
- package/dist/{effect-CiEVLsZz.d.ts → effect-DZaXwSAz.d.ts} +283 -453
- package/dist/{effect-result-Bebwu9yT.d.ts → effect-result-1HpXgeBc.d.ts} +656 -851
- package/dist/{expression-D0Fs0riG.d.ts → expression-DirYKz-f.d.ts} +5 -13
- package/dist/factory/index.d.ts +7 -144
- package/dist/factory/index.js +8 -8
- package/dist/factory-runtime/index.d.ts +7 -6
- package/dist/factory-runtime/index.js +527 -8
- package/dist/factory-runtime/index.js.map +1 -1
- package/dist/fixtures.d.ts +9 -11
- package/dist/fixtures.js +12 -8
- package/dist/fixtures.js.map +1 -1
- package/dist/i18n/index.d.ts +15 -19
- package/dist/i18n/index.js +2 -1
- package/dist/{index-BC-Jycqj.d.ts → index-D7SxwNdv.d.ts} +34 -734
- package/dist/index.d.ts +92 -247
- package/dist/index.js +322 -986
- package/dist/index.js.map +1 -1
- package/dist/kernel-wire.d.ts +3 -3
- package/dist/kernel-wire.js +3 -79
- package/dist/kernel-wire.js.map +1 -1
- package/dist/language/constructs.json +22 -2
- package/dist/language/program-types.json +203 -22
- package/dist/language/protocols.json +46 -0
- package/dist/language/ui-vocabulary.json +1697 -0
- package/dist/language/validation-codes.json +1222 -1212
- package/dist/language/vocabulary.json +44 -8
- package/dist/language-data.d.ts +7 -4
- package/dist/language-data.js +20 -14
- package/dist/language-data.js.map +1 -1
- package/dist/patterns/component-mapping.json +11 -1
- package/dist/patterns/definitions.d.ts +2 -2
- package/dist/patterns/definitions.js +1 -1
- package/dist/patterns/event-contracts.json +1 -15
- package/dist/patterns/game-font-families.json +13 -0
- package/dist/patterns/index.d.ts +24 -120
- package/dist/patterns/index.js +3 -3
- package/dist/patterns/pattern-tile-geometry.json +1065 -0
- package/dist/patterns/patterns-registry.json +2539 -431
- package/dist/patterns/registry.json +2539 -431
- package/dist/trait-sRjIivFq.d.ts +3519 -0
- package/dist/types/index.d.ts +9 -10
- package/dist/types/index.js +11 -5
- package/dist/{types-DGwrltUF.d.ts → types-C6_yPMpn.d.ts} +3 -3
- package/fixtures/events-wire/client-effects-by-trait/response.json +0 -18
- package/fixtures/events-wire/client-effects-provenance/response.json +0 -18
- package/fixtures/events-wire/effect-results-every-kind/response.json +2 -27
- package/fixtures/events-wire/navigate-1/response.json +8 -5
- package/fixtures/events-wire/navigate-2/response.json +11 -8
- package/fixtures/events-wire/navigate-3/response.json +14 -11
- package/fixtures/events-wire/navigate-back/response.json +7 -4
- package/fixtures/events-wire/render-ui-3/response.json +12 -9
- package/fixtures/events-wire/render-ui-clear/response.json +0 -7
- package/fixtures/events-wire/sse-stream/response.json +0 -20
- package/fixtures/events-wire/sse-stream/stream.json +0 -20
- package/fixtures/events-wire/stateless-traits/response.json +14 -5
- package/fixtures/kernel-wire/golden/basic-entity.json +1687 -0
- package/fixtures/kernel-wire/golden/entity-rerender.json +743 -0
- package/fixtures/kernel-wire/golden/rollback.json +793 -0
- package/fixtures/kernel-wire/golden/tick-counter.json +1538 -0
- package/fixtures/kernel-wire/golden/two-orbital-chore.json +847 -0
- package/fixtures/kernel-wire/golden/two-orbital-task.json +457 -0
- package/fixtures/kernel-wire/played-step.json +136 -0
- package/fixtures/kernel-wire/scripts/basic-entity.json +28 -0
- package/fixtures/kernel-wire/scripts/entity-rerender.json +13 -0
- package/fixtures/kernel-wire/scripts/rollback.json +53 -0
- package/fixtures/kernel-wire/scripts/tick-counter.json +26 -0
- package/fixtures/kernel-wire/scripts/two-orbital-chore.json +9 -0
- package/fixtures/kernel-wire/scripts/two-orbital-task.json +9 -0
- package/package.json +28 -19
- package/dist/builders-DmZE5By0.d.ts +0 -2663
- package/dist/chunk-45I2O4SJ.js +0 -4646
- package/dist/chunk-45I2O4SJ.js.map +0 -1
- package/dist/chunk-6LR43Z5E.js +0 -3061
- package/dist/chunk-6LR43Z5E.js.map +0 -1
- package/dist/chunk-GIUA3NUJ.js +0 -809
- package/dist/chunk-GIUA3NUJ.js.map +0 -1
- package/dist/chunk-GTY53NS5.js +0 -1908
- package/dist/chunk-GTY53NS5.js.map +0 -1
- package/dist/chunk-JOHDVS6J.js +0 -1614
- package/dist/chunk-JOHDVS6J.js.map +0 -1
- package/dist/chunk-KDMV222Q.js.map +0 -1
- package/dist/chunk-QRHJUS3D.js +0 -23
- package/dist/chunk-QRHJUS3D.js.map +0 -1
- package/dist/chunk-QUOTJULD.js +0 -4009
- package/dist/chunk-QUOTJULD.js.map +0 -1
- package/dist/chunk-V5VNGRVU.js +0 -66
- package/dist/chunk-V5VNGRVU.js.map +0 -1
- package/dist/chunk-X4SC7FGF.js.map +0 -1
- package/dist/entityAccess-BPSz1i2n.d.ts +0 -80
- package/dist/mock/index.d.ts +0 -153
- package/dist/mock/index.js +0 -190
- package/dist/mock/index.js.map +0 -1
- package/dist/schema-T5RT5s6H.d.ts +0 -282
- package/dist/state-machine/index.d.ts +0 -359
- package/dist/state-machine/index.js +0 -3
- package/dist/state-machine/index.js.map +0 -1
package/dist/chunk-GIUA3NUJ.js
DELETED
|
@@ -1,809 +0,0 @@
|
|
|
1
|
-
// src/state-machine/graph.ts
|
|
2
|
-
function buildStateGraph(transitions) {
|
|
3
|
-
const graph = /* @__PURE__ */ new Map();
|
|
4
|
-
for (const t of transitions) {
|
|
5
|
-
if (t.from === "*") continue;
|
|
6
|
-
if (!graph.has(t.from)) graph.set(t.from, []);
|
|
7
|
-
graph.get(t.from).push({ event: t.event, to: t.to });
|
|
8
|
-
}
|
|
9
|
-
return graph;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// src/state-machine/bfs.ts
|
|
13
|
-
function collectReachableStates(transitions, initialState, maxDepth = 5) {
|
|
14
|
-
const graph = buildStateGraph(transitions);
|
|
15
|
-
const visited = /* @__PURE__ */ new Set([initialState]);
|
|
16
|
-
const queue = [{ state: initialState, depth: 0 }];
|
|
17
|
-
while (queue.length > 0) {
|
|
18
|
-
const current = queue.shift();
|
|
19
|
-
if (current.depth >= maxDepth) continue;
|
|
20
|
-
const edges = graph.get(current.state) ?? [];
|
|
21
|
-
for (const edge of edges) {
|
|
22
|
-
if (!visited.has(edge.to)) {
|
|
23
|
-
visited.add(edge.to);
|
|
24
|
-
queue.push({ state: edge.to, depth: current.depth + 1 });
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return visited;
|
|
29
|
-
}
|
|
30
|
-
async function walkStatePairs(transitions, initialState, maxDepth, visitor) {
|
|
31
|
-
const graph = buildStateGraph(transitions);
|
|
32
|
-
const visitedPairs = /* @__PURE__ */ new Set();
|
|
33
|
-
const queue = [{ state: initialState, depth: 0 }];
|
|
34
|
-
let walkedEdges = 0;
|
|
35
|
-
while (queue.length > 0) {
|
|
36
|
-
const current = queue.shift();
|
|
37
|
-
if (current.depth >= maxDepth) continue;
|
|
38
|
-
const edges = graph.get(current.state) ?? [];
|
|
39
|
-
for (const edge of edges) {
|
|
40
|
-
const pairKey = `${current.state}:${edge.event}`;
|
|
41
|
-
if (visitedPairs.has(pairKey)) continue;
|
|
42
|
-
visitedPairs.add(pairKey);
|
|
43
|
-
const shouldEnqueue = await visitor(current.state, edge, current.depth);
|
|
44
|
-
walkedEdges++;
|
|
45
|
-
if (shouldEnqueue) {
|
|
46
|
-
const stateVisited = [...visitedPairs].some((k) => k.startsWith(`${edge.to}:`));
|
|
47
|
-
if (!stateVisited) {
|
|
48
|
-
queue.push({ state: edge.to, depth: current.depth + 1 });
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return { visitedPairs, walkedEdges };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// src/state-machine/guard-payloads.ts
|
|
57
|
-
function extractPayloadFieldRef(ref) {
|
|
58
|
-
if (typeof ref !== "string") return null;
|
|
59
|
-
const match = ref.match(/^@payload\.([A-Za-z0-9_]+)/);
|
|
60
|
-
return match ? match[1] : null;
|
|
61
|
-
}
|
|
62
|
-
function extractPayloadFieldPath(ref) {
|
|
63
|
-
if (typeof ref !== "string") return null;
|
|
64
|
-
const match = ref.match(/^@payload\.([A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*)/);
|
|
65
|
-
return match ? match[1].split(".") : null;
|
|
66
|
-
}
|
|
67
|
-
function strDefaultPayloadPath(ref) {
|
|
68
|
-
if (!Array.isArray(ref) || ref[0] !== "str/default" || typeof ref[2] !== "string") return null;
|
|
69
|
-
return extractPayloadFieldPath(ref[1]);
|
|
70
|
-
}
|
|
71
|
-
function isComparedLiteral(x) {
|
|
72
|
-
return x === null || typeof x === "number" || typeof x === "boolean" || typeof x === "string" && !x.startsWith("@");
|
|
73
|
-
}
|
|
74
|
-
function payloadComparison(a, b) {
|
|
75
|
-
const plain = extractPayloadFieldPath(a);
|
|
76
|
-
if (plain && b !== void 0) return { path: plain, val: b };
|
|
77
|
-
for (const [side, other] of [[a, b], [b, a]]) {
|
|
78
|
-
const path = extractPayloadFieldPath(side) ?? strDefaultPayloadPath(side);
|
|
79
|
-
if (path && isComparedLiteral(other)) return { path, val: other };
|
|
80
|
-
}
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
function nestedPayload(path, leaf) {
|
|
84
|
-
let value = leaf;
|
|
85
|
-
for (let i = path.length - 1; i >= 1; i--) {
|
|
86
|
-
value = { [path[i]]: value };
|
|
87
|
-
}
|
|
88
|
-
return { [path[0]]: value };
|
|
89
|
-
}
|
|
90
|
-
function isPayloadObject(v) {
|
|
91
|
-
return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Date);
|
|
92
|
-
}
|
|
93
|
-
function extractArrayLenPath(ref) {
|
|
94
|
-
if (!Array.isArray(ref) || ref.length !== 2 || ref[0] !== "array/len") return null;
|
|
95
|
-
return extractPayloadFieldPath(ref[1]);
|
|
96
|
-
}
|
|
97
|
-
function arrayOfLength(n) {
|
|
98
|
-
return Array.from({ length: Math.max(0, n) }, (_, i) => ({ id: `mock-test-id-${i}` }));
|
|
99
|
-
}
|
|
100
|
-
var SYNTHESIZED_GUARD_OPERATORS = /* @__PURE__ */ new Set([
|
|
101
|
-
"not-nil",
|
|
102
|
-
"not_nil",
|
|
103
|
-
"nil",
|
|
104
|
-
"eq",
|
|
105
|
-
"==",
|
|
106
|
-
"=",
|
|
107
|
-
"not-eq",
|
|
108
|
-
"!=",
|
|
109
|
-
"neq",
|
|
110
|
-
"gt",
|
|
111
|
-
">",
|
|
112
|
-
"gte",
|
|
113
|
-
">=",
|
|
114
|
-
"lt",
|
|
115
|
-
"<",
|
|
116
|
-
"lte",
|
|
117
|
-
"<=",
|
|
118
|
-
"and",
|
|
119
|
-
"or",
|
|
120
|
-
"not",
|
|
121
|
-
"object/has",
|
|
122
|
-
"object/get",
|
|
123
|
-
"array/includes",
|
|
124
|
-
"str/startsWith",
|
|
125
|
-
"validate/url",
|
|
126
|
-
"validate/required",
|
|
127
|
-
"agent/is-pinned",
|
|
128
|
-
"agent/memory-strength",
|
|
129
|
-
"if",
|
|
130
|
-
"let",
|
|
131
|
-
"array/some",
|
|
132
|
-
"array/every",
|
|
133
|
-
"grid/in-bounds"
|
|
134
|
-
]);
|
|
135
|
-
var ACKNOWLEDGED_UNSYNTHESIZED_GUARD_OPERATORS = /* @__PURE__ */ new Set();
|
|
136
|
-
var CONSTANT_GUARD_FORMS = /* @__PURE__ */ new Set(["quote"]);
|
|
137
|
-
function isRecognizedGuardOperator(op) {
|
|
138
|
-
return SYNTHESIZED_GUARD_OPERATORS.has(op) || ACKNOWLEDGED_UNSYNTHESIZED_GUARD_OPERATORS.has(op) || CONSTANT_GUARD_FORMS.has(op) || op.startsWith("agent/");
|
|
139
|
-
}
|
|
140
|
-
var unhandledGuardOperators = [];
|
|
141
|
-
function recordUnhandledOperator(op) {
|
|
142
|
-
if (unhandledGuardOperators.includes(op)) return;
|
|
143
|
-
unhandledGuardOperators.push(op);
|
|
144
|
-
console.warn(
|
|
145
|
-
`[@almadar/core buildGuardPayloads] unrecognized guard operator "${op}" \u2014 synthesizing {pass:{}, fail:{}}; this guard arm cannot be walked pass/fail by verify. Add synthesis (or a tracked-gap entry) in guard-payloads.ts.`
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
function splitPayloadArg(a, b) {
|
|
149
|
-
const pathA = extractPayloadFieldPath(a);
|
|
150
|
-
if (pathA) return { path: pathA, collection: b };
|
|
151
|
-
const pathB = extractPayloadFieldPath(b);
|
|
152
|
-
if (pathB) return { path: pathB, collection: a };
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
function isPlainRecord(v) {
|
|
156
|
-
return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Date);
|
|
157
|
-
}
|
|
158
|
-
function absentKey(keys) {
|
|
159
|
-
let candidate = `${keys.reduce((longest, k) => k.length > longest.length ? k : longest, "")}_`;
|
|
160
|
-
while (keys.includes(candidate)) candidate += "_";
|
|
161
|
-
return candidate;
|
|
162
|
-
}
|
|
163
|
-
function mergePayloads(a, b) {
|
|
164
|
-
const out = { ...a };
|
|
165
|
-
for (const [k, v] of Object.entries(b)) {
|
|
166
|
-
const prev = out[k];
|
|
167
|
-
out[k] = prev !== void 0 && isPayloadObject(prev) && v !== void 0 && isPayloadObject(v) ? mergePayloads(prev, v) : v;
|
|
168
|
-
}
|
|
169
|
-
return out;
|
|
170
|
-
}
|
|
171
|
-
function extractObjectGetOperand(x) {
|
|
172
|
-
if (!Array.isArray(x) || x[0] !== "object/get") return null;
|
|
173
|
-
const split = splitPayloadArg(x[1], x[2]);
|
|
174
|
-
if (split && isPlainRecord(split.collection)) {
|
|
175
|
-
return { path: split.path, map: split.collection };
|
|
176
|
-
}
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
function resolveObjectGetComparison(a, b) {
|
|
180
|
-
const getA = extractObjectGetOperand(a);
|
|
181
|
-
if (getA) return { path: getA.path, map: getA.map, literal: b };
|
|
182
|
-
const getB = extractObjectGetOperand(b);
|
|
183
|
-
if (getB) return { path: getB.path, map: getB.map, literal: a };
|
|
184
|
-
return null;
|
|
185
|
-
}
|
|
186
|
-
function buildObjectGetComparisonPayload(a, b, negate) {
|
|
187
|
-
const resolved = resolveObjectGetComparison(a, b);
|
|
188
|
-
if (!resolved) return null;
|
|
189
|
-
const { path, map, literal } = resolved;
|
|
190
|
-
const keys = Object.keys(map);
|
|
191
|
-
const passKey = keys.find((k) => negate ? map[k] !== literal : map[k] === literal);
|
|
192
|
-
const failKey = keys.find((k) => negate ? map[k] === literal : map[k] !== literal);
|
|
193
|
-
return {
|
|
194
|
-
pass: passKey !== void 0 ? nestedPayload(path, passKey) : {},
|
|
195
|
-
fail: failKey !== void 0 ? nestedPayload(path, failKey) : nestedPayload(path, absentKey(keys))
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
function guardPassCandidateSet(guard) {
|
|
199
|
-
if (!Array.isArray(guard) || guard.length === 0) return null;
|
|
200
|
-
const op = String(guard[0]);
|
|
201
|
-
if (op === "object/has") {
|
|
202
|
-
const split = splitPayloadArg(guard[1], guard[2]);
|
|
203
|
-
if (split && isPlainRecord(split.collection)) {
|
|
204
|
-
return { path: split.path, values: Object.keys(split.collection) };
|
|
205
|
-
}
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
if (op === "eq" || op === "==" || op === "=" || op === "not-eq" || op === "!=" || op === "neq") {
|
|
209
|
-
const negate = op === "not-eq" || op === "!=" || op === "neq";
|
|
210
|
-
const resolved = resolveObjectGetComparison(guard[1], guard[2]);
|
|
211
|
-
if (resolved) {
|
|
212
|
-
const values = Object.keys(resolved.map).filter(
|
|
213
|
-
(k) => negate ? resolved.map[k] !== resolved.literal : resolved.map[k] === resolved.literal
|
|
214
|
-
);
|
|
215
|
-
return { path: resolved.path, values };
|
|
216
|
-
}
|
|
217
|
-
if (!negate) {
|
|
218
|
-
const path = extractPayloadFieldPath(guard[1]);
|
|
219
|
-
if (path && typeof guard[2] === "string") return { path, values: [guard[2]] };
|
|
220
|
-
}
|
|
221
|
-
return null;
|
|
222
|
-
}
|
|
223
|
-
return null;
|
|
224
|
-
}
|
|
225
|
-
function withoutField(payload, path) {
|
|
226
|
-
const [head, ...tail] = path;
|
|
227
|
-
if (tail.length === 0) {
|
|
228
|
-
const rest = {};
|
|
229
|
-
for (const k of Object.keys(payload)) {
|
|
230
|
-
if (k !== head) rest[k] = payload[k];
|
|
231
|
-
}
|
|
232
|
-
return rest;
|
|
233
|
-
}
|
|
234
|
-
const nested = payload[head];
|
|
235
|
-
if (!isPayloadObject(nested)) return payload;
|
|
236
|
-
return { ...payload, [head]: withoutField(nested, tail) };
|
|
237
|
-
}
|
|
238
|
-
function applyFieldIntersections(subs, pass) {
|
|
239
|
-
const byField = /* @__PURE__ */ new Map();
|
|
240
|
-
for (const sub of subs) {
|
|
241
|
-
const candidate = guardPassCandidateSet(sub);
|
|
242
|
-
if (!candidate) continue;
|
|
243
|
-
const key = JSON.stringify(candidate.path);
|
|
244
|
-
const entry = byField.get(key);
|
|
245
|
-
if (entry) entry.sets.push(candidate.values);
|
|
246
|
-
else byField.set(key, { path: candidate.path, sets: [candidate.values] });
|
|
247
|
-
}
|
|
248
|
-
let out = pass;
|
|
249
|
-
for (const { path, sets } of byField.values()) {
|
|
250
|
-
if (sets.length < 2) continue;
|
|
251
|
-
const intersection = sets.reduce((acc, set) => acc.filter((v) => set.includes(v)));
|
|
252
|
-
out = intersection.length > 0 ? mergePayloads(out, nestedPayload(path, intersection[0])) : withoutField(out, path);
|
|
253
|
-
}
|
|
254
|
-
return out;
|
|
255
|
-
}
|
|
256
|
-
function constTruth(guard) {
|
|
257
|
-
if (typeof guard === "boolean") return guard;
|
|
258
|
-
if (typeof guard === "string") {
|
|
259
|
-
if (guard.startsWith("@")) return null;
|
|
260
|
-
return guard.length > 0;
|
|
261
|
-
}
|
|
262
|
-
if (!Array.isArray(guard) || guard.length === 0) return null;
|
|
263
|
-
const op = String(guard[0]);
|
|
264
|
-
const isLiteral = (x) => x === null || typeof x === "number" || typeof x === "boolean" || typeof x === "string" && !x.startsWith("@");
|
|
265
|
-
if (op === "=" || op === "==" || op === "eq") {
|
|
266
|
-
return isLiteral(guard[1]) && isLiteral(guard[2]) ? guard[1] === guard[2] : null;
|
|
267
|
-
}
|
|
268
|
-
if (op === "!=" || op === "ne" || op === "not-eq" || op === "neq") {
|
|
269
|
-
return isLiteral(guard[1]) && isLiteral(guard[2]) ? guard[1] !== guard[2] : null;
|
|
270
|
-
}
|
|
271
|
-
if (op === "not") {
|
|
272
|
-
const inner = constTruth(guard[1]);
|
|
273
|
-
return inner === null ? null : !inner;
|
|
274
|
-
}
|
|
275
|
-
if (op === "or") {
|
|
276
|
-
const subs = guard.slice(1).map(constTruth);
|
|
277
|
-
if (subs.some((s) => s === true)) return true;
|
|
278
|
-
if (subs.every((s) => s === false)) return false;
|
|
279
|
-
return null;
|
|
280
|
-
}
|
|
281
|
-
if (op === "and") {
|
|
282
|
-
const subs = guard.slice(1).map(constTruth);
|
|
283
|
-
if (subs.some((s) => s === false)) return false;
|
|
284
|
-
if (subs.every((s) => s === true)) return true;
|
|
285
|
-
return null;
|
|
286
|
-
}
|
|
287
|
-
return null;
|
|
288
|
-
}
|
|
289
|
-
function substituteVar(node, name, mapRef) {
|
|
290
|
-
if (typeof node === "string") {
|
|
291
|
-
if (node === `@${name}`) return mapRef([]) ?? node;
|
|
292
|
-
if (node.startsWith(`@${name}.`)) return mapRef(node.slice(name.length + 2).split(".")) ?? node;
|
|
293
|
-
return node;
|
|
294
|
-
}
|
|
295
|
-
if (Array.isArray(node)) {
|
|
296
|
-
if (node[0] === "fn" && node[1] === name) return node;
|
|
297
|
-
if (node[0] === "object/get" && typeof node[2] === "string" && node[1] === `@${name}`) {
|
|
298
|
-
return mapRef([node[2]]) ?? node;
|
|
299
|
-
}
|
|
300
|
-
return node.map((child) => substituteVar(child, name, mapRef));
|
|
301
|
-
}
|
|
302
|
-
if (typeof node === "object" && node !== null) {
|
|
303
|
-
const out = {};
|
|
304
|
-
for (const [k, v] of Object.entries(node)) out[k] = substituteVar(v, name, mapRef);
|
|
305
|
-
return out;
|
|
306
|
-
}
|
|
307
|
-
return node;
|
|
308
|
-
}
|
|
309
|
-
function readLiteralPath(value, path) {
|
|
310
|
-
let cur = value;
|
|
311
|
-
for (const seg of path) {
|
|
312
|
-
if (!isPlainRecord(cur)) return null;
|
|
313
|
-
const next = cur[seg];
|
|
314
|
-
cur = next === void 0 ? null : next;
|
|
315
|
-
}
|
|
316
|
-
return cur;
|
|
317
|
-
}
|
|
318
|
-
function hasKeys(p) {
|
|
319
|
-
return Object.keys(p).length > 0;
|
|
320
|
-
}
|
|
321
|
-
function buildLetPayloads(guard) {
|
|
322
|
-
const bindings = guard[1];
|
|
323
|
-
const bodyIdx = guard.length - 1;
|
|
324
|
-
if (!Array.isArray(bindings) || bodyIdx < 2) return null;
|
|
325
|
-
const pairs = [];
|
|
326
|
-
for (const b of bindings) {
|
|
327
|
-
if (!Array.isArray(b) || typeof b[0] !== "string" || b.length < 2) return null;
|
|
328
|
-
pairs.push([b[0], b[1]]);
|
|
329
|
-
}
|
|
330
|
-
const bindingRef = (value) => (path) => {
|
|
331
|
-
if (path.length === 0) return value;
|
|
332
|
-
if (typeof value === "string" && value.startsWith("@")) return `${value}.${path.join(".")}`;
|
|
333
|
-
if (isPlainRecord(value)) return readLiteralPath(value, path);
|
|
334
|
-
return void 0;
|
|
335
|
-
};
|
|
336
|
-
let body = guard[bodyIdx];
|
|
337
|
-
const values = pairs.map(([, v]) => v);
|
|
338
|
-
for (let i = 0; i < pairs.length; i++) {
|
|
339
|
-
for (let j = i + 1; j < pairs.length; j++) values[j] = substituteVar(values[j], pairs[i][0], bindingRef(values[i]));
|
|
340
|
-
}
|
|
341
|
-
for (let i = pairs.length - 1; i >= 0; i--) body = substituteVar(body, pairs[i][0], bindingRef(values[i]));
|
|
342
|
-
return buildGuardPayloads(body);
|
|
343
|
-
}
|
|
344
|
-
function buildIfPayloads(guard) {
|
|
345
|
-
if (guard.length < 3) return null;
|
|
346
|
-
const elseG = guard.length > 3 ? guard[3] : false;
|
|
347
|
-
const c = buildGuardPayloads(guard[1]);
|
|
348
|
-
const t = buildGuardPayloads(guard[2]);
|
|
349
|
-
const e = buildGuardPayloads(elseG);
|
|
350
|
-
const cc = constTruth(guard[1]);
|
|
351
|
-
const ct = constTruth(guard[2]);
|
|
352
|
-
const ce = constTruth(elseG);
|
|
353
|
-
const reach = (target) => {
|
|
354
|
-
const thenOk = cc !== false && ct !== !target;
|
|
355
|
-
if (thenOk) return mergePayloads(c.pass, target ? t.pass : t.fail);
|
|
356
|
-
const elseOk = cc !== true && ce !== !target;
|
|
357
|
-
if (elseOk) return mergePayloads(c.fail, target ? e.pass : e.fail);
|
|
358
|
-
return {};
|
|
359
|
-
};
|
|
360
|
-
return { pass: reach(true), fail: reach(false) };
|
|
361
|
-
}
|
|
362
|
-
function buildQuantifierPayloads(op, guard) {
|
|
363
|
-
const fn = guard[2];
|
|
364
|
-
if (!Array.isArray(fn) || fn[0] !== "fn" || typeof fn[1] !== "string" || fn.length < 3) return null;
|
|
365
|
-
const name = fn[1];
|
|
366
|
-
const body = fn[fn.length - 1];
|
|
367
|
-
const some = op === "array/some";
|
|
368
|
-
const listPath = extractPayloadFieldPath(guard[1]);
|
|
369
|
-
if (listPath) {
|
|
370
|
-
const sub = substituteVar(body, name, (p) => p.length > 0 ? `@payload.${p.join(".")}` : void 0);
|
|
371
|
-
const truth = constTruth(sub);
|
|
372
|
-
const built = buildGuardPayloads(sub);
|
|
373
|
-
const witness = truth === true ? { id: "mock-test-id" } : hasKeys(built.pass) && truth !== false ? built.pass : null;
|
|
374
|
-
const violator = truth === false ? { id: "mock-test-id" } : hasKeys(built.fail) && truth !== true ? built.fail : null;
|
|
375
|
-
const list = (el) => el ? nestedPayload(listPath, [el]) : {};
|
|
376
|
-
return some ? { pass: list(witness), fail: nestedPayload(listPath, []) } : { pass: list(witness), fail: list(violator) };
|
|
377
|
-
}
|
|
378
|
-
if (Array.isArray(guard[1])) {
|
|
379
|
-
const items = guard[1];
|
|
380
|
-
const per = items.map((item) => {
|
|
381
|
-
const sub = substituteVar(body, name, (p) => readLiteralPath(item, p));
|
|
382
|
-
return { truth: constTruth(sub), built: buildGuardPayloads(sub) };
|
|
383
|
-
});
|
|
384
|
-
const mergeAll = (pick, skip) => per.reduce((acc, x) => x.truth === skip ? acc : mergePayloads(acc, pick(x.built)), {});
|
|
385
|
-
const firstWhere = (ok, pick) => {
|
|
386
|
-
const hit = per.find((x) => ok(x.truth));
|
|
387
|
-
return hit ? pick(hit.built) : {};
|
|
388
|
-
};
|
|
389
|
-
return some ? {
|
|
390
|
-
pass: per.some((x) => x.truth === true) ? {} : firstWhere((t) => t !== false, (b) => b.pass),
|
|
391
|
-
fail: mergeAll((b) => b.fail, true)
|
|
392
|
-
} : {
|
|
393
|
-
pass: mergeAll((b) => b.pass, true),
|
|
394
|
-
fail: per.some((x) => x.truth === false) ? {} : firstWhere((t) => t !== true, (b) => b.fail)
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
return null;
|
|
398
|
-
}
|
|
399
|
-
function buildGridInBoundsPayloads(guard) {
|
|
400
|
-
const pos = guard[1];
|
|
401
|
-
const w = guard[2];
|
|
402
|
-
const h = guard[3];
|
|
403
|
-
const emptyGrid = typeof w === "number" && w <= 0 || typeof h === "number" && h <= 0;
|
|
404
|
-
const posPath = extractPayloadFieldPath(pos);
|
|
405
|
-
if (posPath) {
|
|
406
|
-
return {
|
|
407
|
-
pass: emptyGrid ? {} : nestedPayload(posPath, { x: 0, y: 0 }),
|
|
408
|
-
fail: nestedPayload(posPath, { x: -1, y: 0 })
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
if (!isPlainRecord(pos)) return null;
|
|
412
|
-
const axes = ["x", "y"].map((k) => ({ k, path: extractPayloadFieldPath(pos[k]) }));
|
|
413
|
-
const steered = axes.filter((a) => a.path !== null);
|
|
414
|
-
if (steered.length === 0) return null;
|
|
415
|
-
const pass = emptyGrid ? {} : steered.reduce((acc, a) => mergePayloads(acc, nestedPayload(a.path, 0)), {});
|
|
416
|
-
return { pass, fail: nestedPayload(steered[0].path, -1) };
|
|
417
|
-
}
|
|
418
|
-
function buildGuardPayloads(guard) {
|
|
419
|
-
if (constTruth(guard) !== null) {
|
|
420
|
-
return { pass: {}, fail: {} };
|
|
421
|
-
}
|
|
422
|
-
if (Array.isArray(guard) && typeof guard[0] === "string" && CONSTANT_GUARD_FORMS.has(guard[0])) {
|
|
423
|
-
return { pass: {}, fail: {} };
|
|
424
|
-
}
|
|
425
|
-
if (typeof guard === "string") {
|
|
426
|
-
const path = extractPayloadFieldPath(guard);
|
|
427
|
-
if (path) {
|
|
428
|
-
return path.length === 1 ? { pass: { [path[0]]: { id: "mock-test-id", name: "mock-test-name" } }, fail: { [path[0]]: null } } : { pass: nestedPayload(path, "mock-test-value"), fail: nestedPayload(path, null) };
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
if (!Array.isArray(guard) || guard.length === 0) {
|
|
432
|
-
return { pass: {}, fail: {} };
|
|
433
|
-
}
|
|
434
|
-
const op = String(guard[0]);
|
|
435
|
-
if (op === "not-nil" || op === "not_nil") {
|
|
436
|
-
const path = extractPayloadFieldPath(guard[1]);
|
|
437
|
-
if (path) return { pass: nestedPayload(path, "mock-test-value"), fail: nestedPayload(path, null) };
|
|
438
|
-
}
|
|
439
|
-
if (op === "nil") {
|
|
440
|
-
const path = extractPayloadFieldPath(guard[1]);
|
|
441
|
-
if (path) return { pass: {}, fail: nestedPayload(path, "mock-test-value") };
|
|
442
|
-
}
|
|
443
|
-
if (op === "eq" || op === "==" || op === "=" || op === "not-eq" || op === "!=" || op === "neq") {
|
|
444
|
-
const arrayPath = extractArrayLenPath(guard[1]);
|
|
445
|
-
if (arrayPath && typeof guard[2] === "number") {
|
|
446
|
-
const n = guard[2];
|
|
447
|
-
const equal = { hit: nestedPayload(arrayPath, arrayOfLength(n)), miss: nestedPayload(arrayPath, arrayOfLength(n + 1)) };
|
|
448
|
-
return op === "eq" || op === "==" || op === "=" ? { pass: equal.hit, fail: equal.miss } : { pass: equal.miss, fail: equal.hit };
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
if (op === "eq" || op === "==" || op === "=") {
|
|
452
|
-
const compared = payloadComparison(guard[1], guard[2]);
|
|
453
|
-
if (compared) {
|
|
454
|
-
const { path, val } = compared;
|
|
455
|
-
const failVal = typeof val === "number" ? val + 1 : typeof val === "string" ? `not-${val}` : null;
|
|
456
|
-
return { pass: nestedPayload(path, val), fail: nestedPayload(path, failVal) };
|
|
457
|
-
}
|
|
458
|
-
const objectGetPayload = buildObjectGetComparisonPayload(guard[1], guard[2], false);
|
|
459
|
-
if (objectGetPayload) return objectGetPayload;
|
|
460
|
-
}
|
|
461
|
-
if (op === "not-eq" || op === "!=" || op === "neq") {
|
|
462
|
-
const compared = payloadComparison(guard[1], guard[2]);
|
|
463
|
-
if (compared) {
|
|
464
|
-
const { path, val } = compared;
|
|
465
|
-
const passVal = typeof val === "number" ? val + 1 : typeof val === "string" ? `not-${val}` : "other";
|
|
466
|
-
return { pass: nestedPayload(path, passVal), fail: nestedPayload(path, val) };
|
|
467
|
-
}
|
|
468
|
-
const objectGetPayload = buildObjectGetComparisonPayload(guard[1], guard[2], true);
|
|
469
|
-
if (objectGetPayload) return objectGetPayload;
|
|
470
|
-
}
|
|
471
|
-
if (op === "gt" || op === ">") {
|
|
472
|
-
const arrayPath = extractArrayLenPath(guard[1]);
|
|
473
|
-
const n = typeof guard[2] === "number" ? guard[2] : 0;
|
|
474
|
-
if (arrayPath) return { pass: nestedPayload(arrayPath, arrayOfLength(n + 1)), fail: nestedPayload(arrayPath, arrayOfLength(n)) };
|
|
475
|
-
const path = extractPayloadFieldPath(guard[1]);
|
|
476
|
-
if (path) return { pass: nestedPayload(path, n + 1), fail: nestedPayload(path, n - 1) };
|
|
477
|
-
}
|
|
478
|
-
if (op === "gte" || op === ">=") {
|
|
479
|
-
const arrayPath = extractArrayLenPath(guard[1]);
|
|
480
|
-
const n = typeof guard[2] === "number" ? guard[2] : 0;
|
|
481
|
-
if (arrayPath) return { pass: nestedPayload(arrayPath, arrayOfLength(n)), fail: nestedPayload(arrayPath, arrayOfLength(n - 1)) };
|
|
482
|
-
const path = extractPayloadFieldPath(guard[1]);
|
|
483
|
-
if (path) return { pass: nestedPayload(path, n), fail: nestedPayload(path, n - 1) };
|
|
484
|
-
}
|
|
485
|
-
if (op === "lt" || op === "<") {
|
|
486
|
-
const arrayPath = extractArrayLenPath(guard[1]);
|
|
487
|
-
const n = typeof guard[2] === "number" ? guard[2] : 0;
|
|
488
|
-
if (arrayPath) return { pass: nestedPayload(arrayPath, arrayOfLength(n - 1)), fail: nestedPayload(arrayPath, arrayOfLength(n + 1)) };
|
|
489
|
-
const path = extractPayloadFieldPath(guard[1]);
|
|
490
|
-
if (path) return { pass: nestedPayload(path, n - 1), fail: nestedPayload(path, n + 1) };
|
|
491
|
-
}
|
|
492
|
-
if (op === "lte" || op === "<=") {
|
|
493
|
-
const arrayPath = extractArrayLenPath(guard[1]);
|
|
494
|
-
const n = typeof guard[2] === "number" ? guard[2] : 0;
|
|
495
|
-
if (arrayPath) return { pass: nestedPayload(arrayPath, arrayOfLength(n)), fail: nestedPayload(arrayPath, arrayOfLength(n + 1)) };
|
|
496
|
-
const path = extractPayloadFieldPath(guard[1]);
|
|
497
|
-
if (path) return { pass: nestedPayload(path, n), fail: nestedPayload(path, n + 1) };
|
|
498
|
-
}
|
|
499
|
-
if (op === "and") {
|
|
500
|
-
const subs = guard.slice(1);
|
|
501
|
-
if (subs.length >= 2) {
|
|
502
|
-
const built = subs.map(buildGuardPayloads);
|
|
503
|
-
const merged = built.reduce((acc, b) => mergePayloads(acc, b.pass), {});
|
|
504
|
-
const pass = applyFieldIntersections(subs, merged);
|
|
505
|
-
const canFail = subs.findIndex((g) => constTruth(g) !== true);
|
|
506
|
-
return { pass, fail: built[canFail >= 0 ? canFail : 0].fail };
|
|
507
|
-
}
|
|
508
|
-
if (subs.length === 1) return buildGuardPayloads(subs[0]);
|
|
509
|
-
}
|
|
510
|
-
if (op === "or") {
|
|
511
|
-
const subs = guard.slice(1);
|
|
512
|
-
if (subs.length >= 2) {
|
|
513
|
-
const s1 = buildGuardPayloads(subs[0]);
|
|
514
|
-
const s2 = buildGuardPayloads(subs[1]);
|
|
515
|
-
const combinedPass = Object.keys(s1.pass).length > 0 ? s1.pass : s2.pass;
|
|
516
|
-
return { pass: combinedPass, fail: mergePayloads(s1.fail, s2.fail) };
|
|
517
|
-
}
|
|
518
|
-
if (subs.length === 1) return buildGuardPayloads(subs[0]);
|
|
519
|
-
}
|
|
520
|
-
if (op === "let") {
|
|
521
|
-
const r = buildLetPayloads(guard);
|
|
522
|
-
if (r) return r;
|
|
523
|
-
}
|
|
524
|
-
if (op === "if") {
|
|
525
|
-
const r = buildIfPayloads(guard);
|
|
526
|
-
if (r) return r;
|
|
527
|
-
}
|
|
528
|
-
if (op === "array/some" || op === "array/every") {
|
|
529
|
-
const r = buildQuantifierPayloads(op, guard);
|
|
530
|
-
if (r) return r;
|
|
531
|
-
}
|
|
532
|
-
if (op === "grid/in-bounds") {
|
|
533
|
-
const r = buildGridInBoundsPayloads(guard);
|
|
534
|
-
if (r) return r;
|
|
535
|
-
}
|
|
536
|
-
if (op === "not") {
|
|
537
|
-
const inner = buildGuardPayloads(guard[1]);
|
|
538
|
-
return { pass: inner.fail, fail: inner.pass };
|
|
539
|
-
}
|
|
540
|
-
if (op === "object/has") {
|
|
541
|
-
const split = splitPayloadArg(guard[1], guard[2]);
|
|
542
|
-
if (split && isPlainRecord(split.collection)) {
|
|
543
|
-
const keys = Object.keys(split.collection);
|
|
544
|
-
if (keys.length > 0) {
|
|
545
|
-
return { pass: nestedPayload(split.path, keys[0]), fail: nestedPayload(split.path, absentKey(keys)) };
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
if (op === "object/get") {
|
|
550
|
-
const split = splitPayloadArg(guard[1], guard[2]);
|
|
551
|
-
if (split && isPlainRecord(split.collection)) {
|
|
552
|
-
const map = split.collection;
|
|
553
|
-
const keys = Object.keys(map);
|
|
554
|
-
const passKey = keys.find((k) => Boolean(map[k]));
|
|
555
|
-
if (passKey !== void 0) {
|
|
556
|
-
return { pass: nestedPayload(split.path, passKey), fail: nestedPayload(split.path, absentKey(keys)) };
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
if (op === "array/includes") {
|
|
561
|
-
const split = splitPayloadArg(guard[1], guard[2]);
|
|
562
|
-
if (split && Array.isArray(split.collection) && split.collection.length > 0) {
|
|
563
|
-
const passVal = split.collection[0];
|
|
564
|
-
const failVal = typeof passVal === "string" ? `${passVal}-not-in-list` : "not-in-list";
|
|
565
|
-
return { pass: nestedPayload(split.path, passVal), fail: nestedPayload(split.path, failVal) };
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
if (op === "str/startsWith") {
|
|
569
|
-
const path = extractPayloadFieldPath(guard[1]);
|
|
570
|
-
const prefix = typeof guard[2] === "string" ? guard[2] : "";
|
|
571
|
-
if (path) {
|
|
572
|
-
return {
|
|
573
|
-
pass: nestedPayload(path, `${prefix}mock-suffix`),
|
|
574
|
-
fail: nestedPayload(path, prefix.length > 0 ? `not-${prefix}` : "mock-test-value")
|
|
575
|
-
};
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
if (op === "validate/url") {
|
|
579
|
-
const path = extractPayloadFieldPath(guard[1]);
|
|
580
|
-
if (path) {
|
|
581
|
-
return { pass: nestedPayload(path, "https://example.test/mock"), fail: nestedPayload(path, "not-a-url") };
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
if (op === "validate/required") {
|
|
585
|
-
const path = extractPayloadFieldPath(guard[1]);
|
|
586
|
-
if (path) {
|
|
587
|
-
return { pass: nestedPayload(path, "mock-required-value"), fail: nestedPayload(path, "") };
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
if (op === "agent/is-pinned") {
|
|
591
|
-
const field = extractPayloadFieldRef(guard[1]);
|
|
592
|
-
if (field) return { pass: { [field]: "mem_test_unpinned" }, fail: { [field]: "mem_test_pinned" } };
|
|
593
|
-
}
|
|
594
|
-
if (op === "agent/memory-strength") {
|
|
595
|
-
const field = extractPayloadFieldRef(guard[1]);
|
|
596
|
-
if (field) return { pass: { [field]: "mem_test_id" }, fail: { [field]: "mem_nonexistent" } };
|
|
597
|
-
}
|
|
598
|
-
if (op.startsWith("agent/")) {
|
|
599
|
-
return { pass: {}, fail: {} };
|
|
600
|
-
}
|
|
601
|
-
if (!isRecognizedGuardOperator(op)) {
|
|
602
|
-
recordUnhandledOperator(op);
|
|
603
|
-
}
|
|
604
|
-
return { pass: {}, fail: {} };
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// src/state-machine/replay-paths.ts
|
|
608
|
-
var ENTITY_PAYLOAD_FIELDS = /* @__PURE__ */ new Set(["data", "row", "item", "id"]);
|
|
609
|
-
function buildReplayPaths(transitions, initialState, maxDepth = 3) {
|
|
610
|
-
const queue = [{ state: initialState, path: [] }];
|
|
611
|
-
const replayPaths = /* @__PURE__ */ new Map();
|
|
612
|
-
replayPaths.set(initialState, []);
|
|
613
|
-
while (queue.length > 0) {
|
|
614
|
-
const { state, path } = queue.shift();
|
|
615
|
-
if (path.length >= maxDepth) continue;
|
|
616
|
-
const fromHere = transitions.filter(
|
|
617
|
-
(t) => t.from === state && t.event !== "INIT"
|
|
618
|
-
);
|
|
619
|
-
for (const transition of fromHere) {
|
|
620
|
-
if (replayPaths.has(transition.to)) continue;
|
|
621
|
-
const renderEffect = transition.renderEffects.find((re) => re.patternType !== null);
|
|
622
|
-
const stepNeedsEntityData = transition.hasGuard || transition.payloadFields.some((f) => ENTITY_PAYLOAD_FIELDS.has(f));
|
|
623
|
-
const step = {
|
|
624
|
-
event: transition.event,
|
|
625
|
-
fromState: state,
|
|
626
|
-
toState: transition.to,
|
|
627
|
-
slot: renderEffect?.slot ?? "main",
|
|
628
|
-
expectedPattern: renderEffect?.patternType ?? void 0,
|
|
629
|
-
needsEntityData: stepNeedsEntityData,
|
|
630
|
-
payloadSchema: transition.payloadSchema.length > 0 ? transition.payloadSchema : void 0
|
|
631
|
-
};
|
|
632
|
-
const newPath = [...path, step];
|
|
633
|
-
replayPaths.set(transition.to, newPath);
|
|
634
|
-
queue.push({ state: transition.to, path: newPath });
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
return replayPaths;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
// src/state-machine/edge-walk.ts
|
|
641
|
-
function buildEdgeCoveringWalk(transitions, initialState) {
|
|
642
|
-
const filtered = transitions.filter(
|
|
643
|
-
(t) => t.from !== "*" && !(t.event === "INIT" && t.from === initialState)
|
|
644
|
-
);
|
|
645
|
-
const graph = /* @__PURE__ */ new Map();
|
|
646
|
-
const allStates = /* @__PURE__ */ new Set();
|
|
647
|
-
for (const t of filtered) {
|
|
648
|
-
allStates.add(t.from);
|
|
649
|
-
allStates.add(t.to);
|
|
650
|
-
if (!graph.has(t.from)) graph.set(t.from, []);
|
|
651
|
-
graph.get(t.from).push({ event: t.event, to: t.to, transition: t });
|
|
652
|
-
}
|
|
653
|
-
allStates.add(initialState);
|
|
654
|
-
const uncovered = /* @__PURE__ */ new Set();
|
|
655
|
-
const edgeMeta = /* @__PURE__ */ new Map();
|
|
656
|
-
for (const t of filtered) {
|
|
657
|
-
if (t.hasGuard) {
|
|
658
|
-
const keyPass = `${t.from}+${t.event}->${t.to}[pass]`;
|
|
659
|
-
const keyFail = `${t.from}+${t.event}->${t.to}[fail]`;
|
|
660
|
-
uncovered.add(keyPass);
|
|
661
|
-
uncovered.add(keyFail);
|
|
662
|
-
edgeMeta.set(keyPass, { transition: t, guardCase: "pass" });
|
|
663
|
-
edgeMeta.set(keyFail, { transition: t, guardCase: "fail" });
|
|
664
|
-
} else {
|
|
665
|
-
const key = `${t.from}+${t.event}->${t.to}`;
|
|
666
|
-
uncovered.add(key);
|
|
667
|
-
edgeMeta.set(key, { transition: t, guardCase: null });
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
if (uncovered.size === 0) return [];
|
|
671
|
-
const shortestPaths = /* @__PURE__ */ new Map();
|
|
672
|
-
for (const state of allStates) {
|
|
673
|
-
shortestPaths.set(state, bfsShortestPaths(state, graph));
|
|
674
|
-
}
|
|
675
|
-
const walk = [];
|
|
676
|
-
let currentState = initialState;
|
|
677
|
-
const maxIterations = uncovered.size * allStates.size * 2;
|
|
678
|
-
let iterations = 0;
|
|
679
|
-
while (uncovered.size > 0 && iterations < maxIterations) {
|
|
680
|
-
iterations++;
|
|
681
|
-
const outgoing = findUncoveredEdges(currentState, graph, uncovered);
|
|
682
|
-
if (outgoing.length > 0) {
|
|
683
|
-
const pick = outgoing[0];
|
|
684
|
-
const payload = buildPayloadForEdge(pick.transition, pick.guardCase);
|
|
685
|
-
walk.push({
|
|
686
|
-
from: currentState,
|
|
687
|
-
event: pick.transition.event,
|
|
688
|
-
to: pick.transition.to,
|
|
689
|
-
guardCase: pick.guardCase,
|
|
690
|
-
payload,
|
|
691
|
-
isRepositioning: false
|
|
692
|
-
});
|
|
693
|
-
uncovered.delete(pick.key);
|
|
694
|
-
if (pick.guardCase !== "fail") {
|
|
695
|
-
currentState = pick.transition.to;
|
|
696
|
-
}
|
|
697
|
-
} else {
|
|
698
|
-
const target = findNearestUncoveredState(currentState, graph, uncovered, shortestPaths);
|
|
699
|
-
if (!target) {
|
|
700
|
-
break;
|
|
701
|
-
}
|
|
702
|
-
const repoPath = shortestPaths.get(currentState)?.get(target);
|
|
703
|
-
if (!repoPath || repoPath.length === 0) break;
|
|
704
|
-
for (const step of repoPath) {
|
|
705
|
-
walk.push({
|
|
706
|
-
from: currentState,
|
|
707
|
-
event: step.event,
|
|
708
|
-
to: step.to,
|
|
709
|
-
guardCase: null,
|
|
710
|
-
payload: {},
|
|
711
|
-
isRepositioning: true
|
|
712
|
-
});
|
|
713
|
-
currentState = step.to;
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
return walk;
|
|
718
|
-
}
|
|
719
|
-
function bfsShortestPaths(source, graph) {
|
|
720
|
-
const paths = /* @__PURE__ */ new Map();
|
|
721
|
-
const visited = /* @__PURE__ */ new Set([source]);
|
|
722
|
-
const queue = [
|
|
723
|
-
{ state: source, path: [] }
|
|
724
|
-
];
|
|
725
|
-
while (queue.length > 0) {
|
|
726
|
-
const { state, path } = queue.shift();
|
|
727
|
-
const edges = graph.get(state) ?? [];
|
|
728
|
-
for (const edge of edges) {
|
|
729
|
-
if (visited.has(edge.to)) continue;
|
|
730
|
-
visited.add(edge.to);
|
|
731
|
-
const newPath = [...path, { event: edge.event, to: edge.to }];
|
|
732
|
-
paths.set(edge.to, newPath);
|
|
733
|
-
queue.push({ state: edge.to, path: newPath });
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
return paths;
|
|
737
|
-
}
|
|
738
|
-
function findUncoveredEdges(state, graph, uncovered) {
|
|
739
|
-
const edges = graph.get(state) ?? [];
|
|
740
|
-
const result = [];
|
|
741
|
-
for (const edge of edges) {
|
|
742
|
-
if (edge.transition.hasGuard) {
|
|
743
|
-
const keyPass = `${state}+${edge.event}->${edge.to}[pass]`;
|
|
744
|
-
const keyFail = `${state}+${edge.event}->${edge.to}[fail]`;
|
|
745
|
-
if (uncovered.has(keyPass)) {
|
|
746
|
-
result.push({ key: keyPass, transition: edge.transition, guardCase: "pass" });
|
|
747
|
-
}
|
|
748
|
-
if (uncovered.has(keyFail)) {
|
|
749
|
-
result.push({ key: keyFail, transition: edge.transition, guardCase: "fail" });
|
|
750
|
-
}
|
|
751
|
-
} else {
|
|
752
|
-
const key = `${state}+${edge.event}->${edge.to}`;
|
|
753
|
-
if (uncovered.has(key)) {
|
|
754
|
-
result.push({ key, transition: edge.transition, guardCase: null });
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
return result;
|
|
759
|
-
}
|
|
760
|
-
function findNearestUncoveredState(currentState, graph, uncovered, shortestPaths) {
|
|
761
|
-
const statesWithUncovered = /* @__PURE__ */ new Set();
|
|
762
|
-
for (const key of uncovered) {
|
|
763
|
-
const fromState = key.split("+")[0];
|
|
764
|
-
statesWithUncovered.add(fromState);
|
|
765
|
-
}
|
|
766
|
-
if (statesWithUncovered.has(currentState)) return currentState;
|
|
767
|
-
const paths = shortestPaths.get(currentState);
|
|
768
|
-
if (!paths) return null;
|
|
769
|
-
let nearestState = null;
|
|
770
|
-
let nearestDist = Infinity;
|
|
771
|
-
for (const target of statesWithUncovered) {
|
|
772
|
-
const path = paths.get(target);
|
|
773
|
-
if (path && path.length < nearestDist) {
|
|
774
|
-
nearestDist = path.length;
|
|
775
|
-
nearestState = target;
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
return nearestState;
|
|
779
|
-
}
|
|
780
|
-
function buildPayloadForEdge(transition, guardCase) {
|
|
781
|
-
if (transition.hasGuard && transition.guard && guardCase) {
|
|
782
|
-
const payloads = buildGuardPayloads(transition.guard);
|
|
783
|
-
return guardCase === "pass" ? payloads.pass : payloads.fail;
|
|
784
|
-
}
|
|
785
|
-
if (transition.payloadSchema && transition.payloadSchema.length > 0) {
|
|
786
|
-
const payload = {};
|
|
787
|
-
for (const field of transition.payloadSchema) {
|
|
788
|
-
if (field.mockValue !== void 0) {
|
|
789
|
-
payload[field.name] = field.mockValue;
|
|
790
|
-
} else if (field.type === "string") {
|
|
791
|
-
payload[field.name] = `mock-${field.name}`;
|
|
792
|
-
} else if (field.type === "number") {
|
|
793
|
-
payload[field.name] = 1;
|
|
794
|
-
} else if (field.type === "boolean") {
|
|
795
|
-
payload[field.name] = true;
|
|
796
|
-
} else if (field.type === "object" || field.type === "any") {
|
|
797
|
-
payload[field.name] = {};
|
|
798
|
-
} else {
|
|
799
|
-
payload[field.name] = `mock-${field.name}`;
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
return payload;
|
|
803
|
-
}
|
|
804
|
-
return {};
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
export { buildEdgeCoveringWalk, buildGuardPayloads, buildReplayPaths, buildStateGraph, collectReachableStates, constTruth, extractPayloadFieldPath, extractPayloadFieldRef, walkStatePairs };
|
|
808
|
-
//# sourceMappingURL=chunk-GIUA3NUJ.js.map
|
|
809
|
-
//# sourceMappingURL=chunk-GIUA3NUJ.js.map
|