Skip to content

Commit 2adc8a3

Browse files
committed
refactor: solid logic
1 parent 8ace3c9 commit 2adc8a3

File tree

4 files changed

+901
-35
lines changed

4 files changed

+901
-35
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@zag-js/solid": patch
3+
---
4+
5+
Fix issue where transition actions received stale event data

packages/frameworks/solid/src/machine.ts

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type {
1212
} from "@zag-js/core"
1313
import { createScope, INIT_STATE, MachineStatus } from "@zag-js/core"
1414
import { compact, isFunction, isString, toArray, warn, ensure } from "@zag-js/utils"
15-
import { type Accessor, createMemo, mergeProps, onCleanup, onMount } from "solid-js"
15+
import { type Accessor, createMemo, mergeProps, onCleanup, onMount, untrack } from "solid-js"
1616
import { createBindable } from "./bindable"
1717
import { createRefs } from "./refs"
1818
import { createTrack } from "./track"
@@ -239,39 +239,41 @@ export function useMachine<T extends MachineSchema>(
239239
})
240240

241241
const send = (event: any) => {
242-
if (status !== MachineStatus.Started) return
243-
244-
previousEventRef.current = eventRef.current
245-
eventRef.current = event
246-
247-
let currentState = state.get()
248-
249-
const transitions =
250-
// @ts-ignore
251-
machine.states[currentState].on?.[event.type] ??
252-
// @ts-ignore
253-
machine.on?.[event.type]
254-
255-
const transition = choose(transitions)
256-
if (!transition) return
257-
258-
// save current transition
259-
transitionRef.current = transition
260-
const target = transition.target ?? currentState
261-
262-
debug("transition", event.type, transition.target || currentState, `(${transition.actions})`)
263-
264-
const changed = target !== currentState
265-
if (changed) {
266-
// state change is high priority
267-
state.set(target)
268-
} else if (transition.reenter && !changed) {
269-
// reenter will re-invoke the current state
270-
state.invoke(currentState, currentState)
271-
} else {
272-
// call transition actions
273-
action(transition.actions)
274-
}
242+
queueMicrotask(() => {
243+
if (status !== MachineStatus.Started) return
244+
245+
previousEventRef.current = eventRef.current
246+
eventRef.current = event
247+
248+
let currentState = untrack(() => state.get())
249+
250+
const transitions =
251+
// @ts-ignore
252+
machine.states[currentState].on?.[event.type] ??
253+
// @ts-ignore
254+
machine.on?.[event.type]
255+
256+
const transition = choose(transitions)
257+
if (!transition) return
258+
259+
// save current transition
260+
transitionRef.current = transition
261+
const target = transition.target ?? currentState
262+
263+
debug("transition", event.type, transition.target || currentState, `(${transition.actions})`)
264+
265+
const changed = target !== currentState
266+
if (changed) {
267+
// state change is high priority
268+
state.set(target)
269+
} else if (transition.reenter && !changed) {
270+
// reenter will re-invoke the current state
271+
state.invoke(currentState, currentState)
272+
} else {
273+
// call transition actions
274+
action(transition.actions)
275+
}
276+
})
275277
}
276278

277279
machine.watch?.(getParams())

0 commit comments

Comments
 (0)