docs(rag): §7 npm bridge = object dispatch (oMod:method), like TFNModule

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
CharlesKWON
2026-06-15 21:31:30 +09:00
parent af5150211e
commit ffafdc8fa5

View File

@@ -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:<name>(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 <pkg>`; 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