@octanejs/xstate-store
v0.0.15
Published
XState Store for Octane — re-exports the framework-agnostic @xstate/store core unchanged and ports the @xstate/store-react 2.0.0 binding onto Octane hooks.
Keywords
Readme
@octanejs/xstate-store
XState Store for Octane — a port of @xstate/[email protected].
The @xstate/store core is framework-neutral, so it is reused unmodified and
re-exported wholesale from this entry point, exactly as upstream does. Only the
React binding is ported. See UPSTREAM.md for the pin, the
export crosswalk, and the disposition of every upstream test.
npm install @octanejs/xstate-store
pnpm add @octanejs/xstate-storeUsage
import { createStore, useSelector } from '@octanejs/xstate-store';
const store = createStore({
context: { count: 0 },
on: {
inc: (context, event: { by: number }) => ({
...context,
count: context.count + event.by,
}),
},
});
export function Counter() @{
const count = useSelector(store, (s) => s.context.count);
<button onClick={() => store.trigger.inc({ by: 1 })}>{count as string}</button>
}createStoreHook bundles the store and its selector into one hook:
import { createStoreHook } from '@octanejs/xstate-store';
const useCountStore = createStoreHook({
context: { count: 0 },
on: { inc: (context, event: { by: number }) => ({ ...context, count: context.count + event.by }) },
});
export function Counter() @{
const [count, store] = useCountStore((s) => s.context.count);
<button onClick={() => store.trigger.inc({ by: 1 })}>{count as string}</button>
}Exports
Everything @xstate/[email protected] exports (createStore, createStoreConfig,
createStoreLogic, createAtom, createAtomConfig, createAsyncAtom,
createReducerAtom, fromStore, shallowEqual, and the full type surface),
plus the ported hooks useSelector, useStore, useAtom, useAtomState, and
createStoreHook.
Intentional differences from @xstate/store-react on React
- Conditional hook calls are legal. Upstream calls hooks inside
ifbranches inuseSelectoranduseAtom. On React that only works because the branch is stable for a given call site. Octane keys hooks by compiler-assigned call site rather than call order, so the shape is sound here — and if a call site ever did flip branches, Octane keeps independent hook cells per branch instead of corrupting hook order. useSyncExternalStoreskips React's commit-timegetSnapshotre-read when the rendered value was unchanged, because Octane's synchronous renderer closes the concurrent-interleaving window React guards there.- Server snapshots.
getServerSnapshotis optional in Octane and falls back togetSnapshot; React throws when it is missing. Every hook here supplies one.
