From 57d6350fa83b4d81ffb98ffbf95613c3d7bb4869 Mon Sep 17 00:00:00 2001 From: CharlesKWON Date: Mon, 15 Jun 2026 17:05:05 +0900 Subject: [PATCH] docs(rag): document Node Require() ecosystem path (vs Go RTL) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add idioms §7: the two ways PRG reaches the outside world — Go RTL (fivenode_go, single binary, production) vs Node Require() (original fivenode, N-API; call npm directly with no wrapper). Includes the proven Require/aWait/__end__ patterns and when to pick Node. Example reference: napi/test/api/sharekit.prg (npm qrcode + Node crypto/os in one PRG). Co-Authored-By: Claude Opus 4.8 (1M context) --- rag/04-idioms.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/rag/04-idioms.md b/rag/04-idioms.md index 7093bd0..0886fb7 100644 --- a/rag/04-idioms.md +++ b/rag/04-idioms.md @@ -206,3 +206,37 @@ exiting non-zero on any failure. Run it after any refactor. Deploy (launchd): `launchctl kickstart -k gui/$(id -u)/kr.solmade.web` (and `...worker1/2/3`). The worker build (`build_worker.sh`) links `cmd_prg/job_worker.prg` plus the shared `app/lib/*.prg` (so `LLM_CHAT` and prompts are available to it too). + +## 7. Reaching the ecosystem — two paths (pick by runtime) + +There are two distinct ways to use the outside world from PRG; they belong to +different runtimes (see [[five-overview]]): + +**(a) Go RTL — `fivenode_go` (single Go binary, NO Node).** Wrap a Go package in a +thin `hbrtl_ext` module, blank-import it with `--rtl`, call the registered function. +This is the production path (solmade): no runtime deps, one binary. Use for anything +with a good Go library (Postgres, PDF, XLSX, crypto/rand, argon2, bluemonday). + +**(b) Node `Require()` — original `fivenode` (Node.js + N-API/koffi).** PRG calls an +**npm package directly**, Node-style, with no wrapper to write: + +```five +oQR := Require( "qrcode" ) // npm package +cSvg := aWait( oQR:toString( cUrl, { "type" => "svg" } ) ) // async → aWait() +oQR:__end__() // release the handle + +oId := Require( "crypto" ):randomUUID() // Node builtin, sync +oOs := Require( "os" ) // builtins: os, path, fs, ... +cHost := oOs:hostname() ; oOs:__end__() +``` +- Sync npm: `obj:methodSync(...)` (e.g. qr-image `imageSync`). Async (Promise): + wrap the call in `aWait(...)`. Always `obj:__end__()` when done. +- Pass PRG hashes as JS objects: `{ "width" => 240, "color" => { "dark" => "#000" } }`. +- The server allowlists each handler — register new ones in `napi/test/server.js` + (`allowedPrg.add('/api/foo.prg')`). + +**When to choose (b):** the npm package has no good Go equivalent, or reimplementing it +would be heavy (QR codes, charting, specialized parsers, ML/JS-only SDKs). You get the +entire npm registry with zero glue code — the cost is a Node runtime instead of a single +static binary. Example: `napi/test/api/sharekit.prg` composes npm `qrcode` + Node +`crypto`/`os` in one PRG to build an article share kit (QR svg+png + tracking UUID).