diff --git a/rag/04-idioms.md b/rag/04-idioms.md index f174ab3..c2f302a 100644 --- a/rag/04-idioms.md +++ b/rag/04-idioms.md @@ -224,22 +224,26 @@ only a JSON glue. The faithful Go port replaces the *glue* (not Node) with Go: version (`require` → handle, `call` → method with auto-await, `end`), **no C/CGO**, and **not** `node -e` string eval. RTL lives in `fivenode_go/hbrtl_ext/nodebridge`: +Same object+method API as Node / the original C++ fivenode `Require()` — +`FN_REQUIRE` returns an **object**, and you call npm methods on it directly: + ```five -// FN_REQUIRE(cModule) -> nHandle ; FN_CALL(nH,cMethod[,cArgsJson]) -> {ok,type,value,err} -LOCAL nH := FN_REQUIRE( "qrcode" ) // npm module handle (persistent) -LOCAL cArgs := hb_jsonEncode( { cUrl, { "type" => "svg", "width" => 280 } } ) // JSON arg array -LOCAL hR := hb_jsonDecode( FN_CALL( nH, "toString", cArgs ) ) // async method auto-awaited -FN_END( nH ) -IF hb_HGetDef( hR, "ok", .f. ) - cSvg := hb_HGetDef( hR, "value", "" ) // type: string|number|boolean|json|buffer(b64) +LOCAL oQR := FN_REQUIRE( "qrcode" ) // = Require(); returns a module object +IF ! HB_ISOBJECT( oQR ) // .F. on failure → FN_LASTERROR() + // handle error ENDIF +LOCAL cSvg := oQR:toString( cUrl, { "type" => "svg", "width" => 280 } ) // async auto-awaited +oQR:__end__() // release the handle ``` +How it works: at `FN_REQUIRE` the bridge enumerates the module's method names and +registers each as a class method whose closure proxies `oObj:(args)` to Node +(mirrors the C++ `TFNModule` `hb_clsAdd(clsH, NAME, DISPATCH)`). Args are native PRG +values (string/number/hash/array → JS); the result comes back as string/number/ +boolean/buffer(base64)/json. `__end__()` frees the node-side handle. - Setup: a `node/` dir with `package.json` + `npm install `; the bridge points - `NODE_PATH` there (default dir via env `SOLMADE_NODE_DIR`). -- One persistent `node` per process; calls are serialized; the Go binary stays pure Go - and only spawns node when `FN_*` is used. `FN_LASTERROR()` for diagnostics. -- Args are a JSON array (`hb_jsonEncode`); user data never concatenated into JS code. -- Real example + live demo: solmade `app/api/qr.prg` → npm `qrcode` → SVG, served at + `NODE_PATH` there (default via env `SOLMADE_NODE_DIR`). +- One persistent `node` per process; calls serialized; pure Go, node spawned on first use. +- Real example + live demo: solmade `app/api/qr.prg` → `oQR:toString()` → SVG, at `solmade.kr/qrcode`. **Legacy (do NOT build new on it):** the original `fivenode` used a **C** N-API/koffi