diff --git a/.changeset/bright-geckos-brake.md b/.changeset/bright-geckos-brake.md
new file mode 100644
index 0000000000..573db9ed62
--- /dev/null
+++ b/.changeset/bright-geckos-brake.md
@@ -0,0 +1,5 @@
+---
+'xstate': patch
+---
+
+The inspection event interfaces now expect `ActorRefLike` instead of `AnyActorRef`
diff --git a/.changeset/moody-rabbits-whisper.md b/.changeset/moody-rabbits-whisper.md
new file mode 100644
index 0000000000..20815f17ae
--- /dev/null
+++ b/.changeset/moody-rabbits-whisper.md
@@ -0,0 +1,32 @@
+---
+'@xstate/store': minor
+---
+
+The `createStoreWithProducer(…)` function now uses the new configuration API:
+
+```ts
+import { createStoreWithProducer } from '@xstate/store';
+// DEPRECATED API
+// const store = createStoreWithProducer(
+// producer,
+// {
+// count: 0
+// },
+// {
+// inc: (context, event) => {
+// context.count++;
+// }
+// }
+// );
+
+const store = createStoreWithProducer(producer, {
+ context: {
+ count: 0
+ },
+ on: {
+ inc: (context, event) => {
+ context.count++;
+ }
+ }
+});
+```
diff --git a/examples/readme.md b/examples/readme.md
index 2846e07dac..34120ea09f 100644
--- a/examples/readme.md
+++ b/examples/readme.md
@@ -6,12 +6,13 @@ These steps assume You've forked the repo and created a branch for your PR. For
```bash
pnpm create vite@latest my-example-react --template react-ts
+cd my-example-react
```
2. Install `xstate` and the library-specific beta (e.g. `@xstate/react`):
```bash
-pnpm i xstate @xstate/react
+pnpm install xstate @xstate/react
```
3. Add your XState-powered demo code ✨
diff --git a/examples/store-counter-react/eslint.config.js b/examples/store-counter-react/eslint.config.js
new file mode 100644
index 0000000000..61f2de9cdc
--- /dev/null
+++ b/examples/store-counter-react/eslint.config.js
@@ -0,0 +1,28 @@
+import js from '@eslint/js';
+import globals from 'globals';
+import reactHooks from 'eslint-plugin-react-hooks';
+import reactRefresh from 'eslint-plugin-react-refresh';
+import tseslint from 'typescript-eslint';
+
+export default tseslint.config(
+ { ignores: ['dist'] },
+ {
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
+ files: ['**/*.{ts,tsx}'],
+ languageOptions: {
+ ecmaVersion: 2020,
+ globals: globals.browser
+ },
+ plugins: {
+ 'react-hooks': reactHooks,
+ 'react-refresh': reactRefresh
+ },
+ rules: {
+ ...reactHooks.configs.recommended.rules,
+ 'react-refresh/only-export-components': [
+ 'warn',
+ { allowConstantExport: true }
+ ]
+ }
+ }
+);
diff --git a/examples/store-counter-react/package.json b/examples/store-counter-react/package.json
index 6d9ae0756b..43efa7b1d1 100644
--- a/examples/store-counter-react/package.json
+++ b/examples/store-counter-react/package.json
@@ -1,29 +1,31 @@
{
- "name": "@xstate/example-store-counter-react",
+ "name": "counter-react",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
- "build": "tsc && vite build",
- "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
+ "build": "tsc -b && vite build",
+ "lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
- "@xstate/store": "^0.0.2",
+ "@statelyai/inspect": "^0.4.0",
+ "@xstate/store": "^2.5.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
- "@types/react": "^18.3.5",
+ "@eslint/js": "^9.10.0",
+ "@types/react": "^18.3.8",
"@types/react-dom": "^18.3.0",
- "@typescript-eslint/eslint-plugin": "^7.18.0",
- "@typescript-eslint/parser": "^7.18.0",
"@vitejs/plugin-react": "^4.3.1",
- "eslint": "^8.57.0",
- "eslint-plugin-react-hooks": "^4.6.2",
- "eslint-plugin-react-refresh": "^0.4.11",
+ "eslint": "^9.10.0",
+ "eslint-plugin-react-hooks": "5.1.0-rc-fb9a90fa48-20240614",
+ "eslint-plugin-react-refresh": "^0.4.12",
+ "globals": "^15.9.0",
"typescript": "^5.6.2",
- "vite": "^5.4.5"
+ "typescript-eslint": "^8.6.0",
+ "vite": "^5.4.6"
}
}
diff --git a/examples/store-counter-react/src/App.tsx b/examples/store-counter-react/src/App.tsx
index ce9f583f86..36602a46a3 100644
--- a/examples/store-counter-react/src/App.tsx
+++ b/examples/store-counter-react/src/App.tsx
@@ -1,28 +1,57 @@
import './App.css';
import { createStore } from '@xstate/store';
import { useSelector } from '@xstate/store/react';
+import { useEffect } from 'react';
+import { createBrowserInspector } from '@statelyai/inspect';
-const store = createStore(
- {
+const inspector = createBrowserInspector();
+
+const store = createStore({
+ context: {
count: 0
},
- {
- inc: {
- count: (ctx) => ctx.count + 1
+ on: {
+ inc: (context, event: { by: number }) => {
+ return {
+ count: context.count + event.by
+ };
+ },
+ reset: (_context, _ev, { emit }) => {
+ emit({ type: 'reset' });
+ return {
+ count: 0
+ };
}
}
-);
+});
+
+store.inspect(inspector.inspect);
function App() {
const count = useSelector(store, (s) => s.context.count);
+ useEffect(() => {
+ const sub = store.on('reset', () => {
+ console.log('Count reset!');
+ });
+
+ return sub.unsubscribe;
+ }, []);
+
return (
<>
-
XState Store counter example
-
-