Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions packages/affine-vscode/mod.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,27 @@ module.exports = function makeVscodeBindings(vscode, lcModule, hostShim) {
: Promise.reject(new Error("fetch unavailable"));
return reg(doFetch.catch((err) => ({ __error: String(err) })));
},

// `jsonField(json, key)` — minimal one-level JSON field read for
// guests with no JSON parser. Mirrors thenableResultJson's
// synchronous reg(string) shape; "" on parse failure / non-object /
// missing key (the guest treats "" as absent). Scalars are coerced
// to their string form; objects/arrays are re-serialised so the
// guest can at least detect presence / pass them on.
jsonField: (jsonPtr, keyPtr) => {
const raw = readString(jsonPtr);
const key = readString(keyPtr);
try {
const obj = JSON.parse(raw);
if (obj === null || typeof obj !== "object") return reg("");
if (!(key in obj)) return reg("");
const v = obj[key];
if (v === null || v === undefined) return reg("");
return reg(typeof v === "object" ? JSON.stringify(v) : String(v));
} catch (_e) {
return reg("");
}
},
};

const VscodeLanguageClient = {
Expand Down
16 changes: 16 additions & 0 deletions stdlib/Vscode.affine
Original file line number Diff line number Diff line change
Expand Up @@ -336,3 +336,19 @@ pub extern fn thenableResultJson(t: Thenable) -> String;
/// Resolves with the JSON-decoded response body. Use thenableThen /
/// thenableResultJson to read the settled value from a wasm guest.
pub extern fn httpPostJson(url: String, body_json: String) -> Thenable / Async;

// ── Minimal JSON field extraction ────────────────────────────────────
//
// The guest has no JSON parser and only stringConcat/stringEndsWith/
// stringIsEmpty for strings, so it cannot decode the payloads returned
// by thenableResultJson / httpPostJson. This synchronous String->String
// extern reads one top-level field, mirroring the thenableResultJson
// shape (no Async; "" sentinel). It deliberately stays minimal (one
// top-level key, scalar coerced to its string form) — enough for result
// objects like { tier, tier_code, score } and the { __error } reject
// shape; nested/array access is out of scope by design.

/// The top-level `key` of JSON object `json`, coerced to its string
/// form (numbers/bools stringified). Empty string if `json` is not an
/// object, does not parse, or has no such key.
pub extern fn jsonField(json: String, key: String) -> String;
Loading