@fluidgrids/workflows 0.0.0-stage → 2026.1027.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.
Files changed (60) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +208 -2
  3. package/dist/assemble-CrpUyd_3.d.ts +587 -0
  4. package/dist/assemble-DEf3znGD.d.cts +587 -0
  5. package/dist/chunk-3M34AUIY.cjs +27 -0
  6. package/dist/chunk-5AW745OG.js +25 -0
  7. package/dist/chunk-5LUIDMF4.js +42 -0
  8. package/dist/chunk-6AIAC2FP.cjs +185 -0
  9. package/dist/chunk-6BEW4QD6.js +95 -0
  10. package/dist/chunk-6U446SKY.js +263 -0
  11. package/dist/chunk-7YR7DI7B.cjs +274 -0
  12. package/dist/chunk-CSYBNN3V.cjs +252 -0
  13. package/dist/chunk-E3APHA6O.cjs +199 -0
  14. package/dist/chunk-EEAIM35V.js +748 -0
  15. package/dist/chunk-G4UEPUGO.cjs +46 -0
  16. package/dist/chunk-IHKXLG6I.js +246 -0
  17. package/dist/chunk-MBBKGD7K.js +440 -0
  18. package/dist/chunk-OSPTJCDI.cjs +102 -0
  19. package/dist/chunk-TQF7MYEN.cjs +771 -0
  20. package/dist/chunk-TWOYB4Y7.cjs +76 -0
  21. package/dist/chunk-UB2BHU2M.js +174 -0
  22. package/dist/chunk-UJNHTS6D.js +181 -0
  23. package/dist/chunk-UWQWD7BP.cjs +931 -0
  24. package/dist/chunk-W32BSO3M.js +74 -0
  25. package/dist/chunk-XBIID5DY.js +893 -0
  26. package/dist/chunk-Y7NWR3WH.cjs +450 -0
  27. package/dist/codegen/index.cjs +18 -0
  28. package/dist/codegen/index.d.cts +15 -0
  29. package/dist/codegen/index.d.ts +15 -0
  30. package/dist/codegen/index.js +5 -0
  31. package/dist/expressions-DhHaqyar.d.cts +62 -0
  32. package/dist/expressions-DhHaqyar.d.ts +62 -0
  33. package/dist/hash-CZkTXPCX.d.cts +15 -0
  34. package/dist/hash-CZkTXPCX.d.ts +15 -0
  35. package/dist/index.cjs +117 -0
  36. package/dist/index.d.cts +27 -0
  37. package/dist/index.d.ts +27 -0
  38. package/dist/index.js +4 -0
  39. package/dist/ir/index.cjs +1246 -0
  40. package/dist/ir/index.d.cts +838 -0
  41. package/dist/ir/index.d.ts +838 -0
  42. package/dist/ir/index.js +1122 -0
  43. package/dist/lower-CXggJTIo.d.ts +67 -0
  44. package/dist/lower-DAzvsJCo.d.cts +67 -0
  45. package/dist/manifest-Bp9ZJlav.d.ts +60 -0
  46. package/dist/manifest-Duf-gHdO.d.cts +60 -0
  47. package/dist/node-evaluator-CH3XCJND.cjs +17 -0
  48. package/dist/node-evaluator-TULXA3WE.js +8 -0
  49. package/dist/quickjs/index.cjs +46 -0
  50. package/dist/quickjs/index.d.cts +18 -0
  51. package/dist/quickjs/index.d.ts +18 -0
  52. package/dist/quickjs/index.js +44 -0
  53. package/dist/roundtrip/index.cjs +1448 -0
  54. package/dist/roundtrip/index.d.cts +290 -0
  55. package/dist/roundtrip/index.d.ts +290 -0
  56. package/dist/roundtrip/index.js +1397 -0
  57. package/dist/types-Dr2Fn1Ax.d.cts +225 -0
  58. package/dist/types-Dr2Fn1Ax.d.ts +225 -0
  59. package/package.json +143 -4
  60. package/schema/ir-v2.schema.json +655 -0
@@ -0,0 +1,76 @@
1
+ 'use strict';
2
+
3
+ var chunk7YR7DI7B_cjs = require('./chunk-7YR7DI7B.cjs');
4
+ var chunkE3APHA6O_cjs = require('./chunk-E3APHA6O.cjs');
5
+
6
+ // src/ir/diff.ts
7
+ function keyPath(base, key) {
8
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? base ? `${base}.${key}` : key : `${base}[${JSON.stringify(key)}]`;
9
+ }
10
+ function diffValues(before, after, path, out) {
11
+ if (chunkE3APHA6O_cjs.deepEqual(before, after)) return;
12
+ if (chunkE3APHA6O_cjs.isRecord(before) && chunkE3APHA6O_cjs.isRecord(after)) {
13
+ const keys = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)])].sort();
14
+ for (const key of keys) {
15
+ const left = chunkE3APHA6O_cjs.ownValue(before, key);
16
+ const right = chunkE3APHA6O_cjs.ownValue(after, key);
17
+ if (left === void 0 && right !== void 0)
18
+ out.push({ kind: "added", path: keyPath(path, key), after: right });
19
+ else if (left !== void 0 && right === void 0)
20
+ out.push({ kind: "removed", path: keyPath(path, key), before: left });
21
+ else diffValues(left, right, keyPath(path, key), out);
22
+ }
23
+ return;
24
+ }
25
+ out.push({ kind: "changed", path, before, after });
26
+ }
27
+ function byId(items) {
28
+ const map = /* @__PURE__ */ new Map();
29
+ if (!Array.isArray(items)) return map;
30
+ items.forEach((item, index) => {
31
+ if (!chunkE3APHA6O_cjs.isRecord(item)) return;
32
+ const id = typeof item["id"] === "string" ? item["id"] : `#${index}`;
33
+ if (!map.has(id)) map.set(id, item);
34
+ });
35
+ return map;
36
+ }
37
+ function diffCollection(before, after, path, out) {
38
+ const left = byId(before);
39
+ const right = byId(after);
40
+ for (const [id, item] of left) {
41
+ if (!right.has(id)) out.push({ kind: "removed", path: `${path}[${id}]`, before: item });
42
+ }
43
+ for (const [id, item] of right) {
44
+ const previous = left.get(id);
45
+ if (!previous) out.push({ kind: "added", path: `${path}[${id}]`, after: item });
46
+ else diffValues(previous, item, `${path}[${id}]`, out);
47
+ }
48
+ const common = (ids, other) => ids.filter((id) => other.has(id));
49
+ const leftOrder = common([...left.keys()], right);
50
+ const rightOrder = common([...right.keys()], left);
51
+ if (!chunkE3APHA6O_cjs.deepEqual(leftOrder, rightOrder)) {
52
+ out.push({ kind: "reordered", path, before: leftOrder, after: rightOrder });
53
+ }
54
+ }
55
+ function diffDefinitions(before, after) {
56
+ const left = chunk7YR7DI7B_cjs.hashedProjection(before);
57
+ const right = chunk7YR7DI7B_cjs.hashedProjection(after);
58
+ const out = [];
59
+ if (!chunkE3APHA6O_cjs.isRecord(left) || !chunkE3APHA6O_cjs.isRecord(right)) {
60
+ diffValues(left, right, "", out);
61
+ return out;
62
+ }
63
+ const { data: leftData, ...leftRest } = left;
64
+ const { data: rightData, ...rightRest } = right;
65
+ diffValues(leftRest, rightRest, "", out);
66
+ const leftDataRecord = chunkE3APHA6O_cjs.isRecord(leftData) ? leftData : {};
67
+ const rightDataRecord = chunkE3APHA6O_cjs.isRecord(rightData) ? rightData : {};
68
+ const { nodes: leftNodes, edges: leftEdges, ...leftDataRest } = leftDataRecord;
69
+ const { nodes: rightNodes, edges: rightEdges, ...rightDataRest } = rightDataRecord;
70
+ diffCollection(leftNodes, rightNodes, "data.nodes", out);
71
+ diffCollection(leftEdges, rightEdges, "data.edges", out);
72
+ diffValues(leftDataRest, rightDataRest, "data", out);
73
+ return out;
74
+ }
75
+
76
+ exports.diffDefinitions = diffDefinitions;
@@ -0,0 +1,174 @@
1
+ import { formatRefTemplate, segmentFromKey } from './chunk-UJNHTS6D.js';
2
+
3
+ // src/builder/refs.ts
4
+ var REF_MODEL = /* @__PURE__ */ Symbol.for("fluidgrids.workflows.ref");
5
+ var PREDICATE = /* @__PURE__ */ Symbol.for("fluidgrids.workflows.predicate");
6
+ var PREDICATE_OPERATORS = {
7
+ eq: { operator: "==", unary: false },
8
+ neq: { operator: "!=", unary: false },
9
+ gt: { operator: ">", unary: false },
10
+ gte: { operator: ">=", unary: false },
11
+ lt: { operator: "<", unary: false },
12
+ lte: { operator: "<=", unary: false },
13
+ contains: { operator: "contains", unary: false },
14
+ notContains: { operator: "notContains", unary: false },
15
+ startsWith: { operator: "startsWith", unary: false },
16
+ endsWith: { operator: "endsWith", unary: false },
17
+ matches: { operator: "regex", unary: false },
18
+ hasProperty: { operator: "hasProperty", unary: false },
19
+ isEmpty: { operator: "isEmpty", unary: true },
20
+ isNotEmpty: { operator: "isNotEmpty", unary: true },
21
+ isNull: { operator: "isNull", unary: true },
22
+ isNotNull: { operator: "isNotNull", unary: true },
23
+ isTrue: { operator: "isTrue", unary: true },
24
+ isFalse: { operator: "isFalse", unary: true }
25
+ };
26
+ var RESERVED_REF_KEYS = /* @__PURE__ */ new Set([
27
+ "then",
28
+ "toJSON",
29
+ "toString",
30
+ "valueOf"
31
+ ]);
32
+ var BuilderError = class extends Error {
33
+ constructor(message) {
34
+ super(message);
35
+ this.name = "BuilderError";
36
+ }
37
+ };
38
+ function isRuleValue(value) {
39
+ return value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value);
40
+ }
41
+ function conditionField(ref) {
42
+ const segments = ref.path.map((segment) => {
43
+ const text = segment.kind === "index" ? String(segment.index) : segment.key;
44
+ if (text === "" || text.includes(".")) {
45
+ throw new BuilderError(
46
+ `A condition cannot address the key "${text}" (condition fields are dot-separated); use a raw condition tree`
47
+ );
48
+ }
49
+ return text;
50
+ });
51
+ switch (ref.root.kind) {
52
+ case "node":
53
+ if (ref.root.nodeId.includes(".")) {
54
+ throw new BuilderError(
55
+ `A condition cannot address node "${ref.root.nodeId}"; its id contains a dot`
56
+ );
57
+ }
58
+ return ["WorkflowState", ref.root.nodeId, ...segments].join(".");
59
+ case "json":
60
+ return ["output", ...segments].join(".");
61
+ default:
62
+ throw new BuilderError(
63
+ `A condition can compare node outputs and $json only, not $${ref.root.kind}; use an expression`
64
+ );
65
+ }
66
+ }
67
+ function makePredicate(target, operator, args, unary) {
68
+ const rule = { type: "rule", field: conditionField(target), operator };
69
+ if (!unary) {
70
+ if (args.length < 1 || !isRuleValue(args[0])) {
71
+ throw new BuilderError(
72
+ `The "${operator}" comparison needs a string, number, boolean or null value`
73
+ );
74
+ }
75
+ rule.value = args[0];
76
+ } else if (args.length > 0) {
77
+ throw new BuilderError(`The "${operator}" comparison takes no value`);
78
+ }
79
+ return { [PREDICATE]: rule };
80
+ }
81
+ function callOnRef(model, args) {
82
+ const last = model.path[model.path.length - 1];
83
+ if (last?.kind !== "key") {
84
+ throw new BuilderError("A reference is not a function; call a comparison such as .gte(500)");
85
+ }
86
+ const parent = { root: model.root, path: model.path.slice(0, -1) };
87
+ if (last.key === "is") {
88
+ const [operator, ...rest] = args;
89
+ if (typeof operator !== "string" || operator === "") {
90
+ throw new BuilderError(".is(operator, value) needs an operator name");
91
+ }
92
+ return makePredicate(parent, operator, rest, rest.length === 0);
93
+ }
94
+ const known = PREDICATE_OPERATORS[last.key];
95
+ if (!known) {
96
+ throw new BuilderError(`"${last.key}" is not a comparison; references are data, not functions`);
97
+ }
98
+ return makePredicate(parent, known.operator, args, known.unary);
99
+ }
100
+ function makeRef(root, path = []) {
101
+ const model = { root, path };
102
+ const render = () => formatRefTemplate(model);
103
+ const target = function fluidgridsRef() {
104
+ return void 0;
105
+ };
106
+ const handler = {
107
+ get(_target, property) {
108
+ if (property === REF_MODEL) return model;
109
+ if (property === Symbol.toPrimitive) return render;
110
+ if (typeof property === "symbol") return void 0;
111
+ if (property === "then") return void 0;
112
+ if (property === "toJSON" || property === "toString" || property === "valueOf") return render;
113
+ return makeRef(root, [...path, segmentFromKey(property)]);
114
+ },
115
+ apply(_target, _thisArg, args) {
116
+ return callOnRef(model, args);
117
+ },
118
+ has(_target, property) {
119
+ return property === REF_MODEL;
120
+ },
121
+ set() {
122
+ throw new BuilderError("References are read-only");
123
+ }
124
+ };
125
+ return new Proxy(target, handler);
126
+ }
127
+ function refModelOf(value) {
128
+ if ((typeof value === "function" || typeof value === "object") && value !== null && REF_MODEL in value) {
129
+ const model = value[REF_MODEL];
130
+ return model;
131
+ }
132
+ return void 0;
133
+ }
134
+ function isPredicate(value) {
135
+ return typeof value === "object" && value !== null && PREDICATE in value;
136
+ }
137
+ function predicateTree(predicate) {
138
+ return predicate[PREDICATE];
139
+ }
140
+ function group(combinator, predicates) {
141
+ if (predicates.length === 0)
142
+ throw new BuilderError(`${combinator.toLowerCase()}() needs at least one condition`);
143
+ for (const predicate of predicates) {
144
+ if (!isPredicate(predicate))
145
+ throw new BuilderError(`${combinator.toLowerCase()}() takes conditions only`);
146
+ }
147
+ return { [PREDICATE]: { type: "group", combinator, children: predicates.map(predicateTree) } };
148
+ }
149
+ function and(...predicates) {
150
+ return group("AND", predicates);
151
+ }
152
+ function or(...predicates) {
153
+ return group("OR", predicates);
154
+ }
155
+ function conditionTreeOf(predicate) {
156
+ const tree = predicateTree(predicate);
157
+ return tree.type === "group" ? tree : { type: "group", combinator: "AND", children: [tree] };
158
+ }
159
+ function expr(strings, ...values) {
160
+ let out = strings[0] ?? "";
161
+ values.forEach((value, index) => {
162
+ const model = refModelOf(value);
163
+ if (model) out += formatRefTemplate(model);
164
+ else if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
165
+ out += String(value);
166
+ } else {
167
+ throw new BuilderError("expr`\u2026` interpolates references, strings, numbers and booleans only");
168
+ }
169
+ out += strings[index + 1] ?? "";
170
+ });
171
+ return out;
172
+ }
173
+
174
+ export { BuilderError, PREDICATE_OPERATORS, RESERVED_REF_KEYS, and, conditionTreeOf, expr, isPredicate, makeRef, or, refModelOf };
@@ -0,0 +1,181 @@
1
+ // src/ir/json-utils.ts
2
+ function isRecord(value) {
3
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4
+ }
5
+ function deepEqual(left, right) {
6
+ if (left === right) return true;
7
+ if (Array.isArray(left)) {
8
+ if (!Array.isArray(right) || left.length !== right.length) return false;
9
+ return left.every((item, index) => deepEqual(item, right[index]));
10
+ }
11
+ if (isRecord(left)) {
12
+ if (!isRecord(right)) return false;
13
+ const leftKeys = Object.keys(left).filter((key) => left[key] !== void 0);
14
+ const rightKeys = Object.keys(right).filter((key) => right[key] !== void 0);
15
+ if (leftKeys.length !== rightKeys.length) return false;
16
+ return leftKeys.every((key) => Object.hasOwn(right, key) && deepEqual(left[key], right[key]));
17
+ }
18
+ return false;
19
+ }
20
+ function setOwn(target, key, value) {
21
+ Object.defineProperty(target, key, {
22
+ value,
23
+ enumerable: true,
24
+ writable: true,
25
+ configurable: true
26
+ });
27
+ }
28
+ function ownValue(record, key) {
29
+ return Object.hasOwn(record, key) ? record[key] : void 0;
30
+ }
31
+ function cloneJson(value) {
32
+ return structuredCloneJson(value);
33
+ }
34
+ function structuredCloneJson(value) {
35
+ if (Array.isArray(value)) return value.map(structuredCloneJson);
36
+ if (isRecord(value)) {
37
+ const out = {};
38
+ for (const [key, child] of Object.entries(value)) {
39
+ if (child !== void 0) setOwn(out, key, structuredCloneJson(child));
40
+ }
41
+ return out;
42
+ }
43
+ return value;
44
+ }
45
+
46
+ // src/ir/expressions.ts
47
+ var IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
48
+ function segmentFromKey(key) {
49
+ return /^(0|[1-9][0-9]{0,8})$/.test(key) ? { kind: "index", index: Number(key) } : { kind: "key", key };
50
+ }
51
+ function formatPath(path) {
52
+ return path.map((segment) => {
53
+ if (segment.kind === "index") return `[${segment.index}]`;
54
+ return IDENTIFIER.test(segment.key) ? `.${segment.key}` : `[${JSON.stringify(segment.key)}]`;
55
+ }).join("");
56
+ }
57
+ function formatRefExpression(ref) {
58
+ const path = formatPath(ref.path);
59
+ switch (ref.root.kind) {
60
+ case "node":
61
+ return `$node[${JSON.stringify(ref.root.nodeId)}].item${path}`;
62
+ case "json":
63
+ return `$json${path}`;
64
+ case "vars":
65
+ return `$vars${path}`;
66
+ case "now":
67
+ return `$now${path}`;
68
+ case "execution":
69
+ return `$execution${path}`;
70
+ }
71
+ }
72
+ function formatRefTemplate(ref) {
73
+ return `{{ ${formatRefExpression(ref)} }}`;
74
+ }
75
+ function readJsonString(text, start) {
76
+ if (text[start] !== '"') return void 0;
77
+ let index = start + 1;
78
+ while (index < text.length) {
79
+ const char = text[index];
80
+ if (char === "\\") {
81
+ index += 2;
82
+ continue;
83
+ }
84
+ if (char === '"') {
85
+ try {
86
+ const value = JSON.parse(text.slice(start, index + 1));
87
+ return typeof value === "string" ? { value, end: index + 1 } : void 0;
88
+ } catch {
89
+ return void 0;
90
+ }
91
+ }
92
+ index++;
93
+ }
94
+ return void 0;
95
+ }
96
+ function parsePath(text, start) {
97
+ const path = [];
98
+ let index = start;
99
+ while (index < text.length) {
100
+ if (text[index] === ".") {
101
+ const match = /^[A-Za-z_$][A-Za-z0-9_$]*/.exec(text.slice(index + 1));
102
+ if (!match) return void 0;
103
+ path.push({ kind: "key", key: match[0] });
104
+ index += 1 + match[0].length;
105
+ continue;
106
+ }
107
+ if (text[index] === "[") {
108
+ const digits = /^\[(0|[1-9][0-9]{0,8})\]/.exec(text.slice(index));
109
+ if (digits?.[1] !== void 0) {
110
+ path.push({ kind: "index", index: Number(digits[1]) });
111
+ index += digits[0].length;
112
+ continue;
113
+ }
114
+ const literal = readJsonString(text, index + 1);
115
+ if (!literal || text[literal.end] !== "]") return void 0;
116
+ path.push({ kind: "key", key: literal.value });
117
+ index = literal.end + 1;
118
+ continue;
119
+ }
120
+ return void 0;
121
+ }
122
+ return path;
123
+ }
124
+ function parseRefExpressionLoose(expression) {
125
+ if (expression.startsWith("$node[")) {
126
+ const literal = readJsonString(expression, "$node[".length);
127
+ if (!literal) return void 0;
128
+ const rest = expression.slice(literal.end);
129
+ if (!rest.startsWith("].item")) return void 0;
130
+ const path = parsePath(expression, literal.end + "].item".length);
131
+ return path ? { root: { kind: "node", nodeId: literal.value }, path } : void 0;
132
+ }
133
+ for (const [prefix, kind] of [
134
+ ["$json", "json"],
135
+ ["$vars", "vars"],
136
+ ["$now", "now"],
137
+ ["$execution", "execution"]
138
+ ]) {
139
+ if (expression === prefix || expression.startsWith(`${prefix}.`) || expression.startsWith(`${prefix}[`)) {
140
+ const path = parsePath(expression, prefix.length);
141
+ return path ? { root: { kind }, path } : void 0;
142
+ }
143
+ }
144
+ return void 0;
145
+ }
146
+ function parseRefExpression(expression) {
147
+ const ref = parseRefExpressionLoose(expression);
148
+ return ref && formatRefExpression(ref) === expression ? ref : void 0;
149
+ }
150
+ function parseTemplate(text) {
151
+ if (!text.includes("{{")) return void 0;
152
+ const parts = [];
153
+ let index = 0;
154
+ let sawRef = false;
155
+ while (index < text.length) {
156
+ const open = text.indexOf("{{", index);
157
+ if (open === -1) {
158
+ parts.push({ kind: "text", text: text.slice(index) });
159
+ break;
160
+ }
161
+ if (open > index) parts.push({ kind: "text", text: text.slice(index, open) });
162
+ const close = text.indexOf(" }}", open);
163
+ if (close === -1 || text[open + 2] !== " ") return void 0;
164
+ const ref = parseRefExpression(text.slice(open + 3, close));
165
+ if (!ref) return void 0;
166
+ parts.push({ kind: "ref", ref });
167
+ sawRef = true;
168
+ index = close + 3;
169
+ }
170
+ if (!sawRef) return void 0;
171
+ const rebuilt = parts.map((part) => part.kind === "text" ? part.text : formatRefTemplate(part.ref)).join("");
172
+ return rebuilt === text ? parts : void 0;
173
+ }
174
+ function hasLegacyTemplate(text) {
175
+ return /\$\{[\s\S]*?\}/.test(text);
176
+ }
177
+ function isJsIdentifier(name) {
178
+ return IDENTIFIER.test(name);
179
+ }
180
+
181
+ export { cloneJson, deepEqual, formatRefExpression, formatRefTemplate, hasLegacyTemplate, isJsIdentifier, isRecord, ownValue, parseRefExpression, parseTemplate, segmentFromKey, setOwn };