@loomwork/compiler 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/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +62 -2
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +81 -0
- package/dist/cli.js.map +1 -0
- package/dist/hash.d.ts +3 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +16 -0
- package/dist/hash.js.map +1 -0
- package/dist/importResolve.d.ts +5 -0
- package/dist/importResolve.d.ts.map +1 -0
- package/dist/importResolve.js +130 -0
- package/dist/importResolve.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/loopIdentity.d.ts +18 -0
- package/dist/loopIdentity.d.ts.map +1 -0
- package/dist/loopIdentity.js +179 -0
- package/dist/loopIdentity.js.map +1 -0
- package/dist/manifest.d.ts +98 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +123 -0
- package/dist/manifest.js.map +1 -0
- package/dist/nondeterminism.d.ts +25 -0
- package/dist/nondeterminism.d.ts.map +1 -0
- package/dist/nondeterminism.js +88 -0
- package/dist/nondeterminism.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +71 -0
- package/dist/plugin.js.map +1 -0
- package/dist/runnerReach.d.ts +136 -0
- package/dist/runnerReach.d.ts.map +1 -0
- package/dist/runnerReach.js +1809 -0
- package/dist/runnerReach.js.map +1 -0
- package/dist/transform.d.ts +6 -0
- package/dist/transform.d.ts.map +1 -0
- package/dist/transform.js +416 -0
- package/dist/transform.js.map +1 -0
- package/dist/types.d.ts +73 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +64 -3
- package/src/cli.ts +90 -0
- package/src/hash.ts +12 -0
- package/src/importResolve.ts +133 -0
- package/src/index.ts +23 -0
- package/src/loopIdentity.ts +210 -0
- package/src/manifest.ts +185 -0
- package/src/nondeterminism.ts +133 -0
- package/src/plugin.ts +74 -0
- package/src/runnerReach.ts +1964 -0
- package/src/transform.ts +523 -0
- package/src/types.ts +79 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.analyzeLoopIdentityNode = analyzeLoopIdentityNode;
|
|
7
|
+
exports.analyzeLoopIdentity = analyzeLoopIdentity;
|
|
8
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
9
|
+
const CALLBACK_LOOPS = new Set(["map", "forEach", "flatMap"]);
|
|
10
|
+
function isRunOrExecuteCall(node) {
|
|
11
|
+
if (!typescript_1.default.isCallExpression(node))
|
|
12
|
+
return false;
|
|
13
|
+
const e = node.expression;
|
|
14
|
+
return (typescript_1.default.isPropertyAccessExpression(e) &&
|
|
15
|
+
typescript_1.default.isIdentifier(e.name) &&
|
|
16
|
+
(e.name.text === "run" || e.name.text === "execute"));
|
|
17
|
+
}
|
|
18
|
+
/** Collect binding names a loop scope introduces or mutates (iteration-varying names). */
|
|
19
|
+
function collectLoopBindings(loop, body) {
|
|
20
|
+
const names = new Set();
|
|
21
|
+
const addDeclarationList = (list) => {
|
|
22
|
+
if (list !== undefined && typescript_1.default.isVariableDeclarationList(list)) {
|
|
23
|
+
for (const d of list.declarations)
|
|
24
|
+
collectBoundNames(d.name, names);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
if (typescript_1.default.isForStatement(loop))
|
|
28
|
+
addDeclarationList(loop.initializer);
|
|
29
|
+
if (typescript_1.default.isForOfStatement(loop) || typescript_1.default.isForInStatement(loop))
|
|
30
|
+
addDeclarationList(loop.initializer);
|
|
31
|
+
// Counters mutated inside the body (`i++`, `i += 1`, `i = i + 1`) vary per
|
|
32
|
+
// iteration even when declared outside the loop (the `while` idiom).
|
|
33
|
+
const scanMutations = (node) => {
|
|
34
|
+
if ((typescript_1.default.isPostfixUnaryExpression(node) || typescript_1.default.isPrefixUnaryExpression(node)) &&
|
|
35
|
+
(node.operator === typescript_1.default.SyntaxKind.PlusPlusToken ||
|
|
36
|
+
node.operator === typescript_1.default.SyntaxKind.MinusMinusToken) &&
|
|
37
|
+
typescript_1.default.isIdentifier(node.operand)) {
|
|
38
|
+
names.add(node.operand.text);
|
|
39
|
+
}
|
|
40
|
+
else if (typescript_1.default.isBinaryExpression(node) &&
|
|
41
|
+
node.operatorToken.kind >= typescript_1.default.SyntaxKind.FirstAssignment &&
|
|
42
|
+
node.operatorToken.kind <= typescript_1.default.SyntaxKind.LastAssignment &&
|
|
43
|
+
typescript_1.default.isIdentifier(node.left)) {
|
|
44
|
+
names.add(node.left.text);
|
|
45
|
+
}
|
|
46
|
+
typescript_1.default.forEachChild(node, scanMutations);
|
|
47
|
+
};
|
|
48
|
+
scanMutations(body);
|
|
49
|
+
return names;
|
|
50
|
+
}
|
|
51
|
+
/** Add every identifier bound by a (possibly destructuring) binding name. */
|
|
52
|
+
function collectBoundNames(name, into) {
|
|
53
|
+
if (typescript_1.default.isIdentifier(name)) {
|
|
54
|
+
into.add(name.text);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
for (const element of name.elements) {
|
|
58
|
+
if (typescript_1.default.isBindingElement(element))
|
|
59
|
+
collectBoundNames(element.name, into);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** True if the subtree references any of the given names as a VALUE (not a property name). */
|
|
63
|
+
function referencesAny(node, names) {
|
|
64
|
+
let found = false;
|
|
65
|
+
const visit = (n) => {
|
|
66
|
+
if (found)
|
|
67
|
+
return;
|
|
68
|
+
if (typescript_1.default.isIdentifier(n) && names.has(n.text)) {
|
|
69
|
+
const parent = n.parent;
|
|
70
|
+
// `obj.i` — the `.i` name position is not a reference to the loop variable.
|
|
71
|
+
const isPropertyNamePosition = (typescript_1.default.isPropertyAccessExpression(parent) && parent.name === n) ||
|
|
72
|
+
(typescript_1.default.isPropertyAssignment(parent) && parent.name === n);
|
|
73
|
+
if (!isPropertyNamePosition) {
|
|
74
|
+
found = true;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
typescript_1.default.forEachChild(n, visit);
|
|
79
|
+
};
|
|
80
|
+
visit(node);
|
|
81
|
+
return found;
|
|
82
|
+
}
|
|
83
|
+
/** A `.map`/`.forEach`/`.flatMap` call whose first argument is a function — treat as a loop. */
|
|
84
|
+
function callbackLoop(node) {
|
|
85
|
+
if (!typescript_1.default.isCallExpression(node))
|
|
86
|
+
return undefined;
|
|
87
|
+
const e = node.expression;
|
|
88
|
+
if (!typescript_1.default.isPropertyAccessExpression(e) || !typescript_1.default.isIdentifier(e.name))
|
|
89
|
+
return undefined;
|
|
90
|
+
if (!CALLBACK_LOOPS.has(e.name.text))
|
|
91
|
+
return undefined;
|
|
92
|
+
const cb = node.arguments[0];
|
|
93
|
+
if (cb === undefined || (!typescript_1.default.isArrowFunction(cb) && !typescript_1.default.isFunctionExpression(cb))) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
const params = new Set();
|
|
97
|
+
for (const p of cb.parameters)
|
|
98
|
+
collectBoundNames(p.name, params);
|
|
99
|
+
return { body: cb.body, params, kind: `.${e.name.text}()` };
|
|
100
|
+
}
|
|
101
|
+
/** Analyze a parsed node (a flow runner / orchestration body) for loop-identity hazards. */
|
|
102
|
+
function analyzeLoopIdentityNode(root, location) {
|
|
103
|
+
const findings = [];
|
|
104
|
+
// Stack of active loop scopes; bindings accumulate (an id derived from ANY
|
|
105
|
+
// enclosing loop's variable is accepted — the nested-loop case is documented
|
|
106
|
+
// as out of scope for the heuristic).
|
|
107
|
+
const loopStack = [];
|
|
108
|
+
const classify = (call) => {
|
|
109
|
+
if (loopStack.length === 0)
|
|
110
|
+
return;
|
|
111
|
+
const step = call.arguments[0];
|
|
112
|
+
if (step === undefined)
|
|
113
|
+
return;
|
|
114
|
+
const callee = call.expression.name.text;
|
|
115
|
+
const loopKind = loopStack[loopStack.length - 1].kind;
|
|
116
|
+
if (typescript_1.default.isIdentifier(step) || typescript_1.default.isPropertyAccessExpression(step)) {
|
|
117
|
+
// A static StepDefinition reference — its id is fixed across iterations.
|
|
118
|
+
findings.push({
|
|
119
|
+
callee,
|
|
120
|
+
loopKind,
|
|
121
|
+
reason: "static-step-in-loop",
|
|
122
|
+
...(location !== undefined && { location }),
|
|
123
|
+
});
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (typescript_1.default.isCallExpression(step) || typescript_1.default.isObjectLiteralExpression(step)) {
|
|
127
|
+
const union = new Set();
|
|
128
|
+
for (const scope of loopStack)
|
|
129
|
+
for (const n of scope.bindings)
|
|
130
|
+
union.add(n);
|
|
131
|
+
if (!referencesAny(step, union)) {
|
|
132
|
+
findings.push({
|
|
133
|
+
callee,
|
|
134
|
+
loopKind,
|
|
135
|
+
reason: "id-not-derived-from-loop-variable",
|
|
136
|
+
...(location !== undefined && { location }),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// Anything else (conditional, array index, helper-derived) — stay quiet.
|
|
142
|
+
};
|
|
143
|
+
const visit = (node) => {
|
|
144
|
+
if (isRunOrExecuteCall(node))
|
|
145
|
+
classify(node);
|
|
146
|
+
if (typescript_1.default.isIterationStatement(node, false)) {
|
|
147
|
+
const body = node.statement;
|
|
148
|
+
loopStack.push({
|
|
149
|
+
kind: typescript_1.default.SyntaxKind[node.kind],
|
|
150
|
+
bindings: collectLoopBindings(node, body),
|
|
151
|
+
});
|
|
152
|
+
typescript_1.default.forEachChild(node, visit);
|
|
153
|
+
loopStack.pop();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const cb = callbackLoop(node);
|
|
157
|
+
if (cb !== undefined) {
|
|
158
|
+
// Visit the receiver/arguments outside the loop scope, then the callback
|
|
159
|
+
// body inside it.
|
|
160
|
+
loopStack.push({ kind: cb.kind, bindings: cb.params });
|
|
161
|
+
visit(cb.body);
|
|
162
|
+
loopStack.pop();
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
typescript_1.default.forEachChild(node, visit);
|
|
166
|
+
};
|
|
167
|
+
visit(root);
|
|
168
|
+
return findings;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Analyze a source string (a flow runner / orchestration body) for `ctx.run`/
|
|
172
|
+
* `ctx.execute` calls inside loops whose step id cannot vary per iteration
|
|
173
|
+
* (ADR 0061). Feed the result to `@loomwork/verify` via `FlowSpec.loopIdentityCalls`.
|
|
174
|
+
*/
|
|
175
|
+
function analyzeLoopIdentity(source, location) {
|
|
176
|
+
const sf = typescript_1.default.createSourceFile("loopid.ts", source, typescript_1.default.ScriptTarget.ESNext, true);
|
|
177
|
+
return analyzeLoopIdentityNode(sf, location);
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=loopIdentity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopIdentity.js","sourceRoot":"","sources":["../src/loopIdentity.ts"],"names":[],"mappings":";;;;;AAiIA,0DAsEC;AAOD,kDAGC;AAjND,4DAA4B;AA8B5B,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAE9D,SAAS,kBAAkB,CAAC,IAAa;IACvC,IAAI,CAAC,oBAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;IAC1B,OAAO,CACL,oBAAE,CAAC,0BAA0B,CAAC,CAAC,CAAC;QAChC,oBAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;QACvB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CACrD,CAAC;AACJ,CAAC;AAED,0FAA0F;AAC1F,SAAS,mBAAmB,CAAC,IAAa,EAAE,IAAa;IACvD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAEhC,MAAM,kBAAkB,GAAG,CAAC,IAAmC,EAAQ,EAAE;QACvE,IAAI,IAAI,KAAK,SAAS,IAAI,oBAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,YAAY;gBAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACtE,CAAC;IACH,CAAC,CAAC;IACF,IAAI,oBAAE,CAAC,cAAc,CAAC,IAAI,CAAC;QAAE,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAClE,IAAI,oBAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,oBAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;QAAE,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAEjG,2EAA2E;IAC3E,qEAAqE;IACrE,MAAM,aAAa,GAAG,CAAC,IAAa,EAAQ,EAAE;QAC5C,IACE,CAAC,oBAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,oBAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;YACvE,CAAC,IAAI,CAAC,QAAQ,KAAK,oBAAE,CAAC,UAAU,CAAC,aAAa;gBAC5C,IAAI,CAAC,QAAQ,KAAK,oBAAE,CAAC,UAAU,CAAC,eAAe,CAAC;YAClD,oBAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAC7B,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;aAAM,IACL,oBAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC;YAC3B,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,oBAAE,CAAC,UAAU,CAAC,eAAe;YACxD,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,oBAAE,CAAC,UAAU,CAAC,cAAc;YACvD,oBAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAC1B,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,oBAAE,CAAC,YAAY,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IACvC,CAAC,CAAC;IACF,aAAa,CAAC,IAAI,CAAC,CAAC;IACpB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,6EAA6E;AAC7E,SAAS,iBAAiB,CAAC,IAAoB,EAAE,IAAiB;IAChE,IAAI,oBAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO;IACT,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,IAAI,oBAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC;YAAE,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,8FAA8F;AAC9F,SAAS,aAAa,CAAC,IAAa,EAAE,KAA0B;IAC9D,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,MAAM,KAAK,GAAG,CAAC,CAAU,EAAQ,EAAE;QACjC,IAAI,KAAK;YAAE,OAAO;QAClB,IAAI,oBAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;YACxB,4EAA4E;YAC5E,MAAM,sBAAsB,GAC1B,CAAC,oBAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC;gBAC5D,CAAC,oBAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;YACzD,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAC5B,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO;YACT,CAAC;QACH,CAAC;QACD,oBAAE,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,OAAO,KAAK,CAAC;AACf,CAAC;AAED,gGAAgG;AAChG,SAAS,YAAY,CACnB,IAAa;IAEb,IAAI,CAAC,oBAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACjD,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;IAC1B,IAAI,CAAC,oBAAE,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACpF,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACvD,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,EAAE,KAAK,SAAS,IAAI,CAAC,CAAC,oBAAE,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAClF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,UAAU;QAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACjE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;AAC9D,CAAC;AAED,4FAA4F;AAC5F,SAAgB,uBAAuB,CACrC,IAAa,EACb,QAAiB;IAEjB,MAAM,QAAQ,GAA8B,EAAE,CAAC;IAC/C,2EAA2E;IAC3E,6EAA6E;IAC7E,sCAAsC;IACtC,MAAM,SAAS,GAAmD,EAAE,CAAC;IAErE,MAAM,QAAQ,GAAG,CAAC,IAAuB,EAAQ,EAAE;QACjD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,MAAM,MAAM,GAAI,IAAI,CAAC,UAA0C,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1E,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC;QAEvD,IAAI,oBAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,oBAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC;YACjE,yEAAyE;YACzE,QAAQ,CAAC,IAAI,CAAC;gBACZ,MAAM;gBACN,QAAQ;gBACR,MAAM,EAAE,qBAAqB;gBAC7B,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;aAC5C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,oBAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,oBAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC;YACpE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;YAChC,KAAK,MAAM,KAAK,IAAI,SAAS;gBAAE,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ;oBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC5E,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;gBAChC,QAAQ,CAAC,IAAI,CAAC;oBACZ,MAAM;oBACN,QAAQ;oBACR,MAAM,EAAE,mCAAmC;oBAC3C,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;iBAC5C,CAAC,CAAC;YACL,CAAC;YACD,OAAO;QACT,CAAC;QACD,yEAAyE;IAC3E,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QACpC,IAAI,kBAAkB,CAAC,IAAI,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE7C,IAAI,oBAAE,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YAC5B,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,oBAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC9B,QAAQ,EAAE,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC;aAC1C,CAAC,CAAC;YACH,oBAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC7B,SAAS,CAAC,GAAG,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QACD,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACrB,yEAAyE;YACzE,kBAAkB;YAClB,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;YACvD,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YACf,SAAS,CAAC,GAAG,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QACD,oBAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,SAAgB,mBAAmB,CAAC,MAAc,EAAE,QAAiB;IACnE,MAAM,EAAE,GAAG,oBAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,oBAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAClF,OAAO,uBAAuB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { PluginState } from "./types";
|
|
2
|
+
/** The compiler manifest schema version (not semver — a monotonic integer string). */
|
|
3
|
+
export declare const COMPILER_MANIFEST_VERSION = "1";
|
|
4
|
+
export interface ManifestFlow {
|
|
5
|
+
version: string;
|
|
6
|
+
steps: string[];
|
|
7
|
+
chunkMap: Record<string, string>;
|
|
8
|
+
suspendPoints: string[];
|
|
9
|
+
warnings: string[];
|
|
10
|
+
/**
|
|
11
|
+
* ADR 0061 — structured loop step-identity findings for this flow's module
|
|
12
|
+
* (also rendered into `warnings`). Feed to `@loomwork/verify` via
|
|
13
|
+
* `FlowSpec.loopIdentityCalls`; additive manifest field.
|
|
14
|
+
*/
|
|
15
|
+
loopIdentity?: Array<{
|
|
16
|
+
callee: string;
|
|
17
|
+
loopKind: string;
|
|
18
|
+
reason: string;
|
|
19
|
+
location?: string;
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* Issue #82 — non-deterministic calls in this flow's module, and whether each
|
|
23
|
+
* sits inside a `ctx.decide`/`ctx.execute` boundary. Feed to `@loomwork/verify`
|
|
24
|
+
* via `FlowSpec.nonDeterministicCalls`; additive manifest field.
|
|
25
|
+
*/
|
|
26
|
+
nonDeterministic?: Array<{
|
|
27
|
+
callee: string;
|
|
28
|
+
insideDecide: boolean;
|
|
29
|
+
location?: string;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* ADR 0086 — runner-body reach: resolved `ctx.run` targets, `ctx.suspend`
|
|
33
|
+
* conditions, and the targets analysis could NOT resolve. Feeds
|
|
34
|
+
* `FlowSpec.effects` / `suspends` / `unresolvedReach`, which is what lets
|
|
35
|
+
* capability-compat, effect-class and suspension-safety see past the flow's
|
|
36
|
+
* DECLARED steps — and state their own coverage when they cannot.
|
|
37
|
+
*/
|
|
38
|
+
runnerReach?: {
|
|
39
|
+
steps: Array<{
|
|
40
|
+
stepId?: string;
|
|
41
|
+
toolId: string;
|
|
42
|
+
viaDecider?: boolean;
|
|
43
|
+
}>;
|
|
44
|
+
unresolved: Array<{
|
|
45
|
+
expr: string;
|
|
46
|
+
kind: "step" | "suspend";
|
|
47
|
+
location?: string;
|
|
48
|
+
}>;
|
|
49
|
+
suspends: Array<{
|
|
50
|
+
id?: string;
|
|
51
|
+
correlationKey?: string;
|
|
52
|
+
timed?: boolean;
|
|
53
|
+
wakeAt?: boolean;
|
|
54
|
+
}>;
|
|
55
|
+
/** L32 — `ctx` (or `ctx.decide`) handed to out-of-module callees; resolved against `verify.reach`. */
|
|
56
|
+
escapes?: Array<{
|
|
57
|
+
callee: string;
|
|
58
|
+
root?: string;
|
|
59
|
+
via: "ctx" | "decide";
|
|
60
|
+
member?: string;
|
|
61
|
+
/** L34 — the hand-off's arguments that resolve to a step, by position. */
|
|
62
|
+
args?: Array<{
|
|
63
|
+
index: number;
|
|
64
|
+
step: {
|
|
65
|
+
stepId?: string;
|
|
66
|
+
toolId: string;
|
|
67
|
+
};
|
|
68
|
+
}>;
|
|
69
|
+
location?: string;
|
|
70
|
+
}>;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* The source module that declared this flow (relative to the project root).
|
|
74
|
+
* Enables tooling and `@loomwork/app`'s manifest cross-check to know where a flow
|
|
75
|
+
* lives. Registration itself stays a static import (see `registerFlowsFrom`) —
|
|
76
|
+
* this is metadata, never a dynamic-import target, so wiring stays
|
|
77
|
+
* deterministic/replay-safe.
|
|
78
|
+
*/
|
|
79
|
+
module: string;
|
|
80
|
+
}
|
|
81
|
+
export interface ManifestSkill {
|
|
82
|
+
chunk: string;
|
|
83
|
+
}
|
|
84
|
+
export interface ManifestProjection {
|
|
85
|
+
eventTypes: string[];
|
|
86
|
+
chunk: string;
|
|
87
|
+
}
|
|
88
|
+
export interface LoomManifest {
|
|
89
|
+
version: "1";
|
|
90
|
+
flows: Record<string, ManifestFlow>;
|
|
91
|
+
skills: Record<string, ManifestSkill>;
|
|
92
|
+
projections: Record<string, ManifestProjection>;
|
|
93
|
+
/** Deduplicated, sorted list of source modules that declare flows. */
|
|
94
|
+
flowModules: string[];
|
|
95
|
+
}
|
|
96
|
+
export declare function buildManifest(state: PluginState, outDir?: string, root?: string): LoomManifest;
|
|
97
|
+
export declare function printWarnings(manifest: LoomManifest): void;
|
|
98
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.COMPILER_MANIFEST_VERSION = void 0;
|
|
37
|
+
exports.buildManifest = buildManifest;
|
|
38
|
+
exports.printWarnings = printWarnings;
|
|
39
|
+
const path = __importStar(require("node:path"));
|
|
40
|
+
/** The compiler manifest schema version (not semver — a monotonic integer string). */
|
|
41
|
+
exports.COMPILER_MANIFEST_VERSION = "1";
|
|
42
|
+
function relModule(sourceFile, root) {
|
|
43
|
+
if (!sourceFile)
|
|
44
|
+
return sourceFile;
|
|
45
|
+
const rel = path.isAbsolute(sourceFile) ? path.relative(root, sourceFile) : sourceFile;
|
|
46
|
+
return rel.split(path.sep).join("/");
|
|
47
|
+
}
|
|
48
|
+
function buildManifest(state, outDir = ".", root = process.cwd()) {
|
|
49
|
+
const flows = {};
|
|
50
|
+
const skills = {};
|
|
51
|
+
const flowModuleSet = new Set();
|
|
52
|
+
for (const [flowId, flow] of state.flows) {
|
|
53
|
+
const chunkMap = {};
|
|
54
|
+
const warnings = [];
|
|
55
|
+
for (const stepId of flow.stepIds) {
|
|
56
|
+
const step = state.steps.get(stepId);
|
|
57
|
+
if (!step) {
|
|
58
|
+
warnings.push(`Step "${stepId}" is referenced in flow "${flowId}" but not found in analysis.`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (step.chunkVirtualId !== undefined) {
|
|
62
|
+
const fileName = `chunks/${stepId}_${step.hash}.js`;
|
|
63
|
+
chunkMap[stepId] = `${outDir}/${fileName}`;
|
|
64
|
+
}
|
|
65
|
+
else if (!step.toolId) {
|
|
66
|
+
warnings.push(`Step "${stepId}" in flow "${flowId}" has neither a handler$ nor a toolId — it must be registered manually. (Steps minted dynamically in the runner body — the interpreter pattern — should instead bind a static toolId to a registered effect and derive ids as \`\${id}#\${index}\`; see ADR 0061.)`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// ADR 0061 — surface loop step-identity findings as warnings (rendered) AND
|
|
70
|
+
// structurally (for @loomwork/verify's determinism rule via loopIdentityCalls).
|
|
71
|
+
for (const f of flow.loopIdentityFindings ?? []) {
|
|
72
|
+
warnings.push(`Flow "${flowId}": ctx.${f.callee} inside ${f.loopKind} uses a step id that cannot vary per iteration (${f.reason}) — frames are keyed by id, so later iterations replay iteration 0's output. Mint \`\${id}#\${index}\` (ADR 0061).`);
|
|
73
|
+
}
|
|
74
|
+
const module = relModule(flow.sourceFile, root);
|
|
75
|
+
if (module)
|
|
76
|
+
flowModuleSet.add(module);
|
|
77
|
+
flows[flowId] = {
|
|
78
|
+
version: flow.version,
|
|
79
|
+
steps: flow.stepIds,
|
|
80
|
+
chunkMap,
|
|
81
|
+
suspendPoints: flow.suspendPoints,
|
|
82
|
+
warnings,
|
|
83
|
+
module,
|
|
84
|
+
...(flow.loopIdentityFindings !== undefined &&
|
|
85
|
+
flow.loopIdentityFindings.length > 0 && { loopIdentity: flow.loopIdentityFindings }),
|
|
86
|
+
...(flow.nonDeterministicCalls !== undefined &&
|
|
87
|
+
flow.nonDeterministicCalls.length > 0 && { nonDeterministic: flow.nonDeterministicCalls }),
|
|
88
|
+
...(flow.runnerReach !== undefined && { runnerReach: flow.runnerReach }),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
for (const [skillId, skill] of state.skills) {
|
|
92
|
+
skills[skillId] = {
|
|
93
|
+
chunk: skill.chunkVirtualId ? `${outDir}/chunks/${skillId}_${skill.hash}.js` : "",
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const projections = {};
|
|
97
|
+
for (const [projectionId, projection] of state.projections) {
|
|
98
|
+
projections[projectionId] = {
|
|
99
|
+
eventTypes: projection.eventTypes,
|
|
100
|
+
chunk: projection.chunkVirtualId
|
|
101
|
+
? `${outDir}/chunks/${projectionId}_${projection.hash}.js`
|
|
102
|
+
: "",
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
version: exports.COMPILER_MANIFEST_VERSION,
|
|
107
|
+
flows,
|
|
108
|
+
skills,
|
|
109
|
+
projections,
|
|
110
|
+
flowModules: [...flowModuleSet].sort(),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function printWarnings(manifest) {
|
|
114
|
+
for (const [flowId, flow] of Object.entries(manifest.flows)) {
|
|
115
|
+
for (const warning of flow.warnings) {
|
|
116
|
+
console.warn(`[loom-compiler] ⚠ ${warning}`);
|
|
117
|
+
}
|
|
118
|
+
if (flow.warnings.length === 0) {
|
|
119
|
+
console.info(`[loom-compiler] ✓ flow "${flowId}" — ${flow.steps.length} step(s), ${Object.keys(flow.chunkMap).length} lazy chunk(s)`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2FA,sCAgFC;AAED,sCAWC;AAxLD,gDAAkC;AAGlC,sFAAsF;AACzE,QAAA,yBAAyB,GAAG,GAAG,CAAC;AAiF7C,SAAS,SAAS,CAAC,UAAkB,EAAE,IAAY;IACjD,IAAI,CAAC,UAAU;QAAE,OAAO,UAAU,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACvF,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,aAAa,CAC3B,KAAkB,EAClB,MAAM,GAAG,GAAG,EACZ,OAAe,OAAO,CAAC,GAAG,EAAE;IAE5B,MAAM,KAAK,GAAiC,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAkC,EAAE,CAAC;IACjD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IAExC,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QACzC,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,MAAM,IAAI,GAA0B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC5D,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,QAAQ,CAAC,IAAI,CACX,SAAS,MAAM,4BAA4B,MAAM,8BAA8B,CAChF,CAAC;gBACF,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;gBACtC,MAAM,QAAQ,GAAG,UAAU,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;gBACpD,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,IAAI,QAAQ,EAAE,CAAC;YAC7C,CAAC;iBAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACxB,QAAQ,CAAC,IAAI,CACX,SAAS,MAAM,cAAc,MAAM,oQAAoQ,CACxS,CAAC;YACJ,CAAC;QACH,CAAC;QAED,4EAA4E;QAC5E,gFAAgF;QAChF,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,oBAAoB,IAAI,EAAE,EAAE,CAAC;YAChD,QAAQ,CAAC,IAAI,CACX,SAAS,MAAM,UAAU,CAAC,CAAC,MAAM,WAAW,CAAC,CAAC,QAAQ,mDAAmD,CAAC,CAAC,MAAM,oHAAoH,CACtO,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAChD,IAAI,MAAM;YAAE,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEtC,KAAK,CAAC,MAAM,CAAC,GAAG;YACd,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,CAAC,OAAO;YACnB,QAAQ;YACR,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,QAAQ;YACR,MAAM;YACN,GAAG,CAAC,IAAI,CAAC,oBAAoB,KAAK,SAAS;gBACzC,IAAI,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACtF,GAAG,CAAC,IAAI,CAAC,qBAAqB,KAAK,SAAS;gBAC1C,IAAI,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC5F,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;SACzE,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,MAAM,WAAW,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE;SAClF,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAuC,EAAE,CAAC;IAC3D,KAAK,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QAC3D,WAAW,CAAC,YAAY,CAAC,GAAG;YAC1B,UAAU,EAAE,UAAU,CAAC,UAAU;YACjC,KAAK,EAAE,UAAU,CAAC,cAAc;gBAC9B,CAAC,CAAC,GAAG,MAAM,WAAW,YAAY,IAAI,UAAU,CAAC,IAAI,KAAK;gBAC1D,CAAC,CAAC,EAAE;SACP,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,iCAAyB;QAClC,KAAK;QACL,MAAM;QACN,WAAW;QACX,WAAW,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,IAAI,EAAE;KACvC,CAAC;AACJ,CAAC;AAED,SAAgB,aAAa,CAAC,QAAsB;IAClD,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5D,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,sBAAsB,OAAO,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,IAAI,CACV,4BAA4B,MAAM,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,aAAa,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,gBAAgB,CACzH,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
export interface NonDeterministicCall {
|
|
3
|
+
callee: string;
|
|
4
|
+
/** True if the call is inside a `ctx.decide`/`ctx.execute` call (its result is logged). */
|
|
5
|
+
insideDecide: boolean;
|
|
6
|
+
location?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface AnalyzeOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Skip `handler$(...)` bodies. Required when analyzing a whole MODULE rather
|
|
11
|
+
* than an isolated runner: a flow module contains both, and reporting a
|
|
12
|
+
* handler's `Math.random` is a false positive — which is precisely the
|
|
13
|
+
* distinction this file's header describes, and precisely what a caller
|
|
14
|
+
* feeding it whole modules will otherwise get wrong.
|
|
15
|
+
*/
|
|
16
|
+
skipMemoized?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** Analyze a parsed node (a function/body) for non-deterministic calls. */
|
|
19
|
+
export declare function analyzeNode(root: ts.Node, location?: string, options?: AnalyzeOptions): NonDeterministicCall[];
|
|
20
|
+
/**
|
|
21
|
+
* Analyze a source string (e.g. a flow runner / orchestration body) for non-deterministic
|
|
22
|
+
* calls. Feed the result to `@loomwork/verify` via `resolveVerifyInput({ nonDeterministicByFlow })`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function analyzeNonDeterminism(source: string, location?: string, options?: AnalyzeOptions): NonDeterministicCall[];
|
|
25
|
+
//# sourceMappingURL=nondeterminism.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nondeterminism.d.ts","sourceRoot":"","sources":["../src/nondeterminism.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAgB5B,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAkDD,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CACzB,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,GAAE,cAAmB,GAC3B,oBAAoB,EAAE,CAgCxB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,GAAE,cAAmB,GAC3B,oBAAoB,EAAE,CAGxB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.analyzeNode = analyzeNode;
|
|
7
|
+
exports.analyzeNonDeterminism = analyzeNonDeterminism;
|
|
8
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
9
|
+
/** Member calls whose result is non-deterministic (object.method form). */
|
|
10
|
+
const NON_DET_MEMBER_CALLS = new Set([
|
|
11
|
+
"Date.now",
|
|
12
|
+
"Math.random",
|
|
13
|
+
"crypto.randomUUID",
|
|
14
|
+
"crypto.getRandomValues",
|
|
15
|
+
"performance.now",
|
|
16
|
+
]);
|
|
17
|
+
/** Bare (identifier) calls that are non-deterministic / side-effectful. */
|
|
18
|
+
const NON_DET_BARE_CALLS = new Set(["fetch"]);
|
|
19
|
+
function calleeName(node) {
|
|
20
|
+
const e = node.expression;
|
|
21
|
+
if (typescript_1.default.isIdentifier(e))
|
|
22
|
+
return e.text;
|
|
23
|
+
if (typescript_1.default.isPropertyAccessExpression(e) &&
|
|
24
|
+
typescript_1.default.isIdentifier(e.name) &&
|
|
25
|
+
typescript_1.default.isIdentifier(e.expression)) {
|
|
26
|
+
return `${e.expression.text}.${e.name.text}`;
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
/** A `ctx.decide(...)`/`ctx.execute(...)`-shaped call (any receiver, method name decide/execute). */
|
|
31
|
+
function isDecideBoundary(node) {
|
|
32
|
+
if (!typescript_1.default.isCallExpression(node))
|
|
33
|
+
return false;
|
|
34
|
+
const e = node.expression;
|
|
35
|
+
return (typescript_1.default.isPropertyAccessExpression(e) &&
|
|
36
|
+
typescript_1.default.isIdentifier(e.name) &&
|
|
37
|
+
(e.name.text === "decide" || e.name.text === "execute"));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A `handler$(...)` call — a MEMOIZED region. Its result is written to
|
|
41
|
+
* STEP_COMPLETED and served from the log on replay, so `Math.random()` inside
|
|
42
|
+
* one is safe by construction; the same call in a runner diverges the fold.
|
|
43
|
+
*/
|
|
44
|
+
function isMemoizedBoundary(node) {
|
|
45
|
+
return (typescript_1.default.isCallExpression(node) &&
|
|
46
|
+
typescript_1.default.isIdentifier(node.expression) &&
|
|
47
|
+
node.expression.text === "handler$");
|
|
48
|
+
}
|
|
49
|
+
/** Analyze a parsed node (a function/body) for non-deterministic calls. */
|
|
50
|
+
function analyzeNode(root, location, options = {}) {
|
|
51
|
+
const calls = [];
|
|
52
|
+
const ancestors = [];
|
|
53
|
+
function record(callee) {
|
|
54
|
+
const insideDecide = ancestors.some(isDecideBoundary);
|
|
55
|
+
calls.push({ callee, insideDecide, ...(location !== undefined && { location }) });
|
|
56
|
+
}
|
|
57
|
+
function visit(node) {
|
|
58
|
+
if (options.skipMemoized === true && isMemoizedBoundary(node))
|
|
59
|
+
return;
|
|
60
|
+
ancestors.push(node);
|
|
61
|
+
if (typescript_1.default.isCallExpression(node)) {
|
|
62
|
+
const name = calleeName(node);
|
|
63
|
+
if (name !== undefined && (NON_DET_MEMBER_CALLS.has(name) || NON_DET_BARE_CALLS.has(name))) {
|
|
64
|
+
record(name);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if (typescript_1.default.isNewExpression(node) &&
|
|
68
|
+
typescript_1.default.isIdentifier(node.expression) &&
|
|
69
|
+
node.expression.text === "Date" &&
|
|
70
|
+
(node.arguments === undefined || node.arguments.length === 0)) {
|
|
71
|
+
// `new Date()` with no args reads the current time.
|
|
72
|
+
record("new Date");
|
|
73
|
+
}
|
|
74
|
+
typescript_1.default.forEachChild(node, visit);
|
|
75
|
+
ancestors.pop();
|
|
76
|
+
}
|
|
77
|
+
visit(root);
|
|
78
|
+
return calls;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Analyze a source string (e.g. a flow runner / orchestration body) for non-deterministic
|
|
82
|
+
* calls. Feed the result to `@loomwork/verify` via `resolveVerifyInput({ nonDeterministicByFlow })`.
|
|
83
|
+
*/
|
|
84
|
+
function analyzeNonDeterminism(source, location, options = {}) {
|
|
85
|
+
const sf = typescript_1.default.createSourceFile("nondet.ts", source, typescript_1.default.ScriptTarget.ESNext, true);
|
|
86
|
+
return analyzeNode(sf, location, options);
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=nondeterminism.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nondeterminism.js","sourceRoot":"","sources":["../src/nondeterminism.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,MAAM,CAAC;AAOnD,wBAAgB,UAAU,IAAI,MAAM,CAgEnC"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loomPlugin = loomPlugin;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
9
|
+
const manifest_1 = require("./manifest");
|
|
10
|
+
const transform_1 = require("./transform");
|
|
11
|
+
const VIRTUAL_PREFIX = "\0loom:chunk:";
|
|
12
|
+
function loomPlugin() {
|
|
13
|
+
const state = {
|
|
14
|
+
chunks: new Map(),
|
|
15
|
+
steps: new Map(),
|
|
16
|
+
stepsByVarName: new Map(),
|
|
17
|
+
flows: new Map(),
|
|
18
|
+
skills: new Map(),
|
|
19
|
+
skillsByVarName: new Map(),
|
|
20
|
+
projections: new Map(),
|
|
21
|
+
};
|
|
22
|
+
let resolvedConfig;
|
|
23
|
+
return {
|
|
24
|
+
name: "loom",
|
|
25
|
+
enforce: "pre",
|
|
26
|
+
configResolved(config) {
|
|
27
|
+
resolvedConfig = config;
|
|
28
|
+
},
|
|
29
|
+
resolveId(id) {
|
|
30
|
+
if (id.startsWith(VIRTUAL_PREFIX) || id.startsWith("\0loom:")) {
|
|
31
|
+
return id;
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
},
|
|
35
|
+
load(id) {
|
|
36
|
+
if (id.startsWith(VIRTUAL_PREFIX)) {
|
|
37
|
+
const chunk = state.chunks.get(id);
|
|
38
|
+
if (chunk) {
|
|
39
|
+
// Transpile TS → JS so Vite/Rollup can parse the chunk (no .ts extension on virtual ids)
|
|
40
|
+
const result = typescript_1.default.transpileModule(chunk.chunkSource, {
|
|
41
|
+
compilerOptions: {
|
|
42
|
+
target: typescript_1.default.ScriptTarget.ESNext,
|
|
43
|
+
module: typescript_1.default.ModuleKind.ESNext,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
return { code: result.outputText };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
},
|
|
51
|
+
transform(code, id) {
|
|
52
|
+
if (!/\.[jt]sx?$/.test(id) || id.includes("node_modules"))
|
|
53
|
+
return undefined;
|
|
54
|
+
const result = (0, transform_1.transformFile)(code, id, state);
|
|
55
|
+
if (!result)
|
|
56
|
+
return undefined;
|
|
57
|
+
return { code: result.code, map: result.map };
|
|
58
|
+
},
|
|
59
|
+
generateBundle() {
|
|
60
|
+
const outDir = resolvedConfig?.build?.outDir ?? "dist";
|
|
61
|
+
const manifest = (0, manifest_1.buildManifest)(state, node_path_1.default.relative(process.cwd(), outDir));
|
|
62
|
+
(0, manifest_1.printWarnings)(manifest);
|
|
63
|
+
this.emitFile({
|
|
64
|
+
type: "asset",
|
|
65
|
+
fileName: "loom-manifest.json",
|
|
66
|
+
source: JSON.stringify(manifest, null, 2),
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":";;;;;AASA,gCAgEC;AAzED,0DAA6B;AAC7B,4DAA4B;AAE5B,yCAA0D;AAC1D,2CAA4C;AAG5C,MAAM,cAAc,GAAG,eAAe,CAAC;AAEvC,SAAgB,UAAU;IACxB,MAAM,KAAK,GAAgB;QACzB,MAAM,EAAE,IAAI,GAAG,EAAE;QACjB,KAAK,EAAE,IAAI,GAAG,EAAE;QAChB,cAAc,EAAE,IAAI,GAAG,EAAE;QACzB,KAAK,EAAE,IAAI,GAAG,EAAE;QAChB,MAAM,EAAE,IAAI,GAAG,EAAE;QACjB,eAAe,EAAE,IAAI,GAAG,EAAE;QAC1B,WAAW,EAAE,IAAI,GAAG,EAAE;KACvB,CAAC;IAEF,IAAI,cAA8B,CAAC;IAEnC,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,KAAK;QAEd,cAAc,CAAC,MAAM;YACnB,cAAc,GAAG,MAAM,CAAC;QAC1B,CAAC;QAED,SAAS,CAAC,EAAE;YACV,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9D,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,EAAE;YACL,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;gBAClC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACnC,IAAI,KAAK,EAAE,CAAC;oBACV,yFAAyF;oBACzF,MAAM,MAAM,GAAG,oBAAE,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,EAAE;wBACnD,eAAe,EAAE;4BACf,MAAM,EAAE,oBAAE,CAAC,YAAY,CAAC,MAAM;4BAC9B,MAAM,EAAE,oBAAE,CAAC,UAAU,CAAC,MAAM;yBAC7B;qBACF,CAAC,CAAC;oBACH,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;gBACrC,CAAC;YACH,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,SAAS,CAAC,IAAI,EAAE,EAAE;YAChB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC5E,MAAM,MAAM,GAAG,IAAA,yBAAa,EAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YAC9C,IAAI,CAAC,MAAM;gBAAE,OAAO,SAAS,CAAC;YAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;QAChD,CAAC;QAED,cAAc;YACZ,MAAM,MAAM,GAAG,cAAc,EAAE,KAAK,EAAE,MAAM,IAAI,MAAM,CAAC;YACvD,MAAM,QAAQ,GAAG,IAAA,wBAAa,EAAC,KAAK,EAAE,mBAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;YAC5E,IAAA,wBAAa,EAAC,QAAQ,CAAC,CAAC;YAExB,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,oBAAoB;gBAC9B,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;aAC1C,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|