Skip to content

Commit 464765e

Browse files
feat(stdlib): add httpPostJson async-extern for out-of-process JSON POST (#210)
Adds `pub extern fn httpPostJson(url, body_json) -> Thenable / Async` to stdlib/Vscode.affine plus the canonical runtime impl in packages/affine-vscode/mod.js, following the exact #205 thenable convention (reg the response Thenable; guest observes via thenableThen / thenableResultJson, same as languageClientSendRequest). Motivation: lets a VS Code extension reach a BoJ-server cartridge endpoint (e.g. reposystem_run_audit on :7700) as a real in-process request rather than shelling a CLI. Unblocks the BoJ-primary tier of the rsr-certifier extension rewire (PR-5d-B). Resolves/rejects settle as { __error } (same shape thenableThen uses for rejections) so guests can branch to a fallback. Full dune gate green (257/257), zero regression. Refs #103 #199 #205 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 73f16b9 commit 464765e

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

packages/affine-vscode/mod.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,27 @@ module.exports = function makeVscodeBindings(vscode, lcModule, hostShim) {
363363
try { return reg(JSON.stringify(__thenableResults.get(tHandle))); }
364364
catch (_e) { return reg(""); }
365365
},
366+
367+
// `httpPostJson(url, body_json)` — out-of-process JSON POST for BoJ
368+
// cartridge calls (e.g. boj-server :7700 reposystem_run_audit). Like
369+
// languageClientSendRequest, we register the response Thenable in the
370+
// handle table and let the guest observe it via thenableThen /
371+
// thenableResultJson. Resolves with the parsed JSON body so
372+
// thenableResultJson re-serialises it consistently; a non-JSON or
373+
// failed response settles as { __error } (same shape thenableThen
374+
// uses for rejections), so the guest can branch to its fallback.
375+
httpPostJson: (urlPtr, bodyPtr) => {
376+
const url = readString(urlPtr);
377+
const body = readString(bodyPtr);
378+
const doFetch = (typeof fetch === "function")
379+
? fetch(url, {
380+
method: "POST",
381+
headers: { "content-type": "application/json" },
382+
body,
383+
}).then((r) => r.json())
384+
: Promise.reject(new Error("fetch unavailable"));
385+
return reg(doFetch.catch((err) => ({ __error: String(err) })));
386+
},
366387
};
367388

368389
const VscodeLanguageClient = {

stdlib/Vscode.affine

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,3 +322,17 @@ pub extern fn thenableThen(t: Thenable, on_settle: fn(Unit) -> Int) -> Disposabl
322322
/// The resolved value of `t`, JSON-encoded. Empty string until `t` has
323323
/// settled (i.e. until the `thenableThen` callback has fired).
324324
pub extern fn thenableResultJson(t: Thenable) -> String;
325+
326+
// ── Out-of-process JSON POST (BoJ cartridge calls) ───────────────────
327+
//
328+
// Lets an extension reach a BoJ-server cartridge endpoint (e.g.
329+
// `reposystem_run_audit` on boj-server :7700) as a real in-process
330+
// request instead of shelling a CLI. Returns a Thenable of the parsed
331+
// JSON response; the wasm guest observes it with the #205 primitives
332+
// (`thenableThen` then `thenableResultJson`), exactly as for
333+
// `languageClientSendRequest`. Same handle/`Async` convention.
334+
335+
/// POST `body_json` to `url` with `Content-Type: application/json`.
336+
/// Resolves with the JSON-decoded response body. Use thenableThen /
337+
/// thenableResultJson to read the settled value from a wasm guest.
338+
pub extern fn httpPostJson(url: String, body_json: String) -> Thenable / Async;

0 commit comments

Comments
 (0)