{"owner":"statelyai","repo":"xstate","hasSkills":true,"totalSkillsCount":17,"totalTokensCount":16652,"categories":["root-instruction","claude-rule","plugin-manifest","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","CLAUDE.md","packages/core/README.md","packages/xstate-immer/README.md","packages/xstate-inspect/README.md","packages/xstate-react/README.md","packages/xstate-solid/README.md","packages/xstate-store-angular/README.md","packages/xstate-store-preact/README.md","packages/xstate-store-react/README.md","packages/xstate-store-solid/README.md","packages/xstate-store-svelte/README.md","packages/xstate-store-vue/README.md","packages/xstate-store/README.md","packages/xstate-store/docs/source-atoms.md","packages/xstate-svelte/README.md","packages/xstate-vue/README.md"],"skills":{"AGENTS.md":"This is a monorepo containing XState, @xstate/store, and related packages.\n\n## Dev environment\n\n- Use pnpm to install dependencies\n\n## PR instructions\n\n- Run `pnpm test` to run the tests in all packages, only for changes that affect mulitple packages.\n- Run `pnpm test:core` to only run core XState tests.\n- Run `pnpm test:store` to only run @xstate/store tests.\n- Run `pnpm lint` and `pnpm format:check` to check linting and formatting.\n- Run `pnpm typecheck` to make sure that there are no type errors.\n- Before making a PR, run `pnpm changeset` to create a changeset with a short description of the changes, and a code example if applicable. Do not include implementation details; only pertinent details for developers using the package.\n","CLAUDE.md":"AGENTS.md","packages/core/README.md":"<p align=\"center\">\n  <br />\n\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/statelyai/public-assets/main/logos/xstate-logo-white-nobg.svg\">\n    <img alt=\"XState logotype\" src=\"https://raw.githubusercontent.com/statelyai/public-assets/main/logos/xstate-logo-black-nobg.svg\" width=\"200\">\n  </picture>\n  <br />\n    <strong>Actor-based state management & orchestration for complex app logic.</strong> <a href=\"https://stately.ai/docs\">→ Documentation</a>\n  <br />\n  <br />\n</p>\n\nXState is a state management and orchestration solution for JavaScript and TypeScript apps. It has _zero_ dependencies, and is useful for frontend and backend application logic.\n\nIt uses event-driven programming, state machines, statecharts, and the actor model to handle complex logic in predictable, robust, and visual ways. XState provides a powerful and flexible way to manage application and workflow state by allowing developers to model logic as actors and state machines.\n\n### ✨ Create state machines visually in Stately Studio → [state.new](https://state.new)\n\n---\n\n📖 [Read the documentation](https://stately.ai/docs)\n\n➡️ [Create state machines with the Stately Editor](https://stately.ai/editor)\n\n🖥 [Download our VS Code extension](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode)\n\n📑 Inspired by the [SCXML specification](https://www.w3.org/TR/scxml/)\n\n💬 Chat on the [Stately Discord Community](https://discord.gg/xstate)\n\n✍️ Browse through the many [XState examples](https://github.com/statelyai/xstate/tree/main/examples)\n\n## Templates\n\nGet started by forking one of these templates on CodeSandbox:\n\n<table>\n<thead>\n<tr><th>Template</th><th></th></tr>\n</thead>\n<tbody>\n\n<tr>\n<td>\n\n[🤖 XState Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/vanilla-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/vanilla-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- XState v5\n- TypeScript\n- _No framework_\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[⚛️ XState + React Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/react-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/react-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [React](https://react.dev/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[💚 XState + Vue Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/vue-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/vue-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [Vue](https://vuejs.org/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[🧡 XState + Svelte Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/svelte-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/svelte-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [Svelte](https://svelte.dev/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n</tbody>\n</table>\n\n## Super quick start\n\n```bash\nnpm install xstate\n```\n\n```ts\nimport { createMachine, createActor, assign } from 'xstate';\n\n// State machine\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  context: {\n    count: 0\n  },\n  states: {\n    inactive: {\n      on: {\n        TOGGLE: { target: 'active' }\n      }\n    },\n    active: {\n      entry: assign({ count: ({ context }) => context.count + 1 }),\n      on: {\n        TOGGLE: { target: 'inactive' }\n      }\n    }\n  }\n});\n\n// Actor (instance of the machine logic, like a store)\nconst toggleActor = createActor(toggleMachine);\ntoggleActor.subscribe((state) => console.log(state.value, state.context));\ntoggleActor.start();\n// => logs 'inactive', { count: 0 }\n\ntoggleActor.send({ type: 'TOGGLE' });\n// => logs 'active', { count: 1 }\n\ntoggleActor.send({ type: 'TOGGLE' });\n// => logs 'inactive', { count: 1 }\n```\n\n## [Stately Studio](https://stately.ai)\n\n- Visually create, edit, and collaborate on state machines\n- Export to many formats, including XState v5\n- Test path & documentation autogeneration\n- Deploy to Stately Sky\n- Generate & modify machines with Stately AI\n\n<a href=\"https://stately.ai/registry/new?ref=github\" title=\"Stately Studio\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/74ed9cbc-b824-4ed7-a16d-f104947af8a7\" alt=\"XState Viz\" width=\"800\" />\n</a>\n\n**[state.new](https://stately.ai/registry/new?ref=github)**\n\n## Why?\n\nStatecharts are a formalism for modeling stateful, reactive systems. This is useful for declaratively describing the _behavior_ of your application, from the individual components to the overall application logic.\n\nRead [📽 the slides](http://slides.com/davidkhourshid/finite-state-machines) ([🎥 video](https://www.youtube.com/watch?v=VU1NKX6Qkxc)) or check out these resources for learning about the importance of finite state machines and statecharts in user interfaces:\n\n- [Statecharts - A Visual Formalism for Complex Systems](https://www.sciencedirect.com/science/article/pii/0167642387900359/pdf) by David Harel\n- [The World of Statecharts](https://statecharts.github.io/) by Erik Mogensen\n\n## Packages\n\n| Package                                                                                       | Description                                                                  |\n| --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |\n| 🤖 `xstate`                                                                                   | Core finite state machine and statecharts library + interpreter              |\n| [⚛️ `@xstate/react`](https://github.com/statelyai/xstate/tree/main/packages/xstate-react)     | React hooks and utilities for using XState in React applications             |\n| [💚 `@xstate/vue`](https://github.com/statelyai/xstate/tree/main/packages/xstate-vue)         | Vue composition functions and utilities for using XState in Vue applications |\n| [🎷 `@xstate/svelte`](https://github.com/statelyai/xstate/tree/main/packages/xstate-svelte)   | Svelte utilities for using XState in Svelte applications                     |\n| [🥏 `@xstate/solid`](https://github.com/statelyai/xstate/tree/main/packages/xstate-solid)     | Solid hooks and utilities for using XState in Solid applications             |\n| [🔍 `@xstate/inspect`](https://github.com/statelyai/xstate/tree/main/packages/xstate-inspect) | Inspection utilities for XState                                              |\n\n## Finite State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst lightMachine = createMachine({\n  id: 'light',\n  initial: 'green',\n  states: {\n    green: {\n      on: {\n        TIMER: 'yellow'\n      }\n    },\n    yellow: {\n      on: {\n        TIMER: 'red'\n      }\n    },\n    red: {\n      on: {\n        TIMER: 'green'\n      }\n    }\n  }\n});\n\nconst actor = createActor(lightMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs 'green'\n\nactor.send({ type: 'TIMER' });\n// logs 'yellow'\n```\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n</td>\n<td>\n\n</td>\n</tr>\n</tbody>\n</table>\n\n</td>\n<td>\n\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=27e86036-f2f7-40f1-9d1e-66ce6e1accc0\" title=\"Finite states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/36d4b6b5-e3d0-4c19-9f41-2e3425ceac88\" alt=\"Finite states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n<br />\n\n</td>\n</tbody>\n</table>\n\n## Hierarchical (Nested) State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst pedestrianStates = {\n  initial: 'walk',\n  states: {\n    walk: {\n      on: {\n        PED_TIMER: 'wait'\n      }\n    },\n    wait: {\n      on: {\n        PED_TIMER: 'stop'\n      }\n    },\n    stop: {}\n  }\n};\n\nconst lightMachine = createMachine({\n  id: 'light',\n  initial: 'green',\n  states: {\n    green: {\n      on: {\n        TIMER: 'yellow'\n      }\n    },\n    yellow: {\n      on: {\n        TIMER: 'red'\n      }\n    },\n    red: {\n      on: {\n        TIMER: 'green'\n      },\n      ...pedestrianStates\n    }\n  }\n});\n\nconst actor = createActor(lightMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs 'green'\n\nactor.send({ type: 'TIMER' });\n// logs 'yellow'\n\nactor.send({ type: 'TIMER' });\n// logs { red: 'walk' }\n\nactor.send({ type: 'PED_TIMER' });\n// logs { red: 'wait' }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=30dffcdd-16c2-49e2-bfc6-a674057cb271\" title=\"Hierarchical states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/32b0692b-1c29-4469-b5e3-03146e3ef249\" alt=\"Hierarchical states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n<br />\n</td>\n</tr>\n</tbody>\n</table>\n\n## Parallel State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```ts\nimport { createMachine, createActor } from 'xstate';\n\nconst wordMachine = createMachine({\n  id: 'word',\n  type: 'parallel',\n  states: {\n    bold: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_BOLD: 'off' }\n        },\n        off: {\n          on: { TOGGLE_BOLD: 'on' }\n        }\n      }\n    },\n    underline: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_UNDERLINE: 'off' }\n        },\n        off: {\n          on: { TOGGLE_UNDERLINE: 'on' }\n        }\n      }\n    },\n    italics: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_ITALICS: 'off' }\n        },\n        off: {\n          on: { TOGGLE_ITALICS: 'on' }\n        }\n      }\n    },\n    list: {\n      initial: 'none',\n      states: {\n        none: {\n          on: {\n            BULLETS: 'bullets',\n            NUMBERS: 'numbers'\n          }\n        },\n        bullets: {\n          on: {\n            NONE: 'none',\n            NUMBERS: 'numbers'\n          }\n        },\n        numbers: {\n          on: {\n            BULLETS: 'bullets',\n            NONE: 'none'\n          }\n        }\n      }\n    }\n  }\n});\n\nconst actor = createActor(wordMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs {\n//   bold: 'off',\n//   italics: 'off',\n//   underline: 'off',\n//   list: 'none'\n// }\n\nactor.send({ type: 'TOGGLE_BOLD' });\n// logs {\n//   bold: 'on',\n//   italics: 'off',\n//   underline: 'off',\n//   list: 'none'\n// }\n\nactor.send({ type: 'TOGGLE_ITALICS' });\n// logs {\n//   bold: 'on',\n//   italics: 'on',\n//   underline: 'off',\n//   list: 'none'\n// }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=980f50d8-e1ff-4441-8c8b-afe41c1610f2\" title=\"Parallel states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/3b1989c0-f4a9-4653-baf2-4df3a40e91a6\" alt=\"Parallel states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n</td>\n</tr>\n</tbody>\n</table>\n\n## History States\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst paymentMachine = createMachine({\n  id: 'payment',\n  initial: 'method',\n  states: {\n    method: {\n      initial: 'cash',\n      states: {\n        cash: {\n          on: {\n            SWITCH_CHECK: 'check'\n          }\n        },\n        check: {\n          on: {\n            SWITCH_CASH: 'cash'\n          }\n        },\n        hist: { type: 'history' }\n      },\n      on: { NEXT: 'review' }\n    },\n    review: {\n      on: { PREVIOUS: 'method.hist' }\n    }\n  }\n});\n\nconst actor = createActor(paymentMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs {\n//   value: { method: 'cash' },\n// }\n\nactor.send({ type: 'SWITCH_CHECK' });\n// logs {\n//   value: { method: 'check' },\n// }\n\nactor.send({ type: 'NEXT' });\n// logs {\n//   value: 'review',\n// }\n\nactor.send({ type: 'PREVIOUS' });\n// logs {\n//   value: { method: 'check' },\n// }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=d1a9bb95-db97-4af3-b38b-71b005c643d3\" title=\"History states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/1be5c495-d560-4660-94f2-5341efbf7128\" alt=\"History state\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n</td>\n</tr>\n</tbody>\n</table>\n\n## Sponsors\n\nSpecial thanks to the sponsors who support this open-source project:\n\n<img src=\"https://opencollective.com/xstate/tiers/backer/badge.svg?label=sponsors&color=brightgreen\" />\n\n<a href=\"https://transloadit.com/?utm_source=xstate&utm_medium=referral&utm_campaign=sponsorship&utm_content=github\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://assets.transloadit.com/assets/images/sponsorships/logo-dark.svg\">\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"https://assets.transloadit.com/assets/images/sponsorships/logo-default.svg\">\n    <img src=\"https://assets.transloadit.com/assets/images/sponsorships/logo-default.svg\" alt=\"Transloadit Logo\">\n  </picture>\n</a>\n\n## SemVer Policy\n\nWe understand the importance of the public contract and do not intend to release any breaking changes to the **runtime** API in a minor or patch release. We consider this with any changes we make to the XState libraries and aim to minimize their effects on existing users.\n\n### Breaking changes\n\nXState executes much of the user logic itself. Therefore, almost any change to its behavior might be considered a breaking change. We recognize this as a potential problem but believe that treating every change as a breaking change is not practical. We do our best to implement new features thoughtfully to enable our users to implement their logic in a better, safer way.\n\nAny change _could_ affect how existing XState machines behave if those machines are using particular configurations. We do not introduce behavior changes on a whim and aim to avoid making changes that affect most existing machines. But we reserve the right to make _some_ behavior changes in minor releases. Our best judgment of the situation will always dictate such changes. Please always read our release notes before deciding to upgrade.\n\n### TypeScript changes\n\nWe also reserve a similar right to adjust declared TypeScript definitions or drop support for older versions of TypeScript in a minor release. The TypeScript language itself evolves quickly and often introduces breaking changes in its minor releases. Our team is also continuously learning how to leverage TypeScript more effectively - and the types improve as a result.\n\nFor these reasons, it is impractical for our team to be bound by decisions taken when an older version of TypeScript was its latest version or when we didn’t know how to declare our types in a better way. We won’t introduce declaration changes often - but we are more likely to do so than with runtime changes.\n\n### Packages\n\nMost of the packages in the XState family declare a peer dependency on XState itself. We’ll be cautious about maintaining compatibility with already-released packages when releasing a new version of XState, **but** each release of packages depending on XState will always adjust the declared peer dependency range to include the latest version of XState. For example, you should always be able to update `xstate` without `@xstate/react`. But when you update `@xstate/react`, we highly recommend updating `xstate` too.\n","packages/xstate-immer/README.md":"# @xstate/immer\n\n<p align=\"center\">\n  <a href=\"https://xstate.js.org\">\n  <br />\n  <img src=\"https://user-images.githubusercontent.com/1093738/79572515-1509e180-808b-11ea-92aa-10958521aa68.png\" alt=\"XState Immer\" width=\"200\"/>\n  <br />\n    <sub><strong>XState with Immer</strong></sub>\n  <br />\n  <br />\n  </a>\n</p>\n\nThis package contains utilities for using [Immer](https://immerjs.github.io/immer/docs/introduction) with [XState](https://github.com/statelyai/xstate).\n\n- [Read the full documentation in the XState docs](https://xstate.js.org/docs/packages/xstate-immer/).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick start\n\nIncluded in `@xstate/immer`:\n\n- `assign()` - an Immer action that allows you to immutably assign to machine `context` in a convenient way\n- `createUpdater()` - a useful function that allows you to cohesively define a context update event event creator and assign action, all together. ([See an example](#createupdatereventtype-recipe) below)\n\n1. Install `immer`, `xstate`, `@xstate/immer`:\n\n```bash\nnpm install immer xstate @xstate/immer\n```\n\n**Note:** You don't need to `import` anything from `immer`; it is a peer-dependency of `@xstate/immer`, so it must be installed.\n\n2. Import the Immer utilities:\n\n```js\nimport { createMachine, interpret } from 'xstate';\nimport { assign, createUpdater } from '@xstate/immer';\n\nconst levelUpdater = createUpdater('UPDATE_LEVEL', (ctx, { input }) => {\n  ctx.level = input;\n});\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  context: {\n    count: 0,\n    level: 0\n  },\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: {\n        TOGGLE: {\n          target: 'active',\n          // Immutably update context the same \"mutable\"\n          // way as you would do with Immer!\n          actions: assign((ctx) => ctx.count++)\n        }\n      }\n    },\n    active: {\n      on: {\n        TOGGLE: {\n          target: 'inactive'\n        },\n        // Use the updater for more convenience:\n        [levelUpdater.type]: {\n          actions: levelUpdater.action\n        }\n      }\n    }\n  }\n});\n\nconst toggleService = interpret(toggleMachine)\n  .onTransition((state) => {\n    console.log(state.context);\n  })\n  .start();\n\ntoggleService.send({ type: 'TOGGLE' });\n// { count: 1, level: 0 }\n\ntoggleService.send(levelUpdater.update(9));\n// { count: 1, level: 9 }\n\ntoggleService.send({ type: 'TOGGLE' });\n// { count: 2, level: 9 }\n\ntoggleService.send(levelUpdater.update(-100));\n// Notice how the level is not updated in 'inactive' state:\n// { count: 2, level: 9 }\n```\n","packages/xstate-inspect/README.md":"# @xstate/inspect\n\nThis package contains inspection tools for XState.\n\n- [Read the full documentation in the XState docs](https://xstate.js.org/docs/packages/xstate-inspect/).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Templates\n\n- [XState (Vanilla)](https://codesandbox.io/s/xstate-ts-viz-template-qzdvv)\n- [XState + TypeScript](https://codesandbox.io/s/xstate-ts-viz-template-qzdvv)\n- [XState + Vue](https://codesandbox.io/s/xstate-vue-viz-template-r5wd7)\n- [XState + React](https://codesandbox.io/s/xstate-react-viz-template-5wq3q)\n\n![Inspector running from CodeSandbox](assets/inspector.png)\n\n[Check out the XState + Vue Minute Timer + Viz example on CodeSandbox](https://codesandbox.io/s/xstate-vue-minute-timer-viz-1txmk)\n\n## Installation\n\n1. Install with npm or yarn:\n\n```bash\nnpm install @xstate/inspect\n# or yarn add @xstate/inspect\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/inspect/dist/xstate-inspect.umd.min.js\"></script>\n```\n\nBy using the global variable `XStateInspect`\n\n2. Import it at the beginning of your project, before any other code is called:\n\n```js\nimport { inspect } from '@xstate/inspect';\n\ninspect({\n  // options\n  // url: 'https://stately.ai/viz?inspect', // (default)\n  iframe: false // open in new window\n});\n```\n\n3. Add `{ devTools: true }` to any interpreted machines you want to visualize:\n\n```js\nimport { interpret } from 'xstate';\nimport { inspect } from '@xstate/inspect';\n// ...\n\nconst service = interpret(someMachine, { devTools: true });\nservice.start();\n```\n\n## Configuration\n\n- `url` _(optional)_ - The endpoint that the Inspector sends events to. Default: https://stately.ai/viz?inspect\n- `iframe` _(optional)_ - The iframe that loads the provided URL. If iframe is set to `false`, then a new tab is opened instead.\n- `devTools` _(optional)_ - Allows custom implementation for lifecycle hooks.\n- `serialize` _(optional)_ - A custom serializer for messages sent to the URL endpoint. Useful for sanitizing sensitive information, such as credentials, from leaving your application.\n- `targetWindow` _(optional)_ - Provide a pre-existing window location that will be used instead of opening a new window etc. When using this option, you must still provide the `url` value due to security checks in browser APIs, and the `iframe` option is ignored in such a case.\n\n### Examples\n\n### Add a custom serializer to @xstate/inspector events and transitions messages\n\nWhen is this useful?\n\n- Remove sensitive items, such as `credentials`\n- Add additional custom handling\n\n```typescript\n// Remove credentials from being forwarded\ninspect({\n  serialize: (key: string, value: any) => {\n    return key === 'credentials' && typeof value === 'object' ? {} : value;\n  }\n});\n\n// Add a custom local log\ninspect({\n  serialize: (key: string, value: any) => {\n    if (key === 'ready') {\n      console.log('Detected ready key');\n    }\n    return value;\n  }\n});\n```\n\n### Easily log all machine events and transitions\n\nWhen is this useful?\n\n- Allows you to quickly see all events and transitions for your machines\n- No need to add manual `console.log` statements to your machine definitions\n\n```typescript\n// The URL and port of your local project (ex. Vite, Webpack, etc).\nconst url = 'http://127.0.0.1:5174/';\n\nconst inspector = inspect({\n  url,\n  iframe: undefined,\n  targetWindow: window\n});\n\n// In the same window, subscribe to messages from @xstate/inspector\ncreateWindowReceiver({}).subscribe(console.log);\n\n// Start your machine, and all events generated are logged to the console\ninterpret(machine, { devTools: true }).start({});\n```\n\n### Send events to a separate, locally hosted tool\n\nWhen is this useful?\n\n- Forward messages to a custom endpoint, that you can then listen to and add custom handling for messages\n\n```typescript\n// In your client application\nconst url = 'http://127.0.0.1:8443/';\nconst targetWindow = window.open(url);\n\nconst inspector = inspect({\n  // The URL must still be provided. This is used by postMessage, as it's\n  // not possible to do targetWindow.location for security reasons\n  url,\n  targetWindow\n});\n\n// In the second, hosted application\ncreateWindowReceiver({}).subscribe((event) => {\n  if (event.type === 'service.register') {\n    // Do something when a new machine is started\n  } else if (event.type === 'service.stop') {\n    // Do something when a machine enters a terminal state\n  } else if (event.type === 'service.event') {\n    // Do something when a machine receives an event\n  } else if (event.type === 'service.state') {\n    // Do something when a machine enters to a new state\n    // Note: Does not handle transitional states.\n  }\n});\n```\n","packages/xstate-react/README.md":"# @xstate/react\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [React](https://github.com/facebook/react/).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-react).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick start\n\n1. Install `xstate` and `@xstate/react`:\n\n```bash\nnpm i xstate @xstate/react\n```\n\n2. Import the `useMachine` hook:\n\n```tsx\nimport { useMachine } from '@xstate/react';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nexport const Toggler = () => {\n  const [state, send] = useMachine(toggleMachine);\n\n  return (\n    <button onClick={() => send({ type: 'TOGGLE' })}>\n      {state.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'}\n    </button>\n  );\n};\n```\n","packages/xstate-solid/README.md":"# @xstate/solid\n\nThe [@xstate/solid package](https://github.com/statelyai/xstate/tree/main/packages/xstate-solid) contains utilities for using [XState](https://github.com/statelyai/xstate) with [SolidJS](https://github.com/solidjs/solid).\n\n[[toc]]\n\n## Quick Start\n\n1. Install `xstate` and `@xstate/solid`:\n\n```bash\nnpm i xstate @xstate/solid\n```\n\n2. Import the `useActor` hook:\n\n```js\nimport { useActor } from '@xstate/solid';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nexport const Toggler = () => {\n  const [snapshot, send] = useActor(toggleMachine);\n\n  return (\n    <button onclick={() => send({ type: 'TOGGLE' })}>\n      {snapshot.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'}\n    </button>\n  );\n};\n```\n\n## API\n\n### `useActor(logic, options?)`\n\nA SolidJS hook that interprets the given `logic` and starts an actor that runs for the lifetime of the component.\n\n**Arguments**\n\n- `logic`\n\n  ```js\n  // existing machine\n  const [snapshot, send] = useMachine(machine);\n  ```\n\n**Returns** a tuple of `[snapshot, send, actorRef]`:\n\n- `snapshot` - Represents the current snapshot of the logic. This is a read-only value that is tracked by SolidJS for granular reactivity.\n- `send` - A function that sends events to the running service.\n- `actorRef` - The created service.\n\n### `fromActorRef(actorRf)`\n\nA SolidJS hook that subscribes to emitted changes from an existing [actor](https://xstate.js.org/docs/guides/actors.html).\n\n**Arguments**\n\n- `actorRef` - an actor object that contains `.send(...)` and `.subscribe(...)` methods. Allows [SolidJS Signal](https://www.solidjs.com/docs/latest/api#createsignal) (or function) to dynamically specify an actor.\n\n```js\nconst snapshot = fromActorRef(someSpawnedActor);\n```\n\n### `useActorRef(logic, options?)`\n\nA SolidJS hook that returns the `actorRef` created from the `logic` with the `options`, if specified. It starts the actor and runs it for the lifetime of the component. This is similar to `useActor`.\n\n`createService` returns a static reference (to just the interpreted logic) which will not rerender when its snapshot changes.\n\n**Arguments**\n\n- `logic`\n- `options` (optional) - [Actor options](https://xstate.js.org/docs/guides/interpretation.html#options)\n\n```js\nimport { useActorRef } from '@xstate/solid';\nimport { someMachine } from '../path/to/someMachine';\n\nconst App = () => {\n  const actorRef = useActorRef(someMachine);\n\n  // ...\n};\n```\n\nWith options:\n\n```js\n// ...\n\nconst App = () => {\n  const service = useActorRef(someMachine, {\n    input: {/* ... */}\n  });\n\n  // ...\n};\n```\n\n## Matching States\n\nWhen using [hierarchical](https://xstate.js.org/docs/guides/hierarchical.html) and [parallel](https://xstate.js.org/docs/guides/parallel.html) machines, the state values will be objects, not strings. In this case, it is best to use [`state.matches(...)`](https://xstate.js.org/docs/guides/states.html#state-methods-and-getters).\n\nThe SolidJS [Switch and Match Components](<>) are ideal for this use case:\n\n```jsx\nconst Loader = () => {\n  const [snapshot, send] = useActor(/* ... */);\n\n  return (\n    <div>\n      <Switch fallback={null}>\n        <Match when={snapshot.matches('idle')}>\n          <Loader.Idle />\n        </Match>\n        <Match when={snapshot.matches({ loading: 'user' })}>\n          <Loader.LoadingUser />\n        </Match>\n        <Match when={snapshot.matches({ loading: 'friends' })}>\n          <Loader.LoadingFriends />\n        </Match>\n      </Switch>\n    </div>\n  );\n};\n```\n\n## Persisted and Rehydrated State\n\nYou can persist and rehydrate state with `useActor(...)` via `options.snapshot`:\n\n```js\n// ...\n\n// Get the persisted state config object from somewhere, e.g. localStorage\nconst persistedSnapshot = JSON.parse(localStorage.getItem('some-persisted-state-key')) || someMachine.initialState;\n\nconst App = () => {\n  const [snapshot, send] = useActor(someMachine, {\n    snapshot: persistedSnapshot\n  });\n\n  // snapshot will rehydrate the provided persisted snapshot, it won't be the machine's initial snapshot\n\n  return (/* ... */)\n}\n```\n\n## Actor refs\n\nThe `actorRef` created in `useActor(logic)` can be referenced as the third returned value:\n\n```js\n//                  vvvvvvv\nconst [snapshot, send, actorRef] = useActor(someMachine);\n```\n\nYou can subscribe to that `actorRef`'s snapshot changes with the [`createEffect` hook](https://www.solidjs.com/docs/latest/api#createeffect):\n\n```js\n// ...\n\ncreateEffect(() => {\n  const subscription = actorRef.subscribe((snapshot) => {\n    // simple snapshot logging\n    console.log(snapshot);\n  });\n\n  onCleanup(() => subscription.unsubscribe());\n}); // note: service should never change\n```\n","packages/xstate-store-angular/README.md":"# @xstate/store-angular\n\nAngular adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-angular\n```\n\n## Quickstart\n\n```ts\nimport { Component } from '@angular/core';\nimport { createStore, injectStore } from '@xstate/store-angular';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\n@Component({\n  selector: 'app-counter',\n  template: `\n    <button (click)=\"store.send({ type: 'inc' })\">Count: {{ count() }}</button>\n  `\n})\nexport class CounterComponent {\n  store = store;\n  count = injectStore(store, (s) => s.context.count);\n}\n```\n\n## API\n\n### `injectStore(store, selector?, compare?)`\n\nAn Angular function that creates a signal subscribed to a store, selecting a value via an optional selector function.\n\n```ts\nimport { Component } from '@angular/core';\nimport { createStore, injectStore } from '@xstate/store-angular';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\n@Component({\n  selector: 'app-counter',\n  template: `<div>{{ count() }}</div>`\n})\nexport class CounterComponent {\n  count = injectStore(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  snapshot = injectStore(store);\n}\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Readonly Angular signal of the selected value\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Angular-specific docs](https://stately.ai/docs/xstate-store#angular) for more Angular examples.\n","packages/xstate-store-preact/README.md":"# @xstate/store-preact\n\nPreact adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-preact\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-preact';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>Count: {count}</button>\n  );\n};\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nSubscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-preact';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  const snapshot = useSelector(store);\n  // ...\n};\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Selected value (re-renders on change)\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Preact-specific docs](https://stately.ai/docs/xstate-store#preact) for more Preact examples.\n","packages/xstate-store-react/README.md":"# @xstate/store-react\n\nReact adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-react\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>Count: {count}</button>\n  );\n};\n```\n\n## API\n\n<!-- selector comparison semantics from src/index.ts -->\n### `useSelector(store, selector?, compare?)`\n\nSubscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  const snapshot = useSelector(store);\n  // ...\n};\n```\n\n**Arguments:**\n\n- `store` - Store or other readable value created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`). Also applies to the full snapshot when `selector` is `undefined`.\n\n**Returns:** Selected value (re-renders on change)\n\n---\n\n<!-- useStore overloads and inspection behavior from packages/xstate-store-react/src/index.ts -->\n\n### `useStore(definition, options?)`\n\nCreates a store instance scoped to a component.\n\n```tsx\nimport { useStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst App = () => {\n  const store = useStore({\n    context: { count: 0 },\n    on: {\n      inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n    }\n  });\n\n  const count = useSelector(store, (s) => s.context.count);\n  // ...\n};\n```\n\nTo wire up an inspector, pass the `inspect` option. The inspector is subscribed while the option is provided and unsubscribed when it is removed or the component unmounts:\n\n```tsx\nconst store = useStore(\n  {\n    context: { count: 0 },\n    on: {\n      inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n    }\n  },\n  { inspect: inspector.inspect }\n);\n```\n\n**Arguments:**\n\n- `definition` - Store configuration object, or store logic created with `createStoreLogic()` (followed by its `input`)\n- `options?` - Options object:\n  - `inspect?` - Observer or callback that receives [inspection events](https://stately.ai/docs/inspection) from the store\n\n**Returns:** Store instance (stable across re-renders)\n\n---\n\n### `useAtom(atom, selector?, compare?)`\n\nSubscribes to an atom and returns its value.\n\n```tsx\nimport { createAtom, useAtom } from '@xstate/store-react';\n// ...\n\nconst countAtom = createAtom(0);\n\nconst App = () => {\n  const count = useAtom(countAtom);\n\n  return <button onClick={() => countAtom.set((c) => c + 1)}>{count}</button>;\n};\n```\n\n**Arguments:**\n\n- `atom` - Atom created with `createAtom()`\n- `selector?` - Selector function\n- `compare?` - Equality function\n\n**Returns:** Atom value (re-renders on change)\n\n---\n\n### `createStoreHook(definition)`\n\nCreates a custom hook that returns `[selectedValue, store]`.\n\n```tsx\nimport { createStoreHook } from '@xstate/store-react';\n// ...\n\nconst useCountStore = createStoreHook({\n  context: { count: 0 },\n  on: {\n    inc: (ctx, e: { by: number }) => ({ ...ctx, count: ctx.count + e.by })\n  }\n});\n\nconst App = () => {\n  const [count, store] = useCountStore((s) => s.context.count);\n\n  return <button onClick={() => store.trigger.inc({ by: 1 })}>{count}</button>;\n};\n```\n\n**Arguments:**\n\n- `definition` - Store configuration object\n\n**Returns:** Custom hook function\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [React-specific docs](https://stately.ai/docs/xstate-store#react) for more React examples.\n","packages/xstate-store-solid/README.md":"# @xstate/store-solid\n\nSolid.js adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-solid\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-solid';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>\n      Count: {count()}\n    </button>\n  );\n};\n```\n\n## API\n\n<!-- selector subscription semantics from src/index.ts -->\n### `useSelector(store, selector, compare?)`\n\nThe accessor reconciles updates made during component setup before its subscription starts.\n\nCreates a signal that subscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-solid';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return <div>{count()}</div>;\n};\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Read-only signal of the selected value\n\n`useSelector` works with the store's readable snapshot interface, while store-specific code can still use `store.getSnapshot()` directly.\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Solid-specific docs](https://stately.ai/docs/xstate-store#solid) for more Solid examples.\n","packages/xstate-store-svelte/README.md":"# @xstate/store-svelte\n\nSvelte adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-svelte\n```\n\n## Quickstart\n\n```svelte\n<script>\nimport { createStore, useSelector } from '@xstate/store-svelte';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n</script>\n\n<button on:click={() => store.send({ type: 'inc' })}>\n  Count: {$count}\n</button>\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nCreates a Svelte readable store that subscribes to an XState store and returns a selected value.\n\n```svelte\n<script>\nimport { createStore, useSelector } from '@xstate/store-svelte';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n// or without selector (returns full snapshot)\nconst snapshot = useSelector(store);\n</script>\n\n<div>{$count}</div>\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Svelte readable store\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Svelte-specific docs](https://stately.ai/docs/xstate-store#svelte) for more Svelte examples.\n","packages/xstate-store-vue/README.md":"# @xstate/store-vue\n\nVue adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-vue\n```\n\n## Quickstart\n\n```vue\n<script setup>\nimport { createStore, useSelector } from '@xstate/store-vue';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n</script>\n\n<template>\n  <button @click=\"store.send({ type: 'inc' })\">Count: {{ count }}</button>\n</template>\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nA composable that subscribes to a store and returns a selected value as a readonly ref.\n\n```vue\n<script setup>\nimport { createStore, useSelector } from '@xstate/store-vue';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n// or without selector (returns full snapshot)\nconst snapshot = useSelector(store);\n</script>\n\n<template>\n  <div>{{ count }}</div>\n</template>\n```\n\n**Arguments:**\n\n- `store` - Store or other readable value created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Readonly ref of the selected value\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Vue-specific docs](https://stately.ai/docs/xstate-store#vue) for more Vue examples.\n","packages/xstate-store/README.md":"# `@xstate/store`\n\nXState Store is a library for **simple event-based state management**. If you want a state management library that allows you to update a store's state via events, `@xstate/store` is a great option. If you need more complex application logic needs, like state machines/statecharts, effects, communicating actors, and more, consider [using XState instead](https://github.com/statelyai/xstate).\n\n<!-- store capabilities from src/index.ts and runtime dependency requirements from package.json -->\n\n- **Extremely simple**: transitions update state via events, just like Redux, Zustand, Pinia, etc.\n- **Small**: no required runtime dependencies\n- **XState compatible**: use it with (or without) XState, or convert to XState machines when you need to handle more complex logic & effects.\n- **Extra type-safe**: great typing out of the box, with strong inference and no awkwardness.\n\n> [!NOTE]\n> This readme is written for [TypeScript](#typescript) users. If you are a JavaScript user, just remove the types.\n\n## Installation\n\n```bash\n# yarn add @xstate/store\n# pnpm add @xstate/store\nnpm install @xstate/store\n```\n\n## Quick start\n\n```ts\nimport { createStore } from '@xstate/store';\n\nexport const donutStore = createStore({\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    addDonut: (context) => ({\n      ...context,\n      donuts: context.donuts + 1\n    }),\n    changeFlavor: (context, event: { flavor: string }) => ({\n      ...context,\n      favoriteFlavor: event.flavor\n    }),\n    eatAllDonuts: (context) => ({\n      ...context,\n      donuts: 0\n    })\n  }\n});\n\ndonutStore.subscribe((snapshot) => {\n  console.log(snapshot.context);\n});\n\n// Equivalent to\n// donutStore.send({ type: 'addDonut' });\ndonutStore.trigger.addDonut();\n// => { donuts: 1, favoriteFlavor: 'chocolate' }\n\n// donutStore.send({\n//   type: 'changeFlavor',\n//   flavor: 'strawberry' // Strongly-typed!\n// });\ndonutStore.trigger.changeFlavor({ flavor: 'strawberry' });\n// => { donuts: 1, favoriteFlavor: 'strawberry' }\n```\n\n## Checking events\n\n<!-- store.can API from packages/xstate-store/src/types.ts -->\n\nUse `store.can` to check whether an event is allowed without updating the store:\n\n```ts\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    increment: (context, event: { by: number }) => {\n      if (context.count + event.by > 10) {\n        return;\n      }\n\n      return {\n        count: context.count + event.by\n      };\n    }\n  }\n});\n\nstore.can.increment({ by: 4 });\n// => true\n```\n\nReturning `undefined` marks the event as not allowed. Returning the same context\nobject is still allowed, and transitions that enqueue effects are allowed.\n\n## Persistence\n\n<!-- persist and flushStorage behavior from src/persist.ts -->\n\nUse the `persist` extension to save state after events are committed. Calling\n`store.can` or the pure `store.transition` method does not schedule writes.\nWrites preserve commit order, including events triggered synchronously by effects\nor subscriptions. A newer eligible event can supersede an older pending write;\n`onDone` runs for writes actually performed. Asynchronous writes execute in event\norder for each store. Call\n`await flushStorage(store)` to write buffered changes and wait for queued writes\nto finish. Synchronous storage adapters continue to write synchronously.\n\nWith throttling, `pick` runs once per write on the latest buffered context.\n`clearStorage(store)` cancels buffered writes and removes saved data after any\nalready queued writes finish; await its result when using asynchronous storage.\nNew events sent after clearing can persist new state. For asynchronous storage,\ncall `await rehydrateStore(store)` to load saved state; initial read failures are\nreported through `onError`.\n\n```ts\nimport { persist, flushStorage } from '@xstate/store/persist';\n\nconst savedDonutStore = donutStore.with(persist({ name: 'donuts' }));\nsavedDonutStore.trigger.addDonut();\nawait flushStorage(savedDonutStore);\n```\n\n### Undo and persistence\n\n<!-- snapshot undo restoration behavior from src/undo.ts -->\n\nSnapshot-based `undoRedo` restores historical state while preserving live\nextension metadata, including persistence hydration. A custom `restore` callback\ncan enqueue events; their updated extension metadata is preserved too. Apply\n`persist` after `undoRedo` when undo and redo themselves should write to storage:\n\n```ts\nimport { undoRedo } from '@xstate/store/undo';\n\nconst undoableDonutStore = donutStore\n  .with(undoRedo({ strategy: 'snapshot' }))\n  .with(persist({ name: 'undoable-donuts' }));\n```\n\n## Atom updates and subscriptions\n\n<!-- writable updater tracking and subscriber errors from src/atom.ts -->\n\nReads inside a writable atom's `set(previous => next)` updater do not create\nreactive dependencies. Use a computed atom getter to track other atoms instead.\nIf a synchronous subscriber throws, other queued subscribers still receive their\nnotifications before the first error is rethrown to the caller. The atom's value\nhas already changed; later updates continue to notify subscribers normally.\n\n## Source atoms\n\n<!-- createSourceAtom snapshot and observed dependency lifecycle from src/atom.ts and src/types.ts -->\n\nUse `createSourceAtom` for a read-only external value. Direct and derived\nsubscribers share one listener; cleanup runs synchronously when the last consumer\nleaves. Plain reads do not start listeners. Resubscribing reconnects and refreshes\nthe snapshot.\n\n```ts\nimport { createAtom, createSourceAtom } from '@xstate/store';\n\nconst media = window.matchMedia('(prefers-color-scheme: dark)');\nconst isDark = createSourceAtom({\n  getSnapshot: () => media.matches,\n  subscribe: (notify) => {\n    media.addEventListener('change', notify);\n    return () => media.removeEventListener('change', notify);\n  }\n});\nconst theme = createAtom(() => (isDark.get() ? 'dark' : 'light'));\nconst subscription = theme.subscribe(console.log);\nsubscription.unsubscribe(); // Removes the media query listener.\n```\n\nSee [source atoms](./docs/source-atoms.md) for snapshot comparison, conditional\ndependencies, and lifecycle timing. Use XState actors for commands, retries, or\nreconnection logic.\n\n## Async atoms\n\n<!-- createAsyncAtom dependency and cancellation behavior from src/atom.ts -->\n\n`createAsyncAtom` loads a value lazily and exposes a `pending`, `done`, or\n`error` state. Atoms read synchronously by its getter remain dependencies after\nthe request succeeds or fails. When a dependency changes, subscribed async atoms\nreload; otherwise, they reload on the next read. Read dependencies before the\nfirst `await` to track them. Errors while delivering a resolved value (including\nsource activation) also become the async atom’s `error` state. If notifying that\nerror state fails, the state remains available through `.get()`.\n\n```ts\nimport { createAtom, createAsyncAtom } from '@xstate/store';\n\nconst userId = createAtom('ada');\nconst user = createAsyncAtom(async ({ signal }) => {\n  const id = userId.get();\n  const response = await fetch(`/users/${id}`, { signal });\n  return response.json();\n});\n\nuser.subscribe((state) => {\n  if (state.status === 'done') {\n    console.log(state.data);\n  }\n});\n\nuserId.set('grace'); // Reloads even after the previous request settled.\n```\n\nRecomputing aborts the previous getter's signal and ignores its stale result.\n\n## Usage with React\n\nImport `useSelector` from `@xstate/store-react`. Select the data you want via `useSelector(…)` and send events using `store.send(eventObject)`:\n\n```tsx\nimport { donutStore } from './donutStore.ts';\nimport { useSelector } from '@xstate/store-react';\n\nfunction DonutCounter() {\n  const donutCount = useSelector(donutStore, (state) => state.context.donuts);\n\n  return (\n    <div>\n      <button onClick={() => donutStore.send({ type: 'addDonut' })}>\n        Add donut ({donutCount})\n      </button>\n    </div>\n  );\n}\n```\n\n## Usage with SolidJS\n\nImport `useSelector` from `@xstate/store-solid`. Select the data you want via `useSelector(…)` and send events using `store.send(eventObject)`:\n\n```tsx\nimport { donutStore } from './donutStore.ts';\nimport { useSelector } from '@xstate/store-solid';\n\nfunction DonutCounter() {\n  const donutCount = useSelector(donutStore, (state) => state.context.donuts);\n\n  return (\n    <div>\n      <button onClick={() => donutStore.send({ type: 'addDonut' })}>\n        Add donut ({donutCount()})\n      </button>\n    </div>\n  );\n}\n```\n\n## Usage with Immer\n\nXState Store works well with immutable update libraries like [Immer](https://github.com/immerjs/immer) or [Mutative](https://github.com/unadlib/mutative). Use `produce(...)` inside your transition functions:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { produce } from 'immer'; // or { create } from 'mutative'\n\nconst donutStore = createStore({\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    addDonut: (context) =>\n      produce(context, (draft) => {\n        draft.donuts++;\n      }),\n    changeFlavor: (context, event: { flavor: string }) =>\n      produce(context, (draft) => {\n        draft.favoriteFlavor = event.flavor;\n      }),\n    eatAllDonuts: (context) =>\n      produce(context, (draft) => {\n        draft.donuts = 0;\n      })\n  }\n});\n```\n\nIf a transition should be unavailable, return `undefined` from the transition\nbefore calling `produce(...)`:\n\n```ts\non: {\n  eatDonut: (context) => {\n    if (context.donuts === 0) {\n      return;\n    }\n\n    return produce(context, (draft) => {\n      draft.donuts--;\n    });\n  };\n}\n```\n\nImmer treats a producer that returns `undefined` the same as a producer that\ndoes not explicitly return anything. If you need `produce(...)` itself to return\n`undefined`, return Immer's `nothing` token from the producer:\n\n```ts\nimport { nothing, produce } from 'immer';\n\non: {\n  eatDonut: (context) =>\n    produce(context, (draft) => {\n      if (draft.donuts === 0) {\n        return nothing;\n      }\n\n      draft.donuts--;\n    });\n}\n```\n\n## TypeScript\n\nXState Store is written in TypeScript and provides full type safety, _without_ you having to specify generic type parameters. The `context` type is inferred from the initial context object, and the event types are inferred from the event object payloads you provide in the transition functions.\n\n```ts\nimport { createStore } from '@xstate/store';\n\nconst donutStore = createStore({\n  // Context inferred as:\n  // {\n  //   donuts: number;\n  //   favoriteFlavor: string;\n  // }\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    // Event inferred as:\n    // {\n    //   type: 'changeFlavor';\n    //   flavor: string;\n    // }\n    changeFlavor: (context, event: { flavor: string }) => {\n      context.favoriteFlavor = event.flavor;\n    }\n  }\n});\n\ndonutStore.getSnapshot().context.favoriteFlavor; // string\ndonutStore.get().context.favoriteFlavor; // same snapshot, readable/tracked read\n\ndonutStore.send({\n  type: 'changeFlavor', // Strongly-typed from transition key\n  flavor: 'strawberry' // Strongly-typed from { flavor: string }\n});\n```\n\nIf you want to provide event or emitted-event types explicitly, you can use `schemas` with any library that implements the [Standard Schema](https://standardschema.dev/) interface. Schemas define the store's runtime-readable contract: the shape of its context, accepted events, and emitted events. Store uses schemas for type inference and metadata by default; it does not validate schema-declared values unless you opt in with `validateSchemas()`.\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    context: z.object({\n      donuts: z.number(),\n      favoriteFlavor: z.string()\n    }),\n    events: {\n      changeFlavor: z.object({\n        flavor: z.string()\n      })\n    },\n    emitted: {\n      flavorChanged: z.object({\n        flavor: z.string()\n      })\n    }\n  },\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    changeFlavor: (context, event, enqueue) => {\n      enqueue.emit.flavorChanged({ flavor: event.flavor });\n      return {\n        ...context,\n        favoriteFlavor: event.flavor\n      };\n    }\n  }\n});\n```\n\nEvent and emitted-event schemas describe payload objects. Use an empty object\nschema for events without payload:\n\n```ts\nschemas: {\n  events: {\n    reset: z.object({})\n  },\n  emitted: {\n    reset: z.object({})\n  }\n}\n```\n\n### Validating schemas\n\nUse the `validateSchemas()` extension when the store should validate its schema\ncontract at runtime:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { validateSchemas } from '@xstate/store/validate';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    context: z.object({\n      count: z.number()\n    }),\n    events: {\n      increment: z.object({\n        by: z.number()\n      })\n    },\n    emitted: {\n      increased: z.object({\n        by: z.number()\n      })\n    }\n  },\n  context: { count: 0 },\n  on: {\n    increment: (context, event, enqueue) => {\n      enqueue.emit.increased({ by: event.by });\n      return { count: context.count + event.by };\n    }\n  }\n}).with(validateSchemas());\n```\n\n`validateSchemas()` validates store macrosteps. It validates the event sent to\nthe store, the final context after the transition completes, and emitted events\nbefore any effects execute. Events queued internally with `enqueue.trigger` are\nprocessed as part of the same macrostep; their payloads are not separately\nvalidated in this version.\n\nInvalid `send(...)`, `trigger.*(...)`, or `transition(...)` calls throw a\n`StoreValidationError`. `store.can.*(...)` always returns a boolean; validation\nerrors make it return `false`.\n\nBy default, unknown events and emitted events throw when the corresponding\nschema map exists. Extension-added event types are treated as known, even when\nthey do not have payload schemas. You can opt out:\n\n```ts\nconst store = createStore({\n  // ...\n}).with(\n  validateSchemas({\n    unknownEvents: 'ignore',\n    unknownEmitted: 'ignore'\n  })\n);\n```\n\nUse `store.getSnapshot()` when you want an explicit snapshot read from the store itself. Use `store.get()` when consuming the store as a `Readable` value in tracked or reactive code.\n\nIf you want to make the `context` type more specific, you can strongly type the `context` outside of `createStore(…)` and pass it in:\n\n```ts\nimport { createStore } from '@xstate/store';\n\ninterface DonutContext {\n  donuts: number;\n  favoriteFlavor: 'chocolate' | 'strawberry' | 'blueberry';\n}\n\nconst donutContext: DonutContext = {\n  donuts: 0,\n  favoriteFlavor: 'chocolate'\n};\n\nconst donutStore = createStore({\n  context: donutContext,\n  on: {\n    // ... (transitions go here)\n  }\n});\n```\n\n## Effects and Side Effects\n\nYou can enqueue effects in state transitions using the `enqueue` argument:\n\n```ts\nimport { createStore } from '@xstate/store';\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    incrementDelayed: (context, event, enqueue) => {\n      enqueue.effect(async () => {\n        await new Promise((resolve) => setTimeout(resolve, 1000));\n        store.send({ type: 'increment' });\n      });\n\n      return context;\n    },\n    increment: (context) => ({\n      ...context,\n      count: context.count + 1\n    })\n  }\n});\n```\n\n## Emitting Events\n\nYou can emit events from transitions by declaring them in `schemas.emitted` and using `enqueue.emit`:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    emitted: {\n      increased: z.object({\n        by: z.number()\n      })\n    }\n  },\n  context: { count: 0 },\n  on: {\n    inc: (context, event: { by: number }, enqueue) => {\n      enqueue.emit.increased({ by: event.by });\n\n      return {\n        ...context,\n        count: context.count + event.by\n      };\n    }\n  }\n});\n\n// Listen for emitted events\nstore.on('increased', (event) => {\n  console.log(`Count increased by ${event.by}`);\n});\n```\n","packages/xstate-store/docs/source-atoms.md":"---\ntitle: Source atoms\ndescription: Share external snapshot subscriptions across atom consumers.\n---\n\nUse `createSourceAtom` to expose an external value, such as a media query or a\nbrowser observer, as a read-only atom. Provide `getSnapshot` to read its current\nvalue and `subscribe` to attach a change listener. The listener calls `notify()`;\nXState Store reads the latest snapshot. Return either a cleanup function or a\nsubscription object with an `unsubscribe()` method. XState Store normalizes the\nadapter result internally; the atom's public `.subscribe()` always returns a\nsubscription object, so consumers call `subscription.unsubscribe()`.\n\n```ts\nimport { createAtom, createSourceAtom } from '@xstate/store';\n\nconst media = window.matchMedia('(prefers-color-scheme: dark)');\nconst isDark = createSourceAtom({\n  getSnapshot: () => media.matches,\n  subscribe: (notify) => {\n    media.addEventListener('change', notify);\n    return () => media.removeEventListener('change', notify);\n  }\n});\nconst theme = createAtom(() => (isDark.get() ? 'dark' : 'light'));\n\n// Starts one media query listener, through the derived atom.\nconst derived = theme.subscribe((value) => console.log(value));\nconst direct = isDark.subscribe((value) => console.log(value));\n\n// The direct subscriber still needs the listener.\nderived.unsubscribe();\n// Removes the listener synchronously.\ndirect.unsubscribe();\n```\n\nCreate browser sources in an environment where their browser APIs are available.\nFor server rendering, provide a snapshot reader that works on the server; a plain\nread does not attach the external listener.\n\n## Reading and subscribing\n\nCreation is lazy. Calling the source atom's `.get()` without a live consumer reads\n`getSnapshot` without calling `subscribe`. Reading an unobserved derived atom also\ndoes not start external subscriptions. Derived atoms cache their values; an\nunobserved derived read does not poll external sources for changes.\n\nThe first direct subscription, or subscription to a derived atom that reads the\nsource, starts the listener. Consumers share one listener per source atom instance.\nSetup occurs after dependency evaluation settles and before the outer subscription\nor update call returns. XState Store attaches the listener before refreshing the\nsnapshot, including when registration calls `notify()` synchronously.\n\nLike other atoms, subscribing does not emit the initial value. Call `.get()` to\nread it. A snapshot change during listener registration can notify subscribers\nbefore `subscribe()` returns.\n\nWhen a conditional derived atom stops reading the source, its consumer is removed.\nThe listener remains active while any other direct or indirect consumer needs it.\nCleanup runs after graph updates settle, before the last `unsubscribe()` or update\ncall returns. Moving a dependency between derived branches during the same update\ndoes not restart a shared listener. Separate unsubscribe/resubscribe calls do.\n\nSubscribing again reconnects the listener and refreshes the snapshot. Notifications\nfrom an earlier, cleaned-up listener are ignored, including after reconnection.\n\n## Snapshot contract\n\n`getSnapshot` should return a stable value until the external source changes, and\n`subscribe` should notify whenever that value changes. Reads inside these\ncallbacks do not establish atom dependencies. Model reactive dependencies in a\nderived atom instead.\n\nSnapshots use `Object.is` comparison by default. Provide a custom comparator when\nan external source returns a new object for an unchanged value:\n\n```ts\nconst size = createSourceAtom(\n  {\n    getSnapshot: () => ({ width: window.innerWidth, height: window.innerHeight }),\n    subscribe: (notify) => {\n      window.addEventListener('resize', notify);\n      return { unsubscribe: () => window.removeEventListener('resize', notify) };\n    }\n  },\n  {\n    compare: (previous, next) =>\n      previous.width === next.width && previous.height === next.height\n  }\n);\n```\n\nSource atoms expose `.get()` and `.subscribe()`, with no `.set()` or `.send()`.\nThey do not provide timed retries or an error state. A failed activation with live\nconsumers remains eligible for another attempt on a later atom operation. It is\nnever retried within the failing operation. Synchronous snapshot, registration,\nnotification, and cleanup errors propagate to the caller. If registration fails\nbefore returning a subscription, the adapter must release any resources it acquired.\n\nUse XState actors when a resource needs commands, retries, reconnection backoff,\nor a richer lifecycle. Adapt an actor snapshot with `getSnapshot: () =>\nactor.getSnapshot()` and `subscribe: (notify) => actor.subscribe(notify)`; the\nactor's owner remains responsible for starting and stopping it.\n","packages/xstate-svelte/README.md":"# @xstate/svelte\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [Svelte](https://github.com/sveltejs/svelte).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-svelte).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick Start\n\n1. Install `xstate` and `@xstate/svelte`:\n\n```bash\nnpm i xstate @xstate/svelte\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/svelte/dist/xstate-svelte.min.js\"></script>\n```\n\nBy using the global variable `XStateSvelte`\n\n2. Import `useMachine`\n\n```svelte\n<script>\n  import { useMachine } from '@xstate/svelte';\n  import { createMachine } from 'xstate';\n\n  const toggleMachine = createMachine({\n    id: 'toggle',\n    initial: 'inactive',\n    states: {\n      inactive: {\n        on: { TOGGLE: 'active' }\n      },\n      active: {\n        on: { TOGGLE: 'inactive' }\n      }\n    }\n  });\n\n  const { state, send } = useMachine(toggleMachine);\n</script>\n\n<button on:click={() => send('TOGGLE')}>\n  {$state.value === 'inactive'\n    ? 'Click to activate'\n    : 'Active! Click to deactivate'}\n</button>\n```\n","packages/xstate-vue/README.md":"# @xstate/vue\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [Vue](https://github.com/vuejs/vue).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-vue).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## :warning: Vue 2 Notice:\n\nIf you're using Vue 2.x, please see [the Vue recipe](https://xstate.js.org/docs/recipes/vue.html) instead, or use the [`xstate-vue2` package](https://github.com/ChrisShank/xstate-vue2) if you want to use the Vue Composition API.\n\n## Quick start\n\n1. Install `xstate` and `@xstate/vue`:\n\n```bash\nnpm i xstate @xstate/vue\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/vue/dist/xstate-vue.min.js\"></script>\n```\n\nBy using the global variable `XStateVue`\n\n2. Import the `useMachine` composition function:\n\n```vue\n<script setup>\nimport { useMachine } from '@xstate/vue';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nconst { snapshot, send } = useMachine(toggleMachine);\n</script>\n\n<template>\n  <button @click=\"send({ type: 'TOGGLE' })\">\n    {{\n      snapshot.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'\n    }}\n  </button>\n</template>\n```\n"},"files":{"AGENTS.md":"This is a monorepo containing XState, @xstate/store, and related packages.\n\n## Dev environment\n\n- Use pnpm to install dependencies\n\n## PR instructions\n\n- Run `pnpm test` to run the tests in all packages, only for changes that affect mulitple packages.\n- Run `pnpm test:core` to only run core XState tests.\n- Run `pnpm test:store` to only run @xstate/store tests.\n- Run `pnpm lint` and `pnpm format:check` to check linting and formatting.\n- Run `pnpm typecheck` to make sure that there are no type errors.\n- Before making a PR, run `pnpm changeset` to create a changeset with a short description of the changes, and a code example if applicable. Do not include implementation details; only pertinent details for developers using the package.\n","CLAUDE.md":"AGENTS.md","packages/core/README.md":"<p align=\"center\">\n  <br />\n\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/statelyai/public-assets/main/logos/xstate-logo-white-nobg.svg\">\n    <img alt=\"XState logotype\" src=\"https://raw.githubusercontent.com/statelyai/public-assets/main/logos/xstate-logo-black-nobg.svg\" width=\"200\">\n  </picture>\n  <br />\n    <strong>Actor-based state management & orchestration for complex app logic.</strong> <a href=\"https://stately.ai/docs\">→ Documentation</a>\n  <br />\n  <br />\n</p>\n\nXState is a state management and orchestration solution for JavaScript and TypeScript apps. It has _zero_ dependencies, and is useful for frontend and backend application logic.\n\nIt uses event-driven programming, state machines, statecharts, and the actor model to handle complex logic in predictable, robust, and visual ways. XState provides a powerful and flexible way to manage application and workflow state by allowing developers to model logic as actors and state machines.\n\n### ✨ Create state machines visually in Stately Studio → [state.new](https://state.new)\n\n---\n\n📖 [Read the documentation](https://stately.ai/docs)\n\n➡️ [Create state machines with the Stately Editor](https://stately.ai/editor)\n\n🖥 [Download our VS Code extension](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode)\n\n📑 Inspired by the [SCXML specification](https://www.w3.org/TR/scxml/)\n\n💬 Chat on the [Stately Discord Community](https://discord.gg/xstate)\n\n✍️ Browse through the many [XState examples](https://github.com/statelyai/xstate/tree/main/examples)\n\n## Templates\n\nGet started by forking one of these templates on CodeSandbox:\n\n<table>\n<thead>\n<tr><th>Template</th><th></th></tr>\n</thead>\n<tbody>\n\n<tr>\n<td>\n\n[🤖 XState Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/vanilla-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/vanilla-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- XState v5\n- TypeScript\n- _No framework_\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[⚛️ XState + React Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/react-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/react-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [React](https://react.dev/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[💚 XState + Vue Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/vue-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/vue-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [Vue](https://vuejs.org/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[🧡 XState + Svelte Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/svelte-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/svelte-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [Svelte](https://svelte.dev/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n</tbody>\n</table>\n\n## Super quick start\n\n```bash\nnpm install xstate\n```\n\n```ts\nimport { createMachine, createActor, assign } from 'xstate';\n\n// State machine\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  context: {\n    count: 0\n  },\n  states: {\n    inactive: {\n      on: {\n        TOGGLE: { target: 'active' }\n      }\n    },\n    active: {\n      entry: assign({ count: ({ context }) => context.count + 1 }),\n      on: {\n        TOGGLE: { target: 'inactive' }\n      }\n    }\n  }\n});\n\n// Actor (instance of the machine logic, like a store)\nconst toggleActor = createActor(toggleMachine);\ntoggleActor.subscribe((state) => console.log(state.value, state.context));\ntoggleActor.start();\n// => logs 'inactive', { count: 0 }\n\ntoggleActor.send({ type: 'TOGGLE' });\n// => logs 'active', { count: 1 }\n\ntoggleActor.send({ type: 'TOGGLE' });\n// => logs 'inactive', { count: 1 }\n```\n\n## [Stately Studio](https://stately.ai)\n\n- Visually create, edit, and collaborate on state machines\n- Export to many formats, including XState v5\n- Test path & documentation autogeneration\n- Deploy to Stately Sky\n- Generate & modify machines with Stately AI\n\n<a href=\"https://stately.ai/registry/new?ref=github\" title=\"Stately Studio\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/74ed9cbc-b824-4ed7-a16d-f104947af8a7\" alt=\"XState Viz\" width=\"800\" />\n</a>\n\n**[state.new](https://stately.ai/registry/new?ref=github)**\n\n## Why?\n\nStatecharts are a formalism for modeling stateful, reactive systems. This is useful for declaratively describing the _behavior_ of your application, from the individual components to the overall application logic.\n\nRead [📽 the slides](http://slides.com/davidkhourshid/finite-state-machines) ([🎥 video](https://www.youtube.com/watch?v=VU1NKX6Qkxc)) or check out these resources for learning about the importance of finite state machines and statecharts in user interfaces:\n\n- [Statecharts - A Visual Formalism for Complex Systems](https://www.sciencedirect.com/science/article/pii/0167642387900359/pdf) by David Harel\n- [The World of Statecharts](https://statecharts.github.io/) by Erik Mogensen\n\n## Packages\n\n| Package                                                                                       | Description                                                                  |\n| --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |\n| 🤖 `xstate`                                                                                   | Core finite state machine and statecharts library + interpreter              |\n| [⚛️ `@xstate/react`](https://github.com/statelyai/xstate/tree/main/packages/xstate-react)     | React hooks and utilities for using XState in React applications             |\n| [💚 `@xstate/vue`](https://github.com/statelyai/xstate/tree/main/packages/xstate-vue)         | Vue composition functions and utilities for using XState in Vue applications |\n| [🎷 `@xstate/svelte`](https://github.com/statelyai/xstate/tree/main/packages/xstate-svelte)   | Svelte utilities for using XState in Svelte applications                     |\n| [🥏 `@xstate/solid`](https://github.com/statelyai/xstate/tree/main/packages/xstate-solid)     | Solid hooks and utilities for using XState in Solid applications             |\n| [🔍 `@xstate/inspect`](https://github.com/statelyai/xstate/tree/main/packages/xstate-inspect) | Inspection utilities for XState                                              |\n\n## Finite State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst lightMachine = createMachine({\n  id: 'light',\n  initial: 'green',\n  states: {\n    green: {\n      on: {\n        TIMER: 'yellow'\n      }\n    },\n    yellow: {\n      on: {\n        TIMER: 'red'\n      }\n    },\n    red: {\n      on: {\n        TIMER: 'green'\n      }\n    }\n  }\n});\n\nconst actor = createActor(lightMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs 'green'\n\nactor.send({ type: 'TIMER' });\n// logs 'yellow'\n```\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n</td>\n<td>\n\n</td>\n</tr>\n</tbody>\n</table>\n\n</td>\n<td>\n\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=27e86036-f2f7-40f1-9d1e-66ce6e1accc0\" title=\"Finite states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/36d4b6b5-e3d0-4c19-9f41-2e3425ceac88\" alt=\"Finite states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n<br />\n\n</td>\n</tbody>\n</table>\n\n## Hierarchical (Nested) State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst pedestrianStates = {\n  initial: 'walk',\n  states: {\n    walk: {\n      on: {\n        PED_TIMER: 'wait'\n      }\n    },\n    wait: {\n      on: {\n        PED_TIMER: 'stop'\n      }\n    },\n    stop: {}\n  }\n};\n\nconst lightMachine = createMachine({\n  id: 'light',\n  initial: 'green',\n  states: {\n    green: {\n      on: {\n        TIMER: 'yellow'\n      }\n    },\n    yellow: {\n      on: {\n        TIMER: 'red'\n      }\n    },\n    red: {\n      on: {\n        TIMER: 'green'\n      },\n      ...pedestrianStates\n    }\n  }\n});\n\nconst actor = createActor(lightMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs 'green'\n\nactor.send({ type: 'TIMER' });\n// logs 'yellow'\n\nactor.send({ type: 'TIMER' });\n// logs { red: 'walk' }\n\nactor.send({ type: 'PED_TIMER' });\n// logs { red: 'wait' }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=30dffcdd-16c2-49e2-bfc6-a674057cb271\" title=\"Hierarchical states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/32b0692b-1c29-4469-b5e3-03146e3ef249\" alt=\"Hierarchical states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n<br />\n</td>\n</tr>\n</tbody>\n</table>\n\n## Parallel State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```ts\nimport { createMachine, createActor } from 'xstate';\n\nconst wordMachine = createMachine({\n  id: 'word',\n  type: 'parallel',\n  states: {\n    bold: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_BOLD: 'off' }\n        },\n        off: {\n          on: { TOGGLE_BOLD: 'on' }\n        }\n      }\n    },\n    underline: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_UNDERLINE: 'off' }\n        },\n        off: {\n          on: { TOGGLE_UNDERLINE: 'on' }\n        }\n      }\n    },\n    italics: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_ITALICS: 'off' }\n        },\n        off: {\n          on: { TOGGLE_ITALICS: 'on' }\n        }\n      }\n    },\n    list: {\n      initial: 'none',\n      states: {\n        none: {\n          on: {\n            BULLETS: 'bullets',\n            NUMBERS: 'numbers'\n          }\n        },\n        bullets: {\n          on: {\n            NONE: 'none',\n            NUMBERS: 'numbers'\n          }\n        },\n        numbers: {\n          on: {\n            BULLETS: 'bullets',\n            NONE: 'none'\n          }\n        }\n      }\n    }\n  }\n});\n\nconst actor = createActor(wordMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs {\n//   bold: 'off',\n//   italics: 'off',\n//   underline: 'off',\n//   list: 'none'\n// }\n\nactor.send({ type: 'TOGGLE_BOLD' });\n// logs {\n//   bold: 'on',\n//   italics: 'off',\n//   underline: 'off',\n//   list: 'none'\n// }\n\nactor.send({ type: 'TOGGLE_ITALICS' });\n// logs {\n//   bold: 'on',\n//   italics: 'on',\n//   underline: 'off',\n//   list: 'none'\n// }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=980f50d8-e1ff-4441-8c8b-afe41c1610f2\" title=\"Parallel states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/3b1989c0-f4a9-4653-baf2-4df3a40e91a6\" alt=\"Parallel states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n</td>\n</tr>\n</tbody>\n</table>\n\n## History States\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst paymentMachine = createMachine({\n  id: 'payment',\n  initial: 'method',\n  states: {\n    method: {\n      initial: 'cash',\n      states: {\n        cash: {\n          on: {\n            SWITCH_CHECK: 'check'\n          }\n        },\n        check: {\n          on: {\n            SWITCH_CASH: 'cash'\n          }\n        },\n        hist: { type: 'history' }\n      },\n      on: { NEXT: 'review' }\n    },\n    review: {\n      on: { PREVIOUS: 'method.hist' }\n    }\n  }\n});\n\nconst actor = createActor(paymentMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs {\n//   value: { method: 'cash' },\n// }\n\nactor.send({ type: 'SWITCH_CHECK' });\n// logs {\n//   value: { method: 'check' },\n// }\n\nactor.send({ type: 'NEXT' });\n// logs {\n//   value: 'review',\n// }\n\nactor.send({ type: 'PREVIOUS' });\n// logs {\n//   value: { method: 'check' },\n// }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=d1a9bb95-db97-4af3-b38b-71b005c643d3\" title=\"History states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/1be5c495-d560-4660-94f2-5341efbf7128\" alt=\"History state\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n</td>\n</tr>\n</tbody>\n</table>\n\n## Sponsors\n\nSpecial thanks to the sponsors who support this open-source project:\n\n<img src=\"https://opencollective.com/xstate/tiers/backer/badge.svg?label=sponsors&color=brightgreen\" />\n\n<a href=\"https://transloadit.com/?utm_source=xstate&utm_medium=referral&utm_campaign=sponsorship&utm_content=github\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://assets.transloadit.com/assets/images/sponsorships/logo-dark.svg\">\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"https://assets.transloadit.com/assets/images/sponsorships/logo-default.svg\">\n    <img src=\"https://assets.transloadit.com/assets/images/sponsorships/logo-default.svg\" alt=\"Transloadit Logo\">\n  </picture>\n</a>\n\n## SemVer Policy\n\nWe understand the importance of the public contract and do not intend to release any breaking changes to the **runtime** API in a minor or patch release. We consider this with any changes we make to the XState libraries and aim to minimize their effects on existing users.\n\n### Breaking changes\n\nXState executes much of the user logic itself. Therefore, almost any change to its behavior might be considered a breaking change. We recognize this as a potential problem but believe that treating every change as a breaking change is not practical. We do our best to implement new features thoughtfully to enable our users to implement their logic in a better, safer way.\n\nAny change _could_ affect how existing XState machines behave if those machines are using particular configurations. We do not introduce behavior changes on a whim and aim to avoid making changes that affect most existing machines. But we reserve the right to make _some_ behavior changes in minor releases. Our best judgment of the situation will always dictate such changes. Please always read our release notes before deciding to upgrade.\n\n### TypeScript changes\n\nWe also reserve a similar right to adjust declared TypeScript definitions or drop support for older versions of TypeScript in a minor release. The TypeScript language itself evolves quickly and often introduces breaking changes in its minor releases. Our team is also continuously learning how to leverage TypeScript more effectively - and the types improve as a result.\n\nFor these reasons, it is impractical for our team to be bound by decisions taken when an older version of TypeScript was its latest version or when we didn’t know how to declare our types in a better way. We won’t introduce declaration changes often - but we are more likely to do so than with runtime changes.\n\n### Packages\n\nMost of the packages in the XState family declare a peer dependency on XState itself. We’ll be cautious about maintaining compatibility with already-released packages when releasing a new version of XState, **but** each release of packages depending on XState will always adjust the declared peer dependency range to include the latest version of XState. For example, you should always be able to update `xstate` without `@xstate/react`. But when you update `@xstate/react`, we highly recommend updating `xstate` too.\n","packages/xstate-immer/README.md":"# @xstate/immer\n\n<p align=\"center\">\n  <a href=\"https://xstate.js.org\">\n  <br />\n  <img src=\"https://user-images.githubusercontent.com/1093738/79572515-1509e180-808b-11ea-92aa-10958521aa68.png\" alt=\"XState Immer\" width=\"200\"/>\n  <br />\n    <sub><strong>XState with Immer</strong></sub>\n  <br />\n  <br />\n  </a>\n</p>\n\nThis package contains utilities for using [Immer](https://immerjs.github.io/immer/docs/introduction) with [XState](https://github.com/statelyai/xstate).\n\n- [Read the full documentation in the XState docs](https://xstate.js.org/docs/packages/xstate-immer/).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick start\n\nIncluded in `@xstate/immer`:\n\n- `assign()` - an Immer action that allows you to immutably assign to machine `context` in a convenient way\n- `createUpdater()` - a useful function that allows you to cohesively define a context update event event creator and assign action, all together. ([See an example](#createupdatereventtype-recipe) below)\n\n1. Install `immer`, `xstate`, `@xstate/immer`:\n\n```bash\nnpm install immer xstate @xstate/immer\n```\n\n**Note:** You don't need to `import` anything from `immer`; it is a peer-dependency of `@xstate/immer`, so it must be installed.\n\n2. Import the Immer utilities:\n\n```js\nimport { createMachine, interpret } from 'xstate';\nimport { assign, createUpdater } from '@xstate/immer';\n\nconst levelUpdater = createUpdater('UPDATE_LEVEL', (ctx, { input }) => {\n  ctx.level = input;\n});\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  context: {\n    count: 0,\n    level: 0\n  },\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: {\n        TOGGLE: {\n          target: 'active',\n          // Immutably update context the same \"mutable\"\n          // way as you would do with Immer!\n          actions: assign((ctx) => ctx.count++)\n        }\n      }\n    },\n    active: {\n      on: {\n        TOGGLE: {\n          target: 'inactive'\n        },\n        // Use the updater for more convenience:\n        [levelUpdater.type]: {\n          actions: levelUpdater.action\n        }\n      }\n    }\n  }\n});\n\nconst toggleService = interpret(toggleMachine)\n  .onTransition((state) => {\n    console.log(state.context);\n  })\n  .start();\n\ntoggleService.send({ type: 'TOGGLE' });\n// { count: 1, level: 0 }\n\ntoggleService.send(levelUpdater.update(9));\n// { count: 1, level: 9 }\n\ntoggleService.send({ type: 'TOGGLE' });\n// { count: 2, level: 9 }\n\ntoggleService.send(levelUpdater.update(-100));\n// Notice how the level is not updated in 'inactive' state:\n// { count: 2, level: 9 }\n```\n","packages/xstate-inspect/README.md":"# @xstate/inspect\n\nThis package contains inspection tools for XState.\n\n- [Read the full documentation in the XState docs](https://xstate.js.org/docs/packages/xstate-inspect/).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Templates\n\n- [XState (Vanilla)](https://codesandbox.io/s/xstate-ts-viz-template-qzdvv)\n- [XState + TypeScript](https://codesandbox.io/s/xstate-ts-viz-template-qzdvv)\n- [XState + Vue](https://codesandbox.io/s/xstate-vue-viz-template-r5wd7)\n- [XState + React](https://codesandbox.io/s/xstate-react-viz-template-5wq3q)\n\n![Inspector running from CodeSandbox](assets/inspector.png)\n\n[Check out the XState + Vue Minute Timer + Viz example on CodeSandbox](https://codesandbox.io/s/xstate-vue-minute-timer-viz-1txmk)\n\n## Installation\n\n1. Install with npm or yarn:\n\n```bash\nnpm install @xstate/inspect\n# or yarn add @xstate/inspect\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/inspect/dist/xstate-inspect.umd.min.js\"></script>\n```\n\nBy using the global variable `XStateInspect`\n\n2. Import it at the beginning of your project, before any other code is called:\n\n```js\nimport { inspect } from '@xstate/inspect';\n\ninspect({\n  // options\n  // url: 'https://stately.ai/viz?inspect', // (default)\n  iframe: false // open in new window\n});\n```\n\n3. Add `{ devTools: true }` to any interpreted machines you want to visualize:\n\n```js\nimport { interpret } from 'xstate';\nimport { inspect } from '@xstate/inspect';\n// ...\n\nconst service = interpret(someMachine, { devTools: true });\nservice.start();\n```\n\n## Configuration\n\n- `url` _(optional)_ - The endpoint that the Inspector sends events to. Default: https://stately.ai/viz?inspect\n- `iframe` _(optional)_ - The iframe that loads the provided URL. If iframe is set to `false`, then a new tab is opened instead.\n- `devTools` _(optional)_ - Allows custom implementation for lifecycle hooks.\n- `serialize` _(optional)_ - A custom serializer for messages sent to the URL endpoint. Useful for sanitizing sensitive information, such as credentials, from leaving your application.\n- `targetWindow` _(optional)_ - Provide a pre-existing window location that will be used instead of opening a new window etc. When using this option, you must still provide the `url` value due to security checks in browser APIs, and the `iframe` option is ignored in such a case.\n\n### Examples\n\n### Add a custom serializer to @xstate/inspector events and transitions messages\n\nWhen is this useful?\n\n- Remove sensitive items, such as `credentials`\n- Add additional custom handling\n\n```typescript\n// Remove credentials from being forwarded\ninspect({\n  serialize: (key: string, value: any) => {\n    return key === 'credentials' && typeof value === 'object' ? {} : value;\n  }\n});\n\n// Add a custom local log\ninspect({\n  serialize: (key: string, value: any) => {\n    if (key === 'ready') {\n      console.log('Detected ready key');\n    }\n    return value;\n  }\n});\n```\n\n### Easily log all machine events and transitions\n\nWhen is this useful?\n\n- Allows you to quickly see all events and transitions for your machines\n- No need to add manual `console.log` statements to your machine definitions\n\n```typescript\n// The URL and port of your local project (ex. Vite, Webpack, etc).\nconst url = 'http://127.0.0.1:5174/';\n\nconst inspector = inspect({\n  url,\n  iframe: undefined,\n  targetWindow: window\n});\n\n// In the same window, subscribe to messages from @xstate/inspector\ncreateWindowReceiver({}).subscribe(console.log);\n\n// Start your machine, and all events generated are logged to the console\ninterpret(machine, { devTools: true }).start({});\n```\n\n### Send events to a separate, locally hosted tool\n\nWhen is this useful?\n\n- Forward messages to a custom endpoint, that you can then listen to and add custom handling for messages\n\n```typescript\n// In your client application\nconst url = 'http://127.0.0.1:8443/';\nconst targetWindow = window.open(url);\n\nconst inspector = inspect({\n  // The URL must still be provided. This is used by postMessage, as it's\n  // not possible to do targetWindow.location for security reasons\n  url,\n  targetWindow\n});\n\n// In the second, hosted application\ncreateWindowReceiver({}).subscribe((event) => {\n  if (event.type === 'service.register') {\n    // Do something when a new machine is started\n  } else if (event.type === 'service.stop') {\n    // Do something when a machine enters a terminal state\n  } else if (event.type === 'service.event') {\n    // Do something when a machine receives an event\n  } else if (event.type === 'service.state') {\n    // Do something when a machine enters to a new state\n    // Note: Does not handle transitional states.\n  }\n});\n```\n","packages/xstate-react/README.md":"# @xstate/react\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [React](https://github.com/facebook/react/).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-react).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick start\n\n1. Install `xstate` and `@xstate/react`:\n\n```bash\nnpm i xstate @xstate/react\n```\n\n2. Import the `useMachine` hook:\n\n```tsx\nimport { useMachine } from '@xstate/react';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nexport const Toggler = () => {\n  const [state, send] = useMachine(toggleMachine);\n\n  return (\n    <button onClick={() => send({ type: 'TOGGLE' })}>\n      {state.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'}\n    </button>\n  );\n};\n```\n","packages/xstate-solid/README.md":"# @xstate/solid\n\nThe [@xstate/solid package](https://github.com/statelyai/xstate/tree/main/packages/xstate-solid) contains utilities for using [XState](https://github.com/statelyai/xstate) with [SolidJS](https://github.com/solidjs/solid).\n\n[[toc]]\n\n## Quick Start\n\n1. Install `xstate` and `@xstate/solid`:\n\n```bash\nnpm i xstate @xstate/solid\n```\n\n2. Import the `useActor` hook:\n\n```js\nimport { useActor } from '@xstate/solid';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nexport const Toggler = () => {\n  const [snapshot, send] = useActor(toggleMachine);\n\n  return (\n    <button onclick={() => send({ type: 'TOGGLE' })}>\n      {snapshot.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'}\n    </button>\n  );\n};\n```\n\n## API\n\n### `useActor(logic, options?)`\n\nA SolidJS hook that interprets the given `logic` and starts an actor that runs for the lifetime of the component.\n\n**Arguments**\n\n- `logic`\n\n  ```js\n  // existing machine\n  const [snapshot, send] = useMachine(machine);\n  ```\n\n**Returns** a tuple of `[snapshot, send, actorRef]`:\n\n- `snapshot` - Represents the current snapshot of the logic. This is a read-only value that is tracked by SolidJS for granular reactivity.\n- `send` - A function that sends events to the running service.\n- `actorRef` - The created service.\n\n### `fromActorRef(actorRf)`\n\nA SolidJS hook that subscribes to emitted changes from an existing [actor](https://xstate.js.org/docs/guides/actors.html).\n\n**Arguments**\n\n- `actorRef` - an actor object that contains `.send(...)` and `.subscribe(...)` methods. Allows [SolidJS Signal](https://www.solidjs.com/docs/latest/api#createsignal) (or function) to dynamically specify an actor.\n\n```js\nconst snapshot = fromActorRef(someSpawnedActor);\n```\n\n### `useActorRef(logic, options?)`\n\nA SolidJS hook that returns the `actorRef` created from the `logic` with the `options`, if specified. It starts the actor and runs it for the lifetime of the component. This is similar to `useActor`.\n\n`createService` returns a static reference (to just the interpreted logic) which will not rerender when its snapshot changes.\n\n**Arguments**\n\n- `logic`\n- `options` (optional) - [Actor options](https://xstate.js.org/docs/guides/interpretation.html#options)\n\n```js\nimport { useActorRef } from '@xstate/solid';\nimport { someMachine } from '../path/to/someMachine';\n\nconst App = () => {\n  const actorRef = useActorRef(someMachine);\n\n  // ...\n};\n```\n\nWith options:\n\n```js\n// ...\n\nconst App = () => {\n  const service = useActorRef(someMachine, {\n    input: {/* ... */}\n  });\n\n  // ...\n};\n```\n\n## Matching States\n\nWhen using [hierarchical](https://xstate.js.org/docs/guides/hierarchical.html) and [parallel](https://xstate.js.org/docs/guides/parallel.html) machines, the state values will be objects, not strings. In this case, it is best to use [`state.matches(...)`](https://xstate.js.org/docs/guides/states.html#state-methods-and-getters).\n\nThe SolidJS [Switch and Match Components](<>) are ideal for this use case:\n\n```jsx\nconst Loader = () => {\n  const [snapshot, send] = useActor(/* ... */);\n\n  return (\n    <div>\n      <Switch fallback={null}>\n        <Match when={snapshot.matches('idle')}>\n          <Loader.Idle />\n        </Match>\n        <Match when={snapshot.matches({ loading: 'user' })}>\n          <Loader.LoadingUser />\n        </Match>\n        <Match when={snapshot.matches({ loading: 'friends' })}>\n          <Loader.LoadingFriends />\n        </Match>\n      </Switch>\n    </div>\n  );\n};\n```\n\n## Persisted and Rehydrated State\n\nYou can persist and rehydrate state with `useActor(...)` via `options.snapshot`:\n\n```js\n// ...\n\n// Get the persisted state config object from somewhere, e.g. localStorage\nconst persistedSnapshot = JSON.parse(localStorage.getItem('some-persisted-state-key')) || someMachine.initialState;\n\nconst App = () => {\n  const [snapshot, send] = useActor(someMachine, {\n    snapshot: persistedSnapshot\n  });\n\n  // snapshot will rehydrate the provided persisted snapshot, it won't be the machine's initial snapshot\n\n  return (/* ... */)\n}\n```\n\n## Actor refs\n\nThe `actorRef` created in `useActor(logic)` can be referenced as the third returned value:\n\n```js\n//                  vvvvvvv\nconst [snapshot, send, actorRef] = useActor(someMachine);\n```\n\nYou can subscribe to that `actorRef`'s snapshot changes with the [`createEffect` hook](https://www.solidjs.com/docs/latest/api#createeffect):\n\n```js\n// ...\n\ncreateEffect(() => {\n  const subscription = actorRef.subscribe((snapshot) => {\n    // simple snapshot logging\n    console.log(snapshot);\n  });\n\n  onCleanup(() => subscription.unsubscribe());\n}); // note: service should never change\n```\n","packages/xstate-store-angular/README.md":"# @xstate/store-angular\n\nAngular adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-angular\n```\n\n## Quickstart\n\n```ts\nimport { Component } from '@angular/core';\nimport { createStore, injectStore } from '@xstate/store-angular';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\n@Component({\n  selector: 'app-counter',\n  template: `\n    <button (click)=\"store.send({ type: 'inc' })\">Count: {{ count() }}</button>\n  `\n})\nexport class CounterComponent {\n  store = store;\n  count = injectStore(store, (s) => s.context.count);\n}\n```\n\n## API\n\n### `injectStore(store, selector?, compare?)`\n\nAn Angular function that creates a signal subscribed to a store, selecting a value via an optional selector function.\n\n```ts\nimport { Component } from '@angular/core';\nimport { createStore, injectStore } from '@xstate/store-angular';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\n@Component({\n  selector: 'app-counter',\n  template: `<div>{{ count() }}</div>`\n})\nexport class CounterComponent {\n  count = injectStore(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  snapshot = injectStore(store);\n}\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Readonly Angular signal of the selected value\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Angular-specific docs](https://stately.ai/docs/xstate-store#angular) for more Angular examples.\n","packages/xstate-store-preact/README.md":"# @xstate/store-preact\n\nPreact adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-preact\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-preact';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>Count: {count}</button>\n  );\n};\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nSubscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-preact';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  const snapshot = useSelector(store);\n  // ...\n};\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Selected value (re-renders on change)\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Preact-specific docs](https://stately.ai/docs/xstate-store#preact) for more Preact examples.\n","packages/xstate-store-react/README.md":"# @xstate/store-react\n\nReact adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-react\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>Count: {count}</button>\n  );\n};\n```\n\n## API\n\n<!-- selector comparison semantics from src/index.ts -->\n### `useSelector(store, selector?, compare?)`\n\nSubscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  const snapshot = useSelector(store);\n  // ...\n};\n```\n\n**Arguments:**\n\n- `store` - Store or other readable value created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`). Also applies to the full snapshot when `selector` is `undefined`.\n\n**Returns:** Selected value (re-renders on change)\n\n---\n\n<!-- useStore overloads and inspection behavior from packages/xstate-store-react/src/index.ts -->\n\n### `useStore(definition, options?)`\n\nCreates a store instance scoped to a component.\n\n```tsx\nimport { useStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst App = () => {\n  const store = useStore({\n    context: { count: 0 },\n    on: {\n      inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n    }\n  });\n\n  const count = useSelector(store, (s) => s.context.count);\n  // ...\n};\n```\n\nTo wire up an inspector, pass the `inspect` option. The inspector is subscribed while the option is provided and unsubscribed when it is removed or the component unmounts:\n\n```tsx\nconst store = useStore(\n  {\n    context: { count: 0 },\n    on: {\n      inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n    }\n  },\n  { inspect: inspector.inspect }\n);\n```\n\n**Arguments:**\n\n- `definition` - Store configuration object, or store logic created with `createStoreLogic()` (followed by its `input`)\n- `options?` - Options object:\n  - `inspect?` - Observer or callback that receives [inspection events](https://stately.ai/docs/inspection) from the store\n\n**Returns:** Store instance (stable across re-renders)\n\n---\n\n### `useAtom(atom, selector?, compare?)`\n\nSubscribes to an atom and returns its value.\n\n```tsx\nimport { createAtom, useAtom } from '@xstate/store-react';\n// ...\n\nconst countAtom = createAtom(0);\n\nconst App = () => {\n  const count = useAtom(countAtom);\n\n  return <button onClick={() => countAtom.set((c) => c + 1)}>{count}</button>;\n};\n```\n\n**Arguments:**\n\n- `atom` - Atom created with `createAtom()`\n- `selector?` - Selector function\n- `compare?` - Equality function\n\n**Returns:** Atom value (re-renders on change)\n\n---\n\n### `createStoreHook(definition)`\n\nCreates a custom hook that returns `[selectedValue, store]`.\n\n```tsx\nimport { createStoreHook } from '@xstate/store-react';\n// ...\n\nconst useCountStore = createStoreHook({\n  context: { count: 0 },\n  on: {\n    inc: (ctx, e: { by: number }) => ({ ...ctx, count: ctx.count + e.by })\n  }\n});\n\nconst App = () => {\n  const [count, store] = useCountStore((s) => s.context.count);\n\n  return <button onClick={() => store.trigger.inc({ by: 1 })}>{count}</button>;\n};\n```\n\n**Arguments:**\n\n- `definition` - Store configuration object\n\n**Returns:** Custom hook function\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [React-specific docs](https://stately.ai/docs/xstate-store#react) for more React examples.\n","packages/xstate-store-solid/README.md":"# @xstate/store-solid\n\nSolid.js adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-solid\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-solid';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>\n      Count: {count()}\n    </button>\n  );\n};\n```\n\n## API\n\n<!-- selector subscription semantics from src/index.ts -->\n### `useSelector(store, selector, compare?)`\n\nThe accessor reconciles updates made during component setup before its subscription starts.\n\nCreates a signal that subscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-solid';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return <div>{count()}</div>;\n};\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Read-only signal of the selected value\n\n`useSelector` works with the store's readable snapshot interface, while store-specific code can still use `store.getSnapshot()` directly.\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Solid-specific docs](https://stately.ai/docs/xstate-store#solid) for more Solid examples.\n","packages/xstate-store-svelte/README.md":"# @xstate/store-svelte\n\nSvelte adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-svelte\n```\n\n## Quickstart\n\n```svelte\n<script>\nimport { createStore, useSelector } from '@xstate/store-svelte';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n</script>\n\n<button on:click={() => store.send({ type: 'inc' })}>\n  Count: {$count}\n</button>\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nCreates a Svelte readable store that subscribes to an XState store and returns a selected value.\n\n```svelte\n<script>\nimport { createStore, useSelector } from '@xstate/store-svelte';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n// or without selector (returns full snapshot)\nconst snapshot = useSelector(store);\n</script>\n\n<div>{$count}</div>\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Svelte readable store\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Svelte-specific docs](https://stately.ai/docs/xstate-store#svelte) for more Svelte examples.\n","packages/xstate-store-vue/README.md":"# @xstate/store-vue\n\nVue adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-vue\n```\n\n## Quickstart\n\n```vue\n<script setup>\nimport { createStore, useSelector } from '@xstate/store-vue';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n</script>\n\n<template>\n  <button @click=\"store.send({ type: 'inc' })\">Count: {{ count }}</button>\n</template>\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nA composable that subscribes to a store and returns a selected value as a readonly ref.\n\n```vue\n<script setup>\nimport { createStore, useSelector } from '@xstate/store-vue';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n// or without selector (returns full snapshot)\nconst snapshot = useSelector(store);\n</script>\n\n<template>\n  <div>{{ count }}</div>\n</template>\n```\n\n**Arguments:**\n\n- `store` - Store or other readable value created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Readonly ref of the selected value\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Vue-specific docs](https://stately.ai/docs/xstate-store#vue) for more Vue examples.\n","packages/xstate-store/README.md":"# `@xstate/store`\n\nXState Store is a library for **simple event-based state management**. If you want a state management library that allows you to update a store's state via events, `@xstate/store` is a great option. If you need more complex application logic needs, like state machines/statecharts, effects, communicating actors, and more, consider [using XState instead](https://github.com/statelyai/xstate).\n\n<!-- store capabilities from src/index.ts and runtime dependency requirements from package.json -->\n\n- **Extremely simple**: transitions update state via events, just like Redux, Zustand, Pinia, etc.\n- **Small**: no required runtime dependencies\n- **XState compatible**: use it with (or without) XState, or convert to XState machines when you need to handle more complex logic & effects.\n- **Extra type-safe**: great typing out of the box, with strong inference and no awkwardness.\n\n> [!NOTE]\n> This readme is written for [TypeScript](#typescript) users. If you are a JavaScript user, just remove the types.\n\n## Installation\n\n```bash\n# yarn add @xstate/store\n# pnpm add @xstate/store\nnpm install @xstate/store\n```\n\n## Quick start\n\n```ts\nimport { createStore } from '@xstate/store';\n\nexport const donutStore = createStore({\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    addDonut: (context) => ({\n      ...context,\n      donuts: context.donuts + 1\n    }),\n    changeFlavor: (context, event: { flavor: string }) => ({\n      ...context,\n      favoriteFlavor: event.flavor\n    }),\n    eatAllDonuts: (context) => ({\n      ...context,\n      donuts: 0\n    })\n  }\n});\n\ndonutStore.subscribe((snapshot) => {\n  console.log(snapshot.context);\n});\n\n// Equivalent to\n// donutStore.send({ type: 'addDonut' });\ndonutStore.trigger.addDonut();\n// => { donuts: 1, favoriteFlavor: 'chocolate' }\n\n// donutStore.send({\n//   type: 'changeFlavor',\n//   flavor: 'strawberry' // Strongly-typed!\n// });\ndonutStore.trigger.changeFlavor({ flavor: 'strawberry' });\n// => { donuts: 1, favoriteFlavor: 'strawberry' }\n```\n\n## Checking events\n\n<!-- store.can API from packages/xstate-store/src/types.ts -->\n\nUse `store.can` to check whether an event is allowed without updating the store:\n\n```ts\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    increment: (context, event: { by: number }) => {\n      if (context.count + event.by > 10) {\n        return;\n      }\n\n      return {\n        count: context.count + event.by\n      };\n    }\n  }\n});\n\nstore.can.increment({ by: 4 });\n// => true\n```\n\nReturning `undefined` marks the event as not allowed. Returning the same context\nobject is still allowed, and transitions that enqueue effects are allowed.\n\n## Persistence\n\n<!-- persist and flushStorage behavior from src/persist.ts -->\n\nUse the `persist` extension to save state after events are committed. Calling\n`store.can` or the pure `store.transition` method does not schedule writes.\nWrites preserve commit order, including events triggered synchronously by effects\nor subscriptions. A newer eligible event can supersede an older pending write;\n`onDone` runs for writes actually performed. Asynchronous writes execute in event\norder for each store. Call\n`await flushStorage(store)` to write buffered changes and wait for queued writes\nto finish. Synchronous storage adapters continue to write synchronously.\n\nWith throttling, `pick` runs once per write on the latest buffered context.\n`clearStorage(store)` cancels buffered writes and removes saved data after any\nalready queued writes finish; await its result when using asynchronous storage.\nNew events sent after clearing can persist new state. For asynchronous storage,\ncall `await rehydrateStore(store)` to load saved state; initial read failures are\nreported through `onError`.\n\n```ts\nimport { persist, flushStorage } from '@xstate/store/persist';\n\nconst savedDonutStore = donutStore.with(persist({ name: 'donuts' }));\nsavedDonutStore.trigger.addDonut();\nawait flushStorage(savedDonutStore);\n```\n\n### Undo and persistence\n\n<!-- snapshot undo restoration behavior from src/undo.ts -->\n\nSnapshot-based `undoRedo` restores historical state while preserving live\nextension metadata, including persistence hydration. A custom `restore` callback\ncan enqueue events; their updated extension metadata is preserved too. Apply\n`persist` after `undoRedo` when undo and redo themselves should write to storage:\n\n```ts\nimport { undoRedo } from '@xstate/store/undo';\n\nconst undoableDonutStore = donutStore\n  .with(undoRedo({ strategy: 'snapshot' }))\n  .with(persist({ name: 'undoable-donuts' }));\n```\n\n## Atom updates and subscriptions\n\n<!-- writable updater tracking and subscriber errors from src/atom.ts -->\n\nReads inside a writable atom's `set(previous => next)` updater do not create\nreactive dependencies. Use a computed atom getter to track other atoms instead.\nIf a synchronous subscriber throws, other queued subscribers still receive their\nnotifications before the first error is rethrown to the caller. The atom's value\nhas already changed; later updates continue to notify subscribers normally.\n\n## Source atoms\n\n<!-- createSourceAtom snapshot and observed dependency lifecycle from src/atom.ts and src/types.ts -->\n\nUse `createSourceAtom` for a read-only external value. Direct and derived\nsubscribers share one listener; cleanup runs synchronously when the last consumer\nleaves. Plain reads do not start listeners. Resubscribing reconnects and refreshes\nthe snapshot.\n\n```ts\nimport { createAtom, createSourceAtom } from '@xstate/store';\n\nconst media = window.matchMedia('(prefers-color-scheme: dark)');\nconst isDark = createSourceAtom({\n  getSnapshot: () => media.matches,\n  subscribe: (notify) => {\n    media.addEventListener('change', notify);\n    return () => media.removeEventListener('change', notify);\n  }\n});\nconst theme = createAtom(() => (isDark.get() ? 'dark' : 'light'));\nconst subscription = theme.subscribe(console.log);\nsubscription.unsubscribe(); // Removes the media query listener.\n```\n\nSee [source atoms](./docs/source-atoms.md) for snapshot comparison, conditional\ndependencies, and lifecycle timing. Use XState actors for commands, retries, or\nreconnection logic.\n\n## Async atoms\n\n<!-- createAsyncAtom dependency and cancellation behavior from src/atom.ts -->\n\n`createAsyncAtom` loads a value lazily and exposes a `pending`, `done`, or\n`error` state. Atoms read synchronously by its getter remain dependencies after\nthe request succeeds or fails. When a dependency changes, subscribed async atoms\nreload; otherwise, they reload on the next read. Read dependencies before the\nfirst `await` to track them. Errors while delivering a resolved value (including\nsource activation) also become the async atom’s `error` state. If notifying that\nerror state fails, the state remains available through `.get()`.\n\n```ts\nimport { createAtom, createAsyncAtom } from '@xstate/store';\n\nconst userId = createAtom('ada');\nconst user = createAsyncAtom(async ({ signal }) => {\n  const id = userId.get();\n  const response = await fetch(`/users/${id}`, { signal });\n  return response.json();\n});\n\nuser.subscribe((state) => {\n  if (state.status === 'done') {\n    console.log(state.data);\n  }\n});\n\nuserId.set('grace'); // Reloads even after the previous request settled.\n```\n\nRecomputing aborts the previous getter's signal and ignores its stale result.\n\n## Usage with React\n\nImport `useSelector` from `@xstate/store-react`. Select the data you want via `useSelector(…)` and send events using `store.send(eventObject)`:\n\n```tsx\nimport { donutStore } from './donutStore.ts';\nimport { useSelector } from '@xstate/store-react';\n\nfunction DonutCounter() {\n  const donutCount = useSelector(donutStore, (state) => state.context.donuts);\n\n  return (\n    <div>\n      <button onClick={() => donutStore.send({ type: 'addDonut' })}>\n        Add donut ({donutCount})\n      </button>\n    </div>\n  );\n}\n```\n\n## Usage with SolidJS\n\nImport `useSelector` from `@xstate/store-solid`. Select the data you want via `useSelector(…)` and send events using `store.send(eventObject)`:\n\n```tsx\nimport { donutStore } from './donutStore.ts';\nimport { useSelector } from '@xstate/store-solid';\n\nfunction DonutCounter() {\n  const donutCount = useSelector(donutStore, (state) => state.context.donuts);\n\n  return (\n    <div>\n      <button onClick={() => donutStore.send({ type: 'addDonut' })}>\n        Add donut ({donutCount()})\n      </button>\n    </div>\n  );\n}\n```\n\n## Usage with Immer\n\nXState Store works well with immutable update libraries like [Immer](https://github.com/immerjs/immer) or [Mutative](https://github.com/unadlib/mutative). Use `produce(...)` inside your transition functions:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { produce } from 'immer'; // or { create } from 'mutative'\n\nconst donutStore = createStore({\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    addDonut: (context) =>\n      produce(context, (draft) => {\n        draft.donuts++;\n      }),\n    changeFlavor: (context, event: { flavor: string }) =>\n      produce(context, (draft) => {\n        draft.favoriteFlavor = event.flavor;\n      }),\n    eatAllDonuts: (context) =>\n      produce(context, (draft) => {\n        draft.donuts = 0;\n      })\n  }\n});\n```\n\nIf a transition should be unavailable, return `undefined` from the transition\nbefore calling `produce(...)`:\n\n```ts\non: {\n  eatDonut: (context) => {\n    if (context.donuts === 0) {\n      return;\n    }\n\n    return produce(context, (draft) => {\n      draft.donuts--;\n    });\n  };\n}\n```\n\nImmer treats a producer that returns `undefined` the same as a producer that\ndoes not explicitly return anything. If you need `produce(...)` itself to return\n`undefined`, return Immer's `nothing` token from the producer:\n\n```ts\nimport { nothing, produce } from 'immer';\n\non: {\n  eatDonut: (context) =>\n    produce(context, (draft) => {\n      if (draft.donuts === 0) {\n        return nothing;\n      }\n\n      draft.donuts--;\n    });\n}\n```\n\n## TypeScript\n\nXState Store is written in TypeScript and provides full type safety, _without_ you having to specify generic type parameters. The `context` type is inferred from the initial context object, and the event types are inferred from the event object payloads you provide in the transition functions.\n\n```ts\nimport { createStore } from '@xstate/store';\n\nconst donutStore = createStore({\n  // Context inferred as:\n  // {\n  //   donuts: number;\n  //   favoriteFlavor: string;\n  // }\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    // Event inferred as:\n    // {\n    //   type: 'changeFlavor';\n    //   flavor: string;\n    // }\n    changeFlavor: (context, event: { flavor: string }) => {\n      context.favoriteFlavor = event.flavor;\n    }\n  }\n});\n\ndonutStore.getSnapshot().context.favoriteFlavor; // string\ndonutStore.get().context.favoriteFlavor; // same snapshot, readable/tracked read\n\ndonutStore.send({\n  type: 'changeFlavor', // Strongly-typed from transition key\n  flavor: 'strawberry' // Strongly-typed from { flavor: string }\n});\n```\n\nIf you want to provide event or emitted-event types explicitly, you can use `schemas` with any library that implements the [Standard Schema](https://standardschema.dev/) interface. Schemas define the store's runtime-readable contract: the shape of its context, accepted events, and emitted events. Store uses schemas for type inference and metadata by default; it does not validate schema-declared values unless you opt in with `validateSchemas()`.\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    context: z.object({\n      donuts: z.number(),\n      favoriteFlavor: z.string()\n    }),\n    events: {\n      changeFlavor: z.object({\n        flavor: z.string()\n      })\n    },\n    emitted: {\n      flavorChanged: z.object({\n        flavor: z.string()\n      })\n    }\n  },\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    changeFlavor: (context, event, enqueue) => {\n      enqueue.emit.flavorChanged({ flavor: event.flavor });\n      return {\n        ...context,\n        favoriteFlavor: event.flavor\n      };\n    }\n  }\n});\n```\n\nEvent and emitted-event schemas describe payload objects. Use an empty object\nschema for events without payload:\n\n```ts\nschemas: {\n  events: {\n    reset: z.object({})\n  },\n  emitted: {\n    reset: z.object({})\n  }\n}\n```\n\n### Validating schemas\n\nUse the `validateSchemas()` extension when the store should validate its schema\ncontract at runtime:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { validateSchemas } from '@xstate/store/validate';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    context: z.object({\n      count: z.number()\n    }),\n    events: {\n      increment: z.object({\n        by: z.number()\n      })\n    },\n    emitted: {\n      increased: z.object({\n        by: z.number()\n      })\n    }\n  },\n  context: { count: 0 },\n  on: {\n    increment: (context, event, enqueue) => {\n      enqueue.emit.increased({ by: event.by });\n      return { count: context.count + event.by };\n    }\n  }\n}).with(validateSchemas());\n```\n\n`validateSchemas()` validates store macrosteps. It validates the event sent to\nthe store, the final context after the transition completes, and emitted events\nbefore any effects execute. Events queued internally with `enqueue.trigger` are\nprocessed as part of the same macrostep; their payloads are not separately\nvalidated in this version.\n\nInvalid `send(...)`, `trigger.*(...)`, or `transition(...)` calls throw a\n`StoreValidationError`. `store.can.*(...)` always returns a boolean; validation\nerrors make it return `false`.\n\nBy default, unknown events and emitted events throw when the corresponding\nschema map exists. Extension-added event types are treated as known, even when\nthey do not have payload schemas. You can opt out:\n\n```ts\nconst store = createStore({\n  // ...\n}).with(\n  validateSchemas({\n    unknownEvents: 'ignore',\n    unknownEmitted: 'ignore'\n  })\n);\n```\n\nUse `store.getSnapshot()` when you want an explicit snapshot read from the store itself. Use `store.get()` when consuming the store as a `Readable` value in tracked or reactive code.\n\nIf you want to make the `context` type more specific, you can strongly type the `context` outside of `createStore(…)` and pass it in:\n\n```ts\nimport { createStore } from '@xstate/store';\n\ninterface DonutContext {\n  donuts: number;\n  favoriteFlavor: 'chocolate' | 'strawberry' | 'blueberry';\n}\n\nconst donutContext: DonutContext = {\n  donuts: 0,\n  favoriteFlavor: 'chocolate'\n};\n\nconst donutStore = createStore({\n  context: donutContext,\n  on: {\n    // ... (transitions go here)\n  }\n});\n```\n\n## Effects and Side Effects\n\nYou can enqueue effects in state transitions using the `enqueue` argument:\n\n```ts\nimport { createStore } from '@xstate/store';\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    incrementDelayed: (context, event, enqueue) => {\n      enqueue.effect(async () => {\n        await new Promise((resolve) => setTimeout(resolve, 1000));\n        store.send({ type: 'increment' });\n      });\n\n      return context;\n    },\n    increment: (context) => ({\n      ...context,\n      count: context.count + 1\n    })\n  }\n});\n```\n\n## Emitting Events\n\nYou can emit events from transitions by declaring them in `schemas.emitted` and using `enqueue.emit`:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    emitted: {\n      increased: z.object({\n        by: z.number()\n      })\n    }\n  },\n  context: { count: 0 },\n  on: {\n    inc: (context, event: { by: number }, enqueue) => {\n      enqueue.emit.increased({ by: event.by });\n\n      return {\n        ...context,\n        count: context.count + event.by\n      };\n    }\n  }\n});\n\n// Listen for emitted events\nstore.on('increased', (event) => {\n  console.log(`Count increased by ${event.by}`);\n});\n```\n","packages/xstate-store/docs/source-atoms.md":"---\ntitle: Source atoms\ndescription: Share external snapshot subscriptions across atom consumers.\n---\n\nUse `createSourceAtom` to expose an external value, such as a media query or a\nbrowser observer, as a read-only atom. Provide `getSnapshot` to read its current\nvalue and `subscribe` to attach a change listener. The listener calls `notify()`;\nXState Store reads the latest snapshot. Return either a cleanup function or a\nsubscription object with an `unsubscribe()` method. XState Store normalizes the\nadapter result internally; the atom's public `.subscribe()` always returns a\nsubscription object, so consumers call `subscription.unsubscribe()`.\n\n```ts\nimport { createAtom, createSourceAtom } from '@xstate/store';\n\nconst media = window.matchMedia('(prefers-color-scheme: dark)');\nconst isDark = createSourceAtom({\n  getSnapshot: () => media.matches,\n  subscribe: (notify) => {\n    media.addEventListener('change', notify);\n    return () => media.removeEventListener('change', notify);\n  }\n});\nconst theme = createAtom(() => (isDark.get() ? 'dark' : 'light'));\n\n// Starts one media query listener, through the derived atom.\nconst derived = theme.subscribe((value) => console.log(value));\nconst direct = isDark.subscribe((value) => console.log(value));\n\n// The direct subscriber still needs the listener.\nderived.unsubscribe();\n// Removes the listener synchronously.\ndirect.unsubscribe();\n```\n\nCreate browser sources in an environment where their browser APIs are available.\nFor server rendering, provide a snapshot reader that works on the server; a plain\nread does not attach the external listener.\n\n## Reading and subscribing\n\nCreation is lazy. Calling the source atom's `.get()` without a live consumer reads\n`getSnapshot` without calling `subscribe`. Reading an unobserved derived atom also\ndoes not start external subscriptions. Derived atoms cache their values; an\nunobserved derived read does not poll external sources for changes.\n\nThe first direct subscription, or subscription to a derived atom that reads the\nsource, starts the listener. Consumers share one listener per source atom instance.\nSetup occurs after dependency evaluation settles and before the outer subscription\nor update call returns. XState Store attaches the listener before refreshing the\nsnapshot, including when registration calls `notify()` synchronously.\n\nLike other atoms, subscribing does not emit the initial value. Call `.get()` to\nread it. A snapshot change during listener registration can notify subscribers\nbefore `subscribe()` returns.\n\nWhen a conditional derived atom stops reading the source, its consumer is removed.\nThe listener remains active while any other direct or indirect consumer needs it.\nCleanup runs after graph updates settle, before the last `unsubscribe()` or update\ncall returns. Moving a dependency between derived branches during the same update\ndoes not restart a shared listener. Separate unsubscribe/resubscribe calls do.\n\nSubscribing again reconnects the listener and refreshes the snapshot. Notifications\nfrom an earlier, cleaned-up listener are ignored, including after reconnection.\n\n## Snapshot contract\n\n`getSnapshot` should return a stable value until the external source changes, and\n`subscribe` should notify whenever that value changes. Reads inside these\ncallbacks do not establish atom dependencies. Model reactive dependencies in a\nderived atom instead.\n\nSnapshots use `Object.is` comparison by default. Provide a custom comparator when\nan external source returns a new object for an unchanged value:\n\n```ts\nconst size = createSourceAtom(\n  {\n    getSnapshot: () => ({ width: window.innerWidth, height: window.innerHeight }),\n    subscribe: (notify) => {\n      window.addEventListener('resize', notify);\n      return { unsubscribe: () => window.removeEventListener('resize', notify) };\n    }\n  },\n  {\n    compare: (previous, next) =>\n      previous.width === next.width && previous.height === next.height\n  }\n);\n```\n\nSource atoms expose `.get()` and `.subscribe()`, with no `.set()` or `.send()`.\nThey do not provide timed retries or an error state. A failed activation with live\nconsumers remains eligible for another attempt on a later atom operation. It is\nnever retried within the failing operation. Synchronous snapshot, registration,\nnotification, and cleanup errors propagate to the caller. If registration fails\nbefore returning a subscription, the adapter must release any resources it acquired.\n\nUse XState actors when a resource needs commands, retries, reconnection backoff,\nor a richer lifecycle. Adapt an actor snapshot with `getSnapshot: () =>\nactor.getSnapshot()` and `subscribe: (notify) => actor.subscribe(notify)`; the\nactor's owner remains responsible for starting and stopping it.\n","packages/xstate-svelte/README.md":"# @xstate/svelte\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [Svelte](https://github.com/sveltejs/svelte).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-svelte).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick Start\n\n1. Install `xstate` and `@xstate/svelte`:\n\n```bash\nnpm i xstate @xstate/svelte\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/svelte/dist/xstate-svelte.min.js\"></script>\n```\n\nBy using the global variable `XStateSvelte`\n\n2. Import `useMachine`\n\n```svelte\n<script>\n  import { useMachine } from '@xstate/svelte';\n  import { createMachine } from 'xstate';\n\n  const toggleMachine = createMachine({\n    id: 'toggle',\n    initial: 'inactive',\n    states: {\n      inactive: {\n        on: { TOGGLE: 'active' }\n      },\n      active: {\n        on: { TOGGLE: 'inactive' }\n      }\n    }\n  });\n\n  const { state, send } = useMachine(toggleMachine);\n</script>\n\n<button on:click={() => send('TOGGLE')}>\n  {$state.value === 'inactive'\n    ? 'Click to activate'\n    : 'Active! Click to deactivate'}\n</button>\n```\n","packages/xstate-vue/README.md":"# @xstate/vue\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [Vue](https://github.com/vuejs/vue).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-vue).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## :warning: Vue 2 Notice:\n\nIf you're using Vue 2.x, please see [the Vue recipe](https://xstate.js.org/docs/recipes/vue.html) instead, or use the [`xstate-vue2` package](https://github.com/ChrisShank/xstate-vue2) if you want to use the Vue Composition API.\n\n## Quick start\n\n1. Install `xstate` and `@xstate/vue`:\n\n```bash\nnpm i xstate @xstate/vue\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/vue/dist/xstate-vue.min.js\"></script>\n```\n\nBy using the global variable `XStateVue`\n\n2. Import the `useMachine` composition function:\n\n```vue\n<script setup>\nimport { useMachine } from '@xstate/vue';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nconst { snapshot, send } = useMachine(toggleMachine);\n</script>\n\n<template>\n  <button @click=\"send({ type: 'TOGGLE' })\">\n    {{\n      snapshot.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'\n    }}\n  </button>\n</template>\n```\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"This is a monorepo containing XState, @xstate/store, and related packages.\n\n## Dev environment\n\n- Use pnpm to install dependencies\n\n## PR instructions\n\n- Run `pnpm test` to run the tests in all packages, only for changes that affect mulitple packages.\n- Run `pnpm test:core` to only run core XState tests.\n- Run `pnpm test:store` to only run @xstate/store tests.\n- Run `pnpm lint` and `pnpm format:check` to check linting and formatting.\n- Run `pnpm typecheck` to make sure that there are no type errors.\n- Before making a PR, run `pnpm changeset` to create a changeset with a short description of the changes, and a code example if applicable. Do not include implementation details; only pertinent details for developers using the package.\n","isInternal":false,"tokens":183,"sizeBytes":741},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"AGENTS.md","isInternal":false,"tokens":3,"sizeBytes":9},{"name":"source-atoms.md","path":"packages/xstate-store/docs/source-atoms.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-store/docs/source-atoms.md","title":"Docs Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Source atoms\ndescription: Share external snapshot subscriptions across atom consumers.\n---\n\nUse `createSourceAtom` to expose an external value, such as a media query or a\nbrowser observer, as a read-only atom. Provide `getSnapshot` to read its current\nvalue and `subscribe` to attach a change listener. The listener calls `notify()`;\nXState Store reads the latest snapshot. Return either a cleanup function or a\nsubscription object with an `unsubscribe()` method. XState Store normalizes the\nadapter result internally; the atom's public `.subscribe()` always returns a\nsubscription object, so consumers call `subscription.unsubscribe()`.\n\n```ts\nimport { createAtom, createSourceAtom } from '@xstate/store';\n\nconst media = window.matchMedia('(prefers-color-scheme: dark)');\nconst isDark = createSourceAtom({\n  getSnapshot: () => media.matches,\n  subscribe: (notify) => {\n    media.addEventListener('change', notify);\n    return () => media.removeEventListener('change', notify);\n  }\n});\nconst theme = createAtom(() => (isDark.get() ? 'dark' : 'light'));\n\n// Starts one media query listener, through the derived atom.\nconst derived = theme.subscribe((value) => console.log(value));\nconst direct = isDark.subscribe((value) => console.log(value));\n\n// The direct subscriber still needs the listener.\nderived.unsubscribe();\n// Removes the listener synchronously.\ndirect.unsubscribe();\n```\n\nCreate browser sources in an environment where their browser APIs are available.\nFor server rendering, provide a snapshot reader that works on the server; a plain\nread does not attach the external listener.\n\n## Reading and subscribing\n\nCreation is lazy. Calling the source atom's `.get()` without a live consumer reads\n`getSnapshot` without calling `subscribe`. Reading an unobserved derived atom also\ndoes not start external subscriptions. Derived atoms cache their values; an\nunobserved derived read does not poll external sources for changes.\n\nThe first direct subscription, or subscription to a derived atom that reads the\nsource, starts the listener. Consumers share one listener per source atom instance.\nSetup occurs after dependency evaluation settles and before the outer subscription\nor update call returns. XState Store attaches the listener before refreshing the\nsnapshot, including when registration calls `notify()` synchronously.\n\nLike other atoms, subscribing does not emit the initial value. Call `.get()` to\nread it. A snapshot change during listener registration can notify subscribers\nbefore `subscribe()` returns.\n\nWhen a conditional derived atom stops reading the source, its consumer is removed.\nThe listener remains active while any other direct or indirect consumer needs it.\nCleanup runs after graph updates settle, before the last `unsubscribe()` or update\ncall returns. Moving a dependency between derived branches during the same update\ndoes not restart a shared listener. Separate unsubscribe/resubscribe calls do.\n\nSubscribing again reconnects the listener and refreshes the snapshot. Notifications\nfrom an earlier, cleaned-up listener are ignored, including after reconnection.\n\n## Snapshot contract\n\n`getSnapshot` should return a stable value until the external source changes, and\n`subscribe` should notify whenever that value changes. Reads inside these\ncallbacks do not establish atom dependencies. Model reactive dependencies in a\nderived atom instead.\n\nSnapshots use `Object.is` comparison by default. Provide a custom comparator when\nan external source returns a new object for an unchanged value:\n\n```ts\nconst size = createSourceAtom(\n  {\n    getSnapshot: () => ({ width: window.innerWidth, height: window.innerHeight }),\n    subscribe: (notify) => {\n      window.addEventListener('resize', notify);\n      return { unsubscribe: () => window.removeEventListener('resize', notify) };\n    }\n  },\n  {\n    compare: (previous, next) =>\n      previous.width === next.width && previous.height === next.height\n  }\n);\n```\n\nSource atoms expose `.get()` and `.subscribe()`, with no `.set()` or `.send()`.\nThey do not provide timed retries or an error state. A failed activation with live\nconsumers remains eligible for another attempt on a later atom operation. It is\nnever retried within the failing operation. Synchronous snapshot, registration,\nnotification, and cleanup errors propagate to the caller. If registration fails\nbefore returning a subscription, the adapter must release any resources it acquired.\n\nUse XState actors when a resource needs commands, retries, reconnection backoff,\nor a richer lifecycle. Adapt an actor snapshot with `getSnapshot: () =>\nactor.getSnapshot()` and `subscribe: (notify) => actor.subscribe(notify)`; the\nactor's owner remains responsible for starting and stopping it.\n","frontmatter":{"title":"Source atoms","description":"Share external snapshot subscriptions across atom consumers."},"isInternal":false,"tokens":946,"sizeBytes":4734},{"name":"README.md","path":"packages/core/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/core/README.md","title":"core Documentation","category":"plugin-manifest","format":"markdown","content":"<p align=\"center\">\n  <br />\n\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/statelyai/public-assets/main/logos/xstate-logo-white-nobg.svg\">\n    <img alt=\"XState logotype\" src=\"https://raw.githubusercontent.com/statelyai/public-assets/main/logos/xstate-logo-black-nobg.svg\" width=\"200\">\n  </picture>\n  <br />\n    <strong>Actor-based state management & orchestration for complex app logic.</strong> <a href=\"https://stately.ai/docs\">→ Documentation</a>\n  <br />\n  <br />\n</p>\n\nXState is a state management and orchestration solution for JavaScript and TypeScript apps. It has _zero_ dependencies, and is useful for frontend and backend application logic.\n\nIt uses event-driven programming, state machines, statecharts, and the actor model to handle complex logic in predictable, robust, and visual ways. XState provides a powerful and flexible way to manage application and workflow state by allowing developers to model logic as actors and state machines.\n\n### ✨ Create state machines visually in Stately Studio → [state.new](https://state.new)\n\n---\n\n📖 [Read the documentation](https://stately.ai/docs)\n\n➡️ [Create state machines with the Stately Editor](https://stately.ai/editor)\n\n🖥 [Download our VS Code extension](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode)\n\n📑 Inspired by the [SCXML specification](https://www.w3.org/TR/scxml/)\n\n💬 Chat on the [Stately Discord Community](https://discord.gg/xstate)\n\n✍️ Browse through the many [XState examples](https://github.com/statelyai/xstate/tree/main/examples)\n\n## Templates\n\nGet started by forking one of these templates on CodeSandbox:\n\n<table>\n<thead>\n<tr><th>Template</th><th></th></tr>\n</thead>\n<tbody>\n\n<tr>\n<td>\n\n[🤖 XState Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/vanilla-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/vanilla-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- XState v5\n- TypeScript\n- _No framework_\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[⚛️ XState + React Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/react-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/react-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [React](https://react.dev/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[💚 XState + Vue Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/vue-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/vue-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [Vue](https://vuejs.org/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[🧡 XState + Svelte Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/svelte-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/svelte-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [Svelte](https://svelte.dev/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n</tbody>\n</table>\n\n## Super quick start\n\n```bash\nnpm install xstate\n```\n\n```ts\nimport { createMachine, createActor, assign } from 'xstate';\n\n// State machine\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  context: {\n    count: 0\n  },\n  states: {\n    inactive: {\n      on: {\n        TOGGLE: { target: 'active' }\n      }\n    },\n    active: {\n      entry: assign({ count: ({ context }) => context.count + 1 }),\n      on: {\n        TOGGLE: { target: 'inactive' }\n      }\n    }\n  }\n});\n\n// Actor (instance of the machine logic, like a store)\nconst toggleActor = createActor(toggleMachine);\ntoggleActor.subscribe((state) => console.log(state.value, state.context));\ntoggleActor.start();\n// => logs 'inactive', { count: 0 }\n\ntoggleActor.send({ type: 'TOGGLE' });\n// => logs 'active', { count: 1 }\n\ntoggleActor.send({ type: 'TOGGLE' });\n// => logs 'inactive', { count: 1 }\n```\n\n## [Stately Studio](https://stately.ai)\n\n- Visually create, edit, and collaborate on state machines\n- Export to many formats, including XState v5\n- Test path & documentation autogeneration\n- Deploy to Stately Sky\n- Generate & modify machines with Stately AI\n\n<a href=\"https://stately.ai/registry/new?ref=github\" title=\"Stately Studio\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/74ed9cbc-b824-4ed7-a16d-f104947af8a7\" alt=\"XState Viz\" width=\"800\" />\n</a>\n\n**[state.new](https://stately.ai/registry/new?ref=github)**\n\n## Why?\n\nStatecharts are a formalism for modeling stateful, reactive systems. This is useful for declaratively describing the _behavior_ of your application, from the individual components to the overall application logic.\n\nRead [📽 the slides](http://slides.com/davidkhourshid/finite-state-machines) ([🎥 video](https://www.youtube.com/watch?v=VU1NKX6Qkxc)) or check out these resources for learning about the importance of finite state machines and statecharts in user interfaces:\n\n- [Statecharts - A Visual Formalism for Complex Systems](https://www.sciencedirect.com/science/article/pii/0167642387900359/pdf) by David Harel\n- [The World of Statecharts](https://statecharts.github.io/) by Erik Mogensen\n\n## Packages\n\n| Package                                                                                       | Description                                                                  |\n| --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |\n| 🤖 `xstate`                                                                                   | Core finite state machine and statecharts library + interpreter              |\n| [⚛️ `@xstate/react`](https://github.com/statelyai/xstate/tree/main/packages/xstate-react)     | React hooks and utilities for using XState in React applications             |\n| [💚 `@xstate/vue`](https://github.com/statelyai/xstate/tree/main/packages/xstate-vue)         | Vue composition functions and utilities for using XState in Vue applications |\n| [🎷 `@xstate/svelte`](https://github.com/statelyai/xstate/tree/main/packages/xstate-svelte)   | Svelte utilities for using XState in Svelte applications                     |\n| [🥏 `@xstate/solid`](https://github.com/statelyai/xstate/tree/main/packages/xstate-solid)     | Solid hooks and utilities for using XState in Solid applications             |\n| [🔍 `@xstate/inspect`](https://github.com/statelyai/xstate/tree/main/packages/xstate-inspect) | Inspection utilities for XState                                              |\n\n## Finite State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst lightMachine = createMachine({\n  id: 'light',\n  initial: 'green',\n  states: {\n    green: {\n      on: {\n        TIMER: 'yellow'\n      }\n    },\n    yellow: {\n      on: {\n        TIMER: 'red'\n      }\n    },\n    red: {\n      on: {\n        TIMER: 'green'\n      }\n    }\n  }\n});\n\nconst actor = createActor(lightMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs 'green'\n\nactor.send({ type: 'TIMER' });\n// logs 'yellow'\n```\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n</td>\n<td>\n\n</td>\n</tr>\n</tbody>\n</table>\n\n</td>\n<td>\n\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=27e86036-f2f7-40f1-9d1e-66ce6e1accc0\" title=\"Finite states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/36d4b6b5-e3d0-4c19-9f41-2e3425ceac88\" alt=\"Finite states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n<br />\n\n</td>\n</tbody>\n</table>\n\n## Hierarchical (Nested) State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst pedestrianStates = {\n  initial: 'walk',\n  states: {\n    walk: {\n      on: {\n        PED_TIMER: 'wait'\n      }\n    },\n    wait: {\n      on: {\n        PED_TIMER: 'stop'\n      }\n    },\n    stop: {}\n  }\n};\n\nconst lightMachine = createMachine({\n  id: 'light',\n  initial: 'green',\n  states: {\n    green: {\n      on: {\n        TIMER: 'yellow'\n      }\n    },\n    yellow: {\n      on: {\n        TIMER: 'red'\n      }\n    },\n    red: {\n      on: {\n        TIMER: 'green'\n      },\n      ...pedestrianStates\n    }\n  }\n});\n\nconst actor = createActor(lightMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs 'green'\n\nactor.send({ type: 'TIMER' });\n// logs 'yellow'\n\nactor.send({ type: 'TIMER' });\n// logs { red: 'walk' }\n\nactor.send({ type: 'PED_TIMER' });\n// logs { red: 'wait' }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=30dffcdd-16c2-49e2-bfc6-a674057cb271\" title=\"Hierarchical states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/32b0692b-1c29-4469-b5e3-03146e3ef249\" alt=\"Hierarchical states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n<br />\n</td>\n</tr>\n</tbody>\n</table>\n\n## Parallel State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```ts\nimport { createMachine, createActor } from 'xstate';\n\nconst wordMachine = createMachine({\n  id: 'word',\n  type: 'parallel',\n  states: {\n    bold: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_BOLD: 'off' }\n        },\n        off: {\n          on: { TOGGLE_BOLD: 'on' }\n        }\n      }\n    },\n    underline: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_UNDERLINE: 'off' }\n        },\n        off: {\n          on: { TOGGLE_UNDERLINE: 'on' }\n        }\n      }\n    },\n    italics: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_ITALICS: 'off' }\n        },\n        off: {\n          on: { TOGGLE_ITALICS: 'on' }\n        }\n      }\n    },\n    list: {\n      initial: 'none',\n      states: {\n        none: {\n          on: {\n            BULLETS: 'bullets',\n            NUMBERS: 'numbers'\n          }\n        },\n        bullets: {\n          on: {\n            NONE: 'none',\n            NUMBERS: 'numbers'\n          }\n        },\n        numbers: {\n          on: {\n            BULLETS: 'bullets',\n            NONE: 'none'\n          }\n        }\n      }\n    }\n  }\n});\n\nconst actor = createActor(wordMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs {\n//   bold: 'off',\n//   italics: 'off',\n//   underline: 'off',\n//   list: 'none'\n// }\n\nactor.send({ type: 'TOGGLE_BOLD' });\n// logs {\n//   bold: 'on',\n//   italics: 'off',\n//   underline: 'off',\n//   list: 'none'\n// }\n\nactor.send({ type: 'TOGGLE_ITALICS' });\n// logs {\n//   bold: 'on',\n//   italics: 'on',\n//   underline: 'off',\n//   list: 'none'\n// }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=980f50d8-e1ff-4441-8c8b-afe41c1610f2\" title=\"Parallel states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/3b1989c0-f4a9-4653-baf2-4df3a40e91a6\" alt=\"Parallel states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n</td>\n</tr>\n</tbody>\n</table>\n\n## History States\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst paymentMachine = createMachine({\n  id: 'payment',\n  initial: 'method',\n  states: {\n    method: {\n      initial: 'cash',\n      states: {\n        cash: {\n          on: {\n            SWITCH_CHECK: 'check'\n          }\n        },\n        check: {\n          on: {\n            SWITCH_CASH: 'cash'\n          }\n        },\n        hist: { type: 'history' }\n      },\n      on: { NEXT: 'review' }\n    },\n    review: {\n      on: { PREVIOUS: 'method.hist' }\n    }\n  }\n});\n\nconst actor = createActor(paymentMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs {\n//   value: { method: 'cash' },\n// }\n\nactor.send({ type: 'SWITCH_CHECK' });\n// logs {\n//   value: { method: 'check' },\n// }\n\nactor.send({ type: 'NEXT' });\n// logs {\n//   value: 'review',\n// }\n\nactor.send({ type: 'PREVIOUS' });\n// logs {\n//   value: { method: 'check' },\n// }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=d1a9bb95-db97-4af3-b38b-71b005c643d3\" title=\"History states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/1be5c495-d560-4660-94f2-5341efbf7128\" alt=\"History state\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n</td>\n</tr>\n</tbody>\n</table>\n\n## Sponsors\n\nSpecial thanks to the sponsors who support this open-source project:\n\n<img src=\"https://opencollective.com/xstate/tiers/backer/badge.svg?label=sponsors&color=brightgreen\" />\n\n<a href=\"https://transloadit.com/?utm_source=xstate&utm_medium=referral&utm_campaign=sponsorship&utm_content=github\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://assets.transloadit.com/assets/images/sponsorships/logo-dark.svg\">\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"https://assets.transloadit.com/assets/images/sponsorships/logo-default.svg\">\n    <img src=\"https://assets.transloadit.com/assets/images/sponsorships/logo-default.svg\" alt=\"Transloadit Logo\">\n  </picture>\n</a>\n\n## SemVer Policy\n\nWe understand the importance of the public contract and do not intend to release any breaking changes to the **runtime** API in a minor or patch release. We consider this with any changes we make to the XState libraries and aim to minimize their effects on existing users.\n\n### Breaking changes\n\nXState executes much of the user logic itself. Therefore, almost any change to its behavior might be considered a breaking change. We recognize this as a potential problem but believe that treating every change as a breaking change is not practical. We do our best to implement new features thoughtfully to enable our users to implement their logic in a better, safer way.\n\nAny change _could_ affect how existing XState machines behave if those machines are using particular configurations. We do not introduce behavior changes on a whim and aim to avoid making changes that affect most existing machines. But we reserve the right to make _some_ behavior changes in minor releases. Our best judgment of the situation will always dictate such changes. Please always read our release notes before deciding to upgrade.\n\n### TypeScript changes\n\nWe also reserve a similar right to adjust declared TypeScript definitions or drop support for older versions of TypeScript in a minor release. The TypeScript language itself evolves quickly and often introduces breaking changes in its minor releases. Our team is also continuously learning how to leverage TypeScript more effectively - and the types improve as a result.\n\nFor these reasons, it is impractical for our team to be bound by decisions taken when an older version of TypeScript was its latest version or when we didn’t know how to declare our types in a better way. We won’t introduce declaration changes often - but we are more likely to do so than with runtime changes.\n\n### Packages\n\nMost of the packages in the XState family declare a peer dependency on XState itself. We’ll be cautious about maintaining compatibility with already-released packages when releasing a new version of XState, **but** each release of packages depending on XState will always adjust the declared peer dependency range to include the latest version of XState. For example, you should always be able to update `xstate` without `@xstate/react`. But when you update `@xstate/react`, we highly recommend updating `xstate` too.\n","isInternal":false,"tokens":4288,"sizeBytes":16224},{"name":"README.md","path":"packages/xstate-immer/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-immer/README.md","title":"xstate-immer Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/immer\n\n<p align=\"center\">\n  <a href=\"https://xstate.js.org\">\n  <br />\n  <img src=\"https://user-images.githubusercontent.com/1093738/79572515-1509e180-808b-11ea-92aa-10958521aa68.png\" alt=\"XState Immer\" width=\"200\"/>\n  <br />\n    <sub><strong>XState with Immer</strong></sub>\n  <br />\n  <br />\n  </a>\n</p>\n\nThis package contains utilities for using [Immer](https://immerjs.github.io/immer/docs/introduction) with [XState](https://github.com/statelyai/xstate).\n\n- [Read the full documentation in the XState docs](https://xstate.js.org/docs/packages/xstate-immer/).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick start\n\nIncluded in `@xstate/immer`:\n\n- `assign()` - an Immer action that allows you to immutably assign to machine `context` in a convenient way\n- `createUpdater()` - a useful function that allows you to cohesively define a context update event event creator and assign action, all together. ([See an example](#createupdatereventtype-recipe) below)\n\n1. Install `immer`, `xstate`, `@xstate/immer`:\n\n```bash\nnpm install immer xstate @xstate/immer\n```\n\n**Note:** You don't need to `import` anything from `immer`; it is a peer-dependency of `@xstate/immer`, so it must be installed.\n\n2. Import the Immer utilities:\n\n```js\nimport { createMachine, interpret } from 'xstate';\nimport { assign, createUpdater } from '@xstate/immer';\n\nconst levelUpdater = createUpdater('UPDATE_LEVEL', (ctx, { input }) => {\n  ctx.level = input;\n});\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  context: {\n    count: 0,\n    level: 0\n  },\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: {\n        TOGGLE: {\n          target: 'active',\n          // Immutably update context the same \"mutable\"\n          // way as you would do with Immer!\n          actions: assign((ctx) => ctx.count++)\n        }\n      }\n    },\n    active: {\n      on: {\n        TOGGLE: {\n          target: 'inactive'\n        },\n        // Use the updater for more convenience:\n        [levelUpdater.type]: {\n          actions: levelUpdater.action\n        }\n      }\n    }\n  }\n});\n\nconst toggleService = interpret(toggleMachine)\n  .onTransition((state) => {\n    console.log(state.context);\n  })\n  .start();\n\ntoggleService.send({ type: 'TOGGLE' });\n// { count: 1, level: 0 }\n\ntoggleService.send(levelUpdater.update(9));\n// { count: 1, level: 9 }\n\ntoggleService.send({ type: 'TOGGLE' });\n// { count: 2, level: 9 }\n\ntoggleService.send(levelUpdater.update(-100));\n// Notice how the level is not updated in 'inactive' state:\n// { count: 2, level: 9 }\n```\n","isInternal":false,"tokens":709,"sizeBytes":2595},{"name":"README.md","path":"packages/xstate-inspect/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-inspect/README.md","title":"xstate-inspect Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/inspect\n\nThis package contains inspection tools for XState.\n\n- [Read the full documentation in the XState docs](https://xstate.js.org/docs/packages/xstate-inspect/).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Templates\n\n- [XState (Vanilla)](https://codesandbox.io/s/xstate-ts-viz-template-qzdvv)\n- [XState + TypeScript](https://codesandbox.io/s/xstate-ts-viz-template-qzdvv)\n- [XState + Vue](https://codesandbox.io/s/xstate-vue-viz-template-r5wd7)\n- [XState + React](https://codesandbox.io/s/xstate-react-viz-template-5wq3q)\n\n![Inspector running from CodeSandbox](assets/inspector.png)\n\n[Check out the XState + Vue Minute Timer + Viz example on CodeSandbox](https://codesandbox.io/s/xstate-vue-minute-timer-viz-1txmk)\n\n## Installation\n\n1. Install with npm or yarn:\n\n```bash\nnpm install @xstate/inspect\n# or yarn add @xstate/inspect\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/inspect/dist/xstate-inspect.umd.min.js\"></script>\n```\n\nBy using the global variable `XStateInspect`\n\n2. Import it at the beginning of your project, before any other code is called:\n\n```js\nimport { inspect } from '@xstate/inspect';\n\ninspect({\n  // options\n  // url: 'https://stately.ai/viz?inspect', // (default)\n  iframe: false // open in new window\n});\n```\n\n3. Add `{ devTools: true }` to any interpreted machines you want to visualize:\n\n```js\nimport { interpret } from 'xstate';\nimport { inspect } from '@xstate/inspect';\n// ...\n\nconst service = interpret(someMachine, { devTools: true });\nservice.start();\n```\n\n## Configuration\n\n- `url` _(optional)_ - The endpoint that the Inspector sends events to. Default: https://stately.ai/viz?inspect\n- `iframe` _(optional)_ - The iframe that loads the provided URL. If iframe is set to `false`, then a new tab is opened instead.\n- `devTools` _(optional)_ - Allows custom implementation for lifecycle hooks.\n- `serialize` _(optional)_ - A custom serializer for messages sent to the URL endpoint. Useful for sanitizing sensitive information, such as credentials, from leaving your application.\n- `targetWindow` _(optional)_ - Provide a pre-existing window location that will be used instead of opening a new window etc. When using this option, you must still provide the `url` value due to security checks in browser APIs, and the `iframe` option is ignored in such a case.\n\n### Examples\n\n### Add a custom serializer to @xstate/inspector events and transitions messages\n\nWhen is this useful?\n\n- Remove sensitive items, such as `credentials`\n- Add additional custom handling\n\n```typescript\n// Remove credentials from being forwarded\ninspect({\n  serialize: (key: string, value: any) => {\n    return key === 'credentials' && typeof value === 'object' ? {} : value;\n  }\n});\n\n// Add a custom local log\ninspect({\n  serialize: (key: string, value: any) => {\n    if (key === 'ready') {\n      console.log('Detected ready key');\n    }\n    return value;\n  }\n});\n```\n\n### Easily log all machine events and transitions\n\nWhen is this useful?\n\n- Allows you to quickly see all events and transitions for your machines\n- No need to add manual `console.log` statements to your machine definitions\n\n```typescript\n// The URL and port of your local project (ex. Vite, Webpack, etc).\nconst url = 'http://127.0.0.1:5174/';\n\nconst inspector = inspect({\n  url,\n  iframe: undefined,\n  targetWindow: window\n});\n\n// In the same window, subscribe to messages from @xstate/inspector\ncreateWindowReceiver({}).subscribe(console.log);\n\n// Start your machine, and all events generated are logged to the console\ninterpret(machine, { devTools: true }).start({});\n```\n\n### Send events to a separate, locally hosted tool\n\nWhen is this useful?\n\n- Forward messages to a custom endpoint, that you can then listen to and add custom handling for messages\n\n```typescript\n// In your client application\nconst url = 'http://127.0.0.1:8443/';\nconst targetWindow = window.open(url);\n\nconst inspector = inspect({\n  // The URL must still be provided. This is used by postMessage, as it's\n  // not possible to do targetWindow.location for security reasons\n  url,\n  targetWindow\n});\n\n// In the second, hosted application\ncreateWindowReceiver({}).subscribe((event) => {\n  if (event.type === 'service.register') {\n    // Do something when a new machine is started\n  } else if (event.type === 'service.stop') {\n    // Do something when a machine enters a terminal state\n  } else if (event.type === 'service.event') {\n    // Do something when a machine receives an event\n  } else if (event.type === 'service.state') {\n    // Do something when a machine enters to a new state\n    // Note: Does not handle transitional states.\n  }\n});\n```\n","isInternal":false,"tokens":1157,"sizeBytes":4691},{"name":"README.md","path":"packages/xstate-react/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-react/README.md","title":"xstate-react Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/react\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [React](https://github.com/facebook/react/).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-react).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick start\n\n1. Install `xstate` and `@xstate/react`:\n\n```bash\nnpm i xstate @xstate/react\n```\n\n2. Import the `useMachine` hook:\n\n```tsx\nimport { useMachine } from '@xstate/react';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nexport const Toggler = () => {\n  const [state, send] = useMachine(toggleMachine);\n\n  return (\n    <button onClick={() => send({ type: 'TOGGLE' })}>\n      {state.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'}\n    </button>\n  );\n};\n```\n","isInternal":false,"tokens":286,"sizeBytes":1056},{"name":"README.md","path":"packages/xstate-solid/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-solid/README.md","title":"xstate-solid Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/solid\n\nThe [@xstate/solid package](https://github.com/statelyai/xstate/tree/main/packages/xstate-solid) contains utilities for using [XState](https://github.com/statelyai/xstate) with [SolidJS](https://github.com/solidjs/solid).\n\n[[toc]]\n\n## Quick Start\n\n1. Install `xstate` and `@xstate/solid`:\n\n```bash\nnpm i xstate @xstate/solid\n```\n\n2. Import the `useActor` hook:\n\n```js\nimport { useActor } from '@xstate/solid';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nexport const Toggler = () => {\n  const [snapshot, send] = useActor(toggleMachine);\n\n  return (\n    <button onclick={() => send({ type: 'TOGGLE' })}>\n      {snapshot.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'}\n    </button>\n  );\n};\n```\n\n## API\n\n### `useActor(logic, options?)`\n\nA SolidJS hook that interprets the given `logic` and starts an actor that runs for the lifetime of the component.\n\n**Arguments**\n\n- `logic`\n\n  ```js\n  // existing machine\n  const [snapshot, send] = useMachine(machine);\n  ```\n\n**Returns** a tuple of `[snapshot, send, actorRef]`:\n\n- `snapshot` - Represents the current snapshot of the logic. This is a read-only value that is tracked by SolidJS for granular reactivity.\n- `send` - A function that sends events to the running service.\n- `actorRef` - The created service.\n\n### `fromActorRef(actorRf)`\n\nA SolidJS hook that subscribes to emitted changes from an existing [actor](https://xstate.js.org/docs/guides/actors.html).\n\n**Arguments**\n\n- `actorRef` - an actor object that contains `.send(...)` and `.subscribe(...)` methods. Allows [SolidJS Signal](https://www.solidjs.com/docs/latest/api#createsignal) (or function) to dynamically specify an actor.\n\n```js\nconst snapshot = fromActorRef(someSpawnedActor);\n```\n\n### `useActorRef(logic, options?)`\n\nA SolidJS hook that returns the `actorRef` created from the `logic` with the `options`, if specified. It starts the actor and runs it for the lifetime of the component. This is similar to `useActor`.\n\n`createService` returns a static reference (to just the interpreted logic) which will not rerender when its snapshot changes.\n\n**Arguments**\n\n- `logic`\n- `options` (optional) - [Actor options](https://xstate.js.org/docs/guides/interpretation.html#options)\n\n```js\nimport { useActorRef } from '@xstate/solid';\nimport { someMachine } from '../path/to/someMachine';\n\nconst App = () => {\n  const actorRef = useActorRef(someMachine);\n\n  // ...\n};\n```\n\nWith options:\n\n```js\n// ...\n\nconst App = () => {\n  const service = useActorRef(someMachine, {\n    input: {/* ... */}\n  });\n\n  // ...\n};\n```\n\n## Matching States\n\nWhen using [hierarchical](https://xstate.js.org/docs/guides/hierarchical.html) and [parallel](https://xstate.js.org/docs/guides/parallel.html) machines, the state values will be objects, not strings. In this case, it is best to use [`state.matches(...)`](https://xstate.js.org/docs/guides/states.html#state-methods-and-getters).\n\nThe SolidJS [Switch and Match Components](<>) are ideal for this use case:\n\n```jsx\nconst Loader = () => {\n  const [snapshot, send] = useActor(/* ... */);\n\n  return (\n    <div>\n      <Switch fallback={null}>\n        <Match when={snapshot.matches('idle')}>\n          <Loader.Idle />\n        </Match>\n        <Match when={snapshot.matches({ loading: 'user' })}>\n          <Loader.LoadingUser />\n        </Match>\n        <Match when={snapshot.matches({ loading: 'friends' })}>\n          <Loader.LoadingFriends />\n        </Match>\n      </Switch>\n    </div>\n  );\n};\n```\n\n## Persisted and Rehydrated State\n\nYou can persist and rehydrate state with `useActor(...)` via `options.snapshot`:\n\n```js\n// ...\n\n// Get the persisted state config object from somewhere, e.g. localStorage\nconst persistedSnapshot = JSON.parse(localStorage.getItem('some-persisted-state-key')) || someMachine.initialState;\n\nconst App = () => {\n  const [snapshot, send] = useActor(someMachine, {\n    snapshot: persistedSnapshot\n  });\n\n  // snapshot will rehydrate the provided persisted snapshot, it won't be the machine's initial snapshot\n\n  return (/* ... */)\n}\n```\n\n## Actor refs\n\nThe `actorRef` created in `useActor(logic)` can be referenced as the third returned value:\n\n```js\n//                  vvvvvvv\nconst [snapshot, send, actorRef] = useActor(someMachine);\n```\n\nYou can subscribe to that `actorRef`'s snapshot changes with the [`createEffect` hook](https://www.solidjs.com/docs/latest/api#createeffect):\n\n```js\n// ...\n\ncreateEffect(() => {\n  const subscription = actorRef.subscribe((snapshot) => {\n    // simple snapshot logging\n    console.log(snapshot);\n  });\n\n  onCleanup(() => subscription.unsubscribe());\n}); // note: service should never change\n```\n","isInternal":false,"tokens":1238,"sizeBytes":4865},{"name":"README.md","path":"packages/xstate-store-angular/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-store-angular/README.md","title":"xstate-store-angular Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/store-angular\n\nAngular adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-angular\n```\n\n## Quickstart\n\n```ts\nimport { Component } from '@angular/core';\nimport { createStore, injectStore } from '@xstate/store-angular';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\n@Component({\n  selector: 'app-counter',\n  template: `\n    <button (click)=\"store.send({ type: 'inc' })\">Count: {{ count() }}</button>\n  `\n})\nexport class CounterComponent {\n  store = store;\n  count = injectStore(store, (s) => s.context.count);\n}\n```\n\n## API\n\n### `injectStore(store, selector?, compare?)`\n\nAn Angular function that creates a signal subscribed to a store, selecting a value via an optional selector function.\n\n```ts\nimport { Component } from '@angular/core';\nimport { createStore, injectStore } from '@xstate/store-angular';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\n@Component({\n  selector: 'app-counter',\n  template: `<div>{{ count() }}</div>`\n})\nexport class CounterComponent {\n  count = injectStore(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  snapshot = injectStore(store);\n}\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Readonly Angular signal of the selected value\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Angular-specific docs](https://stately.ai/docs/xstate-store#angular) for more Angular examples.\n","isInternal":false,"tokens":481,"sizeBytes":1894},{"name":"README.md","path":"packages/xstate-store-preact/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-store-preact/README.md","title":"xstate-store-preact Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/store-preact\n\nPreact adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-preact\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-preact';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>Count: {count}</button>\n  );\n};\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nSubscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-preact';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  const snapshot = useSelector(store);\n  // ...\n};\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Selected value (re-renders on change)\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Preact-specific docs](https://stately.ai/docs/xstate-store#preact) for more Preact examples.\n","isInternal":false,"tokens":429,"sizeBytes":1590},{"name":"README.md","path":"packages/xstate-store-react/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-store-react/README.md","title":"xstate-store-react Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/store-react\n\nReact adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-react\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>Count: {count}</button>\n  );\n};\n```\n\n## API\n\n<!-- selector comparison semantics from src/index.ts -->\n### `useSelector(store, selector?, compare?)`\n\nSubscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  const snapshot = useSelector(store);\n  // ...\n};\n```\n\n**Arguments:**\n\n- `store` - Store or other readable value created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`). Also applies to the full snapshot when `selector` is `undefined`.\n\n**Returns:** Selected value (re-renders on change)\n\n---\n\n<!-- useStore overloads and inspection behavior from packages/xstate-store-react/src/index.ts -->\n\n### `useStore(definition, options?)`\n\nCreates a store instance scoped to a component.\n\n```tsx\nimport { useStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst App = () => {\n  const store = useStore({\n    context: { count: 0 },\n    on: {\n      inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n    }\n  });\n\n  const count = useSelector(store, (s) => s.context.count);\n  // ...\n};\n```\n\nTo wire up an inspector, pass the `inspect` option. The inspector is subscribed while the option is provided and unsubscribed when it is removed or the component unmounts:\n\n```tsx\nconst store = useStore(\n  {\n    context: { count: 0 },\n    on: {\n      inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n    }\n  },\n  { inspect: inspector.inspect }\n);\n```\n\n**Arguments:**\n\n- `definition` - Store configuration object, or store logic created with `createStoreLogic()` (followed by its `input`)\n- `options?` - Options object:\n  - `inspect?` - Observer or callback that receives [inspection events](https://stately.ai/docs/inspection) from the store\n\n**Returns:** Store instance (stable across re-renders)\n\n---\n\n### `useAtom(atom, selector?, compare?)`\n\nSubscribes to an atom and returns its value.\n\n```tsx\nimport { createAtom, useAtom } from '@xstate/store-react';\n// ...\n\nconst countAtom = createAtom(0);\n\nconst App = () => {\n  const count = useAtom(countAtom);\n\n  return <button onClick={() => countAtom.set((c) => c + 1)}>{count}</button>;\n};\n```\n\n**Arguments:**\n\n- `atom` - Atom created with `createAtom()`\n- `selector?` - Selector function\n- `compare?` - Equality function\n\n**Returns:** Atom value (re-renders on change)\n\n---\n\n### `createStoreHook(definition)`\n\nCreates a custom hook that returns `[selectedValue, store]`.\n\n```tsx\nimport { createStoreHook } from '@xstate/store-react';\n// ...\n\nconst useCountStore = createStoreHook({\n  context: { count: 0 },\n  on: {\n    inc: (ctx, e: { by: number }) => ({ ...ctx, count: ctx.count + e.by })\n  }\n});\n\nconst App = () => {\n  const [count, store] = useCountStore((s) => s.context.count);\n\n  return <button onClick={() => store.trigger.inc({ by: 1 })}>{count}</button>;\n};\n```\n\n**Arguments:**\n\n- `definition` - Store configuration object\n\n**Returns:** Custom hook function\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [React-specific docs](https://stately.ai/docs/xstate-store#react) for more React examples.\n","isInternal":false,"tokens":1050,"sizeBytes":4044},{"name":"README.md","path":"packages/xstate-store-solid/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-store-solid/README.md","title":"xstate-store-solid Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/store-solid\n\nSolid.js adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-solid\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-solid';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>\n      Count: {count()}\n    </button>\n  );\n};\n```\n\n## API\n\n<!-- selector subscription semantics from src/index.ts -->\n### `useSelector(store, selector, compare?)`\n\nThe accessor reconciles updates made during component setup before its subscription starts.\n\nCreates a signal that subscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-solid';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return <div>{count()}</div>;\n};\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Read-only signal of the selected value\n\n`useSelector` works with the store's readable snapshot interface, while store-specific code can still use `store.getSnapshot()` directly.\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Solid-specific docs](https://stately.ai/docs/xstate-store#solid) for more Solid examples.\n","isInternal":false,"tokens":464,"sizeBytes":1846},{"name":"README.md","path":"packages/xstate-store-svelte/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-store-svelte/README.md","title":"xstate-store-svelte Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/store-svelte\n\nSvelte adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-svelte\n```\n\n## Quickstart\n\n```svelte\n<script>\nimport { createStore, useSelector } from '@xstate/store-svelte';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n</script>\n\n<button on:click={() => store.send({ type: 'inc' })}>\n  Count: {$count}\n</button>\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nCreates a Svelte readable store that subscribes to an XState store and returns a selected value.\n\n```svelte\n<script>\nimport { createStore, useSelector } from '@xstate/store-svelte';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n// or without selector (returns full snapshot)\nconst snapshot = useSelector(store);\n</script>\n\n<div>{$count}</div>\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Svelte readable store\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Svelte-specific docs](https://stately.ai/docs/xstate-store#svelte) for more Svelte examples.\n","isInternal":false,"tokens":426,"sizeBytes":1607},{"name":"README.md","path":"packages/xstate-store-vue/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-store-vue/README.md","title":"xstate-store-vue Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/store-vue\n\nVue adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-vue\n```\n\n## Quickstart\n\n```vue\n<script setup>\nimport { createStore, useSelector } from '@xstate/store-vue';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n</script>\n\n<template>\n  <button @click=\"store.send({ type: 'inc' })\">Count: {{ count }}</button>\n</template>\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nA composable that subscribes to a store and returns a selected value as a readonly ref.\n\n```vue\n<script setup>\nimport { createStore, useSelector } from '@xstate/store-vue';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n// or without selector (returns full snapshot)\nconst snapshot = useSelector(store);\n</script>\n\n<template>\n  <div>{{ count }}</div>\n</template>\n```\n\n**Arguments:**\n\n- `store` - Store or other readable value created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Readonly ref of the selected value\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Vue-specific docs](https://stately.ai/docs/xstate-store#vue) for more Vue examples.\n","isInternal":false,"tokens":439,"sizeBytes":1661},{"name":"README.md","path":"packages/xstate-store/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-store/README.md","title":"xstate-store Documentation","category":"plugin-manifest","format":"markdown","content":"# `@xstate/store`\n\nXState Store is a library for **simple event-based state management**. If you want a state management library that allows you to update a store's state via events, `@xstate/store` is a great option. If you need more complex application logic needs, like state machines/statecharts, effects, communicating actors, and more, consider [using XState instead](https://github.com/statelyai/xstate).\n\n<!-- store capabilities from src/index.ts and runtime dependency requirements from package.json -->\n\n- **Extremely simple**: transitions update state via events, just like Redux, Zustand, Pinia, etc.\n- **Small**: no required runtime dependencies\n- **XState compatible**: use it with (or without) XState, or convert to XState machines when you need to handle more complex logic & effects.\n- **Extra type-safe**: great typing out of the box, with strong inference and no awkwardness.\n\n> [!NOTE]\n> This readme is written for [TypeScript](#typescript) users. If you are a JavaScript user, just remove the types.\n\n## Installation\n\n```bash\n# yarn add @xstate/store\n# pnpm add @xstate/store\nnpm install @xstate/store\n```\n\n## Quick start\n\n```ts\nimport { createStore } from '@xstate/store';\n\nexport const donutStore = createStore({\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    addDonut: (context) => ({\n      ...context,\n      donuts: context.donuts + 1\n    }),\n    changeFlavor: (context, event: { flavor: string }) => ({\n      ...context,\n      favoriteFlavor: event.flavor\n    }),\n    eatAllDonuts: (context) => ({\n      ...context,\n      donuts: 0\n    })\n  }\n});\n\ndonutStore.subscribe((snapshot) => {\n  console.log(snapshot.context);\n});\n\n// Equivalent to\n// donutStore.send({ type: 'addDonut' });\ndonutStore.trigger.addDonut();\n// => { donuts: 1, favoriteFlavor: 'chocolate' }\n\n// donutStore.send({\n//   type: 'changeFlavor',\n//   flavor: 'strawberry' // Strongly-typed!\n// });\ndonutStore.trigger.changeFlavor({ flavor: 'strawberry' });\n// => { donuts: 1, favoriteFlavor: 'strawberry' }\n```\n\n## Checking events\n\n<!-- store.can API from packages/xstate-store/src/types.ts -->\n\nUse `store.can` to check whether an event is allowed without updating the store:\n\n```ts\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    increment: (context, event: { by: number }) => {\n      if (context.count + event.by > 10) {\n        return;\n      }\n\n      return {\n        count: context.count + event.by\n      };\n    }\n  }\n});\n\nstore.can.increment({ by: 4 });\n// => true\n```\n\nReturning `undefined` marks the event as not allowed. Returning the same context\nobject is still allowed, and transitions that enqueue effects are allowed.\n\n## Persistence\n\n<!-- persist and flushStorage behavior from src/persist.ts -->\n\nUse the `persist` extension to save state after events are committed. Calling\n`store.can` or the pure `store.transition` method does not schedule writes.\nWrites preserve commit order, including events triggered synchronously by effects\nor subscriptions. A newer eligible event can supersede an older pending write;\n`onDone` runs for writes actually performed. Asynchronous writes execute in event\norder for each store. Call\n`await flushStorage(store)` to write buffered changes and wait for queued writes\nto finish. Synchronous storage adapters continue to write synchronously.\n\nWith throttling, `pick` runs once per write on the latest buffered context.\n`clearStorage(store)` cancels buffered writes and removes saved data after any\nalready queued writes finish; await its result when using asynchronous storage.\nNew events sent after clearing can persist new state. For asynchronous storage,\ncall `await rehydrateStore(store)` to load saved state; initial read failures are\nreported through `onError`.\n\n```ts\nimport { persist, flushStorage } from '@xstate/store/persist';\n\nconst savedDonutStore = donutStore.with(persist({ name: 'donuts' }));\nsavedDonutStore.trigger.addDonut();\nawait flushStorage(savedDonutStore);\n```\n\n### Undo and persistence\n\n<!-- snapshot undo restoration behavior from src/undo.ts -->\n\nSnapshot-based `undoRedo` restores historical state while preserving live\nextension metadata, including persistence hydration. A custom `restore` callback\ncan enqueue events; their updated extension metadata is preserved too. Apply\n`persist` after `undoRedo` when undo and redo themselves should write to storage:\n\n```ts\nimport { undoRedo } from '@xstate/store/undo';\n\nconst undoableDonutStore = donutStore\n  .with(undoRedo({ strategy: 'snapshot' }))\n  .with(persist({ name: 'undoable-donuts' }));\n```\n\n## Atom updates and subscriptions\n\n<!-- writable updater tracking and subscriber errors from src/atom.ts -->\n\nReads inside a writable atom's `set(previous => next)` updater do not create\nreactive dependencies. Use a computed atom getter to track other atoms instead.\nIf a synchronous subscriber throws, other queued subscribers still receive their\nnotifications before the first error is rethrown to the caller. The atom's value\nhas already changed; later updates continue to notify subscribers normally.\n\n## Source atoms\n\n<!-- createSourceAtom snapshot and observed dependency lifecycle from src/atom.ts and src/types.ts -->\n\nUse `createSourceAtom` for a read-only external value. Direct and derived\nsubscribers share one listener; cleanup runs synchronously when the last consumer\nleaves. Plain reads do not start listeners. Resubscribing reconnects and refreshes\nthe snapshot.\n\n```ts\nimport { createAtom, createSourceAtom } from '@xstate/store';\n\nconst media = window.matchMedia('(prefers-color-scheme: dark)');\nconst isDark = createSourceAtom({\n  getSnapshot: () => media.matches,\n  subscribe: (notify) => {\n    media.addEventListener('change', notify);\n    return () => media.removeEventListener('change', notify);\n  }\n});\nconst theme = createAtom(() => (isDark.get() ? 'dark' : 'light'));\nconst subscription = theme.subscribe(console.log);\nsubscription.unsubscribe(); // Removes the media query listener.\n```\n\nSee [source atoms](./docs/source-atoms.md) for snapshot comparison, conditional\ndependencies, and lifecycle timing. Use XState actors for commands, retries, or\nreconnection logic.\n\n## Async atoms\n\n<!-- createAsyncAtom dependency and cancellation behavior from src/atom.ts -->\n\n`createAsyncAtom` loads a value lazily and exposes a `pending`, `done`, or\n`error` state. Atoms read synchronously by its getter remain dependencies after\nthe request succeeds or fails. When a dependency changes, subscribed async atoms\nreload; otherwise, they reload on the next read. Read dependencies before the\nfirst `await` to track them. Errors while delivering a resolved value (including\nsource activation) also become the async atom’s `error` state. If notifying that\nerror state fails, the state remains available through `.get()`.\n\n```ts\nimport { createAtom, createAsyncAtom } from '@xstate/store';\n\nconst userId = createAtom('ada');\nconst user = createAsyncAtom(async ({ signal }) => {\n  const id = userId.get();\n  const response = await fetch(`/users/${id}`, { signal });\n  return response.json();\n});\n\nuser.subscribe((state) => {\n  if (state.status === 'done') {\n    console.log(state.data);\n  }\n});\n\nuserId.set('grace'); // Reloads even after the previous request settled.\n```\n\nRecomputing aborts the previous getter's signal and ignores its stale result.\n\n## Usage with React\n\nImport `useSelector` from `@xstate/store-react`. Select the data you want via `useSelector(…)` and send events using `store.send(eventObject)`:\n\n```tsx\nimport { donutStore } from './donutStore.ts';\nimport { useSelector } from '@xstate/store-react';\n\nfunction DonutCounter() {\n  const donutCount = useSelector(donutStore, (state) => state.context.donuts);\n\n  return (\n    <div>\n      <button onClick={() => donutStore.send({ type: 'addDonut' })}>\n        Add donut ({donutCount})\n      </button>\n    </div>\n  );\n}\n```\n\n## Usage with SolidJS\n\nImport `useSelector` from `@xstate/store-solid`. Select the data you want via `useSelector(…)` and send events using `store.send(eventObject)`:\n\n```tsx\nimport { donutStore } from './donutStore.ts';\nimport { useSelector } from '@xstate/store-solid';\n\nfunction DonutCounter() {\n  const donutCount = useSelector(donutStore, (state) => state.context.donuts);\n\n  return (\n    <div>\n      <button onClick={() => donutStore.send({ type: 'addDonut' })}>\n        Add donut ({donutCount()})\n      </button>\n    </div>\n  );\n}\n```\n\n## Usage with Immer\n\nXState Store works well with immutable update libraries like [Immer](https://github.com/immerjs/immer) or [Mutative](https://github.com/unadlib/mutative). Use `produce(...)` inside your transition functions:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { produce } from 'immer'; // or { create } from 'mutative'\n\nconst donutStore = createStore({\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    addDonut: (context) =>\n      produce(context, (draft) => {\n        draft.donuts++;\n      }),\n    changeFlavor: (context, event: { flavor: string }) =>\n      produce(context, (draft) => {\n        draft.favoriteFlavor = event.flavor;\n      }),\n    eatAllDonuts: (context) =>\n      produce(context, (draft) => {\n        draft.donuts = 0;\n      })\n  }\n});\n```\n\nIf a transition should be unavailable, return `undefined` from the transition\nbefore calling `produce(...)`:\n\n```ts\non: {\n  eatDonut: (context) => {\n    if (context.donuts === 0) {\n      return;\n    }\n\n    return produce(context, (draft) => {\n      draft.donuts--;\n    });\n  };\n}\n```\n\nImmer treats a producer that returns `undefined` the same as a producer that\ndoes not explicitly return anything. If you need `produce(...)` itself to return\n`undefined`, return Immer's `nothing` token from the producer:\n\n```ts\nimport { nothing, produce } from 'immer';\n\non: {\n  eatDonut: (context) =>\n    produce(context, (draft) => {\n      if (draft.donuts === 0) {\n        return nothing;\n      }\n\n      draft.donuts--;\n    });\n}\n```\n\n## TypeScript\n\nXState Store is written in TypeScript and provides full type safety, _without_ you having to specify generic type parameters. The `context` type is inferred from the initial context object, and the event types are inferred from the event object payloads you provide in the transition functions.\n\n```ts\nimport { createStore } from '@xstate/store';\n\nconst donutStore = createStore({\n  // Context inferred as:\n  // {\n  //   donuts: number;\n  //   favoriteFlavor: string;\n  // }\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    // Event inferred as:\n    // {\n    //   type: 'changeFlavor';\n    //   flavor: string;\n    // }\n    changeFlavor: (context, event: { flavor: string }) => {\n      context.favoriteFlavor = event.flavor;\n    }\n  }\n});\n\ndonutStore.getSnapshot().context.favoriteFlavor; // string\ndonutStore.get().context.favoriteFlavor; // same snapshot, readable/tracked read\n\ndonutStore.send({\n  type: 'changeFlavor', // Strongly-typed from transition key\n  flavor: 'strawberry' // Strongly-typed from { flavor: string }\n});\n```\n\nIf you want to provide event or emitted-event types explicitly, you can use `schemas` with any library that implements the [Standard Schema](https://standardschema.dev/) interface. Schemas define the store's runtime-readable contract: the shape of its context, accepted events, and emitted events. Store uses schemas for type inference and metadata by default; it does not validate schema-declared values unless you opt in with `validateSchemas()`.\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    context: z.object({\n      donuts: z.number(),\n      favoriteFlavor: z.string()\n    }),\n    events: {\n      changeFlavor: z.object({\n        flavor: z.string()\n      })\n    },\n    emitted: {\n      flavorChanged: z.object({\n        flavor: z.string()\n      })\n    }\n  },\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    changeFlavor: (context, event, enqueue) => {\n      enqueue.emit.flavorChanged({ flavor: event.flavor });\n      return {\n        ...context,\n        favoriteFlavor: event.flavor\n      };\n    }\n  }\n});\n```\n\nEvent and emitted-event schemas describe payload objects. Use an empty object\nschema for events without payload:\n\n```ts\nschemas: {\n  events: {\n    reset: z.object({})\n  },\n  emitted: {\n    reset: z.object({})\n  }\n}\n```\n\n### Validating schemas\n\nUse the `validateSchemas()` extension when the store should validate its schema\ncontract at runtime:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { validateSchemas } from '@xstate/store/validate';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    context: z.object({\n      count: z.number()\n    }),\n    events: {\n      increment: z.object({\n        by: z.number()\n      })\n    },\n    emitted: {\n      increased: z.object({\n        by: z.number()\n      })\n    }\n  },\n  context: { count: 0 },\n  on: {\n    increment: (context, event, enqueue) => {\n      enqueue.emit.increased({ by: event.by });\n      return { count: context.count + event.by };\n    }\n  }\n}).with(validateSchemas());\n```\n\n`validateSchemas()` validates store macrosteps. It validates the event sent to\nthe store, the final context after the transition completes, and emitted events\nbefore any effects execute. Events queued internally with `enqueue.trigger` are\nprocessed as part of the same macrostep; their payloads are not separately\nvalidated in this version.\n\nInvalid `send(...)`, `trigger.*(...)`, or `transition(...)` calls throw a\n`StoreValidationError`. `store.can.*(...)` always returns a boolean; validation\nerrors make it return `false`.\n\nBy default, unknown events and emitted events throw when the corresponding\nschema map exists. Extension-added event types are treated as known, even when\nthey do not have payload schemas. You can opt out:\n\n```ts\nconst store = createStore({\n  // ...\n}).with(\n  validateSchemas({\n    unknownEvents: 'ignore',\n    unknownEmitted: 'ignore'\n  })\n);\n```\n\nUse `store.getSnapshot()` when you want an explicit snapshot read from the store itself. Use `store.get()` when consuming the store as a `Readable` value in tracked or reactive code.\n\nIf you want to make the `context` type more specific, you can strongly type the `context` outside of `createStore(…)` and pass it in:\n\n```ts\nimport { createStore } from '@xstate/store';\n\ninterface DonutContext {\n  donuts: number;\n  favoriteFlavor: 'chocolate' | 'strawberry' | 'blueberry';\n}\n\nconst donutContext: DonutContext = {\n  donuts: 0,\n  favoriteFlavor: 'chocolate'\n};\n\nconst donutStore = createStore({\n  context: donutContext,\n  on: {\n    // ... (transitions go here)\n  }\n});\n```\n\n## Effects and Side Effects\n\nYou can enqueue effects in state transitions using the `enqueue` argument:\n\n```ts\nimport { createStore } from '@xstate/store';\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    incrementDelayed: (context, event, enqueue) => {\n      enqueue.effect(async () => {\n        await new Promise((resolve) => setTimeout(resolve, 1000));\n        store.send({ type: 'increment' });\n      });\n\n      return context;\n    },\n    increment: (context) => ({\n      ...context,\n      count: context.count + 1\n    })\n  }\n});\n```\n\n## Emitting Events\n\nYou can emit events from transitions by declaring them in `schemas.emitted` and using `enqueue.emit`:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    emitted: {\n      increased: z.object({\n        by: z.number()\n      })\n    }\n  },\n  context: { count: 0 },\n  on: {\n    inc: (context, event: { by: number }, enqueue) => {\n      enqueue.emit.increased({ by: event.by });\n\n      return {\n        ...context,\n        count: context.count + event.by\n      };\n    }\n  }\n});\n\n// Listen for emitted events\nstore.on('increased', (event) => {\n  console.log(`Count increased by ${event.by}`);\n});\n```\n","isInternal":false,"tokens":3825,"sizeBytes":15914},{"name":"README.md","path":"packages/xstate-svelte/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-svelte/README.md","title":"xstate-svelte Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/svelte\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [Svelte](https://github.com/sveltejs/svelte).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-svelte).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick Start\n\n1. Install `xstate` and `@xstate/svelte`:\n\n```bash\nnpm i xstate @xstate/svelte\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/svelte/dist/xstate-svelte.min.js\"></script>\n```\n\nBy using the global variable `XStateSvelte`\n\n2. Import `useMachine`\n\n```svelte\n<script>\n  import { useMachine } from '@xstate/svelte';\n  import { createMachine } from 'xstate';\n\n  const toggleMachine = createMachine({\n    id: 'toggle',\n    initial: 'inactive',\n    states: {\n      inactive: {\n        on: { TOGGLE: 'active' }\n      },\n      active: {\n        on: { TOGGLE: 'inactive' }\n      }\n    }\n  });\n\n  const { state, send } = useMachine(toggleMachine);\n</script>\n\n<button on:click={() => send('TOGGLE')}>\n  {$state.value === 'inactive'\n    ? 'Click to activate'\n    : 'Active! Click to deactivate'}\n</button>\n```\n","isInternal":false,"tokens":324,"sizeBytes":1180},{"name":"README.md","path":"packages/xstate-vue/README.md","rawUrl":"https://raw.githubusercontent.com/statelyai/xstate/HEAD/packages/xstate-vue/README.md","title":"xstate-vue Documentation","category":"plugin-manifest","format":"markdown","content":"# @xstate/vue\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [Vue](https://github.com/vuejs/vue).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-vue).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## :warning: Vue 2 Notice:\n\nIf you're using Vue 2.x, please see [the Vue recipe](https://xstate.js.org/docs/recipes/vue.html) instead, or use the [`xstate-vue2` package](https://github.com/ChrisShank/xstate-vue2) if you want to use the Vue Composition API.\n\n## Quick start\n\n1. Install `xstate` and `@xstate/vue`:\n\n```bash\nnpm i xstate @xstate/vue\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/vue/dist/xstate-vue.min.js\"></script>\n```\n\nBy using the global variable `XStateVue`\n\n2. Import the `useMachine` composition function:\n\n```vue\n<script setup>\nimport { useMachine } from '@xstate/vue';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nconst { snapshot, send } = useMachine(toggleMachine);\n</script>\n\n<template>\n  <button @click=\"send({ type: 'TOGGLE' })\">\n    {{\n      snapshot.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'\n    }}\n  </button>\n</template>\n```\n","isInternal":false,"tokens":404,"sizeBytes":1462}],"systemPromptSnippet":"<yakaai_skills repo=\"statelyai/xstate\">\n<!-- File: AGENTS.md (Tokens: ~183 | Category: root-instruction) -->\nThis is a monorepo containing XState, @xstate/store, and related packages.\n\n## Dev environment\n\n- Use pnpm to install dependencies\n\n## PR instructions\n\n- Run `pnpm test` to run the tests in all packages, only for changes that affect mulitple packages.\n- Run `pnpm test:core` to only run core XState tests.\n- Run `pnpm test:store` to only run @xstate/store tests.\n- Run `pnpm lint` and `pnpm format:check` to check linting and formatting.\n- Run `pnpm typecheck` to make sure that there are no type errors.\n- Before making a PR, run `pnpm changeset` to create a changeset with a short description of the changes, and a code example if applicable. Do not include implementation details; only pertinent details for developers using the package.\n\n<!-- File: CLAUDE.md (Tokens: ~3 | Category: claude-rule) -->\nAGENTS.md\n\n<!-- File: packages/xstate-store/docs/source-atoms.md (Tokens: ~946 | Category: anthropic-skill) -->\n---\ntitle: Source atoms\ndescription: Share external snapshot subscriptions across atom consumers.\n---\n\nUse `createSourceAtom` to expose an external value, such as a media query or a\nbrowser observer, as a read-only atom. Provide `getSnapshot` to read its current\nvalue and `subscribe` to attach a change listener. The listener calls `notify()`;\nXState Store reads the latest snapshot. Return either a cleanup function or a\nsubscription object with an `unsubscribe()` method. XState Store normalizes the\nadapter result internally; the atom's public `.subscribe()` always returns a\nsubscription object, so consumers call `subscription.unsubscribe()`.\n\n```ts\nimport { createAtom, createSourceAtom } from '@xstate/store';\n\nconst media = window.matchMedia('(prefers-color-scheme: dark)');\nconst isDark = createSourceAtom({\n  getSnapshot: () => media.matches,\n  subscribe: (notify) => {\n    media.addEventListener('change', notify);\n    return () => media.removeEventListener('change', notify);\n  }\n});\nconst theme = createAtom(() => (isDark.get() ? 'dark' : 'light'));\n\n// Starts one media query listener, through the derived atom.\nconst derived = theme.subscribe((value) => console.log(value));\nconst direct = isDark.subscribe((value) => console.log(value));\n\n// The direct subscriber still needs the listener.\nderived.unsubscribe();\n// Removes the listener synchronously.\ndirect.unsubscribe();\n```\n\nCreate browser sources in an environment where their browser APIs are available.\nFor server rendering, provide a snapshot reader that works on the server; a plain\nread does not attach the external listener.\n\n## Reading and subscribing\n\nCreation is lazy. Calling the source atom's `.get()` without a live consumer reads\n`getSnapshot` without calling `subscribe`. Reading an unobserved derived atom also\ndoes not start external subscriptions. Derived atoms cache their values; an\nunobserved derived read does not poll external sources for changes.\n\nThe first direct subscription, or subscription to a derived atom that reads the\nsource, starts the listener. Consumers share one listener per source atom instance.\nSetup occurs after dependency evaluation settles and before the outer subscription\nor update call returns. XState Store attaches the listener before refreshing the\nsnapshot, including when registration calls `notify()` synchronously.\n\nLike other atoms, subscribing does not emit the initial value. Call `.get()` to\nread it. A snapshot change during listener registration can notify subscribers\nbefore `subscribe()` returns.\n\nWhen a conditional derived atom stops reading the source, its consumer is removed.\nThe listener remains active while any other direct or indirect consumer needs it.\nCleanup runs after graph updates settle, before the last `unsubscribe()` or update\ncall returns. Moving a dependency between derived branches during the same update\ndoes not restart a shared listener. Separate unsubscribe/resubscribe calls do.\n\nSubscribing again reconnects the listener and refreshes the snapshot. Notifications\nfrom an earlier, cleaned-up listener are ignored, including after reconnection.\n\n## Snapshot contract\n\n`getSnapshot` should return a stable value until the external source changes, and\n`subscribe` should notify whenever that value changes. Reads inside these\ncallbacks do not establish atom dependencies. Model reactive dependencies in a\nderived atom instead.\n\nSnapshots use `Object.is` comparison by default. Provide a custom comparator when\nan external source returns a new object for an unchanged value:\n\n```ts\nconst size = createSourceAtom(\n  {\n    getSnapshot: () => ({ width: window.innerWidth, height: window.innerHeight }),\n    subscribe: (notify) => {\n      window.addEventListener('resize', notify);\n      return { unsubscribe: () => window.removeEventListener('resize', notify) };\n    }\n  },\n  {\n    compare: (previous, next) =>\n      previous.width === next.width && previous.height === next.height\n  }\n);\n```\n\nSource atoms expose `.get()` and `.subscribe()`, with no `.set()` or `.send()`.\nThey do not provide timed retries or an error state. A failed activation with live\nconsumers remains eligible for another attempt on a later atom operation. It is\nnever retried within the failing operation. Synchronous snapshot, registration,\nnotification, and cleanup errors propagate to the caller. If registration fails\nbefore returning a subscription, the adapter must release any resources it acquired.\n\nUse XState actors when a resource needs commands, retries, reconnection backoff,\nor a richer lifecycle. Adapt an actor snapshot with `getSnapshot: () =>\nactor.getSnapshot()` and `subscribe: (notify) => actor.subscribe(notify)`; the\nactor's owner remains responsible for starting and stopping it.\n\n<!-- File: packages/core/README.md (Tokens: ~4288 | Category: plugin-manifest) -->\n<p align=\"center\">\n  <br />\n\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/statelyai/public-assets/main/logos/xstate-logo-white-nobg.svg\">\n    <img alt=\"XState logotype\" src=\"https://raw.githubusercontent.com/statelyai/public-assets/main/logos/xstate-logo-black-nobg.svg\" width=\"200\">\n  </picture>\n  <br />\n    <strong>Actor-based state management & orchestration for complex app logic.</strong> <a href=\"https://stately.ai/docs\">→ Documentation</a>\n  <br />\n  <br />\n</p>\n\nXState is a state management and orchestration solution for JavaScript and TypeScript apps. It has _zero_ dependencies, and is useful for frontend and backend application logic.\n\nIt uses event-driven programming, state machines, statecharts, and the actor model to handle complex logic in predictable, robust, and visual ways. XState provides a powerful and flexible way to manage application and workflow state by allowing developers to model logic as actors and state machines.\n\n### ✨ Create state machines visually in Stately Studio → [state.new](https://state.new)\n\n---\n\n📖 [Read the documentation](https://stately.ai/docs)\n\n➡️ [Create state machines with the Stately Editor](https://stately.ai/editor)\n\n🖥 [Download our VS Code extension](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode)\n\n📑 Inspired by the [SCXML specification](https://www.w3.org/TR/scxml/)\n\n💬 Chat on the [Stately Discord Community](https://discord.gg/xstate)\n\n✍️ Browse through the many [XState examples](https://github.com/statelyai/xstate/tree/main/examples)\n\n## Templates\n\nGet started by forking one of these templates on CodeSandbox:\n\n<table>\n<thead>\n<tr><th>Template</th><th></th></tr>\n</thead>\n<tbody>\n\n<tr>\n<td>\n\n[🤖 XState Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/vanilla-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/vanilla-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- XState v5\n- TypeScript\n- _No framework_\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[⚛️ XState + React Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/react-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/react-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [React](https://react.dev/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[💚 XState + Vue Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/vue-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/vue-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [Vue](https://vuejs.org/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n<tr>\n<td>\n\n[🧡 XState + Svelte Template (CodeSandbox)](https://codesandbox.io/p/devbox/github/statelyai/xstate/tree/main/templates/svelte-ts)\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/statelyai/xstate/tree/main/templates/svelte-ts?file=%2Fsrc%2FfeedbackMachine.ts)\n\n</td>\n<td>\n\n- [Svelte](https://svelte.dev/)\n- XState v5\n- TypeScript\n\n</td>\n</tr>\n\n</tbody>\n</table>\n\n## Super quick start\n\n```bash\nnpm install xstate\n```\n\n```ts\nimport { createMachine, createActor, assign } from 'xstate';\n\n// State machine\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  context: {\n    count: 0\n  },\n  states: {\n    inactive: {\n      on: {\n        TOGGLE: { target: 'active' }\n      }\n    },\n    active: {\n      entry: assign({ count: ({ context }) => context.count + 1 }),\n      on: {\n        TOGGLE: { target: 'inactive' }\n      }\n    }\n  }\n});\n\n// Actor (instance of the machine logic, like a store)\nconst toggleActor = createActor(toggleMachine);\ntoggleActor.subscribe((state) => console.log(state.value, state.context));\ntoggleActor.start();\n// => logs 'inactive', { count: 0 }\n\ntoggleActor.send({ type: 'TOGGLE' });\n// => logs 'active', { count: 1 }\n\ntoggleActor.send({ type: 'TOGGLE' });\n// => logs 'inactive', { count: 1 }\n```\n\n## [Stately Studio](https://stately.ai)\n\n- Visually create, edit, and collaborate on state machines\n- Export to many formats, including XState v5\n- Test path & documentation autogeneration\n- Deploy to Stately Sky\n- Generate & modify machines with Stately AI\n\n<a href=\"https://stately.ai/registry/new?ref=github\" title=\"Stately Studio\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/74ed9cbc-b824-4ed7-a16d-f104947af8a7\" alt=\"XState Viz\" width=\"800\" />\n</a>\n\n**[state.new](https://stately.ai/registry/new?ref=github)**\n\n## Why?\n\nStatecharts are a formalism for modeling stateful, reactive systems. This is useful for declaratively describing the _behavior_ of your application, from the individual components to the overall application logic.\n\nRead [📽 the slides](http://slides.com/davidkhourshid/finite-state-machines) ([🎥 video](https://www.youtube.com/watch?v=VU1NKX6Qkxc)) or check out these resources for learning about the importance of finite state machines and statecharts in user interfaces:\n\n- [Statecharts - A Visual Formalism for Complex Systems](https://www.sciencedirect.com/science/article/pii/0167642387900359/pdf) by David Harel\n- [The World of Statecharts](https://statecharts.github.io/) by Erik Mogensen\n\n## Packages\n\n| Package                                                                                       | Description                                                                  |\n| --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |\n| 🤖 `xstate`                                                                                   | Core finite state machine and statecharts library + interpreter              |\n| [⚛️ `@xstate/react`](https://github.com/statelyai/xstate/tree/main/packages/xstate-react)     | React hooks and utilities for using XState in React applications             |\n| [💚 `@xstate/vue`](https://github.com/statelyai/xstate/tree/main/packages/xstate-vue)         | Vue composition functions and utilities for using XState in Vue applications |\n| [🎷 `@xstate/svelte`](https://github.com/statelyai/xstate/tree/main/packages/xstate-svelte)   | Svelte utilities for using XState in Svelte applications                     |\n| [🥏 `@xstate/solid`](https://github.com/statelyai/xstate/tree/main/packages/xstate-solid)     | Solid hooks and utilities for using XState in Solid applications             |\n| [🔍 `@xstate/inspect`](https://github.com/statelyai/xstate/tree/main/packages/xstate-inspect) | Inspection utilities for XState                                              |\n\n## Finite State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst lightMachine = createMachine({\n  id: 'light',\n  initial: 'green',\n  states: {\n    green: {\n      on: {\n        TIMER: 'yellow'\n      }\n    },\n    yellow: {\n      on: {\n        TIMER: 'red'\n      }\n    },\n    red: {\n      on: {\n        TIMER: 'green'\n      }\n    }\n  }\n});\n\nconst actor = createActor(lightMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs 'green'\n\nactor.send({ type: 'TIMER' });\n// logs 'yellow'\n```\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n</td>\n<td>\n\n</td>\n</tr>\n</tbody>\n</table>\n\n</td>\n<td>\n\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=27e86036-f2f7-40f1-9d1e-66ce6e1accc0\" title=\"Finite states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/36d4b6b5-e3d0-4c19-9f41-2e3425ceac88\" alt=\"Finite states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n<br />\n\n</td>\n</tbody>\n</table>\n\n## Hierarchical (Nested) State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst pedestrianStates = {\n  initial: 'walk',\n  states: {\n    walk: {\n      on: {\n        PED_TIMER: 'wait'\n      }\n    },\n    wait: {\n      on: {\n        PED_TIMER: 'stop'\n      }\n    },\n    stop: {}\n  }\n};\n\nconst lightMachine = createMachine({\n  id: 'light',\n  initial: 'green',\n  states: {\n    green: {\n      on: {\n        TIMER: 'yellow'\n      }\n    },\n    yellow: {\n      on: {\n        TIMER: 'red'\n      }\n    },\n    red: {\n      on: {\n        TIMER: 'green'\n      },\n      ...pedestrianStates\n    }\n  }\n});\n\nconst actor = createActor(lightMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs 'green'\n\nactor.send({ type: 'TIMER' });\n// logs 'yellow'\n\nactor.send({ type: 'TIMER' });\n// logs { red: 'walk' }\n\nactor.send({ type: 'PED_TIMER' });\n// logs { red: 'wait' }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=30dffcdd-16c2-49e2-bfc6-a674057cb271\" title=\"Hierarchical states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/32b0692b-1c29-4469-b5e3-03146e3ef249\" alt=\"Hierarchical states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n<br />\n</td>\n</tr>\n</tbody>\n</table>\n\n## Parallel State Machines\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```ts\nimport { createMachine, createActor } from 'xstate';\n\nconst wordMachine = createMachine({\n  id: 'word',\n  type: 'parallel',\n  states: {\n    bold: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_BOLD: 'off' }\n        },\n        off: {\n          on: { TOGGLE_BOLD: 'on' }\n        }\n      }\n    },\n    underline: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_UNDERLINE: 'off' }\n        },\n        off: {\n          on: { TOGGLE_UNDERLINE: 'on' }\n        }\n      }\n    },\n    italics: {\n      initial: 'off',\n      states: {\n        on: {\n          on: { TOGGLE_ITALICS: 'off' }\n        },\n        off: {\n          on: { TOGGLE_ITALICS: 'on' }\n        }\n      }\n    },\n    list: {\n      initial: 'none',\n      states: {\n        none: {\n          on: {\n            BULLETS: 'bullets',\n            NUMBERS: 'numbers'\n          }\n        },\n        bullets: {\n          on: {\n            NONE: 'none',\n            NUMBERS: 'numbers'\n          }\n        },\n        numbers: {\n          on: {\n            BULLETS: 'bullets',\n            NONE: 'none'\n          }\n        }\n      }\n    }\n  }\n});\n\nconst actor = createActor(wordMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs {\n//   bold: 'off',\n//   italics: 'off',\n//   underline: 'off',\n//   list: 'none'\n// }\n\nactor.send({ type: 'TOGGLE_BOLD' });\n// logs {\n//   bold: 'on',\n//   italics: 'off',\n//   underline: 'off',\n//   list: 'none'\n// }\n\nactor.send({ type: 'TOGGLE_ITALICS' });\n// logs {\n//   bold: 'on',\n//   italics: 'on',\n//   underline: 'off',\n//   list: 'none'\n// }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=980f50d8-e1ff-4441-8c8b-afe41c1610f2\" title=\"Parallel states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/3b1989c0-f4a9-4653-baf2-4df3a40e91a6\" alt=\"Parallel states\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n</td>\n</tr>\n</tbody>\n</table>\n\n## History States\n\n<table>\n<thead><tr><th>Code</th><th>Statechart</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```js\nimport { createMachine, createActor } from 'xstate';\n\nconst paymentMachine = createMachine({\n  id: 'payment',\n  initial: 'method',\n  states: {\n    method: {\n      initial: 'cash',\n      states: {\n        cash: {\n          on: {\n            SWITCH_CHECK: 'check'\n          }\n        },\n        check: {\n          on: {\n            SWITCH_CASH: 'cash'\n          }\n        },\n        hist: { type: 'history' }\n      },\n      on: { NEXT: 'review' }\n    },\n    review: {\n      on: { PREVIOUS: 'method.hist' }\n    }\n  }\n});\n\nconst actor = createActor(paymentMachine);\n\nactor.subscribe((state) => {\n  console.log(state.value);\n});\n\nactor.start();\n// logs {\n//   value: { method: 'cash' },\n// }\n\nactor.send({ type: 'SWITCH_CHECK' });\n// logs {\n//   value: { method: 'check' },\n// }\n\nactor.send({ type: 'NEXT' });\n// logs {\n//   value: 'review',\n// }\n\nactor.send({ type: 'PREVIOUS' });\n// logs {\n//   value: { method: 'check' },\n// }\n```\n\n</td>\n<td>\n<a href=\"https://stately.ai/registry/editor/fa443471-b416-4014-8e6f-12417863e4d4?mode=design&machineId=d1a9bb95-db97-4af3-b38b-71b005c643d3\" title=\"History states\">\n  <img src=\"https://github.com/statelyai/xstate/assets/1093738/1be5c495-d560-4660-94f2-5341efbf7128\" alt=\"History state\" width=\"400\" />\n  <br />\n  Open in Stately Studio\n</a>\n</td>\n</tr>\n</tbody>\n</table>\n\n## Sponsors\n\nSpecial thanks to the sponsors who support this open-source project:\n\n<img src=\"https://opencollective.com/xstate/tiers/backer/badge.svg?label=sponsors&color=brightgreen\" />\n\n<a href=\"https://transloadit.com/?utm_source=xstate&utm_medium=referral&utm_campaign=sponsorship&utm_content=github\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://assets.transloadit.com/assets/images/sponsorships/logo-dark.svg\">\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"https://assets.transloadit.com/assets/images/sponsorships/logo-default.svg\">\n    <img src=\"https://assets.transloadit.com/assets/images/sponsorships/logo-default.svg\" alt=\"Transloadit Logo\">\n  </picture>\n</a>\n\n## SemVer Policy\n\nWe understand the importance of the public contract and do not intend to release any breaking changes to the **runtime** API in a minor or patch release. We consider this with any changes we make to the XState libraries and aim to minimize their effects on existing users.\n\n### Breaking changes\n\nXState executes much of the user logic itself. Therefore, almost any change to its behavior might be considered a breaking change. We recognize this as a potential problem but believe that treating every change as a breaking change is not practical. We do our best to implement new features thoughtfully to enable our users to implement their logic in a better, safer way.\n\nAny change _could_ affect how existing XState machines behave if those machines are using particular configurations. We do not introduce behavior changes on a whim and aim to avoid making changes that affect most existing machines. But we reserve the right to make _some_ behavior changes in minor releases. Our best judgment of the situation will always dictate such changes. Please always read our release notes before deciding to upgrade.\n\n### TypeScript changes\n\nWe also reserve a similar right to adjust declared TypeScript definitions or drop support for older versions of TypeScript in a minor release. The TypeScript language itself evolves quickly and often introduces breaking changes in its minor releases. Our team is also continuously learning how to leverage TypeScript more effectively - and the types improve as a result.\n\nFor these reasons, it is impractical for our team to be bound by decisions taken when an older version of TypeScript was its latest version or when we didn’t know how to declare our types in a better way. We won’t introduce declaration changes often - but we are more likely to do so than with runtime changes.\n\n### Packages\n\nMost of the packages in the XState family declare a peer dependency on XState itself. We’ll be cautious about maintaining compatibility with already-released packages when releasing a new version of XState, **but** each release of packages depending on XState will always adjust the declared peer dependency range to include the latest version of XState. For example, you should always be able to update `xstate` without `@xstate/react`. But when you update `@xstate/react`, we highly recommend updating `xstate` too.\n\n<!-- File: packages/xstate-immer/README.md (Tokens: ~709 | Category: plugin-manifest) -->\n# @xstate/immer\n\n<p align=\"center\">\n  <a href=\"https://xstate.js.org\">\n  <br />\n  <img src=\"https://user-images.githubusercontent.com/1093738/79572515-1509e180-808b-11ea-92aa-10958521aa68.png\" alt=\"XState Immer\" width=\"200\"/>\n  <br />\n    <sub><strong>XState with Immer</strong></sub>\n  <br />\n  <br />\n  </a>\n</p>\n\nThis package contains utilities for using [Immer](https://immerjs.github.io/immer/docs/introduction) with [XState](https://github.com/statelyai/xstate).\n\n- [Read the full documentation in the XState docs](https://xstate.js.org/docs/packages/xstate-immer/).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick start\n\nIncluded in `@xstate/immer`:\n\n- `assign()` - an Immer action that allows you to immutably assign to machine `context` in a convenient way\n- `createUpdater()` - a useful function that allows you to cohesively define a context update event event creator and assign action, all together. ([See an example](#createupdatereventtype-recipe) below)\n\n1. Install `immer`, `xstate`, `@xstate/immer`:\n\n```bash\nnpm install immer xstate @xstate/immer\n```\n\n**Note:** You don't need to `import` anything from `immer`; it is a peer-dependency of `@xstate/immer`, so it must be installed.\n\n2. Import the Immer utilities:\n\n```js\nimport { createMachine, interpret } from 'xstate';\nimport { assign, createUpdater } from '@xstate/immer';\n\nconst levelUpdater = createUpdater('UPDATE_LEVEL', (ctx, { input }) => {\n  ctx.level = input;\n});\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  context: {\n    count: 0,\n    level: 0\n  },\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: {\n        TOGGLE: {\n          target: 'active',\n          // Immutably update context the same \"mutable\"\n          // way as you would do with Immer!\n          actions: assign((ctx) => ctx.count++)\n        }\n      }\n    },\n    active: {\n      on: {\n        TOGGLE: {\n          target: 'inactive'\n        },\n        // Use the updater for more convenience:\n        [levelUpdater.type]: {\n          actions: levelUpdater.action\n        }\n      }\n    }\n  }\n});\n\nconst toggleService = interpret(toggleMachine)\n  .onTransition((state) => {\n    console.log(state.context);\n  })\n  .start();\n\ntoggleService.send({ type: 'TOGGLE' });\n// { count: 1, level: 0 }\n\ntoggleService.send(levelUpdater.update(9));\n// { count: 1, level: 9 }\n\ntoggleService.send({ type: 'TOGGLE' });\n// { count: 2, level: 9 }\n\ntoggleService.send(levelUpdater.update(-100));\n// Notice how the level is not updated in 'inactive' state:\n// { count: 2, level: 9 }\n```\n\n<!-- File: packages/xstate-inspect/README.md (Tokens: ~1157 | Category: plugin-manifest) -->\n# @xstate/inspect\n\nThis package contains inspection tools for XState.\n\n- [Read the full documentation in the XState docs](https://xstate.js.org/docs/packages/xstate-inspect/).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Templates\n\n- [XState (Vanilla)](https://codesandbox.io/s/xstate-ts-viz-template-qzdvv)\n- [XState + TypeScript](https://codesandbox.io/s/xstate-ts-viz-template-qzdvv)\n- [XState + Vue](https://codesandbox.io/s/xstate-vue-viz-template-r5wd7)\n- [XState + React](https://codesandbox.io/s/xstate-react-viz-template-5wq3q)\n\n![Inspector running from CodeSandbox](assets/inspector.png)\n\n[Check out the XState + Vue Minute Timer + Viz example on CodeSandbox](https://codesandbox.io/s/xstate-vue-minute-timer-viz-1txmk)\n\n## Installation\n\n1. Install with npm or yarn:\n\n```bash\nnpm install @xstate/inspect\n# or yarn add @xstate/inspect\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/inspect/dist/xstate-inspect.umd.min.js\"></script>\n```\n\nBy using the global variable `XStateInspect`\n\n2. Import it at the beginning of your project, before any other code is called:\n\n```js\nimport { inspect } from '@xstate/inspect';\n\ninspect({\n  // options\n  // url: 'https://stately.ai/viz?inspect', // (default)\n  iframe: false // open in new window\n});\n```\n\n3. Add `{ devTools: true }` to any interpreted machines you want to visualize:\n\n```js\nimport { interpret } from 'xstate';\nimport { inspect } from '@xstate/inspect';\n// ...\n\nconst service = interpret(someMachine, { devTools: true });\nservice.start();\n```\n\n## Configuration\n\n- `url` _(optional)_ - The endpoint that the Inspector sends events to. Default: https://stately.ai/viz?inspect\n- `iframe` _(optional)_ - The iframe that loads the provided URL. If iframe is set to `false`, then a new tab is opened instead.\n- `devTools` _(optional)_ - Allows custom implementation for lifecycle hooks.\n- `serialize` _(optional)_ - A custom serializer for messages sent to the URL endpoint. Useful for sanitizing sensitive information, such as credentials, from leaving your application.\n- `targetWindow` _(optional)_ - Provide a pre-existing window location that will be used instead of opening a new window etc. When using this option, you must still provide the `url` value due to security checks in browser APIs, and the `iframe` option is ignored in such a case.\n\n### Examples\n\n### Add a custom serializer to @xstate/inspector events and transitions messages\n\nWhen is this useful?\n\n- Remove sensitive items, such as `credentials`\n- Add additional custom handling\n\n```typescript\n// Remove credentials from being forwarded\ninspect({\n  serialize: (key: string, value: any) => {\n    return key === 'credentials' && typeof value === 'object' ? {} : value;\n  }\n});\n\n// Add a custom local log\ninspect({\n  serialize: (key: string, value: any) => {\n    if (key === 'ready') {\n      console.log('Detected ready key');\n    }\n    return value;\n  }\n});\n```\n\n### Easily log all machine events and transitions\n\nWhen is this useful?\n\n- Allows you to quickly see all events and transitions for your machines\n- No need to add manual `console.log` statements to your machine definitions\n\n```typescript\n// The URL and port of your local project (ex. Vite, Webpack, etc).\nconst url = 'http://127.0.0.1:5174/';\n\nconst inspector = inspect({\n  url,\n  iframe: undefined,\n  targetWindow: window\n});\n\n// In the same window, subscribe to messages from @xstate/inspector\ncreateWindowReceiver({}).subscribe(console.log);\n\n// Start your machine, and all events generated are logged to the console\ninterpret(machine, { devTools: true }).start({});\n```\n\n### Send events to a separate, locally hosted tool\n\nWhen is this useful?\n\n- Forward messages to a custom endpoint, that you can then listen to and add custom handling for messages\n\n```typescript\n// In your client application\nconst url = 'http://127.0.0.1:8443/';\nconst targetWindow = window.open(url);\n\nconst inspector = inspect({\n  // The URL must still be provided. This is used by postMessage, as it's\n  // not possible to do targetWindow.location for security reasons\n  url,\n  targetWindow\n});\n\n// In the second, hosted application\ncreateWindowReceiver({}).subscribe((event) => {\n  if (event.type === 'service.register') {\n    // Do something when a new machine is started\n  } else if (event.type === 'service.stop') {\n    // Do something when a machine enters a terminal state\n  } else if (event.type === 'service.event') {\n    // Do something when a machine receives an event\n  } else if (event.type === 'service.state') {\n    // Do something when a machine enters to a new state\n    // Note: Does not handle transitional states.\n  }\n});\n```\n\n<!-- File: packages/xstate-react/README.md (Tokens: ~286 | Category: plugin-manifest) -->\n# @xstate/react\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [React](https://github.com/facebook/react/).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-react).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick start\n\n1. Install `xstate` and `@xstate/react`:\n\n```bash\nnpm i xstate @xstate/react\n```\n\n2. Import the `useMachine` hook:\n\n```tsx\nimport { useMachine } from '@xstate/react';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nexport const Toggler = () => {\n  const [state, send] = useMachine(toggleMachine);\n\n  return (\n    <button onClick={() => send({ type: 'TOGGLE' })}>\n      {state.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'}\n    </button>\n  );\n};\n```\n\n<!-- File: packages/xstate-solid/README.md (Tokens: ~1238 | Category: plugin-manifest) -->\n# @xstate/solid\n\nThe [@xstate/solid package](https://github.com/statelyai/xstate/tree/main/packages/xstate-solid) contains utilities for using [XState](https://github.com/statelyai/xstate) with [SolidJS](https://github.com/solidjs/solid).\n\n[[toc]]\n\n## Quick Start\n\n1. Install `xstate` and `@xstate/solid`:\n\n```bash\nnpm i xstate @xstate/solid\n```\n\n2. Import the `useActor` hook:\n\n```js\nimport { useActor } from '@xstate/solid';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nexport const Toggler = () => {\n  const [snapshot, send] = useActor(toggleMachine);\n\n  return (\n    <button onclick={() => send({ type: 'TOGGLE' })}>\n      {snapshot.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'}\n    </button>\n  );\n};\n```\n\n## API\n\n### `useActor(logic, options?)`\n\nA SolidJS hook that interprets the given `logic` and starts an actor that runs for the lifetime of the component.\n\n**Arguments**\n\n- `logic`\n\n  ```js\n  // existing machine\n  const [snapshot, send] = useMachine(machine);\n  ```\n\n**Returns** a tuple of `[snapshot, send, actorRef]`:\n\n- `snapshot` - Represents the current snapshot of the logic. This is a read-only value that is tracked by SolidJS for granular reactivity.\n- `send` - A function that sends events to the running service.\n- `actorRef` - The created service.\n\n### `fromActorRef(actorRf)`\n\nA SolidJS hook that subscribes to emitted changes from an existing [actor](https://xstate.js.org/docs/guides/actors.html).\n\n**Arguments**\n\n- `actorRef` - an actor object that contains `.send(...)` and `.subscribe(...)` methods. Allows [SolidJS Signal](https://www.solidjs.com/docs/latest/api#createsignal) (or function) to dynamically specify an actor.\n\n```js\nconst snapshot = fromActorRef(someSpawnedActor);\n```\n\n### `useActorRef(logic, options?)`\n\nA SolidJS hook that returns the `actorRef` created from the `logic` with the `options`, if specified. It starts the actor and runs it for the lifetime of the component. This is similar to `useActor`.\n\n`createService` returns a static reference (to just the interpreted logic) which will not rerender when its snapshot changes.\n\n**Arguments**\n\n- `logic`\n- `options` (optional) - [Actor options](https://xstate.js.org/docs/guides/interpretation.html#options)\n\n```js\nimport { useActorRef } from '@xstate/solid';\nimport { someMachine } from '../path/to/someMachine';\n\nconst App = () => {\n  const actorRef = useActorRef(someMachine);\n\n  // ...\n};\n```\n\nWith options:\n\n```js\n// ...\n\nconst App = () => {\n  const service = useActorRef(someMachine, {\n    input: {/* ... */}\n  });\n\n  // ...\n};\n```\n\n## Matching States\n\nWhen using [hierarchical](https://xstate.js.org/docs/guides/hierarchical.html) and [parallel](https://xstate.js.org/docs/guides/parallel.html) machines, the state values will be objects, not strings. In this case, it is best to use [`state.matches(...)`](https://xstate.js.org/docs/guides/states.html#state-methods-and-getters).\n\nThe SolidJS [Switch and Match Components](<>) are ideal for this use case:\n\n```jsx\nconst Loader = () => {\n  const [snapshot, send] = useActor(/* ... */);\n\n  return (\n    <div>\n      <Switch fallback={null}>\n        <Match when={snapshot.matches('idle')}>\n          <Loader.Idle />\n        </Match>\n        <Match when={snapshot.matches({ loading: 'user' })}>\n          <Loader.LoadingUser />\n        </Match>\n        <Match when={snapshot.matches({ loading: 'friends' })}>\n          <Loader.LoadingFriends />\n        </Match>\n      </Switch>\n    </div>\n  );\n};\n```\n\n## Persisted and Rehydrated State\n\nYou can persist and rehydrate state with `useActor(...)` via `options.snapshot`:\n\n```js\n// ...\n\n// Get the persisted state config object from somewhere, e.g. localStorage\nconst persistedSnapshot = JSON.parse(localStorage.getItem('some-persisted-state-key')) || someMachine.initialState;\n\nconst App = () => {\n  const [snapshot, send] = useActor(someMachine, {\n    snapshot: persistedSnapshot\n  });\n\n  // snapshot will rehydrate the provided persisted snapshot, it won't be the machine's initial snapshot\n\n  return (/* ... */)\n}\n```\n\n## Actor refs\n\nThe `actorRef` created in `useActor(logic)` can be referenced as the third returned value:\n\n```js\n//                  vvvvvvv\nconst [snapshot, send, actorRef] = useActor(someMachine);\n```\n\nYou can subscribe to that `actorRef`'s snapshot changes with the [`createEffect` hook](https://www.solidjs.com/docs/latest/api#createeffect):\n\n```js\n// ...\n\ncreateEffect(() => {\n  const subscription = actorRef.subscribe((snapshot) => {\n    // simple snapshot logging\n    console.log(snapshot);\n  });\n\n  onCleanup(() => subscription.unsubscribe());\n}); // note: service should never change\n```\n\n<!-- File: packages/xstate-store-angular/README.md (Tokens: ~481 | Category: plugin-manifest) -->\n# @xstate/store-angular\n\nAngular adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-angular\n```\n\n## Quickstart\n\n```ts\nimport { Component } from '@angular/core';\nimport { createStore, injectStore } from '@xstate/store-angular';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\n@Component({\n  selector: 'app-counter',\n  template: `\n    <button (click)=\"store.send({ type: 'inc' })\">Count: {{ count() }}</button>\n  `\n})\nexport class CounterComponent {\n  store = store;\n  count = injectStore(store, (s) => s.context.count);\n}\n```\n\n## API\n\n### `injectStore(store, selector?, compare?)`\n\nAn Angular function that creates a signal subscribed to a store, selecting a value via an optional selector function.\n\n```ts\nimport { Component } from '@angular/core';\nimport { createStore, injectStore } from '@xstate/store-angular';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\n@Component({\n  selector: 'app-counter',\n  template: `<div>{{ count() }}</div>`\n})\nexport class CounterComponent {\n  count = injectStore(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  snapshot = injectStore(store);\n}\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Readonly Angular signal of the selected value\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Angular-specific docs](https://stately.ai/docs/xstate-store#angular) for more Angular examples.\n\n<!-- File: packages/xstate-store-preact/README.md (Tokens: ~429 | Category: plugin-manifest) -->\n# @xstate/store-preact\n\nPreact adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-preact\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-preact';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>Count: {count}</button>\n  );\n};\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nSubscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-preact';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  const snapshot = useSelector(store);\n  // ...\n};\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Selected value (re-renders on change)\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Preact-specific docs](https://stately.ai/docs/xstate-store#preact) for more Preact examples.\n\n<!-- File: packages/xstate-store-react/README.md (Tokens: ~1050 | Category: plugin-manifest) -->\n# @xstate/store-react\n\nReact adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-react\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>Count: {count}</button>\n  );\n};\n```\n\n## API\n\n<!-- selector comparison semantics from src/index.ts -->\n### `useSelector(store, selector?, compare?)`\n\nSubscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n  // or without selector (returns full snapshot)\n  const snapshot = useSelector(store);\n  // ...\n};\n```\n\n**Arguments:**\n\n- `store` - Store or other readable value created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`). Also applies to the full snapshot when `selector` is `undefined`.\n\n**Returns:** Selected value (re-renders on change)\n\n---\n\n<!-- useStore overloads and inspection behavior from packages/xstate-store-react/src/index.ts -->\n\n### `useStore(definition, options?)`\n\nCreates a store instance scoped to a component.\n\n```tsx\nimport { useStore, useSelector } from '@xstate/store-react';\n// ...\n\nconst App = () => {\n  const store = useStore({\n    context: { count: 0 },\n    on: {\n      inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n    }\n  });\n\n  const count = useSelector(store, (s) => s.context.count);\n  // ...\n};\n```\n\nTo wire up an inspector, pass the `inspect` option. The inspector is subscribed while the option is provided and unsubscribed when it is removed or the component unmounts:\n\n```tsx\nconst store = useStore(\n  {\n    context: { count: 0 },\n    on: {\n      inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n    }\n  },\n  { inspect: inspector.inspect }\n);\n```\n\n**Arguments:**\n\n- `definition` - Store configuration object, or store logic created with `createStoreLogic()` (followed by its `input`)\n- `options?` - Options object:\n  - `inspect?` - Observer or callback that receives [inspection events](https://stately.ai/docs/inspection) from the store\n\n**Returns:** Store instance (stable across re-renders)\n\n---\n\n### `useAtom(atom, selector?, compare?)`\n\nSubscribes to an atom and returns its value.\n\n```tsx\nimport { createAtom, useAtom } from '@xstate/store-react';\n// ...\n\nconst countAtom = createAtom(0);\n\nconst App = () => {\n  const count = useAtom(countAtom);\n\n  return <button onClick={() => countAtom.set((c) => c + 1)}>{count}</button>;\n};\n```\n\n**Arguments:**\n\n- `atom` - Atom created with `createAtom()`\n- `selector?` - Selector function\n- `compare?` - Equality function\n\n**Returns:** Atom value (re-renders on change)\n\n---\n\n### `createStoreHook(definition)`\n\nCreates a custom hook that returns `[selectedValue, store]`.\n\n```tsx\nimport { createStoreHook } from '@xstate/store-react';\n// ...\n\nconst useCountStore = createStoreHook({\n  context: { count: 0 },\n  on: {\n    inc: (ctx, e: { by: number }) => ({ ...ctx, count: ctx.count + e.by })\n  }\n});\n\nconst App = () => {\n  const [count, store] = useCountStore((s) => s.context.count);\n\n  return <button onClick={() => store.trigger.inc({ by: 1 })}>{count}</button>;\n};\n```\n\n**Arguments:**\n\n- `definition` - Store configuration object\n\n**Returns:** Custom hook function\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [React-specific docs](https://stately.ai/docs/xstate-store#react) for more React examples.\n\n<!-- File: packages/xstate-store-solid/README.md (Tokens: ~464 | Category: plugin-manifest) -->\n# @xstate/store-solid\n\nSolid.js adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-solid\n```\n\n## Quickstart\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-solid';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return (\n    <button onClick={() => store.send({ type: 'inc' })}>\n      Count: {count()}\n    </button>\n  );\n};\n```\n\n## API\n\n<!-- selector subscription semantics from src/index.ts -->\n### `useSelector(store, selector, compare?)`\n\nThe accessor reconciles updates made during component setup before its subscription starts.\n\nCreates a signal that subscribes to a store and returns a selected value.\n\n```tsx\nimport { createStore, useSelector } from '@xstate/store-solid';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst App = () => {\n  const count = useSelector(store, (s) => s.context.count);\n\n  return <div>{count()}</div>;\n};\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Read-only signal of the selected value\n\n`useSelector` works with the store's readable snapshot interface, while store-specific code can still use `store.getSnapshot()` directly.\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Solid-specific docs](https://stately.ai/docs/xstate-store#solid) for more Solid examples.\n\n<!-- File: packages/xstate-store-svelte/README.md (Tokens: ~426 | Category: plugin-manifest) -->\n# @xstate/store-svelte\n\nSvelte adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-svelte\n```\n\n## Quickstart\n\n```svelte\n<script>\nimport { createStore, useSelector } from '@xstate/store-svelte';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n</script>\n\n<button on:click={() => store.send({ type: 'inc' })}>\n  Count: {$count}\n</button>\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nCreates a Svelte readable store that subscribes to an XState store and returns a selected value.\n\n```svelte\n<script>\nimport { createStore, useSelector } from '@xstate/store-svelte';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n// or without selector (returns full snapshot)\nconst snapshot = useSelector(store);\n</script>\n\n<div>{$count}</div>\n```\n\n**Arguments:**\n\n- `store` - Store created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Svelte readable store\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Svelte-specific docs](https://stately.ai/docs/xstate-store#svelte) for more Svelte examples.\n\n<!-- File: packages/xstate-store-vue/README.md (Tokens: ~439 | Category: plugin-manifest) -->\n# @xstate/store-vue\n\nVue adapter for [@xstate/store](https://stately.ai/docs/xstate-store).\n\n## Installation\n\n```bash\nnpm install @xstate/store-vue\n```\n\n## Quickstart\n\n```vue\n<script setup>\nimport { createStore, useSelector } from '@xstate/store-vue';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n</script>\n\n<template>\n  <button @click=\"store.send({ type: 'inc' })\">Count: {{ count }}</button>\n</template>\n```\n\n## API\n\n### `useSelector(store, selector?, compare?)`\n\nA composable that subscribes to a store and returns a selected value as a readonly ref.\n\n```vue\n<script setup>\nimport { createStore, useSelector } from '@xstate/store-vue';\n// ...\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    inc: (ctx) => ({ ...ctx, count: ctx.count + 1 })\n  }\n});\n\nconst count = useSelector(store, (s) => s.context.count);\n// or without selector (returns full snapshot)\nconst snapshot = useSelector(store);\n</script>\n\n<template>\n  <div>{{ count }}</div>\n</template>\n```\n\n**Arguments:**\n\n- `store` - Store or other readable value created with `createStore()`\n- `selector?` - Function to select a value from snapshot\n- `compare?` - Equality function (default: `===`)\n\n**Returns:** Readonly ref of the selected value\n\n---\n\n## Re-exports\n\nAll exports from `@xstate/store` are re-exported, including `createStore`, `createAtom`, and more.\n\nSee the [XState Store docs](https://stately.ai/docs/xstate-store) for the full API, and the [Vue-specific docs](https://stately.ai/docs/xstate-store#vue) for more Vue examples.\n\n<!-- File: packages/xstate-store/README.md (Tokens: ~3825 | Category: plugin-manifest) -->\n# `@xstate/store`\n\nXState Store is a library for **simple event-based state management**. If you want a state management library that allows you to update a store's state via events, `@xstate/store` is a great option. If you need more complex application logic needs, like state machines/statecharts, effects, communicating actors, and more, consider [using XState instead](https://github.com/statelyai/xstate).\n\n<!-- store capabilities from src/index.ts and runtime dependency requirements from package.json -->\n\n- **Extremely simple**: transitions update state via events, just like Redux, Zustand, Pinia, etc.\n- **Small**: no required runtime dependencies\n- **XState compatible**: use it with (or without) XState, or convert to XState machines when you need to handle more complex logic & effects.\n- **Extra type-safe**: great typing out of the box, with strong inference and no awkwardness.\n\n> [!NOTE]\n> This readme is written for [TypeScript](#typescript) users. If you are a JavaScript user, just remove the types.\n\n## Installation\n\n```bash\n# yarn add @xstate/store\n# pnpm add @xstate/store\nnpm install @xstate/store\n```\n\n## Quick start\n\n```ts\nimport { createStore } from '@xstate/store';\n\nexport const donutStore = createStore({\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    addDonut: (context) => ({\n      ...context,\n      donuts: context.donuts + 1\n    }),\n    changeFlavor: (context, event: { flavor: string }) => ({\n      ...context,\n      favoriteFlavor: event.flavor\n    }),\n    eatAllDonuts: (context) => ({\n      ...context,\n      donuts: 0\n    })\n  }\n});\n\ndonutStore.subscribe((snapshot) => {\n  console.log(snapshot.context);\n});\n\n// Equivalent to\n// donutStore.send({ type: 'addDonut' });\ndonutStore.trigger.addDonut();\n// => { donuts: 1, favoriteFlavor: 'chocolate' }\n\n// donutStore.send({\n//   type: 'changeFlavor',\n//   flavor: 'strawberry' // Strongly-typed!\n// });\ndonutStore.trigger.changeFlavor({ flavor: 'strawberry' });\n// => { donuts: 1, favoriteFlavor: 'strawberry' }\n```\n\n## Checking events\n\n<!-- store.can API from packages/xstate-store/src/types.ts -->\n\nUse `store.can` to check whether an event is allowed without updating the store:\n\n```ts\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    increment: (context, event: { by: number }) => {\n      if (context.count + event.by > 10) {\n        return;\n      }\n\n      return {\n        count: context.count + event.by\n      };\n    }\n  }\n});\n\nstore.can.increment({ by: 4 });\n// => true\n```\n\nReturning `undefined` marks the event as not allowed. Returning the same context\nobject is still allowed, and transitions that enqueue effects are allowed.\n\n## Persistence\n\n<!-- persist and flushStorage behavior from src/persist.ts -->\n\nUse the `persist` extension to save state after events are committed. Calling\n`store.can` or the pure `store.transition` method does not schedule writes.\nWrites preserve commit order, including events triggered synchronously by effects\nor subscriptions. A newer eligible event can supersede an older pending write;\n`onDone` runs for writes actually performed. Asynchronous writes execute in event\norder for each store. Call\n`await flushStorage(store)` to write buffered changes and wait for queued writes\nto finish. Synchronous storage adapters continue to write synchronously.\n\nWith throttling, `pick` runs once per write on the latest buffered context.\n`clearStorage(store)` cancels buffered writes and removes saved data after any\nalready queued writes finish; await its result when using asynchronous storage.\nNew events sent after clearing can persist new state. For asynchronous storage,\ncall `await rehydrateStore(store)` to load saved state; initial read failures are\nreported through `onError`.\n\n```ts\nimport { persist, flushStorage } from '@xstate/store/persist';\n\nconst savedDonutStore = donutStore.with(persist({ name: 'donuts' }));\nsavedDonutStore.trigger.addDonut();\nawait flushStorage(savedDonutStore);\n```\n\n### Undo and persistence\n\n<!-- snapshot undo restoration behavior from src/undo.ts -->\n\nSnapshot-based `undoRedo` restores historical state while preserving live\nextension metadata, including persistence hydration. A custom `restore` callback\ncan enqueue events; their updated extension metadata is preserved too. Apply\n`persist` after `undoRedo` when undo and redo themselves should write to storage:\n\n```ts\nimport { undoRedo } from '@xstate/store/undo';\n\nconst undoableDonutStore = donutStore\n  .with(undoRedo({ strategy: 'snapshot' }))\n  .with(persist({ name: 'undoable-donuts' }));\n```\n\n## Atom updates and subscriptions\n\n<!-- writable updater tracking and subscriber errors from src/atom.ts -->\n\nReads inside a writable atom's `set(previous => next)` updater do not create\nreactive dependencies. Use a computed atom getter to track other atoms instead.\nIf a synchronous subscriber throws, other queued subscribers still receive their\nnotifications before the first error is rethrown to the caller. The atom's value\nhas already changed; later updates continue to notify subscribers normally.\n\n## Source atoms\n\n<!-- createSourceAtom snapshot and observed dependency lifecycle from src/atom.ts and src/types.ts -->\n\nUse `createSourceAtom` for a read-only external value. Direct and derived\nsubscribers share one listener; cleanup runs synchronously when the last consumer\nleaves. Plain reads do not start listeners. Resubscribing reconnects and refreshes\nthe snapshot.\n\n```ts\nimport { createAtom, createSourceAtom } from '@xstate/store';\n\nconst media = window.matchMedia('(prefers-color-scheme: dark)');\nconst isDark = createSourceAtom({\n  getSnapshot: () => media.matches,\n  subscribe: (notify) => {\n    media.addEventListener('change', notify);\n    return () => media.removeEventListener('change', notify);\n  }\n});\nconst theme = createAtom(() => (isDark.get() ? 'dark' : 'light'));\nconst subscription = theme.subscribe(console.log);\nsubscription.unsubscribe(); // Removes the media query listener.\n```\n\nSee [source atoms](./docs/source-atoms.md) for snapshot comparison, conditional\ndependencies, and lifecycle timing. Use XState actors for commands, retries, or\nreconnection logic.\n\n## Async atoms\n\n<!-- createAsyncAtom dependency and cancellation behavior from src/atom.ts -->\n\n`createAsyncAtom` loads a value lazily and exposes a `pending`, `done`, or\n`error` state. Atoms read synchronously by its getter remain dependencies after\nthe request succeeds or fails. When a dependency changes, subscribed async atoms\nreload; otherwise, they reload on the next read. Read dependencies before the\nfirst `await` to track them. Errors while delivering a resolved value (including\nsource activation) also become the async atom’s `error` state. If notifying that\nerror state fails, the state remains available through `.get()`.\n\n```ts\nimport { createAtom, createAsyncAtom } from '@xstate/store';\n\nconst userId = createAtom('ada');\nconst user = createAsyncAtom(async ({ signal }) => {\n  const id = userId.get();\n  const response = await fetch(`/users/${id}`, { signal });\n  return response.json();\n});\n\nuser.subscribe((state) => {\n  if (state.status === 'done') {\n    console.log(state.data);\n  }\n});\n\nuserId.set('grace'); // Reloads even after the previous request settled.\n```\n\nRecomputing aborts the previous getter's signal and ignores its stale result.\n\n## Usage with React\n\nImport `useSelector` from `@xstate/store-react`. Select the data you want via `useSelector(…)` and send events using `store.send(eventObject)`:\n\n```tsx\nimport { donutStore } from './donutStore.ts';\nimport { useSelector } from '@xstate/store-react';\n\nfunction DonutCounter() {\n  const donutCount = useSelector(donutStore, (state) => state.context.donuts);\n\n  return (\n    <div>\n      <button onClick={() => donutStore.send({ type: 'addDonut' })}>\n        Add donut ({donutCount})\n      </button>\n    </div>\n  );\n}\n```\n\n## Usage with SolidJS\n\nImport `useSelector` from `@xstate/store-solid`. Select the data you want via `useSelector(…)` and send events using `store.send(eventObject)`:\n\n```tsx\nimport { donutStore } from './donutStore.ts';\nimport { useSelector } from '@xstate/store-solid';\n\nfunction DonutCounter() {\n  const donutCount = useSelector(donutStore, (state) => state.context.donuts);\n\n  return (\n    <div>\n      <button onClick={() => donutStore.send({ type: 'addDonut' })}>\n        Add donut ({donutCount()})\n      </button>\n    </div>\n  );\n}\n```\n\n## Usage with Immer\n\nXState Store works well with immutable update libraries like [Immer](https://github.com/immerjs/immer) or [Mutative](https://github.com/unadlib/mutative). Use `produce(...)` inside your transition functions:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { produce } from 'immer'; // or { create } from 'mutative'\n\nconst donutStore = createStore({\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    addDonut: (context) =>\n      produce(context, (draft) => {\n        draft.donuts++;\n      }),\n    changeFlavor: (context, event: { flavor: string }) =>\n      produce(context, (draft) => {\n        draft.favoriteFlavor = event.flavor;\n      }),\n    eatAllDonuts: (context) =>\n      produce(context, (draft) => {\n        draft.donuts = 0;\n      })\n  }\n});\n```\n\nIf a transition should be unavailable, return `undefined` from the transition\nbefore calling `produce(...)`:\n\n```ts\non: {\n  eatDonut: (context) => {\n    if (context.donuts === 0) {\n      return;\n    }\n\n    return produce(context, (draft) => {\n      draft.donuts--;\n    });\n  };\n}\n```\n\nImmer treats a producer that returns `undefined` the same as a producer that\ndoes not explicitly return anything. If you need `produce(...)` itself to return\n`undefined`, return Immer's `nothing` token from the producer:\n\n```ts\nimport { nothing, produce } from 'immer';\n\non: {\n  eatDonut: (context) =>\n    produce(context, (draft) => {\n      if (draft.donuts === 0) {\n        return nothing;\n      }\n\n      draft.donuts--;\n    });\n}\n```\n\n## TypeScript\n\nXState Store is written in TypeScript and provides full type safety, _without_ you having to specify generic type parameters. The `context` type is inferred from the initial context object, and the event types are inferred from the event object payloads you provide in the transition functions.\n\n```ts\nimport { createStore } from '@xstate/store';\n\nconst donutStore = createStore({\n  // Context inferred as:\n  // {\n  //   donuts: number;\n  //   favoriteFlavor: string;\n  // }\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    // Event inferred as:\n    // {\n    //   type: 'changeFlavor';\n    //   flavor: string;\n    // }\n    changeFlavor: (context, event: { flavor: string }) => {\n      context.favoriteFlavor = event.flavor;\n    }\n  }\n});\n\ndonutStore.getSnapshot().context.favoriteFlavor; // string\ndonutStore.get().context.favoriteFlavor; // same snapshot, readable/tracked read\n\ndonutStore.send({\n  type: 'changeFlavor', // Strongly-typed from transition key\n  flavor: 'strawberry' // Strongly-typed from { flavor: string }\n});\n```\n\nIf you want to provide event or emitted-event types explicitly, you can use `schemas` with any library that implements the [Standard Schema](https://standardschema.dev/) interface. Schemas define the store's runtime-readable contract: the shape of its context, accepted events, and emitted events. Store uses schemas for type inference and metadata by default; it does not validate schema-declared values unless you opt in with `validateSchemas()`.\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    context: z.object({\n      donuts: z.number(),\n      favoriteFlavor: z.string()\n    }),\n    events: {\n      changeFlavor: z.object({\n        flavor: z.string()\n      })\n    },\n    emitted: {\n      flavorChanged: z.object({\n        flavor: z.string()\n      })\n    }\n  },\n  context: {\n    donuts: 0,\n    favoriteFlavor: 'chocolate'\n  },\n  on: {\n    changeFlavor: (context, event, enqueue) => {\n      enqueue.emit.flavorChanged({ flavor: event.flavor });\n      return {\n        ...context,\n        favoriteFlavor: event.flavor\n      };\n    }\n  }\n});\n```\n\nEvent and emitted-event schemas describe payload objects. Use an empty object\nschema for events without payload:\n\n```ts\nschemas: {\n  events: {\n    reset: z.object({})\n  },\n  emitted: {\n    reset: z.object({})\n  }\n}\n```\n\n### Validating schemas\n\nUse the `validateSchemas()` extension when the store should validate its schema\ncontract at runtime:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { validateSchemas } from '@xstate/store/validate';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    context: z.object({\n      count: z.number()\n    }),\n    events: {\n      increment: z.object({\n        by: z.number()\n      })\n    },\n    emitted: {\n      increased: z.object({\n        by: z.number()\n      })\n    }\n  },\n  context: { count: 0 },\n  on: {\n    increment: (context, event, enqueue) => {\n      enqueue.emit.increased({ by: event.by });\n      return { count: context.count + event.by };\n    }\n  }\n}).with(validateSchemas());\n```\n\n`validateSchemas()` validates store macrosteps. It validates the event sent to\nthe store, the final context after the transition completes, and emitted events\nbefore any effects execute. Events queued internally with `enqueue.trigger` are\nprocessed as part of the same macrostep; their payloads are not separately\nvalidated in this version.\n\nInvalid `send(...)`, `trigger.*(...)`, or `transition(...)` calls throw a\n`StoreValidationError`. `store.can.*(...)` always returns a boolean; validation\nerrors make it return `false`.\n\nBy default, unknown events and emitted events throw when the corresponding\nschema map exists. Extension-added event types are treated as known, even when\nthey do not have payload schemas. You can opt out:\n\n```ts\nconst store = createStore({\n  // ...\n}).with(\n  validateSchemas({\n    unknownEvents: 'ignore',\n    unknownEmitted: 'ignore'\n  })\n);\n```\n\nUse `store.getSnapshot()` when you want an explicit snapshot read from the store itself. Use `store.get()` when consuming the store as a `Readable` value in tracked or reactive code.\n\nIf you want to make the `context` type more specific, you can strongly type the `context` outside of `createStore(…)` and pass it in:\n\n```ts\nimport { createStore } from '@xstate/store';\n\ninterface DonutContext {\n  donuts: number;\n  favoriteFlavor: 'chocolate' | 'strawberry' | 'blueberry';\n}\n\nconst donutContext: DonutContext = {\n  donuts: 0,\n  favoriteFlavor: 'chocolate'\n};\n\nconst donutStore = createStore({\n  context: donutContext,\n  on: {\n    // ... (transitions go here)\n  }\n});\n```\n\n## Effects and Side Effects\n\nYou can enqueue effects in state transitions using the `enqueue` argument:\n\n```ts\nimport { createStore } from '@xstate/store';\n\nconst store = createStore({\n  context: { count: 0 },\n  on: {\n    incrementDelayed: (context, event, enqueue) => {\n      enqueue.effect(async () => {\n        await new Promise((resolve) => setTimeout(resolve, 1000));\n        store.send({ type: 'increment' });\n      });\n\n      return context;\n    },\n    increment: (context) => ({\n      ...context,\n      count: context.count + 1\n    })\n  }\n});\n```\n\n## Emitting Events\n\nYou can emit events from transitions by declaring them in `schemas.emitted` and using `enqueue.emit`:\n\n```ts\nimport { createStore } from '@xstate/store';\nimport { z } from 'zod';\n\nconst store = createStore({\n  schemas: {\n    emitted: {\n      increased: z.object({\n        by: z.number()\n      })\n    }\n  },\n  context: { count: 0 },\n  on: {\n    inc: (context, event: { by: number }, enqueue) => {\n      enqueue.emit.increased({ by: event.by });\n\n      return {\n        ...context,\n        count: context.count + event.by\n      };\n    }\n  }\n});\n\n// Listen for emitted events\nstore.on('increased', (event) => {\n  console.log(`Count increased by ${event.by}`);\n});\n```\n\n<!-- File: packages/xstate-svelte/README.md (Tokens: ~324 | Category: plugin-manifest) -->\n# @xstate/svelte\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [Svelte](https://github.com/sveltejs/svelte).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-svelte).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## Quick Start\n\n1. Install `xstate` and `@xstate/svelte`:\n\n```bash\nnpm i xstate @xstate/svelte\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/svelte/dist/xstate-svelte.min.js\"></script>\n```\n\nBy using the global variable `XStateSvelte`\n\n2. Import `useMachine`\n\n```svelte\n<script>\n  import { useMachine } from '@xstate/svelte';\n  import { createMachine } from 'xstate';\n\n  const toggleMachine = createMachine({\n    id: 'toggle',\n    initial: 'inactive',\n    states: {\n      inactive: {\n        on: { TOGGLE: 'active' }\n      },\n      active: {\n        on: { TOGGLE: 'inactive' }\n      }\n    }\n  });\n\n  const { state, send } = useMachine(toggleMachine);\n</script>\n\n<button on:click={() => send('TOGGLE')}>\n  {$state.value === 'inactive'\n    ? 'Click to activate'\n    : 'Active! Click to deactivate'}\n</button>\n```\n\n<!-- File: packages/xstate-vue/README.md (Tokens: ~404 | Category: plugin-manifest) -->\n# @xstate/vue\n\nThis package contains utilities for using [XState](https://github.com/statelyai/xstate) with [Vue](https://github.com/vuejs/vue).\n\n- [Read the full documentation in the XState docs](https://stately.ai/docs/xstate-vue).\n- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md).\n\n## :warning: Vue 2 Notice:\n\nIf you're using Vue 2.x, please see [the Vue recipe](https://xstate.js.org/docs/recipes/vue.html) instead, or use the [`xstate-vue2` package](https://github.com/ChrisShank/xstate-vue2) if you want to use the Vue Composition API.\n\n## Quick start\n\n1. Install `xstate` and `@xstate/vue`:\n\n```bash\nnpm i xstate @xstate/vue\n```\n\n**Via CDN**\n\n```html\n<script src=\"https://unpkg.com/@xstate/vue/dist/xstate-vue.min.js\"></script>\n```\n\nBy using the global variable `XStateVue`\n\n2. Import the `useMachine` composition function:\n\n```vue\n<script setup>\nimport { useMachine } from '@xstate/vue';\nimport { createMachine } from 'xstate';\n\nconst toggleMachine = createMachine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: {\n      on: { TOGGLE: 'active' }\n    },\n    active: {\n      on: { TOGGLE: 'inactive' }\n    }\n  }\n});\n\nconst { snapshot, send } = useMachine(toggleMachine);\n</script>\n\n<template>\n  <button @click=\"send({ type: 'TOGGLE' })\">\n    {{\n      snapshot.value === 'inactive'\n        ? 'Click to activate'\n        : 'Active! Click to deactivate'\n    }}\n  </button>\n</template>\n```\n</yakaai_skills>"}