Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,41 @@ concurrency:
cancel-in-progress: true

jobs:
react-compatibility:
name: React ${{ matrix.react }} compatibility
runs-on: ubuntu-latest
strategy:
matrix:
include:
- react: 18.0.0
react-dom: 18.0.0
- react: 19.2.0
react-dom: 19.2.0
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- run: pnpm install --frozen-lockfile

- name: Install React compatibility target
run: pnpm add --save-dev --save-exact --lockfile=false react@${{ matrix.react }} react-dom@${{ matrix.react-dom }}

- name: Verify published Store behavior
run: >-
pnpm exec vitest run
src/core/__tests__/createShallowStore.test.ts
src/core/__tests__/createStoreToolkit.test.tsx
src/core/__tests__/createStoreToolkit.ssr.test.tsx
src/hooks/storeSelection/__tests__/createStoreSelectionBindings.test.ts
src/providers/__tests__/createStoreProvider.test.tsx

verify:
name: Verify (Node ${{ matrix.node }})
runs-on: ubuntu-latest
Expand Down
19 changes: 11 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.0.0] - 2026-09-19

### Breaking Changes

- Made the toolkit Resolved-store-first: `Provider`, `useStore`, `useStorePlain`, and
Expand All @@ -30,16 +32,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Standardized package development, CI, and release workflows on pnpm 11.
- Adopted `@okyrychenko-dev/type-utils` as a direct runtime dependency for shared guards.
- Aligned package exports and validation tooling with the other maintained `@okyrychenko-dev` libraries.
- Deprecated `createTransitionAction`, `useActionStateAdapter`, and `useOptimisticReducer` in favor
of composing React's supported primitives directly. The helpers remain runtime-compatible without
warnings, and removal is deferred to the next intentional major release.
- Deprecated `createStoreToolkit().getProvider()` in favor of the canonical `provider` property.
The compatibility accessor still returns the same Provider bindings without runtime warnings;
removal is deferred to the next intentional major release.
- Replaced the removed React 19 helper exports with migration guidance using React's supported
primitives directly.
- Documented the complete migration from legacy Provider, Resolved store, Global store, lifecycle,
and React 19 helper interfaces.

### Removed

- Removed deprecated provider, resolved-store, and lifecycle aliases.
- Removed deprecated Provider, Resolved store, and lifecycle aliases.
- Removed `createTransitionAction`, `useActionStateAdapter`, and `useOptimisticReducer` from the
package interface.

## [0.4.2] - 2026-07-25

Expand Down Expand Up @@ -182,7 +184,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- TypeScript types with generics and mutator support
- Test suite covering core utilities and provider behavior

[Unreleased]: https://github.com/okyrychenko-dev/react-zustand-toolkit/compare/v0.4.2...HEAD
[Unreleased]: https://github.com/okyrychenko-dev/react-zustand-toolkit/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/okyrychenko-dev/react-zustand-toolkit/compare/v0.4.2...v1.0.0
[0.4.2]: https://github.com/okyrychenko-dev/react-zustand-toolkit/compare/v0.4.1...v0.4.2
[0.4.1]: https://github.com/okyrychenko-dev/react-zustand-toolkit/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/okyrychenko-dev/react-zustand-toolkit/compare/v0.3.0...v0.4.0
Expand Down
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ the Store creator returned by the recipe.
pnpm add @okyrychenko-dev/react-zustand-toolkit react zustand
```

The package supports React 18 or 19 and Zustand 5. It ships ESM and CommonJS entry points with
TypeScript declarations.

## Declarative toolkit

Provider placement declares which Store descendants observe. The top-level hooks use the nearest
Expand Down Expand Up @@ -91,8 +94,10 @@ A nested `counter.Provider` wins for its descendants. Each Provider owns an isol

The Store recipe runs synchronously when a Store is created and must be deterministic for equivalent
input and free of external side effects. It constructs state, actions, and middleware together;
the toolkit does not patch initial state afterward. Later Provider `input` changes are ignored. Use
Store actions for live changes or change the Provider `key` to start a new Store lifetime.
the toolkit does not patch initial state afterward. The Global store is created immediately from
`globalInput`; each Provider store is created on that Provider's first render. Later Provider
`input` changes are ignored. Use Store actions for live changes or change the Provider `key` to
start a new Store lifetime.

`onStoreInit` runs synchronously after construction and before descendants observe the Store.
`onStoreReady` runs after commit at most once for a Provider Store. Put subscriptions, analytics,
Expand Down Expand Up @@ -184,7 +189,9 @@ Both the toolkit Provider and standalone Provider support two lifecycle stages:

Use the Store recipe and `onStoreInit` only for synchronous construction and validation. Start
subscriptions, analytics, registrations, and other external effects in `onStoreReady`. Changing
callback identities does not repeat a lifecycle stage that has already completed.
callback identities does not repeat a lifecycle stage that has already completed. If
`onStoreReady` is omitted initially and supplied on a later render, it runs once after that render
commits.

## Server rendering and hydration

Expand Down Expand Up @@ -261,9 +268,10 @@ const resolved = createResolvedStoreHooks(global.store, provider.useProviderStor
`createStoreProvider` also exposes strict `useContextStoreApi`, Shallow `useContextStore`, Plain
`useContextStorePlain`, `useIsInsideProvider`, and advanced `useProviderStoreOptional`. Strict hooks
throw outside the matching Provider. Middleware-enhanced Store capabilities remain on all Store
handles.
handles. `createResolvedStoreHooks` returns `useResolvedStoreApi`, Shallow `useResolvedValue`, and
Plain `useResolvedStorePlain` for custom integrations.

## Migration to the declarative major interface
## Migration to 1.0

| Previous member | Replacement |
| --- | --- |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@okyrychenko-dev/react-zustand-toolkit",
"version": "0.4.2",
"version": "1.0.0",
"packageManager": "pnpm@11.21.0",
"type": "module",
"description": "Type-safe Zustand helpers for shallow-first selectors, isolated providers, and resolved store hooks",
Expand Down
Loading