@shaderfrog/core 0.0.2 → 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.
Files changed (56) hide show
  1. package/README.md +184 -1
  2. package/dist/ast/manipulate.js +328 -0
  3. package/dist/ast/shader-sections.js +256 -0
  4. package/dist/context.js +230 -0
  5. package/dist/engine.js +209 -0
  6. package/dist/evaluate.js +27 -0
  7. package/dist/graph-types.js +7 -0
  8. package/dist/graph.js +381 -0
  9. package/dist/graph.test.js +168 -0
  10. package/dist/nodes/code-nodes.js +18 -0
  11. package/dist/nodes/core-node.js +9 -0
  12. package/dist/nodes/data-nodes.js +123 -0
  13. package/dist/nodes/edge.js +1 -0
  14. package/dist/nodes/engine-node.js +189 -0
  15. package/dist/parsers.js +213 -0
  16. package/dist/plugins/babylon/bablyengine.js +582 -0
  17. package/dist/plugins/babylon/importers.js +64 -0
  18. package/{src/plugins/babylon/index.ts → dist/plugins/babylon/index.js} +0 -1
  19. package/dist/plugins/playcanvas/importers.js +28 -0
  20. package/dist/plugins/playcanvas/index.js +2 -0
  21. package/dist/plugins/playcanvas/playengine.js +510 -0
  22. package/dist/plugins/three/importers.js +15 -0
  23. package/{src/plugins/three/index.ts → dist/plugins/three/index.js} +0 -1
  24. package/dist/plugins/three/threngine.js +495 -0
  25. package/dist/strategy/assignemntTo.js +26 -0
  26. package/dist/strategy/declarationOf.js +23 -0
  27. package/dist/strategy/hardCode.js +23 -0
  28. package/dist/strategy/index.js +38 -0
  29. package/dist/strategy/inject.js +122 -0
  30. package/dist/strategy/namedAttribute.js +48 -0
  31. package/dist/strategy/texture2D.js +83 -0
  32. package/dist/strategy/uniform.js +190 -0
  33. package/dist/strategy/variable.js +80 -0
  34. package/dist/stratgies.test.js +164 -0
  35. package/dist/util/ast.js +9 -0
  36. package/dist/util/ensure.js +7 -0
  37. package/dist/util/id.js +2 -0
  38. package/package.json +12 -4
  39. package/src/ast/manipulate.ts +0 -392
  40. package/src/ast/shader-sections.ts +0 -323
  41. package/src/core/engine.ts +0 -214
  42. package/src/core/file.js +0 -53
  43. package/src/core/graph.ts +0 -1007
  44. package/src/core/nodes/code-nodes.ts +0 -66
  45. package/src/core/nodes/core-node.ts +0 -48
  46. package/src/core/nodes/data-nodes.ts +0 -344
  47. package/src/core/nodes/edge.ts +0 -23
  48. package/src/core/nodes/engine-node.ts +0 -266
  49. package/src/core/strategy.ts +0 -520
  50. package/src/core.test.ts +0 -312
  51. package/src/plugins/babylon/bablyengine.ts +0 -670
  52. package/src/plugins/babylon/importers.ts +0 -69
  53. package/src/plugins/three/importers.ts +0 -18
  54. package/src/plugins/three/threngine.tsx +0 -571
  55. package/src/util/ensure.ts +0 -10
  56. package/src/util/id.ts +0 -2
@@ -0,0 +1,256 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __read = (this && this.__read) || function (o, n) {
13
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
14
+ if (!m) return o;
15
+ var i = m.call(o), r, ar = [], e;
16
+ try {
17
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
18
+ }
19
+ catch (error) { e = { error: error }; }
20
+ finally {
21
+ try {
22
+ if (r && !r.done && (m = i["return"])) m.call(i);
23
+ }
24
+ finally { if (e) throw e.error; }
25
+ }
26
+ return ar;
27
+ };
28
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
29
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
30
+ if (ar || !(i in from)) {
31
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
32
+ ar[i] = from[i];
33
+ }
34
+ }
35
+ return to.concat(ar || Array.prototype.slice.call(from));
36
+ };
37
+ import { generate } from '@shaderfrog/glsl-parser';
38
+ import { makeStatement } from './manipulate';
39
+ export var emptyShaderSections = function () { return ({
40
+ precision: [],
41
+ preprocessor: [],
42
+ version: [],
43
+ structs: [],
44
+ program: [],
45
+ inStatements: [],
46
+ outStatements: [],
47
+ uniforms: [],
48
+ }); };
49
+ var Precision;
50
+ (function (Precision) {
51
+ Precision[Precision["highp"] = 2] = "highp";
52
+ Precision[Precision["mediump"] = 1] = "mediump";
53
+ Precision[Precision["lowp"] = 0] = "lowp";
54
+ })(Precision || (Precision = {}));
55
+ export var higherPrecision = function (p1, p2) {
56
+ return Precision[p1] > Precision[p2] ? p1 : p2;
57
+ };
58
+ export var dedupeVersions = function (nodes) { return nodes[0]; };
59
+ export var highestPrecisions = function (nodes) {
60
+ return Object.entries(nodes.reduce(function (precisions, stmt) {
61
+ var _a;
62
+ return (__assign(__assign({}, precisions), (_a = {}, _a[stmt.declaration.specifier.specifier.token] = higherPrecision(precisions[stmt.declaration.specifier.specifier.token], stmt.declaration.qualifier.token), _a)));
63
+ }, {})).map(function (_a) {
64
+ var _b = __read(_a, 2), typeName = _b[0], precision = _b[1];
65
+ return makeStatement("precision ".concat(precision, " ").concat(typeName));
66
+ });
67
+ };
68
+ export var dedupeQualifiedStatements = function (statements, qualifier) {
69
+ return Object.entries(statements.reduce(function (stmts, stmt) {
70
+ var _a;
71
+ return (__assign(__assign({}, stmts), (_a = {}, _a[stmt.declaration.specified_type.specifier.specifier.token] = __assign(__assign({}, (stmts[stmt.declaration.specified_type.specifier.specifier.token] || {})), stmt.declaration.declarations.reduce(function (types, decl) {
72
+ var _a;
73
+ return (__assign(__assign({}, types), (_a = {}, _a[decl.identifier.identifier] = true, _a)));
74
+ }, {})), _a)));
75
+ }, {})).map(function (_a) {
76
+ var _b = __read(_a, 2), type = _b[0], varNames = _b[1];
77
+ return makeStatement("".concat(qualifier, " ").concat(type, " ").concat(Object.keys(varNames).join(', ')));
78
+ });
79
+ };
80
+ /**
81
+ * Merge uniforms together into lists of identifiers under the same type.
82
+ * There's special case handling for mixing of uniforms with "interface blocks"
83
+ * and those without when merging to make sure the interface block definition is
84
+ * preserved. Check out the tests for more.
85
+ *
86
+ * This function consumes uniforms as found by findShaderSections, so the
87
+ * definitions must line up
88
+ */
89
+ export var dedupeUniforms = function (statements) {
90
+ var groupedByTypeName = Object.entries(statements.reduce(function (stmts, stmt) {
91
+ var _a, _b, _c;
92
+ var _d;
93
+ var decl = stmt.declaration;
94
+ // This is the standard case, a uniform like "uniform vec2 x"
95
+ if ('specified_type' in decl) {
96
+ var specified_type = decl.specified_type;
97
+ var specifier = specified_type.specifier.specifier;
98
+ // Token is for "vec2", "identifier" is for custom names like struct
99
+ var type_1 = 'token' in specifier
100
+ ? specifier.token
101
+ : 'identifier' in specifier
102
+ ? specifier.identifier
103
+ : undefined;
104
+ if (!type_1) {
105
+ console.error('Unknown statement: ', stmt);
106
+ throw new Error("Unknown specifier: ".concat(specifier.type));
107
+ }
108
+ // Groups uniforms into their return type, and for each type, collapses
109
+ // uniform names into an object where the keys determine uniqueness
110
+ // "vec2": { x: x[1] }
111
+ var grouped = decl.declarations.reduce(function (types, decl) {
112
+ var _a;
113
+ var _b, _c, _d;
114
+ var identifier = decl.identifier;
115
+ var quantifier = '';
116
+ if (decl.quantifier) {
117
+ if (!('token' in decl.quantifier[0].expression)) {
118
+ console.error('Unknown expression in quantifier: ', decl);
119
+ throw new Error("Unknown expression in quantifier: ".concat(generate(decl)));
120
+ }
121
+ quantifier = "[".concat(decl.quantifier[0].expression.token, "]");
122
+ }
123
+ return __assign(__assign({}, types), (_a = {}, _a[identifier.identifier] = ((_c = (_b = stmts[type_1]) === null || _b === void 0 ? void 0 : _b[identifier.identifier]) === null || _c === void 0 ? void 0 : _c.hasInterface)
124
+ ? (_d = stmts[type_1]) === null || _d === void 0 ? void 0 : _d[identifier.identifier]
125
+ : {
126
+ hasInterface: false,
127
+ generated: identifier.identifier + quantifier,
128
+ }, _a));
129
+ }, {});
130
+ return __assign(__assign({}, stmts), (_a = {}, _a[type_1] = __assign(__assign({}, (stmts[type_1] || {})), grouped), _a));
131
+ // This is the less common case, a uniform like "uniform Light { vec3 position; } name"
132
+ }
133
+ else if ('interface_type' in decl) {
134
+ var interface_type = decl.interface_type, identifier = decl.identifier;
135
+ // If this is an interface block only, like uniform Scene { mat4 view; };
136
+ // then group the interface block declaration under ''
137
+ var interfaceDeclaredUniform = ((_d = identifier === null || identifier === void 0 ? void 0 : identifier.identifier) === null || _d === void 0 ? void 0 : _d.identifier) || '';
138
+ var node = {
139
+ type: 'interface_declarator',
140
+ lp: decl.lp,
141
+ declarations: decl.declarations,
142
+ qualifiers: [],
143
+ // This is non-nullable, to produce "X" in "uniform X { ... } varName"
144
+ // But it appears "X" is in declarations above
145
+ interface_type: {
146
+ type: 'identifier',
147
+ identifier: '',
148
+ whitespace: '',
149
+ },
150
+ rp: decl.rp,
151
+ };
152
+ return __assign(__assign({}, stmts), (_b = {}, _b[interface_type.identifier] = (_c = {},
153
+ _c[interfaceDeclaredUniform] = {
154
+ generated: "".concat(generate(node)).concat(interfaceDeclaredUniform),
155
+ hasInterface: true,
156
+ },
157
+ _c), _b));
158
+ }
159
+ else {
160
+ console.error('Unknown uniform AST', { stmt: stmt, code: generate(stmt) });
161
+ throw new Error('Unknown uniform AST encountered when merging uniforms');
162
+ }
163
+ }, {}));
164
+ return groupedByTypeName.map(function (_a) {
165
+ var _b = __read(_a, 2), type = _b[0], variables = _b[1];
166
+ return makeStatement("uniform ".concat(type, " ").concat(Object.values(variables)
167
+ .map(function (v) { return v.generated; })
168
+ .join(', ')));
169
+ });
170
+ };
171
+ export var mergeShaderSections = function (s1, s2) {
172
+ return {
173
+ version: __spreadArray(__spreadArray([], __read(s1.version), false), __read(s2.version), false),
174
+ precision: __spreadArray(__spreadArray([], __read(s1.precision), false), __read(s2.precision), false),
175
+ preprocessor: __spreadArray(__spreadArray([], __read(s1.preprocessor), false), __read(s2.preprocessor), false),
176
+ inStatements: __spreadArray(__spreadArray([], __read(s1.inStatements), false), __read(s2.inStatements), false),
177
+ outStatements: __spreadArray(__spreadArray([], __read(s1.outStatements), false), __read(s2.outStatements), false),
178
+ structs: __spreadArray(__spreadArray([], __read(s1.structs), false), __read(s2.structs), false),
179
+ uniforms: __spreadArray(__spreadArray([], __read(s1.uniforms), false), __read(s2.uniforms), false),
180
+ program: __spreadArray(__spreadArray([], __read(s1.program), false), __read(s2.program), false),
181
+ };
182
+ };
183
+ export var shaderSectionsToProgram = function (sections, mergeOptions) { return ({
184
+ type: 'program',
185
+ scopes: [],
186
+ program: __spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read((mergeOptions.includeVersion ? [dedupeVersions(sections.version)] : [])), false), __read((mergeOptions.includePrecisions
187
+ ? highestPrecisions(sections.precision)
188
+ : [])), false), __read(sections.preprocessor), false), __read(sections.structs), false), __read(dedupeQualifiedStatements(sections.inStatements, 'in')), false), __read(dedupeQualifiedStatements(sections.outStatements, 'out')), false), __read(dedupeUniforms(sections.uniforms)), false), __read(sections.program), false),
189
+ }); };
190
+ /**
191
+ * Group an AST into logical sections. The output of this funciton is consumed
192
+ * by the dedupe methods, namely dedupeUniforms, so the data shapes are coupled
193
+ */
194
+ export var findShaderSections = function (ast) {
195
+ var initialValue = {
196
+ precision: [],
197
+ preprocessor: [],
198
+ version: [],
199
+ structs: [],
200
+ inStatements: [],
201
+ outStatements: [],
202
+ uniforms: [],
203
+ program: [],
204
+ };
205
+ return ast.program.reduce(function (sections, node) {
206
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
207
+ if (node.type === 'preprocessor' && node.line.startsWith('#version')) {
208
+ return __assign(__assign({}, sections), { version: sections.version.concat(node) });
209
+ }
210
+ else if (node.type === 'declaration_statement' &&
211
+ node.declaration.type === 'precision') {
212
+ return __assign(__assign({}, sections), { precision: sections.precision.concat(node) });
213
+ }
214
+ else if (node.type === 'preprocessor') {
215
+ return __assign(__assign({}, sections), { preprocessor: sections.preprocessor.concat(node) });
216
+ }
217
+ else if (node.type === 'declaration_statement' &&
218
+ node.declaration.type === 'declarator_list' &&
219
+ ((_d = (_c = (_b = (_a = node.declaration) === null || _a === void 0 ? void 0 : _a.specified_type) === null || _b === void 0 ? void 0 : _b.specifier) === null || _c === void 0 ? void 0 : _c.specifier) === null || _d === void 0 ? void 0 : _d.type) === 'struct') {
220
+ return __assign(__assign({}, sections), { structs: sections.structs.concat(node) });
221
+ // This definition of a uniform lines up with the processing we do in
222
+ // dedupeUniforms
223
+ }
224
+ else if (node.type === 'declaration_statement' &&
225
+ // Ignore lines like "layout(std140,column_major) uniform;"
226
+ !('qualifiers' in node.declaration &&
227
+ ((_f = (_e = node.declaration) === null || _e === void 0 ? void 0 : _e.qualifiers) === null || _f === void 0 ? void 0 : _f.find(function (q) { return 'layout' in q; }))) &&
228
+ // One of these checks is for a uniform with an interface block, and the
229
+ // other is for vanilla uniforms. I don't remember which is which
230
+ (('specified_type' in node.declaration &&
231
+ 'qualifiers' in node.declaration.specified_type &&
232
+ ((_g = node.declaration.specified_type.qualifiers) === null || _g === void 0 ? void 0 : _g.find(function (n) { return 'token' in n && n.token === 'uniform'; }))) ||
233
+ ('qualifiers' in node.declaration &&
234
+ ((_j = (_h = node.declaration) === null || _h === void 0 ? void 0 : _h.qualifiers) === null || _j === void 0 ? void 0 : _j.find(function (n) { return 'token' in n && n.token === 'uniform'; }))))) {
235
+ return __assign(__assign({}, sections), { uniforms: sections.uniforms.concat(node) });
236
+ }
237
+ else if (node.type === 'declaration_statement' &&
238
+ 'specified_type' in node.declaration &&
239
+ ((_m = (_l = (_k = node.declaration) === null || _k === void 0 ? void 0 : _k.specified_type) === null || _l === void 0 ? void 0 : _l.qualifiers) === null || _m === void 0 ? void 0 : _m.find(function (n) { return 'token' in n && n.token === 'in'; }))) {
240
+ if (generate(node).includes('main_Fireball')) {
241
+ console.log('findShaderSections\n', generate(ast));
242
+ console.log("Tracking inStatement \"".concat(generate(node), "\""), node);
243
+ debugger;
244
+ }
245
+ return __assign(__assign({}, sections), { inStatements: sections.inStatements.concat(node) });
246
+ }
247
+ else if (node.type === 'declaration_statement' &&
248
+ 'specified_type' in node.declaration &&
249
+ ((_q = (_p = (_o = node.declaration) === null || _o === void 0 ? void 0 : _o.specified_type) === null || _p === void 0 ? void 0 : _p.qualifiers) === null || _q === void 0 ? void 0 : _q.find(function (n) { return 'token' in n && n.token === 'out'; }))) {
250
+ return __assign(__assign({}, sections), { outStatements: sections.outStatements.concat(node) });
251
+ }
252
+ else {
253
+ return __assign(__assign({}, sections), { program: sections.program.concat(node) });
254
+ }
255
+ }, initialValue);
256
+ };
@@ -0,0 +1,230 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ var __read = (this && this.__read) || function (o, n) {
49
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
50
+ if (!m) return o;
51
+ var i = m.call(o), r, ar = [], e;
52
+ try {
53
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
54
+ }
55
+ catch (error) { e = { error: error }; }
56
+ finally {
57
+ try {
58
+ if (r && !r.done && (m = i["return"])) m.call(i);
59
+ }
60
+ finally { if (e) throw e.error; }
61
+ }
62
+ return ar;
63
+ };
64
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
65
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
66
+ if (ar || !(i in from)) {
67
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
68
+ ar[i] = from[i];
69
+ }
70
+ }
71
+ return to.concat(ar || Array.prototype.slice.call(from));
72
+ };
73
+ import groupBy from 'lodash.groupby';
74
+ import { mapInputName, SourceType, } from './nodes/code-nodes';
75
+ import { NodeType } from './graph-types';
76
+ import { collectConnectedNodes, filterGraphFromNode, isSourceNode, mangleEntireProgram, } from './graph';
77
+ import { coreParsers } from './parsers';
78
+ var makeError = function () {
79
+ var errors = [];
80
+ for (var _i = 0; _i < arguments.length; _i++) {
81
+ errors[_i] = arguments[_i];
82
+ }
83
+ return ({
84
+ type: 'errors',
85
+ errors: errors,
86
+ });
87
+ };
88
+ var isError = function (test) { return (test === null || test === void 0 ? void 0 : test.type) === 'errors'; };
89
+ // Merge existing node inputs, and inputs based on properties, with new ones
90
+ // found from the source code, using the *id* as the uniqueness key. Any filler input gets
91
+ // merged into property inputs with the same id. This preserves the
92
+ // "baked" property on node inputs which is toggle-able in the graph
93
+ var collapseNodeInputs = function (node, updatedInputs) {
94
+ return Object.values(groupBy(__spreadArray(__spreadArray([], __read(updatedInputs), false), __read(node.inputs), false), function (i) { return i.id; })).map(function (dupes) { return dupes.reduce(function (node, dupe) { return (__assign(__assign({}, node), dupe)); }); });
95
+ };
96
+ var computeNodeContext = function (engineContext, engine, graph, node) { return __awaiter(void 0, void 0, void 0, function () {
97
+ var parser, onBeforeCompile, manipulateAst, groupId_1, sibling, inputEdges, ast, dataInputs, computedInputs, nodeContext;
98
+ return __generator(this, function (_a) {
99
+ switch (_a.label) {
100
+ case 0:
101
+ parser = __assign(__assign({}, (coreParsers[node.type] || coreParsers[NodeType.SOURCE])), (engine.parsers[node.type] || {}));
102
+ onBeforeCompile = parser.onBeforeCompile, manipulateAst = parser.manipulateAst;
103
+ if (!onBeforeCompile) return [3 /*break*/, 2];
104
+ groupId_1 = node.groupId;
105
+ sibling = graph.nodes.find(function (n) {
106
+ return n !== node && 'groupId' in n && n.groupId === groupId_1;
107
+ });
108
+ return [4 /*yield*/, onBeforeCompile(graph, engineContext, node, sibling)];
109
+ case 1:
110
+ _a.sent();
111
+ _a.label = 2;
112
+ case 2:
113
+ inputEdges = graph.edges.filter(function (edge) { return edge.to === node.id; });
114
+ try {
115
+ ast = parser.produceAst(engineContext, engine, graph, node, inputEdges);
116
+ if (manipulateAst) {
117
+ ast = manipulateAst(engineContext, engine, graph, node, ast, inputEdges);
118
+ }
119
+ }
120
+ catch (error) {
121
+ console.error('Error parsing source code!', { error: error, node: node });
122
+ return [2 /*return*/, makeError(error)];
123
+ }
124
+ dataInputs = groupBy(filterGraphFromNode(graph, node, {
125
+ input: function (input, b, c, fromNode) {
126
+ return input.bakeable && (fromNode === null || fromNode === void 0 ? void 0 : fromNode.type) === 'source';
127
+ },
128
+ }, 1).inputs[node.id] || [], 'id');
129
+ computedInputs = parser.findInputs(engineContext, node, ast, inputEdges);
130
+ node.inputs = collapseNodeInputs(node, computedInputs.map(function (_a) {
131
+ var _b = __read(_a, 1), i = _b[0];
132
+ return (__assign(__assign({}, i), { displayName: mapInputName(node, i) }));
133
+ })).map(function (input) { return (__assign(__assign({}, input), (input.id in dataInputs ? { baked: true } : {}))); });
134
+ nodeContext = {
135
+ ast: ast,
136
+ id: node.id,
137
+ inputFillers: computedInputs.reduce(function (acc, _a) {
138
+ var _b;
139
+ var _c = __read(_a, 3), input = _c[0], filler = _c[1], args = _c[2];
140
+ return (__assign(__assign({}, acc), (_b = {}, _b[input.id] = {
141
+ filler: filler,
142
+ args: args,
143
+ }, _b)));
144
+ }, {}),
145
+ };
146
+ // Skip mangling if the node tells us to, which probably means it's an engine
147
+ // node where we don't care about renaming all the variables, or if it's
148
+ // an expression, where we want to be in the context of other variables
149
+ // TODO: Use global undefined engine variables here?
150
+ if (node.config.mangle !== false &&
151
+ node.sourceType !== SourceType.EXPRESSION &&
152
+ node.sourceType !== SourceType.FN_BODY_FRAGMENT) {
153
+ mangleEntireProgram(ast, node, engine);
154
+ }
155
+ return [2 /*return*/, nodeContext];
156
+ }
157
+ });
158
+ }); };
159
+ export var computeContextForNodes = function (engineContext, engine, graph, nodes) { return __awaiter(void 0, void 0, void 0, function () {
160
+ return __generator(this, function (_a) {
161
+ return [2 /*return*/, nodes
162
+ .filter(isSourceNode)
163
+ .reduce(function (ctx, node) { return __awaiter(void 0, void 0, void 0, function () {
164
+ var context, nodeContext;
165
+ return __generator(this, function (_a) {
166
+ switch (_a.label) {
167
+ case 0: return [4 /*yield*/, ctx];
168
+ case 1:
169
+ context = _a.sent();
170
+ if (isError(context)) {
171
+ return [2 /*return*/, context];
172
+ }
173
+ return [4 /*yield*/, computeNodeContext(engineContext, engine, graph, node)];
174
+ case 2:
175
+ nodeContext = _a.sent();
176
+ if (isError(nodeContext)) {
177
+ return [2 /*return*/, makeError(nodeContext)];
178
+ }
179
+ context[node.id] = __assign(__assign({}, (context[node.id] || {})), nodeContext);
180
+ return [2 /*return*/, context];
181
+ }
182
+ });
183
+ }); }, Promise.resolve(engineContext.nodes))];
184
+ });
185
+ }); };
186
+ /**
187
+ * Compute the context for every node in the graph, done on initial graph load
188
+ * to compute the inputs/outputs for every node
189
+ */
190
+ export var computeAllContexts = function (engineContext, engine, graph) { return computeContextForNodes(engineContext, engine, graph, graph.nodes); };
191
+ /**
192
+ * Compute the contexts for nodes starting from the outputs, working backwards.
193
+ * Used to only (re)-compute context for any actively used nodes
194
+ */
195
+ export var computeGraphContext = function (engineContext, engine, graph) { return __awaiter(void 0, void 0, void 0, function () {
196
+ var outputFrag, outputVert, vertexIds, fragmentIds, additionalIds;
197
+ return __generator(this, function (_a) {
198
+ switch (_a.label) {
199
+ case 0:
200
+ outputFrag = graph.nodes.find(function (node) { return node.type === 'output' && node.stage === 'fragment'; });
201
+ if (!outputFrag) {
202
+ throw new Error('No fragment output in graph');
203
+ }
204
+ outputVert = graph.nodes.find(function (node) { return node.type === 'output' && node.stage === 'vertex'; });
205
+ if (!outputVert) {
206
+ throw new Error('No vertex output in graph');
207
+ }
208
+ vertexIds = collectConnectedNodes(graph, outputVert);
209
+ fragmentIds = collectConnectedNodes(graph, outputFrag);
210
+ additionalIds = graph.nodes.filter(function (node) {
211
+ return isSourceNode(node) &&
212
+ node.stage === 'vertex' &&
213
+ node.nextStageNodeId &&
214
+ fragmentIds[node.nextStageNodeId] &&
215
+ !vertexIds[node.id];
216
+ });
217
+ return [4 /*yield*/, computeContextForNodes(engineContext, engine, graph, __spreadArray(__spreadArray([
218
+ outputVert
219
+ ], __read(Object.values(vertexIds).filter(function (node) { return node.id !== outputVert.id; })), false), __read(additionalIds), false))];
220
+ case 1:
221
+ _a.sent();
222
+ return [4 /*yield*/, computeContextForNodes(engineContext, engine, graph, __spreadArray([
223
+ outputFrag
224
+ ], __read(Object.values(fragmentIds).filter(function (node) { return node.id !== outputFrag.id; })), false))];
225
+ case 2:
226
+ _a.sent();
227
+ return [2 /*return*/];
228
+ }
229
+ });
230
+ }); };