Skip to content

Solid

Terminal window
npm i @acheul/ahoi-js solid-js
import { createAhoi } from "@acheul/ahoi-js/solid";
export const { PierProvider, usePier } = createAhoi<
Pier,
Hail,
Tell,
HailRets,
TellRets
>({
/* wasm exports */
});

Solid is the only adapter that hands you a single object rather than separate hooks. Ahoi’s hails map straight onto Solid signals, so there is nothing to reconcile.

function Counter() {
const pier = usePier();
const [count, setCount] = pier.hail("Count"); // () => number
const doubled = pier.readHail("Doubled"); // () => number
return (
<>
<p>
{count()} · {doubled()}
</p>
<button onClick={() => setCount(count() + 1)}>+1</button>
<button onClick={() => pier.tell("Increase")}>tell</button>
</>
);
}

Values are accessors: call them. That is ordinary Solid, and it means a hail can be passed around without losing reactivity.

<PierProvider pier="Top">
<Counter />
</PierProvider>

Nest them for child scopes:

<PierProvider pier="Top">
<Counter />
<Show when={open()}>
<PierProvider pier="Panel">
<Panel />
</PierProvider>
</Show>
</PierProvider>

Nothing to do. The adapter registers onCleanup for you, so unmounting a provider clears its sphere, and that cascades to any child piers.

Hails release themselves the same way when the component that read them goes away.

Because a hail is a signal, only the expressions that actually read it update.

<p>{count()}</p> {/* updates */}
<p>{other()}</p> {/* does not */}

No component re-runs. This is the closest fit of the four adapters: Solid’s model and ahoi’s are the same shape.

  • usePier() throws if there is no provider above it.

  • The object usePier() returns is stable. You can destructure it once and keep it. Its type is PierSphere: a pier is a sphere underneath.

  • Wasm cannot hot-reload. In Vite, force a full reload when your wiring module changes:

    if (import.meta.hot)
    import.meta.hot.accept(() => import.meta.hot!.invalidate());