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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions .changeset/drop-component-effects-alias.md

This file was deleted.

2 changes: 0 additions & 2 deletions .changeset/fresh-chicken-raise.md

This file was deleted.

45 changes: 0 additions & 45 deletions .changeset/rename-adapters-to-prefix.md

This file was deleted.

2 changes: 0 additions & 2 deletions .changeset/thick-hands-rush.md

This file was deleted.

9 changes: 9 additions & 0 deletions benchmark/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# benchmark

## 0.1.3

### Patch Changes

- Updated dependencies [[`521440e`](https://github.com/dunky-dev/state-machine/commit/521440e452c9686ad871e00a15a5af3f771a6228), [`58f9d7e`](https://github.com/dunky-dev/state-machine/commit/58f9d7e2c2dc8e432650fcfdb9ebf91bda50bb5f)]:
- @dunky.dev/react-state-machine@0.3.0
- @dunky.dev/state-machine@0.3.0

## 0.1.2

### Patch Changes
Expand All @@ -25,6 +33,7 @@
The suite measures `@dunky.dev/state-machine`'s hot paths in isolation and compares the runnable parts against XState and Zag. It runs in one Node process with `--expose-gc` (Node 24, Apple Silicon for the published figures); each section is also exported as a `run*()` function for isolation.

Fairness rules that define what the numbers mean:

- **Synchronous-only comparison in ops/sec loops.** Dunky and XState `send` synchronously and are measured everywhere; Zag's `send` is microtask-batched (async), so it appears only where it runs synchronously — construction, memory (headless `VanillaMachine`), and React rendering (`@zag-js/react`). A tight `tinybench` loop can't fairly time an async engine, so those cells are marked `n/a ᵃ`. Missing first-class primitives (e.g. XState has no lazy/memoized `computed`) are marked `n/a ᶠ`.
- **Shared module-level config across instances.** All engines reuse one `const` config — matching how a real app declares a machine once and instantiates it many times — so construction/memory loops time machine construction, not config-literal allocation.
- **Two XState variants** in fine-grain tables: `xstate` (subscribe + hand-written value diff, matching Dunky's built-in dedup) and `xstate-raw` (stock subscribe, fires on every snapshot).
Expand Down
8 changes: 8 additions & 0 deletions benchmark/demo/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# benchmark-demo

## 0.1.4

### Patch Changes

- Updated dependencies []:
- @dunky.dev/state-machine@0.3.0

## 0.1.3

### Patch Changes
Expand Down Expand Up @@ -52,6 +59,7 @@
The demo makes the ops/sec tables **visible**: four panels (Dunky, XState, Zag, and a Plain JS control), each a grid of real per-cell state machines fed one ramping change stream under an equal per-frame budget. Run it with `pnpm benchmark:demo`; it's idle until you press **Start**.

It is deliberately **engine-bound, not DOM-bound** — a naive "render a grid" demo would measure React's render cost (which dominates and ties every engine), so the design isolates engine cost:

- **Every cell is a real machine** doing the work the suite measures per update: a guarded transition (guard fallthrough) that writes context feeding a computed/derived value, then reads it back.
- **Paint is off the hot path.** Each panel is a `<canvas>` heatmap on a throttled ~10fps tick — one cheap fill per cell, no per-cell React — so paint cost is tiny and identical across panels; what differs is the engine.
- **Equal time budget.** Each frame, every panel gets the same few ms to drain its queue; a cheaper-per-update engine clears more and its backlog stays near zero, a costlier one falls behind.
Expand Down
2 changes: 1 addition & 1 deletion benchmark/demo/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "benchmark-demo",
"version": "0.1.3",
"version": "0.1.4",
"private": true,
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion benchmark/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "benchmark",
"version": "0.1.2",
"version": "0.1.3",
"private": true,
"type": "module",
"scripts": {
Expand Down
12 changes: 7 additions & 5 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# @dunky.dev/state-machine

## 0.3.0

## 0.2.0

## 0.1.0
Expand All @@ -19,15 +21,15 @@
**⚡️ Blazing fast.** Design systems and complex UIs can run hundreds of live machines at once. Dunky is tuned for exactly that load. [See the benchmark →](https://github.com/dunky-dev/state-machine/tree/main/benchmark#readme)

```ts
import { setup } from '@dunky.dev/state-machine'
import { setup } from "@dunky.dev/state-machine";

const toggle = setup({
initial: 'off',
initial: "off",
states: {
off: { on: { TOGGLE: 'on' } },
on: { on: { TOGGLE: 'off' } },
off: { on: { TOGGLE: "on" } },
on: { on: { TOGGLE: "off" } },
},
})
});
```

This is our first public release (`0.1.0`). The engine is stable and tested; the target bridges are early and evolving. Come kick the tires, watch the live benchmark, and tell us where it breaks.
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dunky.dev/state-machine",
"version": "0.2.0",
"version": "0.3.0",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
77 changes: 72 additions & 5 deletions packages/native/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,77 @@
# @dunky.dev/native-state-machine

## 0.3.0

### Minor Changes

- [#49](https://github.com/dunky-dev/state-machine/pull/49) [`521440e`](https://github.com/dunky-dev/state-machine/commit/521440e452c9686ad871e00a15a5af3f771a6228) Thanks [@ivanbanov](https://github.com/ivanbanov)! - **Breaking:** remove the `ComponentEffects<M, P>` type alias. It was a pure
alias for `ComponentEffect<M, P>[]` — a second public name for the same
concept, with no semantics of its own (it can't enforce the static-list rule
it documented). One concept, one export.

Migration is mechanical:

```diff
-import { type ComponentEffects } from '@dunky.dev/react-state-machine'
+import { type ComponentEffect } from '@dunky.dev/react-state-machine'

-const tooltipEffects: ComponentEffects<TooltipMachine, TooltipProps> = [trackEscape]
+const tooltipEffects: ComponentEffect<TooltipMachine, TooltipProps>[] = [trackEscape]
```

- [#43](https://github.com/dunky-dev/state-machine/pull/43) [`58f9d7e`](https://github.com/dunky-dev/state-machine/commit/58f9d7e2c2dc8e432650fcfdb9ebf91bda50bb5f) Thanks [@ivanbanov](https://github.com/ivanbanov)! - Rename the framework adapters back to a `*-state-machine` substrate-prefix convention.

We tried the `state-machine-*` suffix convention (see the previous rename) to
keep the whole `@dunky.dev/*` scope alphabetically consistent. In practice it
proved ergonomically wrong once you picture it scaled to more than one
package family:

```
suffix (tried): prefix (this change):
button-react react-button
dropdown-react react-dropdown
state-machine-react react-state-machine
```

Picture browsing npm under `@dunky.dev/react-*` — every React package for
this scope, together, in one look. That's the whole point of an org scope:
someone building a React app should be able to find everything React-related
under `@dunky.dev/react-*`. The suffix form breaks that; `button-react`,
`dropdown-react`, and `state-machine-react` don't show up together anywhere,
because "react" isn't what they're named _by_.

It reads backwards at the import site too —
`import { useMachine } from '@dunky.dev/state-machine-react'` names the
library before the framework, when every other adapter a React codebase
imports (`react-redux`, `react-query`, `react-hook-form`) names the framework
first.

- `@dunky.dev/state-machine-react` → `@dunky.dev/react-state-machine`
- `@dunky.dev/state-machine-native` → `@dunky.dev/native-state-machine`
- `@dunky.dev/state-machine-opentui` → `@dunky.dev/opentui-state-machine`

The previous suffix-named packages are deprecated on npm in favor of these.

```diff
- import { useMachine } from '@dunky.dev/state-machine-react'
+ import { useMachine } from '@dunky.dev/react-state-machine'
```

`@dunky.dev/state-machine` (core), `@dunky.dev/state-machine-utils`, and `@dunky.dev/state-machine-bindings` are unchanged — they aren't tied to one substrate, so the prefix convention doesn't apply to them.

### Patch Changes

- Updated dependencies [[`521440e`](https://github.com/dunky-dev/state-machine/commit/521440e452c9686ad871e00a15a5af3f771a6228), [`58f9d7e`](https://github.com/dunky-dev/state-machine/commit/58f9d7e2c2dc8e432650fcfdb9ebf91bda50bb5f)]:
- @dunky.dev/react-state-machine@0.3.0
- @dunky.dev/state-machine@0.3.0
- @dunky.dev/state-machine-utils@0.3.0

## 0.2.0

### Minor Changes

- [`d0e20a5`](https://github.com/dunky-dev/state-machine/commit/d0e20a5ac3ca953c923e05819034e420394af83b) Thanks [@ivanbanov](https://github.com/ivanbanov)! - Rename the framework adapters to the `state-machine-*` suffix convention so the whole scope is consistent (`state-machine`, `state-machine-react`, `state-machine-native`, `state-machine-opentui`, `state-machine-utils`, `state-machine-bindings`).

- `@dunky.dev/react-state-machine` → `@dunky.dev/state-machine-react`
- `@dunky.dev/native-state-machine` → `@dunky.dev/state-machine-native`
- `@dunky.dev/opentui-state-machine` → `@dunky.dev/state-machine-opentui`
Expand Down Expand Up @@ -35,15 +102,15 @@
**⚡️ Blazing fast.** Design systems and complex UIs can run hundreds of live machines at once. Dunky is tuned for exactly that load. [See the benchmark →](https://github.com/dunky-dev/state-machine/tree/main/benchmark#readme)

```ts
import { setup } from '@dunky.dev/state-machine'
import { setup } from "@dunky.dev/state-machine";

const toggle = setup({
initial: 'off',
initial: "off",
states: {
off: { on: { TOGGLE: 'on' } },
on: { on: { TOGGLE: 'off' } },
off: { on: { TOGGLE: "on" } },
on: { on: { TOGGLE: "off" } },
},
})
});
```

This is our first public release (`0.1.0`). The engine is stable and tested; the target bridges are early and evolving. Come kick the tires, watch the live benchmark, and tell us where it breaks.
Expand Down
2 changes: 1 addition & 1 deletion packages/native/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dunky.dev/native-state-machine",
"version": "0.2.0",
"version": "0.3.0",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
60 changes: 55 additions & 5 deletions packages/opentui/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,60 @@
# @dunky.dev/opentui-state-machine

## 0.3.0

### Minor Changes

- [#43](https://github.com/dunky-dev/state-machine/pull/43) [`58f9d7e`](https://github.com/dunky-dev/state-machine/commit/58f9d7e2c2dc8e432650fcfdb9ebf91bda50bb5f) Thanks [@ivanbanov](https://github.com/ivanbanov)! - Rename the framework adapters back to a `*-state-machine` substrate-prefix convention.

We tried the `state-machine-*` suffix convention (see the previous rename) to
keep the whole `@dunky.dev/*` scope alphabetically consistent. In practice it
proved ergonomically wrong once you picture it scaled to more than one
package family:

```
suffix (tried): prefix (this change):
button-react react-button
dropdown-react react-dropdown
state-machine-react react-state-machine
```

Picture browsing npm under `@dunky.dev/react-*` — every React package for
this scope, together, in one look. That's the whole point of an org scope:
someone building a React app should be able to find everything React-related
under `@dunky.dev/react-*`. The suffix form breaks that; `button-react`,
`dropdown-react`, and `state-machine-react` don't show up together anywhere,
because "react" isn't what they're named _by_.

It reads backwards at the import site too —
`import { useMachine } from '@dunky.dev/state-machine-react'` names the
library before the framework, when every other adapter a React codebase
imports (`react-redux`, `react-query`, `react-hook-form`) names the framework
first.

- `@dunky.dev/state-machine-react` → `@dunky.dev/react-state-machine`
- `@dunky.dev/state-machine-native` → `@dunky.dev/native-state-machine`
- `@dunky.dev/state-machine-opentui` → `@dunky.dev/opentui-state-machine`

The previous suffix-named packages are deprecated on npm in favor of these.

```diff
- import { useMachine } from '@dunky.dev/state-machine-react'
+ import { useMachine } from '@dunky.dev/react-state-machine'
```

`@dunky.dev/state-machine` (core), `@dunky.dev/state-machine-utils`, and `@dunky.dev/state-machine-bindings` are unchanged — they aren't tied to one substrate, so the prefix convention doesn't apply to them.

### Patch Changes

- Updated dependencies []:
- @dunky.dev/state-machine-utils@0.3.0

## 0.2.0

### Minor Changes

- [`d0e20a5`](https://github.com/dunky-dev/state-machine/commit/d0e20a5ac3ca953c923e05819034e420394af83b) Thanks [@ivanbanov](https://github.com/ivanbanov)! - Rename the framework adapters to the `state-machine-*` suffix convention so the whole scope is consistent (`state-machine`, `state-machine-react`, `state-machine-native`, `state-machine-opentui`, `state-machine-utils`, `state-machine-bindings`).

- `@dunky.dev/react-state-machine` → `@dunky.dev/state-machine-react`
- `@dunky.dev/native-state-machine` → `@dunky.dev/state-machine-native`
- `@dunky.dev/opentui-state-machine` → `@dunky.dev/state-machine-opentui`
Expand Down Expand Up @@ -33,15 +83,15 @@
**⚡️ Blazing fast.** Design systems and complex UIs can run hundreds of live machines at once. Dunky is tuned for exactly that load. [See the benchmark →](https://github.com/dunky-dev/state-machine/tree/main/benchmark#readme)

```ts
import { setup } from '@dunky.dev/state-machine'
import { setup } from "@dunky.dev/state-machine";

const toggle = setup({
initial: 'off',
initial: "off",
states: {
off: { on: { TOGGLE: 'on' } },
on: { on: { TOGGLE: 'off' } },
off: { on: { TOGGLE: "on" } },
on: { on: { TOGGLE: "off" } },
},
})
});
```

This is our first public release (`0.1.0`). The engine is stable and tested; the target bridges are early and evolving. Come kick the tires, watch the live benchmark, and tell us where it breaks.
Expand Down
2 changes: 1 addition & 1 deletion packages/opentui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dunky.dev/opentui-state-machine",
"version": "0.2.0",
"version": "0.3.0",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
Loading