@zephytiju/prism-react
v0.2.0
Published
React channel bindings for Prism micro-UI composition: id-keyed shared state and events over nanostores, host-mediated action transport, and the build-time channel-graph scanner.
Readme
PrismReact
@zephytiju/prism-react — React channel bindings for Prism micro-UI composition.
Published to npm as @zephytiju/prism-react.
Install
npm install @zephytiju/prism-reactPeer dependency: react (>=18). Runtime dependencies nanostores and @nanostores/react
are installed automatically. The CLI (prism-react-scan) ships with the package and runs
the compiled scanner from dist/ — run npm run build in this repo before invoking it
from source.
Implements the channel design recorded in §7 (Prism rework) and §8 (Lattice rework) of the Guanlan Lattice Ontology Design:
- Id-keyed state channels over nanostores, created lazily and shared by nothing but the id — no central state registry, no library coupling.
- Render granularity by design:
usePrismStateSettersubscribes to nothing (publishers never re-render from publications);usePrismStateValuere-renders only on its own channel;usePrismStateSelectornarrows to selected fields;===-equal sets are deduped by the atom. - Events (
emitPrismEvent/usePrismEvent): ephemeral notifications with zero-or-more subscribers; handlers run without re-rendering unless they set state. - Host-mediated actions (
setPrismActionExecutor/prismHostExecuteAction): components hold no URLs, clients, or credentials; the host routes actions to PrismRuntimeHost. - Lattice transport (
useLatticeTransport, design record §8): binds TypeScript clients generated from bundle interface declarations to typed per-method routes (interfaces/{interfaceId}/{method}), verifying the API-surface digest on first call so client/runtime drift fails fast. - Build-time scanner (
src/scanner.ts,bin/prism-react-scan.mjs): derives the deterministic publish/consume/action graph from hook call-site id literals — the replacement for authored state-contract registries. - Scoped registries (
<ChannelScope>): an isolated channel+event registry for a subtree — two scopes may mount the same component over the same channel ids with independent data; a nested scope wins for its own subtree; aseedmap applies initial values on mount; atoms and events die with the scope's unmount. Without a scope everything resolves to the module-global registry exactly as before (task a842de6b).
Hooks
| Hook | Binding |
| --- | --- |
| usePrismState<T>(id) | read-write (subscribes; publish + consume) |
| usePrismStateValue<T>(id) | read-only consumer |
| usePrismStateSetter<T>(id) | write-only publisher (no subscription) |
| usePrismStateSelector<T, S>(id, select) | field-level consumer (stable select) |
| usePrismEvent(id, handler) / emitPrismEvent(id, payload) | event channel |
| useLatticeTransport(digest?) | transport for generated interface clients |
| usePrismRegistry() | the registry in scope (global when no <ChannelScope> wraps the tree) |
Scopes
<ChannelScope seed={{ "viewport.camera": { lon: 116.4, lat: 39.9 } }}>
<TwoIndependentGlobeViewports /> // same component, same channel ids, independent data
</ChannelScope>Hooks inside a ChannelScope resolve channels/events through a React context (default: the
module-global registry, so existing trees are unaffected). Imperative writeChannel /
readChannel / emitPrismEvent calls resolve to the innermost mounted scope, and to the global
registry when none is mounted. On unmount the scope destroys its registry — its atoms and event
handlers do not outlive it, and the global registry is never touched.
Status
Tracking: Prism rework task [prism-react channel hooks + build-time id scanner]
(https://applink.feishu.cn/client/todo/detail?guid=1df460ea-a4e5-458e-af34-86ae3f6a88ce) and
Lattice rework task [prism-react useLatticeTransport binding]
(https://applink.feishu.cn/client/todo/detail?guid=9d062586-9d39-4fa9-bfec-be3523b4903a).
The interfaces/__surface digest probe is provisional pending the generator task's digest
emission contract.
Development
npm install
npm run typecheck
npm test