@proophboard/exploration-runtime 0.0.0-stage → 0.1.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/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/connectionRules.d.ts +39 -0
- package/dist/lib/connectionRules.d.ts.map +1 -0
- package/dist/lib/connectionRules.js +475 -0
- package/dist/lib/connectionRules.js.map +1 -0
- package/dist/lib/toClassName.d.ts +42 -0
- package/dist/lib/toClassName.d.ts.map +1 -0
- package/dist/lib/toClassName.js +82 -0
- package/dist/lib/toClassName.js.map +1 -0
- package/dist/playFunction/ambientTypes.d.ts +30 -0
- package/dist/playFunction/ambientTypes.d.ts.map +1 -0
- package/dist/playFunction/ambientTypes.js +174 -0
- package/dist/playFunction/ambientTypes.js.map +1 -0
- package/dist/playFunction/cascadeBudget.d.ts +53 -0
- package/dist/playFunction/cascadeBudget.d.ts.map +1 -0
- package/dist/playFunction/cascadeBudget.js +74 -0
- package/dist/playFunction/cascadeBudget.js.map +1 -0
- package/dist/playFunction/clock.d.ts +58 -0
- package/dist/playFunction/clock.d.ts.map +1 -0
- package/dist/playFunction/clock.js +104 -0
- package/dist/playFunction/clock.js.map +1 -0
- package/dist/playFunction/modelTypes.d.ts +74 -0
- package/dist/playFunction/modelTypes.d.ts.map +1 -0
- package/dist/playFunction/modelTypes.js +345 -0
- package/dist/playFunction/modelTypes.js.map +1 -0
- package/dist/playFunction/playLog.d.ts +29 -0
- package/dist/playFunction/playLog.d.ts.map +1 -0
- package/dist/playFunction/playLog.js +64 -0
- package/dist/playFunction/playLog.js.map +1 -0
- package/dist/playFunction/playType.d.ts +52 -0
- package/dist/playFunction/playType.d.ts.map +1 -0
- package/dist/playFunction/playType.js +94 -0
- package/dist/playFunction/playType.js.map +1 -0
- package/dist/playFunction/runtimeFold.d.ts +51 -0
- package/dist/playFunction/runtimeFold.d.ts.map +1 -0
- package/dist/playFunction/runtimeFold.js +620 -0
- package/dist/playFunction/runtimeFold.js.map +1 -0
- package/dist/playFunction/runtimeSteps.d.ts +45 -0
- package/dist/playFunction/runtimeSteps.d.ts.map +1 -0
- package/dist/playFunction/runtimeSteps.js +112 -0
- package/dist/playFunction/runtimeSteps.js.map +1 -0
- package/dist/playFunction/sandbox.d.ts +52 -0
- package/dist/playFunction/sandbox.d.ts.map +1 -0
- package/dist/playFunction/sandbox.js +91 -0
- package/dist/playFunction/sandbox.js.map +1 -0
- package/dist/playFunction/scenarioRunner.d.ts +49 -0
- package/dist/playFunction/scenarioRunner.d.ts.map +1 -0
- package/dist/playFunction/scenarioRunner.js +331 -0
- package/dist/playFunction/scenarioRunner.js.map +1 -0
- package/dist/playFunction/transpile.d.ts +33 -0
- package/dist/playFunction/transpile.d.ts.map +1 -0
- package/dist/playFunction/transpile.js +71 -0
- package/dist/playFunction/transpile.js.map +1 -0
- package/dist/types/eventModel.d.ts +79 -0
- package/dist/types/eventModel.d.ts.map +1 -0
- package/dist/types/eventModel.js +12 -0
- package/dist/types/eventModel.js.map +1 -0
- package/dist/types/exploration.d.ts +143 -0
- package/dist/types/exploration.d.ts.map +1 -0
- package/dist/types/exploration.js +28 -0
- package/dist/types/exploration.js.map +1 -0
- package/package.json +48 -4
- package/README.md +0 -3
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scenarioRunner — the pure Exploration "scenarios as tests" oracle (M5).
|
|
3
|
+
*
|
|
4
|
+
* A scenario becomes a recorded test by carrying pinned `expectations`
|
|
5
|
+
* (requirements R29/R30/R34). This module replays the scenario ONCE at the final
|
|
6
|
+
* playhead via the pure `foldChapter`, then resolves each expectation by its
|
|
7
|
+
* stable `sliceId` (never a step index) and matches it against the fold result:
|
|
8
|
+
*
|
|
9
|
+
* - events → the events emitted by the pinned slice must match.
|
|
10
|
+
* - information → a specific Information instance's value (stored | read view)
|
|
11
|
+
* at the end of replay must match.
|
|
12
|
+
* - rejection → the pinned slice must produce a `rejected` runtime error
|
|
13
|
+
* (optionally matching a message) AND emit no events.
|
|
14
|
+
*
|
|
15
|
+
* The golden-master snapshot is deliberately NOT used — expectations are the sole
|
|
16
|
+
* correctness oracle (a chapter's flow may legitimately change; only the pins
|
|
17
|
+
* must hold). Verdict:
|
|
18
|
+
*
|
|
19
|
+
* pass — ≥1 expectation, all matched.
|
|
20
|
+
* broken — ≥1 expectation, at least one failed (mismatch OR structural: a
|
|
21
|
+
* dangling reference / handler threw / cascade exceeded at the pin).
|
|
22
|
+
* neutral — zero expectations (nothing asserted yet).
|
|
23
|
+
*
|
|
24
|
+
* This file is PURE and framework-free (no DOM/worker), so it is fully
|
|
25
|
+
* unit-testable — the same reason the fold lives in runtimeFold.ts. "Run all" is
|
|
26
|
+
* just `scenarios.map(runScenario)`.
|
|
27
|
+
*/
|
|
28
|
+
import { toImplicitScenario, } from '../types/exploration.js';
|
|
29
|
+
import { toClassName } from '../lib/toClassName.js';
|
|
30
|
+
import { deriveRuntimeSteps } from './runtimeSteps.js';
|
|
31
|
+
import { foldChapter } from './runtimeFold.js';
|
|
32
|
+
/** Deep structural equality for JSON-ish values (order-sensitive for arrays). */
|
|
33
|
+
function deepEqual(a, b) {
|
|
34
|
+
if (a === b)
|
|
35
|
+
return true;
|
|
36
|
+
if (typeof a !== typeof b)
|
|
37
|
+
return false;
|
|
38
|
+
if (a === null || b === null)
|
|
39
|
+
return a === b;
|
|
40
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
41
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)
|
|
42
|
+
return false;
|
|
43
|
+
return a.every((v, i) => deepEqual(v, b[i]));
|
|
44
|
+
}
|
|
45
|
+
if (typeof a === 'object') {
|
|
46
|
+
const ao = a;
|
|
47
|
+
const bo = b;
|
|
48
|
+
const ak = Object.keys(ao);
|
|
49
|
+
const bk = Object.keys(bo);
|
|
50
|
+
if (ak.length !== bk.length)
|
|
51
|
+
return false;
|
|
52
|
+
return ak.every((k) => Object.prototype.hasOwnProperty.call(bo, k) && deepEqual(ao[k], bo[k]));
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Subset match: every key/element in `expected` must be present and (recursively)
|
|
58
|
+
* subset-match in `actual`. Arrays: each expected element must subset-match the
|
|
59
|
+
* element at the SAME index in actual (actual may be longer). Scalars: deep-equal.
|
|
60
|
+
*/
|
|
61
|
+
function isSubset(expected, actual) {
|
|
62
|
+
if (expected === actual)
|
|
63
|
+
return true;
|
|
64
|
+
if (expected === null || expected === undefined)
|
|
65
|
+
return deepEqual(expected, actual);
|
|
66
|
+
if (Array.isArray(expected)) {
|
|
67
|
+
if (!Array.isArray(actual) || actual.length < expected.length)
|
|
68
|
+
return false;
|
|
69
|
+
return expected.every((e, i) => isSubset(e, actual[i]));
|
|
70
|
+
}
|
|
71
|
+
if (typeof expected === 'object') {
|
|
72
|
+
if (typeof actual !== 'object' || actual === null || Array.isArray(actual))
|
|
73
|
+
return false;
|
|
74
|
+
const eo = expected;
|
|
75
|
+
const ao = actual;
|
|
76
|
+
return Object.keys(eo).every((k) => Object.prototype.hasOwnProperty.call(ao, k) && isSubset(eo[k], ao[k]));
|
|
77
|
+
}
|
|
78
|
+
return deepEqual(expected, actual);
|
|
79
|
+
}
|
|
80
|
+
/** Apply the chosen match mode. */
|
|
81
|
+
function valueMatches(expected, actual, mode) {
|
|
82
|
+
return mode === 'exact' ? deepEqual(expected, actual) : isSubset(expected, actual);
|
|
83
|
+
}
|
|
84
|
+
/** The className-form state key (`Ctx.El`) for an Information element. */
|
|
85
|
+
function infoKey(el) {
|
|
86
|
+
return `${toClassName(el.context || 'App')}.${toClassName(el.name)}`;
|
|
87
|
+
}
|
|
88
|
+
/** Read a dotted `Ctx.El` key out of the (possibly nested) state tree. */
|
|
89
|
+
function readStateKey(state, key) {
|
|
90
|
+
const [ctx, el] = key.split('.');
|
|
91
|
+
const bucket = state[ctx];
|
|
92
|
+
if (bucket === null || typeof bucket !== 'object')
|
|
93
|
+
return undefined;
|
|
94
|
+
return bucket[el];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Evaluate a single expectation against the fold result. Pure; returns the
|
|
98
|
+
* per-expectation verdict. Resolution is by stable `sliceId` / `elementId`; if
|
|
99
|
+
* either no longer resolves in the chapter, the expectation is a dangling
|
|
100
|
+
* reference (⇒ broken), which is exactly the "the model moved under the test"
|
|
101
|
+
* signal we want to surface rather than silently pass.
|
|
102
|
+
*/
|
|
103
|
+
function evaluateExpectation(exp, chapter, result) {
|
|
104
|
+
const base = {
|
|
105
|
+
expectationId: exp.id,
|
|
106
|
+
sliceId: exp.sliceId,
|
|
107
|
+
kind: exp.kind,
|
|
108
|
+
elementId: exp.elementId,
|
|
109
|
+
matched: false,
|
|
110
|
+
};
|
|
111
|
+
// Dangling slice? The pinned slice no longer exists in the chapter.
|
|
112
|
+
const sliceExists = chapter.slices.some((s) => s.id === exp.sliceId);
|
|
113
|
+
if (!sliceExists) {
|
|
114
|
+
return {
|
|
115
|
+
...base,
|
|
116
|
+
failureKind: 'dangling-reference',
|
|
117
|
+
message: `Pinned slice ${exp.sliceId} no longer exists in the chapter.`,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// Structural error at the pinned slice (threw / cascade-exceeded) ⇒ broken,
|
|
121
|
+
// regardless of kind: the slice could not produce a trustworthy outcome.
|
|
122
|
+
const structuralAtSlice = result.errors.find((e) => e.sliceId === exp.sliceId && (e.kind === 'threw' || e.kind === 'cascade-exceeded'));
|
|
123
|
+
if (structuralAtSlice) {
|
|
124
|
+
return {
|
|
125
|
+
...base,
|
|
126
|
+
failureKind: structuralAtSlice.kind,
|
|
127
|
+
message: `${structuralAtSlice.kind === 'threw' ? 'A handler threw' : 'Cascade budget exceeded'} at the pinned slice: ${structuralAtSlice.message}`,
|
|
128
|
+
actual: structuralAtSlice,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const eventsFromSlice = result.events.filter((e) => e.sliceId === exp.sliceId);
|
|
132
|
+
if (exp.kind === 'events') {
|
|
133
|
+
const expected = exp.expected.events ?? [];
|
|
134
|
+
const mode = exp.match ?? 'exact';
|
|
135
|
+
const actual = eventsFromSlice.map((e) => ({ name: e.name, context: e.context, payload: e.payload }));
|
|
136
|
+
// Compare the ordered list by name/context, and payload per the match mode.
|
|
137
|
+
let matched = actual.length === expected.length || (mode === 'subset' && actual.length >= expected.length);
|
|
138
|
+
if (matched) {
|
|
139
|
+
matched = expected.every((exp_e, i) => {
|
|
140
|
+
const act = actual[i];
|
|
141
|
+
if (!act)
|
|
142
|
+
return false;
|
|
143
|
+
if (act.name !== exp_e.name)
|
|
144
|
+
return false;
|
|
145
|
+
if (exp_e.context && act.context !== exp_e.context)
|
|
146
|
+
return false;
|
|
147
|
+
if (exp_e.payload === undefined)
|
|
148
|
+
return true; // name/context-only pin
|
|
149
|
+
return valueMatches(exp_e.payload, act.payload, mode);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
...base,
|
|
154
|
+
matched,
|
|
155
|
+
failureKind: matched ? undefined : 'mismatch',
|
|
156
|
+
message: matched ? undefined : `Expected ${expected.length} event(s), the slice emitted ${actual.length}; names/payloads differ.`,
|
|
157
|
+
actual,
|
|
158
|
+
expected,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
if (exp.kind === 'information') {
|
|
162
|
+
const expInfo = exp.expected;
|
|
163
|
+
const mode = exp.match ?? 'subset';
|
|
164
|
+
// Resolve the Information element instance (by id) to compute its state key.
|
|
165
|
+
const el = exp.elementId ? chapter.elements.find((e) => e.id === exp.elementId) : undefined;
|
|
166
|
+
if (!el || el.type !== 'information') {
|
|
167
|
+
return {
|
|
168
|
+
...base,
|
|
169
|
+
failureKind: 'dangling-reference',
|
|
170
|
+
message: `Pinned Information element ${exp.elementId ?? '(none)'} no longer exists.`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
let actual;
|
|
174
|
+
if (expInfo.view === 'read') {
|
|
175
|
+
const view = result.readViews.find((v) => v.elementId === el.id);
|
|
176
|
+
actual = view?.view;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
actual = readStateKey(result.state, infoKey(el));
|
|
180
|
+
}
|
|
181
|
+
const matched = valueMatches(expInfo.value, actual, mode);
|
|
182
|
+
return {
|
|
183
|
+
...base,
|
|
184
|
+
matched,
|
|
185
|
+
failureKind: matched ? undefined : 'mismatch',
|
|
186
|
+
message: matched
|
|
187
|
+
? undefined
|
|
188
|
+
: `Information "${el.name}" (${expInfo.view}) does not match the pinned value (${mode}).`,
|
|
189
|
+
actual,
|
|
190
|
+
expected: expInfo.value,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
// kind === 'rejection'
|
|
194
|
+
{
|
|
195
|
+
const expRej = exp.expected;
|
|
196
|
+
const rejection = result.errors.find((e) => e.sliceId === exp.sliceId && e.kind === 'rejected');
|
|
197
|
+
if (!rejection) {
|
|
198
|
+
return {
|
|
199
|
+
...base,
|
|
200
|
+
failureKind: 'rejected-missing',
|
|
201
|
+
message: `Expected a rejection at this slice, but none occurred.`,
|
|
202
|
+
actual: eventsFromSlice.map((e) => e.name),
|
|
203
|
+
expected: expRej,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// A rejection must also mean NO events were emitted by the slice.
|
|
207
|
+
if (eventsFromSlice.length > 0) {
|
|
208
|
+
return {
|
|
209
|
+
...base,
|
|
210
|
+
failureKind: 'unexpected-events',
|
|
211
|
+
message: `Rejection expected, but the slice also emitted ${eventsFromSlice.length} event(s).`,
|
|
212
|
+
actual: eventsFromSlice.map((e) => e.name),
|
|
213
|
+
expected: expRej,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
// Optional message match (substring, case-insensitive).
|
|
217
|
+
if (expRej.message && !rejection.message.toLowerCase().includes(expRej.message.toLowerCase())) {
|
|
218
|
+
return {
|
|
219
|
+
...base,
|
|
220
|
+
failureKind: 'mismatch',
|
|
221
|
+
message: `Rejection message "${rejection.message}" does not contain "${expRej.message}".`,
|
|
222
|
+
actual: rejection.message,
|
|
223
|
+
expected: expRej.message,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return { ...base, matched: true, actual: rejection.message };
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Run one scenario as a test. Pure: `(chapter, scenario, handlers) → result`.
|
|
231
|
+
*
|
|
232
|
+
* `handlers` are pre-transpiled JS keyed by element id (same contract as the
|
|
233
|
+
* fold). Pass `{}` for the defaults-only path.
|
|
234
|
+
*
|
|
235
|
+
* Fold strategy:
|
|
236
|
+
* - events / rejection expectations → fold to the END (events accumulate; a
|
|
237
|
+
* rejection is an error that happened during that slice's execution regardless
|
|
238
|
+
* of later steps).
|
|
239
|
+
* - information expectations → fold to the step that CONTAINS the pinned slice,
|
|
240
|
+
* because state is cumulative: a value that was correct at step 2 may differ
|
|
241
|
+
* at step 5 due to later mutations. We want the state AT the pinned moment.
|
|
242
|
+
* Multiple information pins that share the same step index reuse one fold.
|
|
243
|
+
*/
|
|
244
|
+
export function runScenario(chapter, scenario, handlers = {}) {
|
|
245
|
+
const expectations = scenario.expectations ?? [];
|
|
246
|
+
const steps = deriveRuntimeSteps(chapter);
|
|
247
|
+
const implicitScenario = toImplicitScenario(scenario);
|
|
248
|
+
// ── Full-length fold (events + rejections) ─────────────────────────────
|
|
249
|
+
const fullPlayhead = Math.max(0, steps.length - 1);
|
|
250
|
+
const fullFold = foldChapter(chapter, implicitScenario, fullPlayhead, handlers, undefined, undefined, 'PlayWorker');
|
|
251
|
+
const fullFoldView = {
|
|
252
|
+
events: fullFold.events,
|
|
253
|
+
state: fullFold.state,
|
|
254
|
+
errors: fullFold.errors ?? [],
|
|
255
|
+
readViews: fullFold.readViews ?? [],
|
|
256
|
+
};
|
|
257
|
+
// ── Per-step folds for information expectations ─────────────────────────
|
|
258
|
+
// Build a map from stepIndex → fold result (lazy, deduplicated).
|
|
259
|
+
// stepIndex = index of the first step whose slice.id matches the pinned sliceId.
|
|
260
|
+
const stepFoldCache = new Map();
|
|
261
|
+
function foldAtStep(stepIndex) {
|
|
262
|
+
const cached = stepFoldCache.get(stepIndex);
|
|
263
|
+
if (cached)
|
|
264
|
+
return cached;
|
|
265
|
+
const fold = foldChapter(chapter, implicitScenario, stepIndex, handlers, undefined, undefined, 'PlayWorker');
|
|
266
|
+
const view = {
|
|
267
|
+
events: fold.events,
|
|
268
|
+
state: fold.state,
|
|
269
|
+
errors: fold.errors ?? [],
|
|
270
|
+
readViews: fold.readViews ?? [],
|
|
271
|
+
};
|
|
272
|
+
stepFoldCache.set(stepIndex, view);
|
|
273
|
+
return view;
|
|
274
|
+
}
|
|
275
|
+
// ── Evaluate each expectation ───────────────────────────────────────────
|
|
276
|
+
const expectationResults = expectations.map((exp) => {
|
|
277
|
+
if (exp.kind === 'information') {
|
|
278
|
+
// Find the step index at or just before the pinned slice.
|
|
279
|
+
// Read slices (pure Information, no UI/automation) don't produce steps,
|
|
280
|
+
// so we must find the last step whose slice appears at or before the pinned
|
|
281
|
+
// slice in the chapter's slice order.
|
|
282
|
+
const sliceOrder = new Map(chapter.slices.map((s, i) => [s.id, i]));
|
|
283
|
+
const pinnedSliceOrder = sliceOrder.get(exp.sliceId);
|
|
284
|
+
if (pinnedSliceOrder === undefined) {
|
|
285
|
+
// Slice gone — dangling reference, let evaluateExpectation handle it.
|
|
286
|
+
return evaluateExpectation(exp, chapter, fullFoldView);
|
|
287
|
+
}
|
|
288
|
+
// Find the last step whose slice is at or before the pinned slice's position.
|
|
289
|
+
let stepIndex = -1;
|
|
290
|
+
for (let i = steps.length - 1; i >= 0; i--) {
|
|
291
|
+
const stepSliceOrder = sliceOrder.get(steps[i].slice.id) ?? Infinity;
|
|
292
|
+
if (stepSliceOrder <= pinnedSliceOrder) {
|
|
293
|
+
stepIndex = i;
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (stepIndex === -1) {
|
|
298
|
+
// No steps at or before the pinned slice — fold to the start (step 0).
|
|
299
|
+
stepIndex = 0;
|
|
300
|
+
}
|
|
301
|
+
return evaluateExpectation(exp, chapter, foldAtStep(stepIndex));
|
|
302
|
+
}
|
|
303
|
+
// events + rejection: use the full-length fold.
|
|
304
|
+
return evaluateExpectation(exp, chapter, fullFoldView);
|
|
305
|
+
});
|
|
306
|
+
// Structural errors not already surfaced by an expectation (for repair context).
|
|
307
|
+
const pinnedSlices = new Set(expectations.map((e) => e.sliceId));
|
|
308
|
+
const structuralErrors = fullFoldView.errors.filter((e) => (e.kind === 'threw' || e.kind === 'cascade-exceeded') && !pinnedSlices.has(e.sliceId ?? ''));
|
|
309
|
+
let status;
|
|
310
|
+
if (expectations.length === 0) {
|
|
311
|
+
status = 'neutral';
|
|
312
|
+
}
|
|
313
|
+
else if (expectationResults.every((r) => r.matched)) {
|
|
314
|
+
status = 'pass';
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
status = 'broken';
|
|
318
|
+
}
|
|
319
|
+
return {
|
|
320
|
+
scenarioId: scenario.id,
|
|
321
|
+
scenarioName: scenario.name,
|
|
322
|
+
status,
|
|
323
|
+
expectationResults,
|
|
324
|
+
structuralErrors,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/** Run every scenario in a chapter (the chapter-level "Run all"). */
|
|
328
|
+
export function runAllScenarios(chapter, scenarios, handlers = {}) {
|
|
329
|
+
return scenarios.map((s) => runScenario(chapter, s, handlers));
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=scenarioRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenarioRunner.js","sourceRoot":"","sources":["../../src/playFunction/scenarioRunner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* transpile — lazy TS → JS type-erasure for Play Functions (Exploration R18).
|
|
3
|
+
*
|
|
4
|
+
* Handlers are authored and stored as TypeScript (verbatim). Browsers can't run
|
|
5
|
+
* TS, so before execution the type annotations are stripped to plain JS. We use
|
|
6
|
+
* `sucrase` with the `typescript` transform only (no bundling, no type-checking —
|
|
7
|
+
* pure syntactic erasure), which is the smallest/fastest option for this job.
|
|
8
|
+
*
|
|
9
|
+
* `sucrase` is loaded LAZILY (dynamic import) so it only enters the bundle with
|
|
10
|
+
* the Play Function runtime chunk, keeping M1–M3 (defaults-only) unaffected.
|
|
11
|
+
*
|
|
12
|
+
* Results are cached per source string: the same handler text transpiles once per
|
|
13
|
+
* session. The fold may transpile many handlers across replays/scrubs, so the
|
|
14
|
+
* cache matters.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Transpile a Play Function's TypeScript source to JavaScript (type-erasure).
|
|
18
|
+
* Cached per exact source string. Throws if sucrase fails to parse (surfaced to
|
|
19
|
+
* the caller as a handler error).
|
|
20
|
+
*/
|
|
21
|
+
export declare function transpilePlayFunction(source: string): Promise<string>;
|
|
22
|
+
/**
|
|
23
|
+
* Synchronous cache read — returns the transpiled JS if this source has already
|
|
24
|
+
* been transpiled this session, else null. Lets the fold stay synchronous once
|
|
25
|
+
* all handlers in play have been pre-transpiled (the worker pre-warms the cache
|
|
26
|
+
* before folding).
|
|
27
|
+
*/
|
|
28
|
+
export declare function getTranspiledSync(source: string): string | null;
|
|
29
|
+
/** Pre-transpile a batch of sources (used to pre-warm before a synchronous fold). */
|
|
30
|
+
export declare function pretranspile(sources: Iterable<string>): Promise<void>;
|
|
31
|
+
/** Test seam: clear the cache. */
|
|
32
|
+
export declare function __clearTranspileCache(): void;
|
|
33
|
+
//# sourceMappingURL=transpile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transpile.d.ts","sourceRoot":"","sources":["../../src/playFunction/transpile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA0BH;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS3E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE/D;AAED,qFAAqF;AACrF,wBAAsB,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3E;AAED,kCAAkC;AAClC,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* transpile — lazy TS → JS type-erasure for Play Functions (Exploration R18).
|
|
3
|
+
*
|
|
4
|
+
* Handlers are authored and stored as TypeScript (verbatim). Browsers can't run
|
|
5
|
+
* TS, so before execution the type annotations are stripped to plain JS. We use
|
|
6
|
+
* `sucrase` with the `typescript` transform only (no bundling, no type-checking —
|
|
7
|
+
* pure syntactic erasure), which is the smallest/fastest option for this job.
|
|
8
|
+
*
|
|
9
|
+
* `sucrase` is loaded LAZILY (dynamic import) so it only enters the bundle with
|
|
10
|
+
* the Play Function runtime chunk, keeping M1–M3 (defaults-only) unaffected.
|
|
11
|
+
*
|
|
12
|
+
* Results are cached per source string: the same handler text transpiles once per
|
|
13
|
+
* session. The fold may transpile many handlers across replays/scrubs, so the
|
|
14
|
+
* cache matters.
|
|
15
|
+
*/
|
|
16
|
+
let transformerPromise = null;
|
|
17
|
+
/** Lazily load sucrase and return a bound TS→JS transform fn. */
|
|
18
|
+
async function getTransformer() {
|
|
19
|
+
if (!transformerPromise) {
|
|
20
|
+
transformerPromise = import('sucrase').then(({ transform }) => {
|
|
21
|
+
return (code) => transform(code, {
|
|
22
|
+
transforms: ['typescript'],
|
|
23
|
+
// Keep output ES-module-free: handlers are wrapped as function bodies,
|
|
24
|
+
// not modules, so we don't want import/export handling here.
|
|
25
|
+
disableESTransforms: true,
|
|
26
|
+
production: true,
|
|
27
|
+
}).code;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return transformerPromise;
|
|
31
|
+
}
|
|
32
|
+
/** Per-source transpile cache (source string → JS). */
|
|
33
|
+
const cache = new Map();
|
|
34
|
+
/**
|
|
35
|
+
* Transpile a Play Function's TypeScript source to JavaScript (type-erasure).
|
|
36
|
+
* Cached per exact source string. Throws if sucrase fails to parse (surfaced to
|
|
37
|
+
* the caller as a handler error).
|
|
38
|
+
*/
|
|
39
|
+
export async function transpilePlayFunction(source) {
|
|
40
|
+
const trimmed = source ?? '';
|
|
41
|
+
const cached = cache.get(trimmed);
|
|
42
|
+
if (cached !== undefined)
|
|
43
|
+
return cached;
|
|
44
|
+
const transform = await getTransformer();
|
|
45
|
+
const js = transform(trimmed);
|
|
46
|
+
cache.set(trimmed, js);
|
|
47
|
+
return js;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Synchronous cache read — returns the transpiled JS if this source has already
|
|
51
|
+
* been transpiled this session, else null. Lets the fold stay synchronous once
|
|
52
|
+
* all handlers in play have been pre-transpiled (the worker pre-warms the cache
|
|
53
|
+
* before folding).
|
|
54
|
+
*/
|
|
55
|
+
export function getTranspiledSync(source) {
|
|
56
|
+
return cache.get(source ?? '') ?? null;
|
|
57
|
+
}
|
|
58
|
+
/** Pre-transpile a batch of sources (used to pre-warm before a synchronous fold). */
|
|
59
|
+
export async function pretranspile(sources) {
|
|
60
|
+
const unique = new Set();
|
|
61
|
+
for (const s of sources) {
|
|
62
|
+
if (s && s.trim().length > 0)
|
|
63
|
+
unique.add(s);
|
|
64
|
+
}
|
|
65
|
+
await Promise.all([...unique].map((s) => transpilePlayFunction(s)));
|
|
66
|
+
}
|
|
67
|
+
/** Test seam: clear the cache. */
|
|
68
|
+
export function __clearTranspileCache() {
|
|
69
|
+
cache.clear();
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=transpile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transpile.js","sourceRoot":"","sources":["../../src/playFunction/transpile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,IAAI,kBAAkB,GAAgC,IAAI,CAAC;AAE3D,iEAAiE;AACjE,KAAK,UAAU,cAAc;IAC3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,kBAAkB,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;YAC5D,OAAO,CAAC,IAAY,EAAE,EAAE,CACtB,SAAS,CAAC,IAAI,EAAE;gBACd,UAAU,EAAE,CAAC,YAAY,CAAC;gBAC1B,uEAAuE;gBACvE,6DAA6D;gBAC7D,mBAAmB,EAAE,IAAI;gBACzB,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC,IAAI,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED,uDAAuD;AACvD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;AAExC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAAc;IACxD,MAAM,OAAO,GAAG,MAAM,IAAI,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IAExC,MAAM,SAAS,GAAG,MAAM,cAAc,EAAE,CAAC;IACzC,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC9B,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC;AACzC,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAyB;IAC1D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,qBAAqB;IACnC,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* eventModel — the MINIMAL subset of prooph board's Event Model domain types the
|
|
3
|
+
* Exploration runtime depends on. Mirrors the fields the fold, connection rules,
|
|
4
|
+
* and dts builders read; it is intentionally not the full editor model.
|
|
5
|
+
*
|
|
6
|
+
* Keep this in sync with eventflow-designer's `src/types/eventModel.ts` for the
|
|
7
|
+
* fields used here (type, name, context, laneId, sliceId, index, noArrow*,
|
|
8
|
+
* playFunction, playType; lane label/type/index; slice index/status; chapter
|
|
9
|
+
* slices/lanes/elements/mode/context). The parity test guards against drift.
|
|
10
|
+
*/
|
|
11
|
+
export type ElementType = 'command' | 'event' | 'information' | 'automation' | 'hotspot' | 'ui' | 'slice';
|
|
12
|
+
export type LaneType = 'user-lane' | 'information-flow' | 'system';
|
|
13
|
+
export interface Comment {
|
|
14
|
+
id: string;
|
|
15
|
+
text: string;
|
|
16
|
+
createdAt: number;
|
|
17
|
+
author: string;
|
|
18
|
+
userId: string;
|
|
19
|
+
}
|
|
20
|
+
export interface Element {
|
|
21
|
+
id: string;
|
|
22
|
+
type: ElementType;
|
|
23
|
+
name: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
details?: string;
|
|
26
|
+
context: string;
|
|
27
|
+
icon?: string;
|
|
28
|
+
laneId: string;
|
|
29
|
+
sliceId: string;
|
|
30
|
+
index: number;
|
|
31
|
+
comments?: Comment[];
|
|
32
|
+
noArrowSource?: boolean;
|
|
33
|
+
noArrowTarget?: boolean;
|
|
34
|
+
hasSimilarElement?: boolean;
|
|
35
|
+
/** Exploration play function (handler) authored on this element, TS source. */
|
|
36
|
+
playFunction?: string;
|
|
37
|
+
/** Exploration payload type (bare TS type expression) authored on this element. */
|
|
38
|
+
playType?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface Lane {
|
|
41
|
+
id: string;
|
|
42
|
+
label: string;
|
|
43
|
+
type: LaneType;
|
|
44
|
+
height: number;
|
|
45
|
+
icon?: string;
|
|
46
|
+
details?: string;
|
|
47
|
+
index: number;
|
|
48
|
+
}
|
|
49
|
+
export type SliceStatus = 'draft' | 'planned' | 'in-progress' | 'blocked' | 'reviewed' | 'ready' | 'deployed';
|
|
50
|
+
export interface Slice {
|
|
51
|
+
id: string;
|
|
52
|
+
label: string;
|
|
53
|
+
width: number;
|
|
54
|
+
index: number;
|
|
55
|
+
icon?: string;
|
|
56
|
+
details?: string;
|
|
57
|
+
status?: SliceStatus;
|
|
58
|
+
assigneeId?: string | null;
|
|
59
|
+
data?: {
|
|
60
|
+
estimate?: string | null;
|
|
61
|
+
timeSpent?: string | null;
|
|
62
|
+
comments?: unknown[];
|
|
63
|
+
milestoneIds?: string[];
|
|
64
|
+
currentMilestone?: string | null;
|
|
65
|
+
[key: string]: unknown;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export type ChapterMode = 'event-modeling' | 'freestyle';
|
|
69
|
+
export interface Chapter {
|
|
70
|
+
id: string;
|
|
71
|
+
name: string;
|
|
72
|
+
lanes: Lane[];
|
|
73
|
+
slices: Slice[];
|
|
74
|
+
elements: Element[];
|
|
75
|
+
index: number;
|
|
76
|
+
context: string;
|
|
77
|
+
mode: ChapterMode;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=eventModel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventModel.d.ts","sourceRoot":"","sources":["../../src/types/eventModel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,OAAO,GACP,aAAa,GACb,YAAY,GACZ,SAAS,GACT,IAAI,GACJ,OAAO,CAAC;AAEZ,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,kBAAkB,GAAG,QAAQ,CAAC;AAEnE,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,SAAS,GACT,aAAa,GACb,SAAS,GACT,UAAU,GACV,OAAO,GACP,UAAU,CAAC;AAEf,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,WAAW,CAAC;AAEzD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC;CACnB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* eventModel — the MINIMAL subset of prooph board's Event Model domain types the
|
|
3
|
+
* Exploration runtime depends on. Mirrors the fields the fold, connection rules,
|
|
4
|
+
* and dts builders read; it is intentionally not the full editor model.
|
|
5
|
+
*
|
|
6
|
+
* Keep this in sync with eventflow-designer's `src/types/eventModel.ts` for the
|
|
7
|
+
* fields used here (type, name, context, laneId, sliceId, index, noArrow*,
|
|
8
|
+
* playFunction, playType; lane label/type/index; slice index/status; chapter
|
|
9
|
+
* slices/lanes/elements/mode/context). The parity test guards against drift.
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=eventModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventModel.js","sourceRoot":"","sources":["../../src/types/eventModel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|