@tracecode/harness 0.4.0 → 0.5.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 (43) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/browser.cjs +16 -4
  3. package/dist/browser.cjs.map +1 -1
  4. package/dist/browser.d.cts +2 -2
  5. package/dist/browser.d.ts +2 -2
  6. package/dist/browser.js +16 -4
  7. package/dist/browser.js.map +1 -1
  8. package/dist/cli.js +0 -0
  9. package/dist/core.cjs +16 -4
  10. package/dist/core.cjs.map +1 -1
  11. package/dist/core.d.cts +9 -6
  12. package/dist/core.d.ts +9 -6
  13. package/dist/core.js +16 -4
  14. package/dist/core.js.map +1 -1
  15. package/dist/index.cjs +305 -13
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +2 -2
  18. package/dist/index.d.ts +2 -2
  19. package/dist/index.js +305 -13
  20. package/dist/index.js.map +1 -1
  21. package/dist/internal/browser.d.cts +1 -1
  22. package/dist/internal/browser.d.ts +1 -1
  23. package/dist/javascript.cjs +227 -9
  24. package/dist/javascript.cjs.map +1 -1
  25. package/dist/javascript.d.cts +4 -4
  26. package/dist/javascript.d.ts +4 -4
  27. package/dist/javascript.js +227 -9
  28. package/dist/javascript.js.map +1 -1
  29. package/dist/python.cjs +62 -0
  30. package/dist/python.cjs.map +1 -1
  31. package/dist/python.d.cts +2 -2
  32. package/dist/python.d.ts +2 -2
  33. package/dist/python.js +62 -0
  34. package/dist/python.js.map +1 -1
  35. package/dist/{runtime-types-Dvgn07z9.d.cts → runtime-types--lBQ6rYu.d.cts} +1 -1
  36. package/dist/{runtime-types-C7d1LFbx.d.ts → runtime-types-DtaaAhHL.d.ts} +1 -1
  37. package/dist/{types-Bzr1Ohcf.d.cts → types-DwIYM3Ku.d.cts} +5 -2
  38. package/dist/{types-Bzr1Ohcf.d.ts → types-DwIYM3Ku.d.ts} +5 -2
  39. package/package.json +12 -10
  40. package/workers/javascript/javascript-worker.js +455 -31
  41. package/workers/python/generated-python-harness-snippets.js +1 -1
  42. package/workers/python/pyodide-worker.js +31 -0
  43. package/workers/python/runtime-core.js +235 -8
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- export { L as Language, a as LanguageRuntimeProfile, R as RuntimeCapabilities, b as RuntimeClient, c as RuntimeExecutionStyle, d as RuntimeMaturity, T as TraceExecutionOptions } from './runtime-types-Dvgn07z9.cjs';
2
- export { C as CallStackFrame, a as CodeExecutionResult, E as ExecutionResult, b as ExecutionStatus, P as ProcessedStep, c as PyodideState, R as RawTraceStep, d as RuntimeHashMapEntry, e as RuntimeHashMapVisualization, f as RuntimeObjectKind, g as RuntimeTraceAccessEvent, h as RuntimeTraceAccessKind, i as RuntimeVisualizationPayload, T as TestResult } from './types-Bzr1Ohcf.cjs';
1
+ export { L as Language, a as LanguageRuntimeProfile, R as RuntimeCapabilities, b as RuntimeClient, c as RuntimeExecutionStyle, d as RuntimeMaturity, T as TraceExecutionOptions } from './runtime-types--lBQ6rYu.cjs';
2
+ export { C as CallStackFrame, a as CodeExecutionResult, E as ExecutionResult, b as ExecutionStatus, P as ProcessedStep, c as PyodideState, R as RawTraceStep, d as RuntimeHashMapEntry, e as RuntimeHashMapVisualization, f as RuntimeObjectKind, g as RuntimeTraceAccessEvent, h as RuntimeTraceAccessKind, i as RuntimeVisualizationPayload, T as TestResult } from './types-DwIYM3Ku.cjs';
3
3
  export { RUNTIME_TRACE_CONTRACT_SCHEMA_VERSION, RuntimeTraceContractCallStackFrame, RuntimeTraceContractEvent, RuntimeTraceContractHashMap, RuntimeTraceContractHashMapEntry, RuntimeTraceContractResult, RuntimeTraceContractStep, RuntimeTraceContractVisualization, adaptJavaScriptTraceExecutionResult, adaptPythonTraceExecutionResult, adaptTraceExecutionResult, normalizeRuntimeTraceContract, stableStringifyRuntimeTraceContract } from './core.cjs';
4
4
  export { BrowserHarness, BrowserHarnessAssetOverrides, BrowserHarnessAssets, CreateBrowserHarnessOptions, DEFAULT_BROWSER_HARNESS_ASSET_RELATIVE_PATHS, LANGUAGE_RUNTIME_PROFILES, SUPPORTED_LANGUAGES, assertRuntimeRequestSupported, createBrowserHarness, getLanguageRuntimeProfile, getSupportedLanguageProfiles, isLanguageSupported, resolveBrowserHarnessAssets } from './browser.cjs';
5
5
  export { PYTHON_CLASS_DEFINITIONS, PYTHON_CONVERSION_HELPERS, PYTHON_EXECUTE_SERIALIZE_FUNCTION, PYTHON_INTERVIEW_MATERIALIZE_SERIALIZE_FUNCTION, PYTHON_PRACTICE_MATERIALIZE_SERIALIZE_FUNCTION, PYTHON_SERIALIZE_FUNCTION, PYTHON_TRACE_SERIALIZE_FUNCTION, TEMPLATE_PYTHON_CLASS_DEFINITIONS, TEMPLATE_PYTHON_CONVERSION_HELPERS, TEMPLATE_PYTHON_EXECUTE_SERIALIZE_FUNCTION, TEMPLATE_PYTHON_INTERVIEW_MATERIALIZE_SERIALIZE_FUNCTION, TEMPLATE_PYTHON_PRACTICE_MATERIALIZE_SERIALIZE_FUNCTION, TEMPLATE_PYTHON_SERIALIZE_FUNCTION, TEMPLATE_PYTHON_TRACE_SERIALIZE_FUNCTION, generateConversionCode, generateInputSetup, generateSolutionScript, identifyConversions, templateToPythonLiteral, toPythonLiteral } from './python.cjs';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { L as Language, a as LanguageRuntimeProfile, R as RuntimeCapabilities, b as RuntimeClient, c as RuntimeExecutionStyle, d as RuntimeMaturity, T as TraceExecutionOptions } from './runtime-types-C7d1LFbx.js';
2
- export { C as CallStackFrame, a as CodeExecutionResult, E as ExecutionResult, b as ExecutionStatus, P as ProcessedStep, c as PyodideState, R as RawTraceStep, d as RuntimeHashMapEntry, e as RuntimeHashMapVisualization, f as RuntimeObjectKind, g as RuntimeTraceAccessEvent, h as RuntimeTraceAccessKind, i as RuntimeVisualizationPayload, T as TestResult } from './types-Bzr1Ohcf.js';
1
+ export { L as Language, a as LanguageRuntimeProfile, R as RuntimeCapabilities, b as RuntimeClient, c as RuntimeExecutionStyle, d as RuntimeMaturity, T as TraceExecutionOptions } from './runtime-types-DtaaAhHL.js';
2
+ export { C as CallStackFrame, a as CodeExecutionResult, E as ExecutionResult, b as ExecutionStatus, P as ProcessedStep, c as PyodideState, R as RawTraceStep, d as RuntimeHashMapEntry, e as RuntimeHashMapVisualization, f as RuntimeObjectKind, g as RuntimeTraceAccessEvent, h as RuntimeTraceAccessKind, i as RuntimeVisualizationPayload, T as TestResult } from './types-DwIYM3Ku.js';
3
3
  export { RUNTIME_TRACE_CONTRACT_SCHEMA_VERSION, RuntimeTraceContractCallStackFrame, RuntimeTraceContractEvent, RuntimeTraceContractHashMap, RuntimeTraceContractHashMapEntry, RuntimeTraceContractResult, RuntimeTraceContractStep, RuntimeTraceContractVisualization, adaptJavaScriptTraceExecutionResult, adaptPythonTraceExecutionResult, adaptTraceExecutionResult, normalizeRuntimeTraceContract, stableStringifyRuntimeTraceContract } from './core.js';
4
4
  export { BrowserHarness, BrowserHarnessAssetOverrides, BrowserHarnessAssets, CreateBrowserHarnessOptions, DEFAULT_BROWSER_HARNESS_ASSET_RELATIVE_PATHS, LANGUAGE_RUNTIME_PROFILES, SUPPORTED_LANGUAGES, assertRuntimeRequestSupported, createBrowserHarness, getLanguageRuntimeProfile, getSupportedLanguageProfiles, isLanguageSupported, resolveBrowserHarnessAssets } from './browser.js';
5
5
  export { PYTHON_CLASS_DEFINITIONS, PYTHON_CONVERSION_HELPERS, PYTHON_EXECUTE_SERIALIZE_FUNCTION, PYTHON_INTERVIEW_MATERIALIZE_SERIALIZE_FUNCTION, PYTHON_PRACTICE_MATERIALIZE_SERIALIZE_FUNCTION, PYTHON_SERIALIZE_FUNCTION, PYTHON_TRACE_SERIALIZE_FUNCTION, TEMPLATE_PYTHON_CLASS_DEFINITIONS, TEMPLATE_PYTHON_CONVERSION_HELPERS, TEMPLATE_PYTHON_EXECUTE_SERIALIZE_FUNCTION, TEMPLATE_PYTHON_INTERVIEW_MATERIALIZE_SERIALIZE_FUNCTION, TEMPLATE_PYTHON_PRACTICE_MATERIALIZE_SERIALIZE_FUNCTION, TEMPLATE_PYTHON_SERIALIZE_FUNCTION, TEMPLATE_PYTHON_TRACE_SERIALIZE_FUNCTION, generateConversionCode, generateInputSetup, generateSolutionScript, identifyConversions, templateToPythonLiteral, toPythonLiteral } from './python.js';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // packages/harness-core/src/trace-contract.ts
2
- var RUNTIME_TRACE_CONTRACT_SCHEMA_VERSION = "2026-03-07";
2
+ var RUNTIME_TRACE_CONTRACT_SCHEMA_VERSION = "2026-03-13";
3
3
  var TRACE_EVENTS = /* @__PURE__ */ new Set([
4
4
  "line",
5
5
  "call",
@@ -42,13 +42,13 @@ function normalizeFunctionName(value) {
42
42
  return "<module>";
43
43
  }
44
44
  function normalizeKind(value) {
45
- if (value === "map" || value === "set" || value === "hashmap") {
45
+ if (value === "map" || value === "set" || value === "hashmap" || value === "object") {
46
46
  return value;
47
47
  }
48
48
  return "hashmap";
49
49
  }
50
50
  function normalizeObjectKind(value) {
51
- if (value === "hashmap" || value === "map" || value === "set" || value === "tree" || value === "linked-list" || value === "graph-adjacency") {
51
+ if (value === "hashmap" || value === "object" || value === "map" || value === "set" || value === "tree" || value === "linked-list" || value === "graph-adjacency") {
52
52
  return value;
53
53
  }
54
54
  return null;
@@ -126,6 +126,14 @@ function normalizeRecord(value) {
126
126
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
127
127
  return normalizeUnknown(value);
128
128
  }
129
+ function normalizeVariableSources(value) {
130
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
131
+ const entries = Object.entries(value).filter(
132
+ ([name, source]) => typeof name === "string" && name.length > 0 && (source === "user" || source === "user-input" || source === "harness-prelude")
133
+ ).sort((a, b) => a[0].localeCompare(b[0]));
134
+ if (entries.length === 0) return void 0;
135
+ return Object.fromEntries(entries);
136
+ }
129
137
  function normalizeCallStackFrame(frame) {
130
138
  return {
131
139
  function: normalizeFunctionName(frame?.function),
@@ -143,7 +151,9 @@ function normalizeVisualizationPayload(payload) {
143
151
  ...item?.highlight ? { highlight: true } : {}
144
152
  })) : [],
145
153
  ...entry?.highlightedKey !== void 0 ? { highlightedKey: normalizeUnknown(entry.highlightedKey) } : {},
146
- ...entry?.deletedKey !== void 0 ? { deletedKey: normalizeUnknown(entry.deletedKey) } : {}
154
+ ...entry?.deletedKey !== void 0 ? { deletedKey: normalizeUnknown(entry.deletedKey) } : {},
155
+ ...typeof entry?.objectClassName === "string" && entry.objectClassName.length > 0 ? { objectClassName: entry.objectClassName } : {},
156
+ ...typeof entry?.objectId === "string" && entry.objectId.length > 0 ? { objectId: entry.objectId } : {}
147
157
  })).sort((a, b) => `${a.name}:${a.kind}`.localeCompare(`${b.name}:${b.kind}`)) : [];
148
158
  const objectKinds = payload?.objectKinds && typeof payload.objectKinds === "object" ? Object.fromEntries(
149
159
  Object.entries(payload.objectKinds).filter(([name]) => typeof name === "string" && name.length > 0).map(([name, kind]) => [name, normalizeObjectKind(kind)]).filter((entry) => entry[1] !== null).sort((a, b) => a[0].localeCompare(b[0]))
@@ -160,11 +170,13 @@ function normalizeTraceStep(step) {
160
170
  const normalizedStdoutCount = normalizeOutputLineCount(step?.stdoutLineCount);
161
171
  const normalizedVisualization = normalizeVisualizationPayload(step?.visualization);
162
172
  const normalizedAccesses = normalizeAccesses(step?.accesses);
173
+ const normalizedVariableSources = normalizeVariableSources(step?.variableSources);
163
174
  return {
164
175
  event: normalizeEvent(step?.event),
165
176
  line: normalizeLineNumber(step?.line, 1),
166
177
  function: normalizeFunctionName(step?.function),
167
178
  variables: normalizeRecord(step?.variables),
179
+ ...normalizedVariableSources ? { variableSources: normalizedVariableSources } : {},
168
180
  ...Array.isArray(step?.callStack) && step.callStack.length > 0 ? { callStack: step.callStack.map(normalizeCallStackFrame) } : {},
169
181
  ...normalizedAccesses ? { accesses: normalizedAccesses } : {},
170
182
  ...step?.returnValue !== void 0 ? { returnValue: normalizeUnknown(step.returnValue) } : {},
@@ -1375,6 +1387,7 @@ var PYTHON_TRACE_SERIALIZE_FUNCTION = `
1375
1387
  # Sentinel to mark skipped values (functions, etc.) - distinct from None
1376
1388
  _SKIP_SENTINEL = "__TRACECODE_SKIP__"
1377
1389
  _MAX_SERIALIZE_DEPTH = 48
1390
+ _MAX_OBJECT_FIELDS = 32
1378
1391
 
1379
1392
  def _serialize(obj, depth=0, node_refs=None):
1380
1393
  if node_refs is None:
@@ -1431,6 +1444,36 @@ def _serialize(obj, depth=0, node_refs=None):
1431
1444
  }
1432
1445
  result["next"] = _serialize(obj.next, depth + 1, node_refs)
1433
1446
  return result
1447
+ elif hasattr(obj, '__dict__'):
1448
+ obj_ref = id(obj)
1449
+ if obj_ref in node_refs:
1450
+ return {"__ref__": node_refs[obj_ref]}
1451
+ node_id = f"object-{obj_ref}"
1452
+ node_refs[obj_ref] = node_id
1453
+ class_name = getattr(getattr(obj, '__class__', None), '__name__', 'object')
1454
+ result = {
1455
+ "__type__": "object",
1456
+ "__class__": class_name,
1457
+ "__id__": node_id,
1458
+ }
1459
+ try:
1460
+ raw_fields = getattr(obj, '__dict__', None)
1461
+ except Exception:
1462
+ raw_fields = None
1463
+ if isinstance(raw_fields, dict):
1464
+ added = 0
1465
+ for key, value in raw_fields.items():
1466
+ key_str = str(key)
1467
+ if key_str.startswith('_'):
1468
+ continue
1469
+ if callable(value):
1470
+ continue
1471
+ result[key_str] = _serialize(value, depth + 1, node_refs)
1472
+ added += 1
1473
+ if added >= _MAX_OBJECT_FIELDS:
1474
+ result["__truncated__"] = True
1475
+ break
1476
+ return result
1434
1477
  elif callable(obj):
1435
1478
  # Skip functions entirely - return sentinel
1436
1479
  return _SKIP_SENTINEL
@@ -1794,6 +1837,7 @@ var TEMPLATE_PYTHON_TRACE_SERIALIZE_FUNCTION = `
1794
1837
  # Sentinel to mark skipped values (functions, etc.) - distinct from None
1795
1838
  _SKIP_SENTINEL = "__TRACECODE_SKIP__"
1796
1839
  _MAX_SERIALIZE_DEPTH = 48
1840
+ _MAX_OBJECT_FIELDS = 32
1797
1841
 
1798
1842
  def _serialize(obj, depth=0, node_refs=None):
1799
1843
  if node_refs is None:
@@ -1850,6 +1894,36 @@ def _serialize(obj, depth=0, node_refs=None):
1850
1894
  }
1851
1895
  result["next"] = _serialize(obj.next, depth + 1, node_refs)
1852
1896
  return result
1897
+ elif hasattr(obj, '__dict__'):
1898
+ obj_ref = id(obj)
1899
+ if obj_ref in node_refs:
1900
+ return {"__ref__": node_refs[obj_ref]}
1901
+ node_id = f"object-{obj_ref}"
1902
+ node_refs[obj_ref] = node_id
1903
+ class_name = getattr(getattr(obj, '__class__', None), '__name__', 'object')
1904
+ result = {
1905
+ "__type__": "object",
1906
+ "__class__": class_name,
1907
+ "__id__": node_id,
1908
+ }
1909
+ try:
1910
+ raw_fields = getattr(obj, '__dict__', None)
1911
+ except Exception:
1912
+ raw_fields = None
1913
+ if isinstance(raw_fields, dict):
1914
+ added = 0
1915
+ for key, value in raw_fields.items():
1916
+ key_str = str(key)
1917
+ if key_str.startswith('_'):
1918
+ continue
1919
+ if callable(value):
1920
+ continue
1921
+ result[key_str] = _serialize(value, depth + 1, node_refs)
1922
+ added += 1
1923
+ if added >= _MAX_OBJECT_FIELDS:
1924
+ result["__truncated__"] = True
1925
+ break
1926
+ return result
1853
1927
  elif callable(obj):
1854
1928
  # Skip functions entirely - return sentinel
1855
1929
  return _SKIP_SENTINEL
@@ -2079,6 +2153,17 @@ function isLikelyListNodeValue(value) {
2079
2153
  const hasListLinks = "next" in value || "prev" in value;
2080
2154
  return hasValue && hasListLinks && !hasTreeLinks;
2081
2155
  }
2156
+ function getCustomClassName(value) {
2157
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
2158
+ if (value instanceof Map || value instanceof Set) return null;
2159
+ if (isLikelyTreeNodeValue(value) || isLikelyListNodeValue(value)) return null;
2160
+ const ctor = value.constructor;
2161
+ const name = typeof ctor?.name === "string" ? ctor.name : "";
2162
+ if (!name || name === "Object" || name === "Array" || name === "Map" || name === "Set") {
2163
+ return null;
2164
+ }
2165
+ return name;
2166
+ }
2082
2167
  function serializeValue(value, depth = 0, seen = /* @__PURE__ */ new WeakSet(), nodeRefState = { ids: /* @__PURE__ */ new Map(), nextId: 1 }) {
2083
2168
  if (depth > 48) return "<max depth>";
2084
2169
  if (value === null || value === void 0) return value;
@@ -2138,6 +2223,28 @@ function serializeValue(value, depth = 0, seen = /* @__PURE__ */ new WeakSet(),
2138
2223
  ..."prev" in nodeValue ? { prev: serializeValue(nodeValue.prev ?? null, depth + 1, seen, nodeRefState) } : {}
2139
2224
  };
2140
2225
  }
2226
+ const customClassName = getCustomClassName(value);
2227
+ if (customClassName) {
2228
+ const objectValue = value;
2229
+ const existingId = nodeRefState.ids.get(objectValue);
2230
+ if (existingId) {
2231
+ return { __ref__: existingId };
2232
+ }
2233
+ const objectId = `object-${nodeRefState.nextId++}`;
2234
+ nodeRefState.ids.set(objectValue, objectId);
2235
+ if (seen.has(objectValue)) return { __ref__: objectId };
2236
+ seen.add(objectValue);
2237
+ const out2 = {
2238
+ __type__: "object",
2239
+ __class__: customClassName,
2240
+ __id__: objectId
2241
+ };
2242
+ for (const [k, v] of Object.entries(value)) {
2243
+ out2[k] = serializeValue(v, depth + 1, seen, nodeRefState);
2244
+ }
2245
+ seen.delete(objectValue);
2246
+ return out2;
2247
+ }
2141
2248
  if (seen.has(value)) return "<cycle>";
2142
2249
  seen.add(value);
2143
2250
  const out = {};
@@ -2227,6 +2334,180 @@ function normalizeInputs(inputs) {
2227
2334
  }
2228
2335
  return hydrated;
2229
2336
  }
2337
+ function buildTreeNodeFromLevelOrder(values) {
2338
+ if (!Array.isArray(values) || values.length === 0) return null;
2339
+ const firstValue = values[0];
2340
+ if (firstValue === null || firstValue === void 0) return null;
2341
+ const root = {
2342
+ val: firstValue,
2343
+ value: firstValue,
2344
+ left: null,
2345
+ right: null
2346
+ };
2347
+ const queue = [root];
2348
+ let index = 1;
2349
+ while (queue.length > 0 && index < values.length) {
2350
+ const node = queue.shift();
2351
+ if (!node) break;
2352
+ const leftValue = values[index++];
2353
+ if (leftValue !== null && leftValue !== void 0) {
2354
+ const leftNode = {
2355
+ val: leftValue,
2356
+ value: leftValue,
2357
+ left: null,
2358
+ right: null
2359
+ };
2360
+ node.left = leftNode;
2361
+ queue.push(leftNode);
2362
+ }
2363
+ if (index >= values.length) break;
2364
+ const rightValue = values[index++];
2365
+ if (rightValue !== null && rightValue !== void 0) {
2366
+ const rightNode = {
2367
+ val: rightValue,
2368
+ value: rightValue,
2369
+ left: null,
2370
+ right: null
2371
+ };
2372
+ node.right = rightNode;
2373
+ queue.push(rightNode);
2374
+ }
2375
+ }
2376
+ return root;
2377
+ }
2378
+ function materializeTreeInput(value) {
2379
+ if (value === null || value === void 0) return value;
2380
+ if (Array.isArray(value)) {
2381
+ return buildTreeNodeFromLevelOrder(value);
2382
+ }
2383
+ if (!isPlainObjectRecord(value)) {
2384
+ return value;
2385
+ }
2386
+ const record = value;
2387
+ if (isLikelyTreeNodeValue(record)) {
2388
+ return {
2389
+ val: record.val ?? record.value ?? null,
2390
+ value: record.val ?? record.value ?? null,
2391
+ left: materializeTreeInput(record.left ?? null),
2392
+ right: materializeTreeInput(record.right ?? null)
2393
+ };
2394
+ }
2395
+ const taggedRecord = value;
2396
+ if (taggedRecord.__type__ === "TreeNode") {
2397
+ return {
2398
+ val: taggedRecord.val ?? taggedRecord.value ?? null,
2399
+ value: taggedRecord.val ?? taggedRecord.value ?? null,
2400
+ left: materializeTreeInput(taggedRecord.left ?? null),
2401
+ right: materializeTreeInput(taggedRecord.right ?? null)
2402
+ };
2403
+ }
2404
+ return value;
2405
+ }
2406
+ function materializeListInput(value, refs = /* @__PURE__ */ new Map(), materialized = /* @__PURE__ */ new WeakMap()) {
2407
+ if (value === null || value === void 0) return value;
2408
+ if (Array.isArray(value)) {
2409
+ if (value.length === 0) return null;
2410
+ const head = {
2411
+ val: value[0],
2412
+ value: value[0],
2413
+ next: null
2414
+ };
2415
+ let current = head;
2416
+ for (let i = 1; i < value.length; i++) {
2417
+ const nextNode = { val: value[i], value: value[i], next: null };
2418
+ current.next = nextNode;
2419
+ current = nextNode;
2420
+ }
2421
+ return head;
2422
+ }
2423
+ if (!isPlainObjectRecord(value)) {
2424
+ return value;
2425
+ }
2426
+ const record = value;
2427
+ if (typeof record.__ref__ === "string") {
2428
+ return refs.get(record.__ref__) ?? null;
2429
+ }
2430
+ const taggedRecord = value;
2431
+ if (isLikelyListNodeValue(record) || taggedRecord.__type__ === "ListNode") {
2432
+ const existingMaterialized = materialized.get(record);
2433
+ if (existingMaterialized) {
2434
+ return existingMaterialized;
2435
+ }
2436
+ const node = {
2437
+ val: taggedRecord.val ?? taggedRecord.value ?? null,
2438
+ value: taggedRecord.val ?? taggedRecord.value ?? null,
2439
+ next: null
2440
+ };
2441
+ materialized.set(record, node);
2442
+ if (typeof taggedRecord.__id__ === "string" && taggedRecord.__id__.length > 0) {
2443
+ refs.set(taggedRecord.__id__, node);
2444
+ }
2445
+ node.next = materializeListInput(taggedRecord.next ?? null, refs, materialized);
2446
+ return node;
2447
+ }
2448
+ return value;
2449
+ }
2450
+ function detectMaterializerKind(ts, typeNode) {
2451
+ if (!typeNode) return null;
2452
+ if (ts.isParenthesizedTypeNode(typeNode)) {
2453
+ return detectMaterializerKind(ts, typeNode.type);
2454
+ }
2455
+ if (ts.isUnionTypeNode(typeNode)) {
2456
+ for (const child of typeNode.types) {
2457
+ const resolved = detectMaterializerKind(ts, child);
2458
+ if (resolved) return resolved;
2459
+ }
2460
+ return null;
2461
+ }
2462
+ if (ts.isTypeReferenceNode(typeNode)) {
2463
+ const typeNameText = typeNode.typeName.getText();
2464
+ if (typeNameText === "TreeNode") return "tree";
2465
+ if (typeNameText === "ListNode") return "list";
2466
+ return null;
2467
+ }
2468
+ return null;
2469
+ }
2470
+ function collectInputMaterializers(ts, functionLikeNode) {
2471
+ const out = {};
2472
+ for (const parameter of functionLikeNode.parameters ?? []) {
2473
+ if (!ts.isIdentifier(parameter.name)) continue;
2474
+ if (parameter.name.text === "this") continue;
2475
+ const kind = detectMaterializerKind(ts, parameter.type);
2476
+ if (kind) {
2477
+ out[parameter.name.text] = kind;
2478
+ }
2479
+ }
2480
+ return out;
2481
+ }
2482
+ async function resolveInputMaterializers(code, functionName, executionStyle, language) {
2483
+ if (!functionName || executionStyle === "ops-class" || language !== "typescript") {
2484
+ return {};
2485
+ }
2486
+ try {
2487
+ const ts = await getTypeScriptModule();
2488
+ const sourceFile = ts.createSourceFile(
2489
+ "runtime-input.ts",
2490
+ code,
2491
+ ts.ScriptTarget.ES2020,
2492
+ true,
2493
+ ts.ScriptKind.TS
2494
+ );
2495
+ const target = findFunctionLikeNode(ts, sourceFile, functionName, executionStyle);
2496
+ if (!target) return {};
2497
+ return collectInputMaterializers(ts, target);
2498
+ } catch {
2499
+ return {};
2500
+ }
2501
+ }
2502
+ function applyInputMaterializers(inputs, materializers) {
2503
+ if (Object.keys(materializers).length === 0) return inputs;
2504
+ const next = { ...inputs };
2505
+ for (const [name, kind] of Object.entries(materializers)) {
2506
+ if (!Object.prototype.hasOwnProperty.call(next, name)) continue;
2507
+ next[name] = kind === "tree" ? materializeTreeInput(next[name]) : materializeListInput(next[name]);
2508
+ }
2509
+ return next;
2510
+ }
2230
2511
  function collectSimpleParameterNames(ts, functionLikeNode) {
2231
2512
  const names = [];
2232
2513
  for (const parameter of functionLikeNode.parameters ?? []) {
@@ -2280,14 +2561,20 @@ function findFunctionLikeNode(ts, sourceFile, functionName, executionStyle) {
2280
2561
  visit(sourceFile);
2281
2562
  return found;
2282
2563
  }
2283
- async function resolveOrderedInputKeys(code, functionName, inputs, executionStyle) {
2564
+ async function resolveOrderedInputKeys(code, functionName, inputs, executionStyle, language = "javascript") {
2284
2565
  const fallbackKeys = Object.keys(inputs);
2285
2566
  if (!functionName || executionStyle === "ops-class" || fallbackKeys.length <= 1) {
2286
2567
  return fallbackKeys;
2287
2568
  }
2288
2569
  try {
2289
2570
  const ts = await getTypeScriptModule();
2290
- const sourceFile = ts.createSourceFile("runtime-input.js", code, ts.ScriptTarget.ES2020, true, ts.ScriptKind.JS);
2571
+ const sourceFile = ts.createSourceFile(
2572
+ `runtime-input.${language === "typescript" ? "ts" : "js"}`,
2573
+ code,
2574
+ ts.ScriptTarget.ES2020,
2575
+ true,
2576
+ language === "typescript" ? ts.ScriptKind.TS : ts.ScriptKind.JS
2577
+ );
2291
2578
  const target = findFunctionLikeNode(ts, sourceFile, functionName, executionStyle);
2292
2579
  if (!target) {
2293
2580
  return fallbackKeys;
@@ -2431,20 +2718,22 @@ async function transpileTypeScript(code) {
2431
2718
  }
2432
2719
  return transpiled.outputText;
2433
2720
  }
2434
- async function executeJavaScriptCode(code, functionName, inputs, executionStyle = "function") {
2721
+ async function executeJavaScriptCode(code, functionName, inputs, executionStyle = "function", language = "javascript") {
2435
2722
  const consoleOutput = [];
2436
2723
  const consoleProxy = createConsoleProxy(consoleOutput);
2437
2724
  const normalizedInputs = normalizeInputs(inputs);
2725
+ const materializers = await resolveInputMaterializers(code, functionName, executionStyle, language);
2726
+ const materializedInputs = applyInputMaterializers(normalizedInputs, materializers);
2438
2727
  try {
2439
2728
  let output;
2440
2729
  if (executionStyle === "ops-class") {
2441
- const { operations, argumentsList } = getOpsClassInputs(normalizedInputs);
2730
+ const { operations, argumentsList } = getOpsClassInputs(materializedInputs);
2442
2731
  const runner = buildRunner(code, executionStyle, []);
2443
2732
  output = await Promise.resolve(runner(consoleProxy, functionName, operations, argumentsList));
2444
2733
  } else {
2445
- const inputKeys = await resolveOrderedInputKeys(code, functionName, normalizedInputs, executionStyle);
2734
+ const inputKeys = await resolveOrderedInputKeys(code, functionName, materializedInputs, executionStyle, language);
2446
2735
  const argNames = inputKeys.map((_, index) => `__arg${index}`);
2447
- const argValues = inputKeys.map((key) => normalizedInputs[key]);
2736
+ const argValues = inputKeys.map((key) => materializedInputs[key]);
2448
2737
  const runner = buildRunner(code, executionStyle, argNames);
2449
2738
  output = await Promise.resolve(runner(consoleProxy, functionName, ...argValues));
2450
2739
  }
@@ -2463,9 +2752,9 @@ async function executeJavaScriptCode(code, functionName, inputs, executionStyle
2463
2752
  };
2464
2753
  }
2465
2754
  }
2466
- async function executeJavaScriptWithTracing(code, functionName, inputs, executionStyle = "function") {
2755
+ async function executeJavaScriptWithTracing(code, functionName, inputs, executionStyle = "function", language = "javascript") {
2467
2756
  const startedAt = performanceNow();
2468
- const codeResult = await executeJavaScriptCode(code, functionName ?? "", inputs, executionStyle);
2757
+ const codeResult = await executeJavaScriptCode(code, functionName ?? "", inputs, executionStyle, language);
2469
2758
  const executionTimeMs = performanceNow() - startedAt;
2470
2759
  if (!codeResult.success) {
2471
2760
  return {
@@ -2490,8 +2779,11 @@ async function executeJavaScriptWithTracing(code, functionName, inputs, executio
2490
2779
  };
2491
2780
  }
2492
2781
  async function executeTypeScriptCode(code, functionName, inputs, executionStyle = "function") {
2782
+ const normalizedInputs = normalizeInputs(inputs);
2783
+ const materializers = await resolveInputMaterializers(code, functionName, executionStyle, "typescript");
2784
+ const materializedInputs = applyInputMaterializers(normalizedInputs, materializers);
2493
2785
  const transpiledCode = await transpileTypeScript(code);
2494
- return executeJavaScriptCode(transpiledCode, functionName, inputs, executionStyle);
2786
+ return executeJavaScriptCode(transpiledCode, functionName, materializedInputs, executionStyle, "typescript");
2495
2787
  }
2496
2788
  export {
2497
2789
  DEFAULT_BROWSER_HARNESS_ASSET_RELATIVE_PATHS,