Skip to content

refactor(codemode): make the host boundary JSON.stringify plus a short table - #49128

Merged
rekram1-node merged 2 commits into
v2from
json-seam
Sep 15, 2026
Merged

rekram1-node merged 2 commits into
v2from
json-seam

Conversation

@rekram1-node

@rekram1-node rekram1-node commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

The host boundary is JSON.stringify, plus a short table for values that cannot be JSON but whose intent is clear.

program ──► tool args / result    JSON.stringify, then the table below
tool result ──► program           JSON.parse(JSON.stringify(result))

One walker replaces four conversion modes and a second copy of itself.

 data.ts
-copy(value, label, mode: "program" | "data" | "json" | "result", depth, seen, protos?, boundary)
-toProgram / fromData / toData
+toJson(ctx, value, replacer?)     the JSON.stringify walk: toJSON honored, cycles → TypeError
+toBoundary(ctx, value)            toJson plus the table
+fromJson(ctx, json)               host JSON → Obj / Arr

 stdlib/json.ts
-second stringify walker for function replacers
+JSON.stringify(toJson(ctx, value, replacer), properties, indent)

tool-runtime.ts now deals only in Json: arguments arrive converted and results leave as JSON.parse(JSON.stringify(decoded)), so program values never enter it. The conversion sits in one place, Interpreter.tool, which both tools.* calls and search go through. ToolRuntimeError moves there from data.ts.

The table

value at the boundary before after
un-awaited promise rejected with hint awaited; a rejection fails the program with its reason
Set array array
URLSearchParams query string query string
Error { name, message, ...own } same (also in-program JSON.stringify)
Uint8Array rejected with encode hint same
own __proto__ key dropped dropped
RegExp "/src/flags" {} like JS
extension handle, generator rejected with hint {} like JS
function rejected dropped like JS
undefined property in the result null dropped like JS
cyclic value InvalidDataValue TypeError: Converting circular structure to JSON.
user-defined toJSON honored only with a function replacer honored everywhere
tool output decode → host value → lossy copy decode → JSON.stringify → JSON.parse

Map stays {} for now; a smarter form is a follow-up.

In-program JSON.stringify keeps JS behavior except for the Error form and a promise, which is a TypeError with an await hint — it cannot await synchronously, and a silent {} there is the footgun the table exists to prevent.

Also gone: the toProgram(...) calls on literals, operator results, and template interpolations in interpreter.ts — those values are already primitives. BigInt literals now fail with a plain TypeError at the literal.

Files

src/data.ts                     239 → 120 lines
src/stdlib/json.ts              second walker deleted
src/tool-runtime.ts             Json in, Json out; ToolRuntimeError lives here
src/interpreter/interpreter.ts  Interpreter.tool; toProgram calls removed
src/interpreter/errors.ts       thrown-value message via console formatter
src/stdlib/{string,object,value,url,console}.ts   toProgram / toData callers
interpreter-support.md          boundary rule rewritten as one paragraph

Checks

bun run check clean; bun test 5125 pass / 0 fail; test262 report unchanged at 3858 pass / 426 known-gap.

@rekram1-node rekram1-node changed the title refactor(codemode): make the host boundary JSON.stringify refactor(codemode): make the host boundary JSON.stringify plus a short table Sep 15, 2026
@rekram1-node
rekram1-node merged commit 0b15abb into v2 Sep 15, 2026
9 of 10 checks passed
@rekram1-node
rekram1-node deleted the json-seam branch September 15, 2026 06:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant