feat(wasmguest): HostServices() — per-instance CoreServices accessor

Block/template render funcs receive only ctx+content over the ABI, no
services. Load runs on a single pooled instance, so a DB-backed block on
any other pooled instance had a nil pool. HostServices() exposes the
CoreServices bound at _initialize on every instance (live db.* Pool +
capability stubs) so render funcs resolve their pool per-instance. Zero
value in native builds (Serve never called); callers nil-check Pool.

Enables the symposium wasm port (WO-WZ-012).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Alex Dunmow 2026-07-03 21:35:16 +08:00
parent f708a0269d
commit b9e8fe4bf1

View File

@ -36,6 +36,26 @@ func Serve(reg plugin.PluginRegistration) {
current = newGuest(reg) current = newGuest(reg)
} }
// HostServices returns the CoreServices bound to THIS guest instance. Unlike
// the deps handed to Load/HTTPHandler/JobHandlers — which the host delivers on
// only one pooled instance (Load) or lazily on first use — these services are
// bound at `_initialize` on EVERY pooled instance (newGuest). The interface
// fields are host_call-backed capability stubs and Pool is a live db.* bridge.
//
// This is the escape hatch for entry points the ABI does not hand deps to —
// most importantly block/template render funcs (HOOK_RENDER_BLOCK gives the
// closure only ctx+content, no services). A DB-backed block reads its pool from
// HostServices().Pool so it works on any pooled instance, not just the one that
// happened to run Load. In a native build (Serve never called — no wasip1
// _initialize) current is nil and this returns the zero CoreServices, so guest
// code must nil-check Pool (native tests inject a real pool by other means).
func HostServices() plugin.CoreServices {
if current == nil {
return plugin.CoreServices{}
}
return current.services
}
// guest adapts a plugin.PluginRegistration to ABI hook calls. // guest adapts a plugin.PluginRegistration to ABI hook calls.
type guest struct { type guest struct {
reg plugin.PluginRegistration reg plugin.PluginRegistration