diff --git a/plugin/wasmguest/dispatch.go b/plugin/wasmguest/dispatch.go index 8366344..43f4276 100644 --- a/plugin/wasmguest/dispatch.go +++ b/plugin/wasmguest/dispatch.go @@ -36,6 +36,26 @@ func Serve(reg plugin.PluginRegistration) { 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. type guest struct { reg plugin.PluginRegistration