@n8n/expression-runtime 0.30.0 → 0.31.0

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 (120) hide show
  1. package/README.md +4 -0
  2. package/dist/bundle/runtime.esm.js +17 -17
  3. package/dist/bundle/runtime.esm.js.map +4 -4
  4. package/dist/bundle/runtime.iife.js +17 -17
  5. package/dist/bundle/runtime.iife.js.map +4 -4
  6. package/dist/cjs/bridge/host-functions.d.ts +74 -0
  7. package/dist/cjs/bridge/host-functions.d.ts.map +1 -0
  8. package/dist/cjs/bridge/host-functions.js +336 -0
  9. package/dist/cjs/bridge/host-functions.js.map +1 -0
  10. package/dist/cjs/bridge/isolated-vm-bridge.d.ts +24 -150
  11. package/dist/cjs/bridge/isolated-vm-bridge.d.ts.map +1 -1
  12. package/dist/cjs/bridge/isolated-vm-bridge.js +130 -429
  13. package/dist/cjs/bridge/isolated-vm-bridge.js.map +1 -1
  14. package/dist/cjs/bridge/quickjs-bridge.d.ts +21 -6
  15. package/dist/cjs/bridge/quickjs-bridge.d.ts.map +1 -1
  16. package/dist/cjs/bridge/quickjs-bridge.js +377 -402
  17. package/dist/cjs/bridge/quickjs-bridge.js.map +1 -1
  18. package/dist/cjs/build.tsbuildinfo +1 -1
  19. package/dist/cjs/evaluator/expression-evaluator.d.ts +17 -0
  20. package/dist/cjs/evaluator/expression-evaluator.d.ts.map +1 -1
  21. package/dist/cjs/evaluator/expression-evaluator.js +61 -1
  22. package/dist/cjs/evaluator/expression-evaluator.js.map +1 -1
  23. package/dist/cjs/extensions/array-extensions.d.ts.map +1 -1
  24. package/dist/cjs/extensions/array-extensions.js +7 -15
  25. package/dist/cjs/extensions/array-extensions.js.map +1 -1
  26. package/dist/cjs/extensions/function-extensions.d.ts.map +1 -1
  27. package/dist/cjs/extensions/function-extensions.js +2 -10
  28. package/dist/cjs/extensions/function-extensions.js.map +1 -1
  29. package/dist/cjs/extensions/object-extensions.d.ts.map +1 -1
  30. package/dist/cjs/extensions/object-extensions.js +3 -11
  31. package/dist/cjs/extensions/object-extensions.js.map +1 -1
  32. package/dist/cjs/extensions/utils.d.ts +1 -0
  33. package/dist/cjs/extensions/utils.d.ts.map +1 -1
  34. package/dist/cjs/extensions/utils.js +10 -0
  35. package/dist/cjs/extensions/utils.js.map +1 -1
  36. package/dist/cjs/observability/metrics.d.ts +12 -0
  37. package/dist/cjs/observability/metrics.d.ts.map +1 -1
  38. package/dist/cjs/observability/metrics.js +12 -0
  39. package/dist/cjs/observability/metrics.js.map +1 -1
  40. package/dist/cjs/runtime/lazy-proxy.d.ts +2 -0
  41. package/dist/cjs/runtime/lazy-proxy.d.ts.map +1 -1
  42. package/dist/cjs/runtime/lazy-proxy.js +29 -15
  43. package/dist/cjs/runtime/lazy-proxy.js.map +1 -1
  44. package/dist/cjs/runtime/luxon-transfer.d.ts +62 -0
  45. package/dist/cjs/runtime/luxon-transfer.d.ts.map +1 -0
  46. package/dist/cjs/runtime/luxon-transfer.js +200 -0
  47. package/dist/cjs/runtime/luxon-transfer.js.map +1 -0
  48. package/dist/cjs/runtime/serialize.d.ts +7 -7
  49. package/dist/cjs/runtime/serialize.d.ts.map +1 -1
  50. package/dist/cjs/runtime/serialize.js +42 -30
  51. package/dist/cjs/runtime/serialize.js.map +1 -1
  52. package/dist/cjs/runtime/transfer.d.ts +77 -0
  53. package/dist/cjs/runtime/transfer.d.ts.map +1 -0
  54. package/dist/cjs/runtime/transfer.js +183 -0
  55. package/dist/cjs/runtime/transfer.js.map +1 -0
  56. package/dist/cjs/types/bridge.d.ts +16 -0
  57. package/dist/cjs/types/bridge.d.ts.map +1 -1
  58. package/dist/cjs/types/bridge.js +1 -0
  59. package/dist/cjs/types/bridge.js.map +1 -1
  60. package/dist/cjs/types/evaluator.d.ts +9 -0
  61. package/dist/cjs/types/evaluator.d.ts.map +1 -1
  62. package/dist/cjs/types/evaluator.js.map +1 -1
  63. package/dist/esm/bridge/host-functions.d.ts +74 -0
  64. package/dist/esm/bridge/host-functions.d.ts.map +1 -0
  65. package/dist/esm/bridge/host-functions.js +328 -0
  66. package/dist/esm/bridge/host-functions.js.map +1 -0
  67. package/dist/esm/bridge/isolated-vm-bridge.d.ts +24 -150
  68. package/dist/esm/bridge/isolated-vm-bridge.d.ts.map +1 -1
  69. package/dist/esm/bridge/isolated-vm-bridge.js +126 -425
  70. package/dist/esm/bridge/isolated-vm-bridge.js.map +1 -1
  71. package/dist/esm/bridge/quickjs-bridge.d.ts +21 -6
  72. package/dist/esm/bridge/quickjs-bridge.d.ts.map +1 -1
  73. package/dist/esm/bridge/quickjs-bridge.js +368 -393
  74. package/dist/esm/bridge/quickjs-bridge.js.map +1 -1
  75. package/dist/esm/build.tsbuildinfo +1 -1
  76. package/dist/esm/evaluator/expression-evaluator.d.ts +17 -0
  77. package/dist/esm/evaluator/expression-evaluator.d.ts.map +1 -1
  78. package/dist/esm/evaluator/expression-evaluator.js +61 -1
  79. package/dist/esm/evaluator/expression-evaluator.js.map +1 -1
  80. package/dist/esm/extensions/array-extensions.d.ts.map +1 -1
  81. package/dist/esm/extensions/array-extensions.js +1 -9
  82. package/dist/esm/extensions/array-extensions.js.map +1 -1
  83. package/dist/esm/extensions/function-extensions.d.ts.map +1 -1
  84. package/dist/esm/extensions/function-extensions.js +1 -9
  85. package/dist/esm/extensions/function-extensions.js.map +1 -1
  86. package/dist/esm/extensions/object-extensions.d.ts.map +1 -1
  87. package/dist/esm/extensions/object-extensions.js +1 -9
  88. package/dist/esm/extensions/object-extensions.js.map +1 -1
  89. package/dist/esm/extensions/utils.d.ts +1 -0
  90. package/dist/esm/extensions/utils.d.ts.map +1 -1
  91. package/dist/esm/extensions/utils.js +9 -0
  92. package/dist/esm/extensions/utils.js.map +1 -1
  93. package/dist/esm/observability/metrics.d.ts +12 -0
  94. package/dist/esm/observability/metrics.d.ts.map +1 -1
  95. package/dist/esm/observability/metrics.js +12 -0
  96. package/dist/esm/observability/metrics.js.map +1 -1
  97. package/dist/esm/runtime/lazy-proxy.d.ts +2 -0
  98. package/dist/esm/runtime/lazy-proxy.d.ts.map +1 -1
  99. package/dist/esm/runtime/lazy-proxy.js +29 -15
  100. package/dist/esm/runtime/lazy-proxy.js.map +1 -1
  101. package/dist/esm/runtime/luxon-transfer.d.ts +62 -0
  102. package/dist/esm/runtime/luxon-transfer.d.ts.map +1 -0
  103. package/dist/esm/runtime/luxon-transfer.js +183 -0
  104. package/dist/esm/runtime/luxon-transfer.js.map +1 -0
  105. package/dist/esm/runtime/serialize.d.ts +7 -7
  106. package/dist/esm/runtime/serialize.d.ts.map +1 -1
  107. package/dist/esm/runtime/serialize.js +42 -30
  108. package/dist/esm/runtime/serialize.js.map +1 -1
  109. package/dist/esm/runtime/transfer.d.ts +77 -0
  110. package/dist/esm/runtime/transfer.d.ts.map +1 -0
  111. package/dist/esm/runtime/transfer.js +173 -0
  112. package/dist/esm/runtime/transfer.js.map +1 -0
  113. package/dist/esm/types/bridge.d.ts +16 -0
  114. package/dist/esm/types/bridge.d.ts.map +1 -1
  115. package/dist/esm/types/bridge.js +1 -0
  116. package/dist/esm/types/bridge.js.map +1 -1
  117. package/dist/esm/types/evaluator.d.ts +9 -0
  118. package/dist/esm/types/evaluator.d.ts.map +1 -1
  119. package/dist/esm/types/evaluator.js.map +1 -1
  120. package/package.json +6 -6
@@ -0,0 +1,74 @@
1
+ import type { WorkflowData } from '../types';
2
+ import type { ErrorSentinel } from '../runtime/lazy-proxy';
3
+ /** Check if a value is an error sentinel returned by serializeError. */
4
+ export declare function isErrorSentinel(value: unknown): value is ErrorSentinel;
5
+ /**
6
+ * Serialize an error into a transferable metadata object.
7
+ *
8
+ * Host-side callbacks (getValueAtPath, etc.) catch errors and return this
9
+ * sentinel instead of letting the error cross the boundary (which strips
10
+ * custom class identity and properties). The guest-side proxy detects
11
+ * __isError and throws the sentinel; the host reconstructs a real Error
12
+ * after it round-trips back (see reconstructError).
13
+ */
14
+ export declare function serializeError(err: unknown): ErrorSentinel;
15
+ /**
16
+ * Reconstruct an error from a serialized error sentinel.
17
+ *
18
+ * Restores the name, stack, and custom properties that would otherwise be
19
+ * lost crossing the guest boundary.
20
+ */
21
+ export declare function reconstructError(data: ErrorSentinel): Error;
22
+ /**
23
+ * Navigate the data object by path and return metadata or a primitive value.
24
+ *
25
+ * Used by createDeepLazyProxy when accessing properties. Returns metadata
26
+ * markers for arrays and objects, or the primitive value directly.
27
+ *
28
+ * Special-case: paths starting with ['$item', index] call data.$item(index)
29
+ * to get the sub-proxy for that item, then continue navigating the rest;
30
+ * likewise ['$', nodeName] calls data.$(nodeName).
31
+ *
32
+ * Function-typed values are returned as `undefined` — every callable on
33
+ * the host data surface (`$('Foo').first()`, `$items()`, `$fromAI()`,
34
+ * `$evaluateExpression()`, `$getPairedItem()`) is wired guest-side via
35
+ * the typed-RPC dispatcher (`callHost`). No expression form should
36
+ * reach a function through this path (invariant:
37
+ * __tests__/host-fn-shadowing.test.ts).
38
+ */
39
+ export declare function getValueAtPath(data: WorkflowData, pathArr: string[]): unknown;
40
+ /**
41
+ * Get an array element at an index, navigating to the array by path first
42
+ * (same `$`/`$item` special-casing as getValueAtPath).
43
+ *
44
+ * Used by the array proxy when accessing numeric indices.
45
+ */
46
+ export declare function getArrayElement(data: WorkflowData, pathArr: string[], index: number): unknown;
47
+ /**
48
+ * Host-side dispatcher for the typed-RPC `callHost` channel.
49
+ *
50
+ * The guest sends one envelope per typed RPC invocation:
51
+ * `callHost({ type: 'getNodeFirst', nodeName, branchIndex?, runIndex? })`
52
+ *
53
+ * Inputs cross a trust boundary, so the dispatcher parses every envelope
54
+ * with the host-side zod schema (`bridgeMessageSchema`) before any
55
+ * dispatch happens. Anything that deviates from the declared shape —
56
+ * unknown `type`, missing required fields, extra unexpected fields,
57
+ * wrong field types — fails the parse and throws; the calling bridge
58
+ * catches and returns an error sentinel to the guest.
59
+ *
60
+ * After parsing, `switch (msg.type)` dispatches with a fully narrowed
61
+ * message type. The operation set is exactly the cases in this switch;
62
+ * the `type` field selects a static branch in source, not a property
63
+ * lookup on a runtime object. Each case reads a fixed literal property
64
+ * name off the host-side data proxy — the guest cannot influence which
65
+ * property is dereferenced.
66
+ *
67
+ * Return-value note: cases must return plain, structured-clone-able,
68
+ * JSON-shaped data. Each bridge marshals the result across its own
69
+ * boundary (structured clone for isolated-vm, sentinel-wrapped JSON
70
+ * round-trip for QuickJS), so engine objects or other non-cloneable
71
+ * values must not be returned.
72
+ */
73
+ export declare function dispatchHostCall(rawMsg: unknown, data: WorkflowData): unknown;
74
+ //# sourceMappingURL=host-functions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-functions.d.ts","sourceRoot":"","sources":["../../../src/bridge/host-functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAc3D,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAMtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CAc1D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,KAAK,CAa3D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CA0D7E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAmE7F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CA2G7E"}
@@ -0,0 +1,336 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isErrorSentinel = isErrorSentinel;
4
+ exports.serializeError = serializeError;
5
+ exports.reconstructError = reconstructError;
6
+ exports.getValueAtPath = getValueAtPath;
7
+ exports.getArrayElement = getArrayElement;
8
+ exports.dispatchHostCall = dispatchHostCall;
9
+ const bridge_messages_1 = require("./bridge-messages");
10
+ // ============================================================================
11
+ // Host-side functions shared by the expression bridges.
12
+ //
13
+ // Both IsolatedVmBridge and QuickJsBridge expose the same three host
14
+ // callbacks to the guest — getValueAtPath, getArrayElement, callHost — plus
15
+ // the error-sentinel helpers and bundle loader around them. The logic is
16
+ // engine-agnostic: each bridge wraps these pure functions in its own
17
+ // callback mechanism (ivm.Callback / vm.newFunction) and marshals the
18
+ // plain, JSON-shaped return values across its own boundary.
19
+ // ============================================================================
20
+ /** Check if a value is an error sentinel returned by serializeError. */
21
+ function isErrorSentinel(value) {
22
+ return (typeof value === 'object' &&
23
+ value !== null &&
24
+ value.__isError === true);
25
+ }
26
+ /**
27
+ * Serialize an error into a transferable metadata object.
28
+ *
29
+ * Host-side callbacks (getValueAtPath, etc.) catch errors and return this
30
+ * sentinel instead of letting the error cross the boundary (which strips
31
+ * custom class identity and properties). The guest-side proxy detects
32
+ * __isError and throws the sentinel; the host reconstructs a real Error
33
+ * after it round-trips back (see reconstructError).
34
+ */
35
+ function serializeError(err) {
36
+ if (err instanceof Error) {
37
+ const extra = Object.fromEntries(Object.entries(err).filter(([key]) => key !== 'name' && key !== 'message' && key !== 'stack'));
38
+ return {
39
+ __isError: true,
40
+ name: err.name,
41
+ message: err.message,
42
+ stack: err.stack,
43
+ extra,
44
+ };
45
+ }
46
+ return { __isError: true, name: 'Error', message: String(err), extra: {} };
47
+ }
48
+ /**
49
+ * Reconstruct an error from a serialized error sentinel.
50
+ *
51
+ * Restores the name, stack, and custom properties that would otherwise be
52
+ * lost crossing the guest boundary.
53
+ */
54
+ function reconstructError(data) {
55
+ const error = new Error(data.message);
56
+ error.name = data.name || 'Error';
57
+ if (data.stack) {
58
+ error.stack = data.stack;
59
+ }
60
+ // Restore custom properties transferred across the boundary
61
+ if (data.extra) {
62
+ Object.assign(error, data.extra);
63
+ }
64
+ return error;
65
+ }
66
+ /**
67
+ * Navigate the data object by path and return metadata or a primitive value.
68
+ *
69
+ * Used by createDeepLazyProxy when accessing properties. Returns metadata
70
+ * markers for arrays and objects, or the primitive value directly.
71
+ *
72
+ * Special-case: paths starting with ['$item', index] call data.$item(index)
73
+ * to get the sub-proxy for that item, then continue navigating the rest;
74
+ * likewise ['$', nodeName] calls data.$(nodeName).
75
+ *
76
+ * Function-typed values are returned as `undefined` — every callable on
77
+ * the host data surface (`$('Foo').first()`, `$items()`, `$fromAI()`,
78
+ * `$evaluateExpression()`, `$getPairedItem()`) is wired guest-side via
79
+ * the typed-RPC dispatcher (`callHost`). No expression form should
80
+ * reach a function through this path (invariant:
81
+ * __tests__/host-fn-shadowing.test.ts).
82
+ */
83
+ function getValueAtPath(data, pathArr) {
84
+ let value = data;
85
+ let startIndex = 0;
86
+ const itemFn = data.$item;
87
+ if (pathArr.length >= 2 && pathArr[0] === '$item' && typeof itemFn === 'function') {
88
+ const itemIndex = parseInt(pathArr[1], 10);
89
+ if (!isNaN(itemIndex)) {
90
+ value = itemFn(itemIndex);
91
+ startIndex = 2;
92
+ }
93
+ }
94
+ else {
95
+ const dollarFn = data.$;
96
+ if (pathArr.length >= 2 && pathArr[0] === '$' && typeof dollarFn === 'function') {
97
+ value = dollarFn(pathArr[1]);
98
+ startIndex = 2;
99
+ }
100
+ }
101
+ for (let i = startIndex; i < pathArr.length; i++) {
102
+ value = value?.[pathArr[i]];
103
+ if (value === undefined || value === null) {
104
+ return value;
105
+ }
106
+ }
107
+ // Functions are not reachable via the lazy-proxy data path —
108
+ // every callable on the host data surface routes through the
109
+ // typed-RPC dispatcher. Return undefined so any residual
110
+ // access surfaces as missing rather than as a stale metadata
111
+ // marker the runtime no longer knows how to interpret.
112
+ if (typeof value === 'function') {
113
+ return undefined;
114
+ }
115
+ // Handle arrays - always lazy, only transfer length
116
+ if (Array.isArray(value)) {
117
+ return {
118
+ __isArray: true,
119
+ __length: value.length,
120
+ __data: null,
121
+ };
122
+ }
123
+ // Dates have no enumerable own keys; pass through instead of
124
+ // marshaling as an empty object.
125
+ if (value instanceof Date) {
126
+ return value;
127
+ }
128
+ // Handle objects - return metadata with keys
129
+ if (value !== null && typeof value === 'object') {
130
+ return {
131
+ __isObject: true,
132
+ __keys: Object.keys(value),
133
+ };
134
+ }
135
+ // Primitive value
136
+ return value;
137
+ }
138
+ /**
139
+ * Get an array element at an index, navigating to the array by path first
140
+ * (same `$`/`$item` special-casing as getValueAtPath).
141
+ *
142
+ * Used by the array proxy when accessing numeric indices.
143
+ */
144
+ function getArrayElement(data, pathArr, index) {
145
+ let arr = data;
146
+ let startIndex = 0;
147
+ const itemFn = data.$item;
148
+ if (pathArr.length >= 2 && pathArr[0] === '$item' && typeof itemFn === 'function') {
149
+ const itemIndex = parseInt(pathArr[1], 10);
150
+ if (!isNaN(itemIndex)) {
151
+ arr = itemFn(itemIndex);
152
+ startIndex = 2;
153
+ }
154
+ }
155
+ else {
156
+ const dollarFn = data.$;
157
+ if (pathArr.length >= 2 && pathArr[0] === '$' && typeof dollarFn === 'function') {
158
+ arr = dollarFn(pathArr[1]);
159
+ startIndex = 2;
160
+ }
161
+ }
162
+ for (let i = startIndex; i < pathArr.length; i++) {
163
+ arr = arr?.[pathArr[i]];
164
+ if (arr === undefined || arr === null) {
165
+ return undefined;
166
+ }
167
+ }
168
+ if (!Array.isArray(arr)) {
169
+ return undefined;
170
+ }
171
+ // Only genuine array indices are reachable; anything else (e.g.
172
+ // 'constructor', '__lookupGetter__') would read off the prototype
173
+ // chain and could leak a host function reference across the boundary.
174
+ if (!Number.isInteger(index) || index < 0) {
175
+ return undefined;
176
+ }
177
+ const element = arr[index];
178
+ // Functions are never reachable through the data surface — mirror the
179
+ // guard in getValueAtPath so a host callable can't cross the boundary
180
+ // (invariant: __tests__/host-fn-shadowing.test.ts).
181
+ if (typeof element === 'function') {
182
+ return undefined;
183
+ }
184
+ // Dates have no enumerable own keys; pass through instead of
185
+ // marshaling as an empty object.
186
+ if (element instanceof Date) {
187
+ return element;
188
+ }
189
+ // If element is object/array, return metadata
190
+ if (element !== null && typeof element === 'object') {
191
+ if (Array.isArray(element)) {
192
+ return {
193
+ __isArray: true,
194
+ __length: element.length,
195
+ __data: null,
196
+ };
197
+ }
198
+ return {
199
+ __isObject: true,
200
+ __keys: Object.keys(element),
201
+ };
202
+ }
203
+ // Primitive element
204
+ return element;
205
+ }
206
+ /**
207
+ * Host-side dispatcher for the typed-RPC `callHost` channel.
208
+ *
209
+ * The guest sends one envelope per typed RPC invocation:
210
+ * `callHost({ type: 'getNodeFirst', nodeName, branchIndex?, runIndex? })`
211
+ *
212
+ * Inputs cross a trust boundary, so the dispatcher parses every envelope
213
+ * with the host-side zod schema (`bridgeMessageSchema`) before any
214
+ * dispatch happens. Anything that deviates from the declared shape —
215
+ * unknown `type`, missing required fields, extra unexpected fields,
216
+ * wrong field types — fails the parse and throws; the calling bridge
217
+ * catches and returns an error sentinel to the guest.
218
+ *
219
+ * After parsing, `switch (msg.type)` dispatches with a fully narrowed
220
+ * message type. The operation set is exactly the cases in this switch;
221
+ * the `type` field selects a static branch in source, not a property
222
+ * lookup on a runtime object. Each case reads a fixed literal property
223
+ * name off the host-side data proxy — the guest cannot influence which
224
+ * property is dereferenced.
225
+ *
226
+ * Return-value note: cases must return plain, structured-clone-able,
227
+ * JSON-shaped data. Each bridge marshals the result across its own
228
+ * boundary (structured clone for isolated-vm, sentinel-wrapped JSON
229
+ * round-trip for QuickJS), so engine objects or other non-cloneable
230
+ * values must not be returned.
231
+ */
232
+ function dispatchHostCall(rawMsg, data) {
233
+ const msg = bridge_messages_1.bridgeMessageSchema.parse(rawMsg);
234
+ switch (msg.type) {
235
+ // The `$('Foo').{first,last,all}` typed RPCs.
236
+ //
237
+ // Eliminating `data.$` as a host-callable entirely would require
238
+ // reaching the `WorkflowDataProxy` internals (e.g.
239
+ // `getNodeExecutionOrPinnedData`) rather than the public `$()` API;
240
+ // that's a follow-up.
241
+ //
242
+ // `data.$` is a host-wired function (`WorkflowDataProxy`'s `$`). If it
243
+ // ever isn't, optional chaining short-circuits to `undefined` — the
244
+ // same observable result the runtime's `E()` handler produces from any
245
+ // thrown error here.
246
+ case 'getNodeFirst':
247
+ return data.$?.(msg.nodeName)?.first?.(msg.branchIndex, msg.runIndex);
248
+ case 'getNodeLast':
249
+ return data.$?.(msg.nodeName)?.last?.(msg.branchIndex, msg.runIndex);
250
+ case 'getNodeAll':
251
+ return data.$?.(msg.nodeName)?.all?.(msg.branchIndex, msg.runIndex);
252
+ // The `$input.{first,last,all}` typed RPCs.
253
+ //
254
+ // Each reads a fixed literal property name off `data.$input` (the
255
+ // host's `WorkflowDataProxy` input proxy). The host enforces zero
256
+ // arguments on these methods — the schemas have no fields besides
257
+ // `type`, so the guest cannot pass anything that would trigger the
258
+ // "should have no arguments" error path on the host side.
259
+ case 'getInputFirst':
260
+ return data.$input?.first?.();
261
+ case 'getInputLast':
262
+ return data.$input?.last?.();
263
+ case 'getInputAll':
264
+ return data.$input?.all?.();
265
+ // `$items(nodeName?, outputIndex?, runIndex?)` — the global accessor
266
+ // for a node's execution data. Reads the literal `$items` property
267
+ // off `data` (host-wired by `WorkflowDataProxy`) and forwards the
268
+ // validated args verbatim. The host applies its own defaults when
269
+ // fields are `undefined`.
270
+ case 'getItems':
271
+ return data.$items?.(msg.nodeName, msg.outputIndex, msg.runIndex);
272
+ // `$fromAI(name, description?, type?, defaultValue?)` and its
273
+ // `$fromAi` / `$fromai` aliases. Reads the literal `$fromAI` property
274
+ // off `data` (host-wired) and forwards the args. The host validates
275
+ // `name` (required + regex) and applies its own resolution / fallback
276
+ // logic, so empty / invalid names surface as the host's structured
277
+ // `ExpressionError` rather than a generic zod parse error.
278
+ //
279
+ // Note: `msg.valueType` maps to the host's third positional parameter
280
+ // (`_type` in `WorkflowDataProxy.handleFromAi`). The bridge protocol
281
+ // renames it to avoid collision with the `type` discriminator on the
282
+ // envelope — the host parameter currently goes unused, but if it ever
283
+ // gains a name (`type`), this mapping should stay explicit.
284
+ case 'fromAi':
285
+ return data.$fromAI?.(msg.name, msg.description, msg.valueType, msg.defaultValue);
286
+ // The `$('Foo').pairedItem(itemIndex?)` / `.itemMatching(...)` /
287
+ // `.item` cluster. Three separate typed RPCs, each reading exactly one
288
+ // literal property off the host node proxy.
289
+ //
290
+ // The split is load-bearing: the host's `pairedItemMethod` closure
291
+ // captures which property name the proxy `get` trap saw, and uses
292
+ // that to pick the right error message (e.g. "Missing item index for
293
+ // .itemMatching()") and to decide between method-call vs getter
294
+ // semantics for `.item`. Reading the matching property here lets
295
+ // those host-side branches fire exactly as they do in the legacy
296
+ // engine; no in-guest validation needed.
297
+ case 'getNodePairedItem':
298
+ return data.$?.(msg.nodeName)?.pairedItem?.(msg.itemIndex);
299
+ case 'getNodeItemMatching':
300
+ return data.$?.(msg.nodeName)?.itemMatching?.(msg.itemIndex);
301
+ case 'getNodeItem':
302
+ // `.item` is a host getter — accessing it invokes the resolver and
303
+ // returns the value immediately. Optional chaining only short-
304
+ // circuits on null/undefined; the getter still fires on access.
305
+ return data.$?.(msg.nodeName)?.item;
306
+ // `$evaluateExpression(expression, itemIndex?)`. Forwards the string
307
+ // to the host's nested-evaluation helper, which re-enters the
308
+ // expression engine on the inner expression. Under the VM engine this
309
+ // round-trips through the bridge again on a fresh evaluation cycle,
310
+ // which is the same shape the legacy engine supports.
311
+ case 'evaluateExpression':
312
+ return data.$evaluateExpression?.(msg.expression, msg.itemIndex);
313
+ // `$getPairedItem(destinationNodeName, incomingSourceData,
314
+ // initialPairedItem)`. Forwards directly to the host binding, which
315
+ // walks the paired-item ancestry chain back to the named upstream
316
+ // node and returns the matching execution item.
317
+ //
318
+ // The two trailing host parameters — `usedMethodName` and
319
+ // `nodeBeforeLast` — are deliberately not part of the wire protocol:
320
+ // the host's default for `usedMethodName` is already `$getPairedItem`,
321
+ // and `nodeBeforeLast` is an internal recursion argument the host sets
322
+ // during traversal.
323
+ case 'getPairedItem':
324
+ return data.$getPairedItem?.(msg.destinationNodeName, msg.incomingSourceData, msg.initialPairedItem);
325
+ default: {
326
+ // Unreachable at runtime — zod rejects unknown `type` values
327
+ // before the switch. The `never` assignment is the compile-time
328
+ // guard: a new schema added to `bridgeMessageSchema` without a
329
+ // matching case here becomes a type error.
330
+ const exhaustive = msg;
331
+ void exhaustive;
332
+ throw new Error('Unhandled bridge message');
333
+ }
334
+ }
335
+ }
336
+ //# sourceMappingURL=host-functions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-functions.js","sourceRoot":"","sources":["../../../src/bridge/host-functions.ts"],"names":[],"mappings":"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"}
@@ -43,16 +43,6 @@ export declare class IsolatedVmBridge implements RuntimeBridge {
43
43
  * @throws {Error} If context not initialized or bundle loading fails
44
44
  */
45
45
  private loadVendorLibraries;
46
- /**
47
- * Verify the proxy system loaded correctly.
48
- *
49
- * The proxy system is loaded as part of the runtime bundle in loadVendorLibraries().
50
- * This method verifies all required components are available.
51
- *
52
- * @private
53
- * @throws {Error} If context not initialized or proxy system verification fails
54
- */
55
- private verifyProxySystem;
56
46
  /**
57
47
  * Inject the E() error handler into the isolate context.
58
48
  *
@@ -77,17 +67,20 @@ export declare class IsolatedVmBridge implements RuntimeBridge {
77
67
  * @throws {Error} If context not initialized
78
68
  */
79
69
  private injectErrorHandler;
70
+ /**
71
+ * Synchronous variant of initialize(): the same steps through isolated-vm's
72
+ * sync APIs, for on-demand creation inside the synchronous evaluate() path
73
+ * (lazy acquisition with an exhausted pool). Blocks the event loop for the
74
+ * duration of one isolate setup — pool warmup should stay on the async
75
+ * initialize().
76
+ */
77
+ initializeSync(): void;
80
78
  /**
81
79
  * Create an ivm.Callback for getting value/metadata at a path.
82
80
  *
83
- * Used by createDeepLazyProxy when accessing properties. Returns metadata
84
- * markers for arrays and objects, or the primitive value directly.
85
- *
86
- * Function-typed values are returned as `undefined` — every callable on
87
- * the host data surface (`$('Foo').first()`, `$items()`, `$fromAI()`,
88
- * `$evaluateExpression()`, `$getPairedItem()`) is wired in-isolate via
89
- * the typed-RPC dispatcher (`callHost`). No expression form should
90
- * reach a function through this path.
81
+ * Thin wrapper around the shared getValueAtPath (see host-functions.ts
82
+ * for navigation and guard semantics); errors are caught and returned
83
+ * as sentinels instead of crossing the isolate boundary.
91
84
  *
92
85
  * @param data - Current workflow data to use for callback responses
93
86
  * @private
@@ -96,144 +89,32 @@ export declare class IsolatedVmBridge implements RuntimeBridge {
96
89
  /**
97
90
  * Create an ivm.Callback for getting array elements at an index.
98
91
  *
99
- * Used by array proxy when accessing numeric indices.
92
+ * Thin wrapper around the shared getArrayElement (see host-functions.ts
93
+ * for navigation and guard semantics); errors are caught and returned
94
+ * as sentinels instead of crossing the isolate boundary.
100
95
  *
101
96
  * @param data - Current workflow data to use for callback responses
102
97
  * @private
103
98
  */
104
99
  private createGetArrayElementRef;
105
100
  /**
106
- * Create the single typed-RPC dispatcher.
107
- *
108
- * The isolate sends one envelope per typed RPC invocation:
109
- * `callHost({ type: 'getNodeFirst', nodeName, branchIndex?, runIndex? })`
101
+ * Create the ivm.Callback for the typed-RPC `callHost` channel.
110
102
  *
111
- * Inputs cross a trust boundary, so the dispatcher parses every envelope
112
- * with the host-side zod schema (`bridgeMessageSchema`) before any
113
- * dispatch happens. Anything that deviates from the declared shape —
114
- * unknown `type`, missing required fields, extra unexpected fields,
115
- * wrong field types — fails the parse and an error sentinel is returned
116
- * to the caller.
103
+ * Thin wrapper around the shared dispatchHostCall (see host-functions.ts
104
+ * for envelope validation and per-message rationale); errors — including
105
+ * zod parse failures — are caught and returned as sentinels instead of
106
+ * crossing the isolate boundary.
117
107
  *
118
- * After parsing, `switch (msg.type)` dispatches to a private handler with
119
- * a fully narrowed message type. The operation set is exactly the cases
120
- * in this switch; the `type` field selects a static branch in source,
121
- * not a property lookup on a runtime object.
122
- *
123
- * Return-value note: handlers must return plain, structured-clone-able
124
- * data. Results cross into the isolate through an ivm.Callback, which copies
125
- * them via the structured-clone algorithm — return JSON-shaped values, not
126
- * isolated-vm objects (`Reference`/`ExternalCopy`) or other non-cloneable
127
- * values.
108
+ * Return-value note: the dispatcher returns plain, structured-clone-able
109
+ * data. Results cross into the isolate through an ivm.Callback, which
110
+ * copies them via the structured-clone algorithm — JSON-shaped values,
111
+ * not isolated-vm objects (`Reference`/`ExternalCopy`) or other
112
+ * non-cloneable values.
128
113
  *
129
114
  * @param data - Current workflow data
130
115
  * @private
131
116
  */
132
117
  private createCallHostRef;
133
- /**
134
- * Handlers for the `$('Foo').{first,last,all}` typed RPCs.
135
- *
136
- * Each handler reads a fixed literal property name off the host-side node
137
- * proxy — the isolate cannot influence which property is dereferenced.
138
- * Eliminating `data.$` as a host-callable entirely would require reaching
139
- * the `WorkflowDataProxy` internals (e.g. `getNodeExecutionOrPinnedData`)
140
- * rather than the public `$()` API; that's a follow-up.
141
- *
142
- * `data.$` is a host-wired function (`WorkflowDataProxy`'s `$`). If it
143
- * ever isn't, optional chaining short-circuits to `undefined` — the same
144
- * observable result the runtime's `E()` handler produces from any thrown
145
- * error here.
146
- *
147
- * @private
148
- */
149
- private handleGetNodeFirst;
150
- private handleGetNodeLast;
151
- private handleGetNodeAll;
152
- /**
153
- * Handlers for the `$input.{first,last,all}` typed RPCs.
154
- *
155
- * Each reads a fixed literal property name off `data.$input` (the host's
156
- * `WorkflowDataProxy` input proxy). The host enforces zero arguments on
157
- * these methods — the schemas have no fields besides `type`, so the
158
- * isolate cannot pass anything that would trigger the "should have no
159
- * arguments" error path on the host side.
160
- *
161
- * @private
162
- */
163
- private handleGetInputFirst;
164
- private handleGetInputLast;
165
- private handleGetInputAll;
166
- /**
167
- * Handler for `$items(nodeName?, outputIndex?, runIndex?)` — the
168
- * global accessor for a node's execution data. Reads the literal
169
- * `$items` property off `data` (host-wired by `WorkflowDataProxy`)
170
- * and forwards the validated args verbatim. The host applies its own
171
- * defaults when fields are `undefined`.
172
- *
173
- * @private
174
- */
175
- private handleGetItems;
176
- /**
177
- * Handler for `$fromAI(name, description?, type?, defaultValue?)` and its
178
- * `$fromAi` / `$fromai` aliases. Reads the literal `$fromAI` property
179
- * off `data` (host-wired) and forwards the args. The host validates
180
- * `name` (required + regex) and applies its own resolution / fallback
181
- * logic, so empty / invalid names surface as the host's structured
182
- * `ExpressionError` rather than a generic zod parse error.
183
- *
184
- * Note: `msg.valueType` maps to the host's third positional parameter
185
- * (`_type` in `WorkflowDataProxy.handleFromAi`). The bridge protocol
186
- * renames it to avoid collision with the `type` discriminator on the
187
- * envelope — the host parameter currently goes unused, but if it ever
188
- * gains a name (`type`), this mapping should stay explicit.
189
- *
190
- * @private
191
- */
192
- private handleFromAi;
193
- /**
194
- * Handlers for the `$('Foo').pairedItem(itemIndex?)` / `.itemMatching(...)` /
195
- * `.item` cluster. Three separate typed RPCs, each reading exactly one
196
- * literal property off the host node proxy.
197
- *
198
- * The split is load-bearing: the host's `pairedItemMethod` closure
199
- * captures which property name the proxy `get` trap saw, and uses
200
- * that to pick the right error message (e.g. "Missing item index for
201
- * .itemMatching()") and to decide between method-call vs getter
202
- * semantics for `.item`. Reading the matching property here lets
203
- * those host-side branches fire exactly as they do in the legacy
204
- * engine; no in-isolate validation needed.
205
- *
206
- * @private
207
- */
208
- private handleGetNodePairedItem;
209
- private handleGetNodeItemMatching;
210
- private handleGetNodeItem;
211
- /**
212
- * Handler for `$evaluateExpression(expression, itemIndex?)`. Forwards
213
- * the string to the host's nested-evaluation helper, which re-enters
214
- * the expression engine on the inner expression. Under the VM engine
215
- * this round-trips through the bridge again as a new evaluation on the
216
- * enclosing call's time budget, which is the same shape the legacy
217
- * engine supports.
218
- *
219
- * @private
220
- */
221
- private handleEvaluateExpression;
222
- /**
223
- * Handler for `$getPairedItem(destinationNodeName, incomingSourceData,
224
- * initialPairedItem)`. Forwards directly to the host binding, which
225
- * walks the paired-item ancestry chain back to the named upstream node
226
- * and returns the matching execution item.
227
- *
228
- * The two trailing host parameters — `usedMethodName` and
229
- * `nodeBeforeLast` — are deliberately not part of the wire protocol:
230
- * the host's default for `usedMethodName` is already `$getPairedItem`,
231
- * and `nodeBeforeLast` is an internal recursion argument the host sets
232
- * during traversal.
233
- *
234
- * @private
235
- */
236
- private handleGetPairedItem;
237
118
  /**
238
119
  * Execute JavaScript code in the isolated context.
239
120
  *
@@ -260,13 +141,6 @@ export declare class IsolatedVmBridge implements RuntimeBridge {
260
141
  * ran on — reporting "timed out after 137ms" would misstate the limit.
261
142
  */
262
143
  private timeoutError;
263
- /**
264
- * Reconstruct an error from serialized isolate data.
265
- *
266
- * Maps error names back to their host-side classes and restores
267
- * custom properties that would otherwise be lost crossing the boundary.
268
- */
269
- private reconstructError;
270
144
  /**
271
145
  * Dispose of the isolate and free resources.
272
146
  *
@@ -1 +1 @@
1
- {"version":3,"file":"isolated-vm-bridge.d.ts","sourceRoot":"","sources":["../../../src/bridge/isolated-vm-bridge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AA+E1F;;;;;;;;;;GAUG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IACrD,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,MAAM,CAAmC;IAEjD,YAAY,MAAM,GAAE,YAAiB,EAUpC;IAED;;;;;;;;;;OAUG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CA4BhC;IAED;;;;;;;;;;;OAWG;YACW,mBAAmB;IAgCjC;;;;;;;;OAQG;YACW,iBAAiB;IA4B/B;;;;;;;;;;;;;;;;;;;;;;OAsBG;YACW,kBAAkB;IAwBhC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,uBAAuB;IAqE/B;;;;;;;OAOG;IACH,OAAO,CAAC,wBAAwB;IA4EhC;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,OAAO,CAAC,iBAAiB;IA+CzB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IAOxB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,iBAAiB;IAIzB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAOtB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,YAAY;IAOpB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,yBAAyB;IAOjC,OAAO,CAAC,iBAAiB;IAUzB;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB;IAOhC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CA4G3E;IAED;;;OAGG;IACH,OAAO,CAAC,YAAY;IASpB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAc7B;IAED;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAEpB;CACD"}
1
+ {"version":3,"file":"isolated-vm-bridge.d.ts","sourceRoot":"","sources":["../../../src/bridge/isolated-vm-bridge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AA8G1F;;;;;;;;;;GAUG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IACrD,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,MAAM,CAAmC;IAEjD,YAAY,MAAM,GAAE,YAAiB,EAUpC;IAED;;;;;;;;;;OAUG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAyBhC;IAED;;;;;;;;;;;OAWG;YACW,mBAAmB;IA8BjC;;;;;;;;;;;;;;;;;;;;;;OAsBG;YACW,kBAAkB;IAUhC;;;;;;OAMG;IACH,cAAc,IAAI,IAAI,CAgCrB;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,uBAAuB;IAU/B;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB;IAUhC;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CA8G3E;IAED;;;OAGG;IACH,OAAO,CAAC,YAAY;IASpB;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAc7B;IAED;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAEpB;CACD"}