@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.
- package/CHANGELOG.md +15 -0
- package/dist/browser.cjs +16 -4
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +16 -4
- package/dist/browser.js.map +1 -1
- package/dist/cli.js +0 -0
- package/dist/core.cjs +16 -4
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +9 -6
- package/dist/core.d.ts +9 -6
- package/dist/core.js +16 -4
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +305 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +305 -13
- package/dist/index.js.map +1 -1
- package/dist/internal/browser.d.cts +1 -1
- package/dist/internal/browser.d.ts +1 -1
- package/dist/javascript.cjs +227 -9
- package/dist/javascript.cjs.map +1 -1
- package/dist/javascript.d.cts +4 -4
- package/dist/javascript.d.ts +4 -4
- package/dist/javascript.js +227 -9
- package/dist/javascript.js.map +1 -1
- package/dist/python.cjs +62 -0
- package/dist/python.cjs.map +1 -1
- package/dist/python.d.cts +2 -2
- package/dist/python.d.ts +2 -2
- package/dist/python.js +62 -0
- package/dist/python.js.map +1 -1
- package/dist/{runtime-types-Dvgn07z9.d.cts → runtime-types--lBQ6rYu.d.cts} +1 -1
- package/dist/{runtime-types-C7d1LFbx.d.ts → runtime-types-DtaaAhHL.d.ts} +1 -1
- package/dist/{types-Bzr1Ohcf.d.cts → types-DwIYM3Ku.d.cts} +5 -2
- package/dist/{types-Bzr1Ohcf.d.ts → types-DwIYM3Ku.d.ts} +5 -2
- package/package.json +12 -10
- package/workers/javascript/javascript-worker.js +455 -31
- package/workers/python/generated-python-harness-snippets.js +1 -1
- package/workers/python/pyodide-worker.js +31 -0
- 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
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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(
|
|
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(
|
|
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,
|
|
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) =>
|
|
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,
|
|
2786
|
+
return executeJavaScriptCode(transpiledCode, functionName, materializedInputs, executionStyle, "typescript");
|
|
2495
2787
|
}
|
|
2496
2788
|
export {
|
|
2497
2789
|
DEFAULT_BROWSER_HARNESS_ASSET_RELATIVE_PATHS,
|