You're Invited: Meet the Socket team at BSidesSF and RSAC - April 27 - May 1.RSVP
Socket
Sign inDemoInstall
Socket

@zag-js/core

Package Overview
Dependencies
Maintainers
0
Versions
937
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zag-js/core - npm Package Compare versions

Comparing version

to
0.0.0-v1-beta-20250220125322

624

dist/index.d.ts

@@ -1,425 +0,239 @@

export { Ref, proxy, ref, snapshot, subscribe } from '@zag-js/store';
interface Props {
[key: string]: any;
}
type TupleTypes<T extends any[]> = T[number];
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
declare function mergeProps<T extends Props>(...args: T[]): UnionToIntersection<TupleTypes<T[]>>;
declare function deepMerge<T extends Record<string, any>>(source: T, ...objects: T[]): T;
type NoInfer<T> = [T][T extends any ? 0 : never];
declare function memo<TDeps extends any[], TDepArgs, TResult>(getDeps: (depArgs: TDepArgs) => [...TDeps], fn: (...args: NoInfer<[...TDeps]>) => TResult, opts?: {
onChange?: (result: TResult) => void;
}): (depArgs: TDepArgs) => TResult;
type Dict<T = any> = Record<string, T>;
type MaybeArray<T> = T | T[];
type VoidFunction = () => void;
type IfEquals<X, Y, A, B> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? A : B;
type WritableKey<T> = {
[P in keyof T]: IfEquals<{
[Q in P]: T[P];
}, {
-readonly [Q in P]: T[P];
}, P, never>;
}[keyof T];
type Writable<T> = Pick<T, WritableKey<T>>;
type Computed<T> = Omit<T, WritableKey<T>>;
declare namespace StateMachine {
type Context<V, C> = V & Readonly<C>;
type TComputedContext<T> = {
[K in keyof Computed<T>]: (ctx: T) => T[K];
};
type UserContext<TContext> = Partial<Writable<TContext>>;
type ContextListener<TContext extends Dict> = (context: TContext) => void;
type EventObject = {
type: string;
};
type Event<TEvent extends EventObject = EventObject> = TEvent["type"] | TEvent;
interface AnyEventObject extends EventObject {
type Dict = Record<string, any>;
interface ComputedParams<T extends Dict> {
context: BindableContext<T>;
event: EventType<T["event"]>;
prop: PropFn<T>;
refs: BindableRefs<T>;
scope: Scope;
computed: ComputedFn<T>;
}
interface ContextParams<T extends Dict> {
prop: PropFn<T>;
bindable: BindableFn;
scope: Scope;
getContext: () => BindableContext<T>;
getComputed: () => ComputedFn<T>;
flush: (fn: VoidFunction) => void;
}
interface PropFn<T extends Dict> {
<K extends keyof T["props"]>(key: K): T["props"][K];
}
interface ComputedFn<T extends Dict> {
<K extends keyof T["computed"]>(key: K): T["computed"][K];
}
type AnyFunction = () => string | number | boolean | null | undefined;
type TrackFn = (deps: AnyFunction[], fn: VoidFunction) => void;
interface BindableParams<T> {
defaultValue?: T | undefined;
value?: T | undefined;
hash?: (a: T) => string;
isEqual?: (a: T, b: T | undefined) => boolean;
onChange?: (value: T, prev: T | undefined) => void;
debug?: string;
sync?: boolean;
}
type ValueOrFn<T> = T | ((prev: T) => T);
interface Bindable<T> {
initial: T | undefined;
ref: any;
get: () => T;
set(value: ValueOrFn<T>): void;
invoke(nextValue: T, prevValue: T): void;
hash(value: T): string;
}
interface BindableRefs<T extends Dict> {
set<K extends keyof T["refs"]>(key: K, value: T["refs"][K]): void;
get<K extends keyof T["refs"]>(key: K): T["refs"][K];
}
interface BindableContext<T extends Dict> {
set<K extends keyof T["context"]>(key: K, value: ValueOrFn<T["context"][K]>): void;
get<K extends keyof T["context"]>(key: K): T["context"][K];
initial<K extends keyof T["context"]>(key: K): T["context"][K];
hash<K extends keyof T["context"]>(key: K): string;
}
interface BindableFn {
<K>(params: () => BindableParams<K>): Bindable<K>;
}
interface Scope {
id?: string | undefined;
ids?: Record<string, any> | undefined;
getRootNode: () => ShadowRoot | Document | Node;
getById: <T extends Element = HTMLElement>(id: string) => T | null;
getActiveElement: () => HTMLElement | null;
isActiveElement: (elem: HTMLElement | null) => boolean;
getDoc: () => typeof document;
getWin: () => typeof window;
}
type EventType<T = any> = T & {
previousEvent?: T & {
[key: string]: any;
}
type Send<TEvent extends EventObject = AnyEventObject> = (event: Event<TEvent>) => void;
type EventListener<TEvent extends EventObject = AnyEventObject> = (event: TEvent) => void;
type ExtractEvent<TEvent extends EventObject, K> = K extends TEvent["type"] ? Extract<TEvent, {
type: K;
}> : EventObject;
type Expression<TContext extends Dict, TEvent extends EventObject, TReturn> = (context: TContext, event: TEvent) => TReturn;
type Meta<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
state: State<TContext, TState>;
guards: Dict;
send: Send<TEvent>;
self: Self<TContext, TState, TEvent>;
initialContext: TContext;
initialState: string;
getState: () => State<TContext, TState, TEvent>;
getAction: (key: string) => ExpressionWithMeta<TContext, TState, TEvent, void>;
getGuard: (key: string) => GuardExpression<TContext, TState, TEvent>;
};
type ExpressionWithMeta<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject, TReturn> = (context: TContext, event: TEvent, meta: Meta<TContext, TState, TEvent>) => TReturn;
type Action<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = string | ExpressionWithMeta<TContext, TState, TEvent, void>;
type Actions<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = ChooseHelper<TContext, TState, TEvent> | MaybeArray<Action<TContext, TState, TEvent>>;
type PureActions<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = MaybeArray<Action<TContext, TState, TEvent>>;
type ActionMap<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
[action: string]: ExpressionWithMeta<TContext, TState, TEvent, void>;
src?: string;
[key: string]: any;
};
type EventObject = EventType<{
type: string;
}>;
interface Params<T extends Dict> {
prop: PropFn<T>;
action: (action: T["action"][]) => void;
context: BindableContext<T>;
refs: BindableRefs<T>;
track: TrackFn;
flush: (fn: VoidFunction) => void;
event: EventType<T["event"]> & {
current: () => EventType<T["event"]>;
previous: () => EventType<T["event"]>;
};
type Activity<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = string | ExpressionWithMeta<TContext, TState, TEvent, VoidFunction | void | undefined>;
type Activities<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = MaybeArray<Activity<TContext, TState, TEvent>>;
type ActivityMap<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
[activity: string]: ExpressionWithMeta<TContext, TState, TEvent, VoidFunction | void | undefined>;
send: (event: EventType<T["event"]>) => void;
computed: ComputedFn<T>;
scope: Scope;
state: Bindable<T["state"]> & {
matches: (...values: T["state"][]) => boolean;
hasTag: (tag: T["tag"]) => boolean;
};
type TransitionDefinition<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
target?: TState["value"];
actions?: Actions<TContext, TState, TEvent>;
guard?: Guard<TContext, TState, TEvent>;
internal?: boolean;
choose: ChooseFn<T>;
guard: (key: T["guard"] | GuardFn<T>) => boolean | undefined;
}
type GuardFn<T extends Dict> = (params: Params<T>) => boolean;
interface Transition<T extends Dict> {
target?: T["state"];
actions?: T["action"][];
guard?: T["guard"] | GuardFn<T>;
}
type MaybeArray<T> = T | T[];
type ChooseFn<T extends Dict> = (transitions: MaybeArray<Omit<Transition<T>, "target">>) => Transition<T> | undefined;
interface PropsParams<T extends Dict> {
props: Partial<T["props"]>;
scope: Scope;
}
interface RefsParams<T extends Dict> {
prop: PropFn<T>;
context: BindableContext<T>;
}
type ActionsOrFn<T extends Dict> = T["action"][] | ((params: Params<T>) => T["action"][] | undefined);
type EffectsOrFn<T extends Dict> = T["effect"][] | ((params: Params<T>) => T["effect"][] | undefined);
interface MachineConfig<T extends Dict> {
debug?: boolean;
props?: (params: PropsParams<T>) => T["props"];
context?: (params: ContextParams<T>) => {
[K in keyof T["context"]]: Bindable<T["context"][K]>;
};
type DelayExpression<TContext extends Dict, TEvent extends EventObject> = Expression<TContext, TEvent, number>;
type Delay<TContext extends Dict, TEvent extends EventObject> = string | number | DelayExpression<TContext, TEvent>;
type DelayMap<TContext extends Dict, TEvent extends EventObject> = {
[delay: string]: number | DelayExpression<TContext, TEvent>;
computed?: {
[K in keyof T["computed"]]: (params: ComputedParams<T>) => T["computed"][K];
};
type DelayedTransition<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = TransitionDefinition<TContext, TState, TEvent> & {
/**
* The time to delay the event, in milliseconds.
*/
delay?: Delay<TContext, TEvent>;
initialState: (params: {
prop: PropFn<T>;
}) => T["state"];
entry?: ActionsOrFn<T>;
exit?: ActionsOrFn<T>;
effects?: EffectsOrFn<T>;
refs?: (params: RefsParams<T>) => T["refs"];
watch?: (params: Params<T>) => void;
on?: {
[E in T["event"]["type"]]?: Transition<T> | Array<Transition<T>>;
};
type DelayedTransitions<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = Record<string | number, TState["value"] | MaybeArray<TransitionDefinition<TContext, TState, TEvent>>> | Array<DelayedTransition<TContext, TState, TEvent>>;
/**
* a transition can be a string (e.g "off") or a full definition object
* { target: "off", actions: [...], guard: "isEmpty" }
*/
type Transition<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = TState["value"] | TransitionDefinition<TContext, TState, TEvent>;
/**
* Transition can be a string (representing the `target`), an object or an array of possible
* transitions with `guard` to determine the selected transition
*/
type Transitions<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = Transition<TContext, TState, TEvent> | Array<TransitionDefinition<TContext, TState, TEvent>>;
type TransitionDefinitionMap<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
[K in TEvent["type"]]?: TState["value"] | MaybeArray<TransitionDefinition<TContext, TState, ExtractEvent<TEvent, K>>>;
states: {
[K in T["state"]]: {
tags?: T["tag"][];
entry?: ActionsOrFn<T>;
exit?: ActionsOrFn<T>;
effects?: EffectsOrFn<T>;
on?: {
[E in T["event"]["type"]]?: Transition<T> | Array<Transition<T>>;
};
};
};
interface StateNode<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> {
/**
* The type of this state node.
*/
type?: "final";
/**
* The tags for the state node.
*/
tags?: MaybeArray<TState["tags"] extends string ? TState["tags"] : string>;
/**
* The activities to be started upon entering the state node,
* and stopped upon exiting the state node.
*/
activities?: Activities<TContext, TState, TEvent>;
/**
* The mapping of event types to their potential transition(s).
*/
on?: TransitionDefinitionMap<TContext, TState, TEvent>;
/**
* The action(s) to be executed upon entering the state node.
*/
entry?: Actions<TContext, TState, TEvent>;
/**
* The action(s) to be executed upon exiting the state node.
*/
exit?: Actions<TContext, TState, TEvent>;
/**
* The meta data associated with this state node.
*/
meta?: string | Dict;
/**
* The mapping (or array) of delays (in `ms`) to their potential transition(s) to run after
* the specified delay. Uses `setTimeout` under the hood.
*/
after?: DelayedTransitions<TContext, TState, TEvent>;
/**
* The mapping (or array) of intervals (in `ms`) to their potential actions(s) to run at interval.
* Uses `setInterval` under the hood.
*/
every?: Record<string | number, Actions<TContext, TState, TEvent>> | Array<{
delay?: number | string | Expression<TContext, TEvent, number>;
actions: Actions<TContext, TState, TEvent>;
guard?: Guard<TContext, TState, TEvent>;
}>;
}
type GuardMeta<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
state: Pick<State<TContext, TState, TEvent>, "matches">;
};
type GuardExpression<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject, TReturn = boolean> = (context: TContext, event: TEvent, guardMeta: GuardMeta<TContext, TState, TEvent>) => TReturn;
type GuardHelper<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
predicate: (guards: Dict) => GuardExpression<TContext, TState, TEvent>;
};
type ChooseHelper<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
predicate: (guards: Dict) => GuardExpression<TContext, TState, TEvent, PureActions<TContext, TState, TEvent> | undefined>;
};
type Guard<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = string | GuardExpression<TContext, TState, TEvent> | GuardHelper<TContext, TState, TEvent>;
type GuardMap<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
[guard: string]: GuardExpression<TContext, TState, TEvent>;
};
type StateSchema = {
value: string;
tags?: string;
};
type StateInitObject<TContext, TState extends StateSchema> = {
context: TContext;
value: TState["value"] | null;
tags?: TState["tags"][];
};
type StateInit<TContext, TState extends StateSchema> = StateInitObject<TContext, TState>;
type StateListener<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject = EventObject> = (state: State<TContext, TState, TEvent>) => void;
interface StateInfo<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> {
reenter: boolean;
changed: boolean;
transition: TransitionDefinition<TContext, TState, TEvent> | undefined;
stateNode: StateNode<TContext, TState, TEvent> | undefined;
target: TState["value"];
}
interface MachineConfig<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> {
/**
* Function called synchronously after the machine has been instantiated,
* before it is started.
*/
created?: Actions<TContext, TState, TEvent>;
/**
* The actions to run when the machine has started. This is usually
* called in the `beforeMount`, `onMount` or `useLayoutEffect` lifecycle methods.
*/
entry?: Actions<TContext, TState, TEvent>;
/**
* The actions to run when the machine has stopped. This is usually
* called in the `onUnmount` or `useLayoutEffect` cleanup lifecycle methods.
*/
exit?: Actions<TContext, TState, TEvent>;
/**
* The root level activities to run when the machine is started
*/
activities?: Activities<TContext, TState, TEvent>;
/**
* The unique identifier for the invoked machine.
*/
id?: string;
/**
* The extended state used to store `data` for your machine
*/
context?: Writable<TContext>;
/**
* A generic way to react to context value changes
*/
watch?: {
[K in keyof TContext]?: Actions<TContext, TState, TEvent>;
implementations?: {
guards?: {
[K in T["guard"]]: (params: Params<T>) => boolean;
};
/**
* The computed properties based on the state
*/
computed?: Partial<TComputedContext<TContext>>;
/**
* The initial state to start with
*/
initial?: TState["value"];
/**
* The mapping of state node keys to their state node configurations (recursive).
*/
states?: Partial<Record<TState["value"], StateNode<TContext, TState, TEvent>>>;
/**
* Mapping events to transitions
*/
on?: TransitionDefinitionMap<TContext, TState, TEvent>;
}
interface State<TContext extends Dict, TState extends StateSchema = StateSchema, TEvent extends EventObject = AnyEventObject> {
value: TState["value"] | null;
previousValue: TState["value"] | null;
event: TEvent;
previousEvent: TEvent;
context: TContext;
done: boolean;
can(event: string): boolean;
matches(...value: TState["value"][]): boolean;
hasTag(value: TState["tags"]): boolean;
nextEvents: string[];
changed: boolean;
tags: TState["tags"][];
}
interface MachineOptions<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> {
debug?: boolean;
guards?: GuardMap<TContext, TState, TEvent>;
actions?: ActionMap<TContext, TState, TEvent>;
delays?: DelayMap<TContext, TEvent>;
activities?: ActivityMap<TContext, TState, TEvent>;
sync?: boolean;
compareFns?: {
[K in keyof TContext]?: CompareFn<TContext[K]>;
actions?: {
[K in T["action"]]: (params: Params<T>) => void;
};
}
type HookOptions<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
actions?: ActionMap<TContext, TState, TEvent>;
state?: StateInit<TContext, TState>;
context?: UserContext<TContext>;
effects?: {
[K in T["effect"]]: (params: Params<T>) => void | VoidFunction;
};
};
type Self<TContext extends Dict, TState extends StateSchema, TEvent extends EventObject> = {
id: string;
send: (event: Event<TEvent>) => void;
sendParent: (evt: AnyEventObject) => void;
sendChild: (evt: Event<TEvent>, to: string | ((ctx: TContext) => string)) => void;
stop: VoidFunction;
stopChild: (id: string) => void;
stopActivity: (id: string) => void;
spawn<T>(src: T | (() => T), id?: string): T;
state: State<TContext, TState, TEvent>;
initialContext: TContext;
initialState: string;
};
}
declare enum MachineStatus {
NotStarted = "Not Started",
Running = "Running",
Stopped = "Stopped"
interface BaseProps {
id?: string | undefined;
ids?: Record<string, any> | undefined;
getRootNode?: (() => ShadowRoot | Document | Node) | undefined;
[key: string]: any;
}
declare enum MachineType {
Machine = "machine",
Actor = "machine.actor"
interface BaseSchema {
props?: BaseProps;
context?: Record<string, any>;
refs?: Record<string, any>;
computed?: Record<string, any>;
state?: string;
tag?: string;
guard?: string;
action?: string;
effect?: string;
event?: {
type: string;
} & Dict;
}
type CompareFn<T = any> = (prev: T, next: T) => boolean;
type State<T extends BaseSchema> = Bindable<T["state"]> & {
hasTag: (tag: T["tag"]) => boolean;
matches: (...values: T["state"][]) => boolean;
};
type Service<T extends BaseSchema> = {
state: State<T> & {
matches: (...values: T["state"][]) => boolean;
hasTag: (tag: T["tag"]) => boolean;
};
context: BindableContext<T>;
send: (event: EventType<T["event"]>) => void;
prop: PropFn<T>;
scope: Scope;
computed: ComputedFn<T>;
refs: BindableRefs<T>;
event: EventType<T["event"]> & {
current: () => EventType<T["event"]>;
previous: () => EventType<T["event"]>;
};
};
declare function or<TContext extends Dict, TState extends StateMachine.StateSchema, TEvent extends StateMachine.EventObject>(...conditions: Array<StateMachine.Guard<TContext, TState, TEvent>>): StateMachine.GuardHelper<TContext, TState, TEvent>;
declare function and<TContext extends Dict, TState extends StateMachine.StateSchema, TEvent extends StateMachine.EventObject>(...conditions: Array<StateMachine.Guard<TContext, TState, TEvent>>): StateMachine.GuardHelper<TContext, TState, TEvent>;
declare function not<TContext extends Dict, TState extends StateMachine.StateSchema, TEvent extends StateMachine.EventObject>(condition: StateMachine.Guard<TContext, TState, TEvent>): StateMachine.GuardHelper<TContext, TState, TEvent>;
declare function stateIn<TContext extends Dict, TState extends StateMachine.StateSchema, TEvent extends StateMachine.EventObject>(...values: TState["value"][]): StateMachine.GuardExpression<TContext, TState, TEvent>;
declare const guards: {
or: typeof or;
and: typeof and;
not: typeof not;
stateIn: typeof stateIn;
declare function createGuards<T extends BaseSchema>(): {
and: (...guards: Array<GuardFn<T> | T["guard"]>) => (params: any) => boolean;
or: (...guards: Array<GuardFn<T> | T["guard"]>) => (params: any) => boolean;
not: (guard: GuardFn<T> | T["guard"]) => (params: any) => boolean;
};
declare function choose<TContext extends Dict, TState extends StateMachine.StateSchema, TEvent extends StateMachine.EventObject = StateMachine.AnyEventObject>(actions: Array<{
guard?: StateMachine.Guard<TContext, TState, TEvent>;
actions: StateMachine.PureActions<TContext, TState, TEvent>;
}>): StateMachine.ChooseHelper<TContext, TState, TEvent>;
declare function createMachine<T extends BaseSchema>(config: MachineConfig<T>): MachineConfig<T>;
declare function setup<T extends BaseSchema>(): {
guards: {
and: (...guards: (T["guard"] | GuardFn<T>)[]) => (params: any) => boolean;
or: (...guards: (T["guard"] | GuardFn<T>)[]) => (params: any) => boolean;
not: (guard: T["guard"] | GuardFn<T>) => (params: any) => boolean;
};
createMachine: (config: MachineConfig<T>) => MachineConfig<T>;
choose: (transitions: Transition<T> | Transition<T>[]) => ({ choose }: Params<T>) => T["action"][] | undefined;
};
declare class Machine<TContext extends Dict, TState extends StateMachine.StateSchema, TEvent extends StateMachine.EventObject = StateMachine.AnyEventObject> {
status: MachineStatus;
readonly state: StateMachine.State<TContext, TState, TEvent>;
initialState: StateMachine.StateInfo<TContext, TState, TEvent> | undefined;
initialContext: TContext;
id: string;
type: MachineType;
private activityEvents;
private delayedEvents;
private stateListeners;
private doneListeners;
private contextWatchers;
private removeStateListener;
private parent?;
private children;
private guardMap;
private actionMap;
private delayMap;
private activityMap;
private sync;
options: StateMachine.MachineOptions<TContext, TState, TEvent>;
config: StateMachine.MachineConfig<TContext, TState, TEvent>;
constructor(config: StateMachine.MachineConfig<TContext, TState, TEvent>, options?: StateMachine.MachineOptions<TContext, TState, TEvent>);
private get stateSnapshot();
getState(): StateMachine.State<TContext, TState, TEvent>;
get contextSnapshot(): TContext;
_created: () => void;
start: (init?: StateMachine.StateInit<TContext, TState>) => this;
private setupContextWatchers;
stop: () => this | undefined;
private stopStateListeners;
private stopContextWatchers;
private stopDelayedEvents;
private stopActivities;
/**
* Function to send event to spawned child machine or actor
*/
sendChild: (evt: StateMachine.Event<StateMachine.AnyEventObject>, to: string | ((ctx: TContext) => string)) => void;
/**
* Function to stop a running child machine or actor
*/
stopChild: (id: string) => void;
removeChild: (id: string) => void;
private stopChildren;
private setParent;
spawn: <TContext_1 extends Dict, TState_1 extends StateMachine.StateSchema, TEvent_1 extends StateMachine.EventObject = StateMachine.AnyEventObject>(src: MachineSrc<TContext_1, TState_1, TEvent_1>, id?: string) => Machine<TContext_1, TState_1, TEvent_1>;
private stopActivity;
private addActivityCleanup;
private setState;
/**
* To used within side effects for React or Vue to update context
*/
setContext: (context: Partial<Writable<TContext>> | undefined) => void;
setOptions: (options: Partial<StateMachine.MachineOptions<TContext, TState, TEvent>>) => void;
private getStateNode;
private getNextStateInfo;
private getAfterActions;
/**
* All `after` events leverage `setTimeout` and `clearTimeout`,
* we invoke the `clearTimeout` on exit and `setTimeout` on entry.
*
* To achieve this, we split the `after` defintion into `entry` and `exit`
* functions and append them to the state's `entry` and `exit` actions
*/
private getDelayedEventActions;
/**
* A reference to the instance methods of the machine.
* Useful when spawning child machines and managing the communication between them.
*/
private get self();
private get meta();
private get guardMeta();
/**
* Function to executes defined actions. It can accept actions as string
* (referencing `options.actions`) or actual functions.
*/
private executeActions;
/**
* Function to execute running activities and registers
* their cleanup function internally (to be called later on when we exit the state)
*/
private executeActivities;
/**
* Normalizes the `every` definition to transition. `every` can be:
* - An array of possible actions to run (we need to pick the first match based on guard)
* - An object of intervals and actions
*/
private createEveryActivities;
private setEvent;
private performExitEffects;
private performEntryEffects;
private performTransitionEffects;
/**
* Performs all the requires side-effects or reactions when
* we move from state A => state B.
*
* The Effect order:
* Exit actions (current state) => Transition actions => Go to state => Entry actions (next state)
*/
private performStateChangeEffects;
private determineTransition;
/**
* Function to send event to parent machine from spawned child
*/
sendParent: (evt: StateMachine.Event<StateMachine.AnyEventObject>) => void;
private log;
/**
* Function to send an event to current machine
*/
send: (evt: StateMachine.Event<TEvent>) => void;
transition: (state: TState["value"] | StateMachine.StateInfo<TContext, TState, TEvent> | null, evt: StateMachine.Event<TEvent>) => StateMachine.StateNode<TContext, TState, TEvent> | undefined;
subscribe: (listener: StateMachine.StateListener<TContext, TState, TEvent>) => () => void;
onDone: (listener: StateMachine.StateListener<TContext, TState, TEvent>) => this;
onTransition: (listener: StateMachine.StateListener<TContext, TState, TEvent>) => this;
get [Symbol.toStringTag](): string;
getHydrationState(): StateMachine.StateInit<TContext, TState>;
}
type MachineSrc<TContext extends Dict, TState extends StateMachine.StateSchema, TEvent extends StateMachine.EventObject = StateMachine.AnyEventObject> = Machine<TContext, TState, TEvent> | (() => Machine<TContext, TState, TEvent>);
type AnyMachine = Machine<Dict, StateMachine.StateSchema, StateMachine.AnyEventObject>;
declare const createMachine: <TContext extends Dict, TState extends StateMachine.StateSchema = StateMachine.StateSchema, TEvent extends StateMachine.EventObject = StateMachine.AnyEventObject>(config: StateMachine.MachineConfig<TContext, TState, TEvent>, options?: StateMachine.MachineOptions<TContext, TState, TEvent>) => Machine<TContext, TState, TEvent>;
declare const isMachine: (value: any) => value is AnyMachine;
declare function createScope(props: Pick<Scope, "id" | "ids" | "getRootNode">): {
getRootNode: () => Document | ShadowRoot;
getDoc: () => Document;
getWin: () => Window & typeof globalThis;
getActiveElement: () => HTMLElement | null;
isActiveElement: (elem: HTMLElement | null) => boolean;
getById: <T extends Element = HTMLElement>(id: string) => T | null;
id?: string | undefined | undefined;
ids?: Record<string, any> | undefined;
};
interface Props {
[key: string]: any;
}
type TupleTypes<T extends any[]> = T[number];
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
declare function mergeProps<T extends Props>(...args: T[]): UnionToIntersection<TupleTypes<T[]>>;
type AnyFunction = (...args: any[]) => any;
type ReturnTypeOrValue<T> = T extends AnyFunction ? ReturnType<T> : T;
type StateFrom<T> = ReturnTypeOrValue<T> extends infer R ? R extends Machine<infer TContext, infer TState, infer TEvent> ? StateMachine.State<TContext, TState, TEvent> : never : never;
type ContextFrom<T> = ReturnTypeOrValue<T> extends infer R ? (R extends Machine<infer TContext, any, any> ? TContext : never) : never;
type EventFrom<T> = ReturnTypeOrValue<T> extends infer R ? (R extends Machine<any, any, infer TEvent> ? TEvent : never) : never;
export { type AnyMachine, type ContextFrom, type EventFrom, Machine, type MachineSrc, type StateFrom, StateMachine, choose, createMachine, deepMerge, guards, isMachine, mergeProps };
export { type ActionsOrFn, type BaseSchema, type Bindable, type BindableContext, type BindableParams, type BindableRefs, type ChooseFn, type ComputedFn, type EffectsOrFn, type EventObject, type GuardFn, type MachineConfig, type Params, type PropFn, type Scope, type Service, type Transition, type ValueOrFn, createGuards, createMachine, createScope, memo, mergeProps, setup };

@@ -1,884 +0,6 @@

"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
'use strict';
// src/index.ts
var src_exports = {};
__export(src_exports, {
Machine: () => Machine,
choose: () => choose,
createMachine: () => createMachine,
deepMerge: () => deepMerge,
guards: () => guards,
isMachine: () => isMachine,
mergeProps: () => mergeProps,
proxy: () => import_store3.proxy,
ref: () => import_store3.ref,
snapshot: () => import_store3.snapshot,
subscribe: () => import_store3.subscribe
});
module.exports = __toCommonJS(src_exports);
var import_store3 = require("@zag-js/store");
var utils = require('@zag-js/utils');
var domQuery = require('@zag-js/dom-query');
// ../utilities/core/src/array.ts
function clear(v) {
while (v.length > 0) v.pop();
return v;
}
// ../utilities/core/src/functions.ts
var runIfFn = (v, ...a) => {
const res = typeof v === "function" ? v(...a) : v;
return res ?? void 0;
};
var cast = (v) => v;
var noop = () => {
};
var callAll = (...fns) => (...a) => {
fns.forEach(function(fn) {
fn?.(...a);
});
};
var uuid = /* @__PURE__ */ (() => {
let id = 0;
return () => {
id++;
return id.toString(36);
};
})();
// ../utilities/core/src/guard.ts
var isDev = () => process.env.NODE_ENV !== "production";
var isArray = (v) => Array.isArray(v);
var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
var isNumber = (v) => typeof v === "number" && !Number.isNaN(v);
var isString = (v) => typeof v === "string";
var isFunction = (v) => typeof v === "function";
var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
// ../utilities/core/src/split-props.ts
function splitProps(props, keys) {
const rest = {};
const result = {};
const keySet = new Set(keys);
for (const key in props) {
if (keySet.has(key)) {
result[key] = props[key];
} else {
rest[key] = props[key];
}
}
return [result, rest];
}
var createSplitProps = (keys) => {
return function split(props) {
return splitProps(props, keys);
};
};
// ../utilities/core/src/object.ts
function compact(obj) {
if (!isPlainObject(obj) || obj === void 0) {
return obj;
}
const keys = Reflect.ownKeys(obj).filter((key) => typeof key === "string");
const filtered = {};
for (const key of keys) {
const value = obj[key];
if (value !== void 0) {
filtered[key] = compact(value);
}
}
return filtered;
}
var isPlainObject = (value) => {
return value && typeof value === "object" && value.constructor === Object;
};
function omit(obj, keys) {
return createSplitProps(keys)(obj)[1];
}
// ../utilities/core/src/warning.ts
function warn(...a) {
const m = a.length === 1 ? a[0] : a[1];
const c = a.length === 2 ? a[0] : true;
if (c && process.env.NODE_ENV !== "production") {
console.warn(m);
}
}
function invariant(...a) {
const m = a.length === 1 ? a[0] : a[1];
const c = a.length === 2 ? a[0] : true;
if (c && process.env.NODE_ENV !== "production") {
throw new Error(m);
}
}
// src/deep-merge.ts
function deepMerge(source, ...objects) {
for (const obj of objects) {
const target = compact(obj);
for (const key in target) {
if (isObject(obj[key])) {
if (!source[key]) {
source[key] = {};
}
deepMerge(source[key], obj[key]);
} else {
source[key] = obj[key];
}
}
}
return source;
}
// src/utils.ts
var import_full = require("klona/full");
function structuredClone(v) {
return (0, import_full.klona)(v);
}
function toEvent(event) {
const obj = isString(event) ? { type: event } : event;
return obj;
}
function toArray(value) {
if (!value) return [];
return isArray(value) ? value.slice() : [value];
}
function isGuardHelper(value) {
return isObject(value) && value.predicate != null;
}
// src/guard-utils.ts
var Truthy = () => true;
function exec(guardMap, ctx, event, meta) {
return (guard) => {
if (isString(guard)) {
return !!guardMap[guard]?.(ctx, event, meta);
}
if (isFunction(guard)) {
return guard(ctx, event, meta);
}
return guard.predicate(guardMap)(ctx, event, meta);
};
}
function or(...conditions) {
return {
predicate: (guardMap) => (ctx, event, meta) => conditions.map(exec(guardMap, ctx, event, meta)).some(Boolean)
};
}
function and(...conditions) {
return {
predicate: (guardMap) => (ctx, event, meta) => conditions.map(exec(guardMap, ctx, event, meta)).every(Boolean)
};
}
function not(condition) {
return {
predicate: (guardMap) => (ctx, event, meta) => {
return !exec(guardMap, ctx, event, meta)(condition);
}
};
}
function stateIn(...values) {
return (_ctx, _evt, meta) => meta.state.matches(...values);
}
var guards = { or, and, not, stateIn };
function choose(actions) {
return {
predicate: (guardMap) => (ctx, event, meta) => actions.find((def) => {
const guard = def.guard ?? Truthy;
return exec(guardMap, ctx, event, meta)(guard);
})?.actions
};
}
function determineGuardFn(guard, guardMap) {
guard = guard ?? Truthy;
return (context, event, meta) => {
if (isString(guard)) {
const value = guardMap[guard];
return isFunction(value) ? value(context, event, meta) : value;
}
if (isGuardHelper(guard)) {
return guard.predicate(guardMap)(context, event, meta);
}
return guard?.(context, event, meta);
};
}
function determineActionsFn(values, guardMap) {
return (context, event, meta) => {
if (isGuardHelper(values)) {
return values.predicate(guardMap)(context, event, meta);
}
return values;
};
}
// src/machine.ts
var import_store2 = require("@zag-js/store");
// src/create-proxy.ts
var import_store = require("@zag-js/store");
function createProxy(config) {
const computedContext = config.computed ?? cast({});
const initialContext = config.context ?? cast({});
const initialTags = config.initial ? config.states?.[config.initial]?.tags : [];
const state = (0, import_store.proxy)({
value: config.initial ?? "",
previousValue: "",
event: cast({}),
previousEvent: cast({}),
context: (0, import_store.proxyWithComputed)(initialContext, computedContext),
done: false,
tags: initialTags ?? [],
hasTag(tag) {
return this.tags.includes(tag);
},
matches(...value) {
return value.includes(this.value);
},
can(event) {
return cast(this).nextEvents.includes(event);
},
get nextEvents() {
const stateEvents = config.states?.[this.value]?.["on"] ?? {};
const globalEvents = config?.on ?? {};
return Object.keys({ ...stateEvents, ...globalEvents });
},
get changed() {
if (this.event.value === "machine.init" /* Init */ || !this.previousValue) return false;
return this.value !== this.previousValue;
}
});
return cast(state);
}
// src/delay-utils.ts
function determineDelayFn(delay, delaysMap) {
return (context, event) => {
if (isNumber(delay)) return delay;
if (isFunction(delay)) {
return delay(context, event);
}
if (isString(delay)) {
const value = Number.parseFloat(delay);
if (!Number.isNaN(value)) {
return value;
}
if (delaysMap) {
const valueOrFn = delaysMap?.[delay];
invariant(
valueOrFn == null,
`[@zag-js/core > determine-delay] Cannot determine delay for \`${delay}\`. It doesn't exist in \`options.delays\``
);
return isFunction(valueOrFn) ? valueOrFn(context, event) : valueOrFn;
}
}
};
}
// src/transition-utils.ts
function toTarget(target) {
return isString(target) ? { target } : target;
}
function determineTransitionFn(transitions, guardMap) {
return (context, event, meta) => {
return toArray(transitions).map(toTarget).find((transition) => {
const determineGuard = determineGuardFn(transition.guard, guardMap);
const guard = determineGuard(context, event, meta);
return guard ?? transition.target ?? transition.actions;
});
};
}
// src/machine.ts
var Machine = class {
// Let's get started!
constructor(config, options) {
__publicField(this, "status", "Not Started" /* NotStarted */);
__publicField(this, "state");
__publicField(this, "initialState");
__publicField(this, "initialContext");
__publicField(this, "id");
__publicField(this, "type", "machine" /* Machine */);
// Cleanup function map (per state)
__publicField(this, "activityEvents", /* @__PURE__ */ new Map());
__publicField(this, "delayedEvents", /* @__PURE__ */ new Map());
// state update listeners the user can opt-in for
__publicField(this, "stateListeners", /* @__PURE__ */ new Set());
__publicField(this, "doneListeners", /* @__PURE__ */ new Set());
__publicField(this, "contextWatchers", /* @__PURE__ */ new Set());
// Cleanup functions (for `subscribe`)
__publicField(this, "removeStateListener", noop);
// For Parent <==> Spawned Actor relationship
__publicField(this, "parent");
__publicField(this, "children", /* @__PURE__ */ new Map());
// A map of guard, action, delay implementations
__publicField(this, "guardMap");
__publicField(this, "actionMap");
__publicField(this, "delayMap");
__publicField(this, "activityMap");
__publicField(this, "sync");
__publicField(this, "options");
__publicField(this, "config");
__publicField(this, "_created", () => {
const event = toEvent("machine.created" /* Created */);
this.executeActions(this.config?.created, event);
});
// Starts the interpreted machine.
__publicField(this, "start", (init) => {
this.state.value = "";
this.state.tags = [];
if (this.status === "Running" /* Running */) {
return this;
}
this.status = "Running" /* Running */;
this.removeStateListener = (0, import_store2.subscribe)(
this.state,
() => {
this.stateListeners.forEach((listener) => {
listener(this.stateSnapshot);
});
},
this.sync
);
this.setupContextWatchers();
this.executeActivities(toEvent("machine.start" /* Start */), toArray(this.config.activities), "machine.start" /* Start */);
this.executeActions(this.config.entry, toEvent("machine.start" /* Start */));
const event = toEvent("machine.init" /* Init */);
const target = isObject(init) ? init.value : init;
const context = isObject(init) ? init.context : void 0;
if (context) {
this.setContext(context);
}
const transition = {
target: target ?? this.config.initial
};
const next = this.getNextStateInfo(transition, event);
this.initialState = next;
this.performStateChangeEffects(this.state.value, next, event);
return this;
});
__publicField(this, "setupContextWatchers", () => {
const { watch } = this.config;
if (!watch) return;
let prev = (0, import_store2.snapshot)(this.state.context);
const cleanup = (0, import_store2.subscribe)(this.state.context, () => {
const next = (0, import_store2.snapshot)(this.state.context);
for (const [key, fn] of Object.entries(watch)) {
const isEqual = this.options.compareFns?.[key] ?? Object.is;
if (isEqual(prev[key], next[key])) continue;
this.executeActions(fn, this.state.event);
}
prev = next;
});
this.contextWatchers.add(cleanup);
});
// Stops the interpreted machine
__publicField(this, "stop", () => {
if (this.status === "Stopped" /* Stopped */) return;
this.performExitEffects(this.state.value, toEvent("machine.stop" /* Stop */));
this.executeActions(this.config.exit, toEvent("machine.stop" /* Stop */));
this.setState("");
this.setEvent("machine.stop" /* Stop */);
this.stopStateListeners();
this.stopChildren();
this.stopActivities();
this.stopDelayedEvents();
this.stopContextWatchers();
this.status = "Stopped" /* Stopped */;
return this;
});
__publicField(this, "stopStateListeners", () => {
this.removeStateListener();
this.stateListeners.clear();
});
__publicField(this, "stopContextWatchers", () => {
this.contextWatchers.forEach((fn) => fn());
this.contextWatchers.clear();
});
__publicField(this, "stopDelayedEvents", () => {
this.delayedEvents.forEach((state) => {
state.forEach((stop) => stop());
});
this.delayedEvents.clear();
});
// Cleanup running activities (e.g `setInterval`, invoked callbacks, promises)
__publicField(this, "stopActivities", (state) => {
if (state) {
this.activityEvents.get(state)?.forEach((stop) => stop());
this.activityEvents.get(state)?.clear();
this.activityEvents.delete(state);
} else {
this.activityEvents.forEach((state2) => {
state2.forEach((stop) => stop());
state2.clear();
});
this.activityEvents.clear();
}
});
/**
* Function to send event to spawned child machine or actor
*/
__publicField(this, "sendChild", (evt, to) => {
const event = toEvent(evt);
const id = runIfFn(to, this.contextSnapshot);
const child = this.children.get(id);
if (!child) {
invariant(`[@zag-js/core] Cannot send '${event.type}' event to unknown child`);
}
child.send(event);
});
/**
* Function to stop a running child machine or actor
*/
__publicField(this, "stopChild", (id) => {
if (!this.children.has(id)) {
invariant(`[@zag-js/core > stop-child] Cannot stop unknown child ${id}`);
}
this.children.get(id).stop();
this.children.delete(id);
});
__publicField(this, "removeChild", (id) => {
this.children.delete(id);
});
// Stop and delete spawned actors
__publicField(this, "stopChildren", () => {
this.children.forEach((child) => child.stop());
this.children.clear();
});
__publicField(this, "setParent", (parent) => {
this.parent = parent;
});
__publicField(this, "spawn", (src, id) => {
const actor = runIfFn(src);
if (id) actor.id = id;
actor.type = "machine.actor" /* Actor */;
actor.setParent(this);
this.children.set(actor.id, cast(actor));
actor.onDone(() => {
this.removeChild(actor.id);
}).start();
return cast((0, import_store2.ref)(actor));
});
__publicField(this, "stopActivity", (key) => {
if (!this.state.value) return;
const cleanups = this.activityEvents.get(this.state.value);
cleanups?.get(key)?.();
cleanups?.delete(key);
});
__publicField(this, "addActivityCleanup", (state, key, cleanup) => {
if (!state) return;
if (!this.activityEvents.has(state)) {
this.activityEvents.set(state, /* @__PURE__ */ new Map([[key, cleanup]]));
} else {
this.activityEvents.get(state)?.set(key, cleanup);
}
});
__publicField(this, "setState", (target) => {
this.state.previousValue = this.state.value;
this.state.value = target;
const stateNode = this.getStateNode(target);
if (target == null) {
clear(this.state.tags);
} else {
this.state.tags = toArray(stateNode?.tags);
}
});
/**
* To used within side effects for React or Vue to update context
*/
__publicField(this, "setContext", (context) => {
if (!context) return;
deepMerge(this.state.context, compact(context));
});
__publicField(this, "setOptions", (options) => {
const opts = compact(options);
this.actionMap = { ...this.actionMap, ...opts.actions };
this.delayMap = { ...this.delayMap, ...opts.delays };
this.activityMap = { ...this.activityMap, ...opts.activities };
this.guardMap = { ...this.guardMap, ...opts.guards };
});
__publicField(this, "getStateNode", (state) => {
if (!state) return;
return this.config.states?.[state];
});
__publicField(this, "getNextStateInfo", (transitions, event) => {
const transition = this.determineTransition(transitions, event);
const isTargetless = !transition?.target;
const target = transition?.target ?? this.state.value;
const changed = this.state.value !== target;
const stateNode = this.getStateNode(target);
const reenter = !isTargetless && !changed && !transition?.internal;
const info = {
reenter,
transition,
stateNode,
target,
changed
};
this.log("NextState:", `[${event.type}]`, this.state.value, "---->", info.target);
return info;
});
__publicField(this, "getAfterActions", (transition, delay) => {
let id;
return {
entry: () => {
id = globalThis.setTimeout(() => {
const next = this.getNextStateInfo(transition, this.state.event);
this.performStateChangeEffects(this.state.value, next, this.state.event);
}, delay);
},
exit: () => {
globalThis.clearTimeout(id);
}
};
});
/**
* All `after` events leverage `setTimeout` and `clearTimeout`,
* we invoke the `clearTimeout` on exit and `setTimeout` on entry.
*
* To achieve this, we split the `after` defintion into `entry` and `exit`
* functions and append them to the state's `entry` and `exit` actions
*/
__publicField(this, "getDelayedEventActions", (state) => {
const stateNode = this.getStateNode(state);
const event = this.state.event;
if (!stateNode || !stateNode.after) return;
const entries = [];
const exits = [];
if (isArray(stateNode.after)) {
const transition = this.determineTransition(stateNode.after, event);
if (!transition) return;
if (!hasProp(transition, "delay")) {
throw new Error(`[@zag-js/core > after] Delay is required for after transition: ${JSON.stringify(transition)}`);
}
const determineDelay = determineDelayFn(transition.delay, this.delayMap);
const __delay = determineDelay(this.contextSnapshot, event);
const actions = this.getAfterActions(transition, __delay);
entries.push(actions.entry);
exits.push(actions.exit);
return { entries, exits };
}
if (isObject(stateNode.after)) {
for (const delay in stateNode.after) {
const transition = stateNode.after[delay];
const determineDelay = determineDelayFn(delay, this.delayMap);
const __delay = determineDelay(this.contextSnapshot, event);
const actions = this.getAfterActions(transition, __delay);
entries.push(actions.entry);
exits.push(actions.exit);
}
}
return { entries, exits };
});
/**
* Function to executes defined actions. It can accept actions as string
* (referencing `options.actions`) or actual functions.
*/
__publicField(this, "executeActions", (actions, event) => {
const pickedActions = determineActionsFn(actions, this.guardMap)(this.contextSnapshot, event, this.guardMeta);
for (const action of toArray(pickedActions)) {
const fn = isString(action) ? this.actionMap?.[action] : action;
warn(
isString(action) && !fn,
`[@zag-js/core > execute-actions] No implementation found for action: \`${action}\``
);
fn?.(this.state.context, event, this.meta);
}
});
/**
* Function to execute running activities and registers
* their cleanup function internally (to be called later on when we exit the state)
*/
__publicField(this, "executeActivities", (event, activities, state) => {
for (const activity of activities) {
const fn = isString(activity) ? this.activityMap?.[activity] : activity;
if (!fn) {
warn(`[@zag-js/core > execute-activity] No implementation found for activity: \`${activity}\``);
continue;
}
const cleanup = fn(this.state.context, event, this.meta);
if (cleanup) {
const key = isString(activity) ? activity : activity.name || uuid();
this.addActivityCleanup(state ?? this.state.value, key, cleanup);
}
}
});
/**
* Normalizes the `every` definition to transition. `every` can be:
* - An array of possible actions to run (we need to pick the first match based on guard)
* - An object of intervals and actions
*/
__publicField(this, "createEveryActivities", (every, callbackfn) => {
if (!every) return;
if (isArray(every)) {
const picked = toArray(every).find((transition) => {
const delayOrFn = transition.delay;
const determineDelay2 = determineDelayFn(delayOrFn, this.delayMap);
const delay2 = determineDelay2(this.contextSnapshot, this.state.event);
const determineGuard = determineGuardFn(transition.guard, this.guardMap);
const guard = determineGuard(this.contextSnapshot, this.state.event, this.guardMeta);
return guard ?? delay2 != null;
});
if (!picked) return;
const determineDelay = determineDelayFn(picked.delay, this.delayMap);
const delay = determineDelay(this.contextSnapshot, this.state.event);
const activity = () => {
const id = globalThis.setInterval(() => {
this.executeActions(picked.actions, this.state.event);
}, delay);
return () => {
globalThis.clearInterval(id);
};
};
callbackfn(activity);
} else {
for (const interval in every) {
const actions = every?.[interval];
const determineDelay = determineDelayFn(interval, this.delayMap);
const delay = determineDelay(this.contextSnapshot, this.state.event);
const activity = () => {
const id = globalThis.setInterval(() => {
this.executeActions(actions, this.state.event);
}, delay);
return () => {
globalThis.clearInterval(id);
};
};
callbackfn(activity);
}
}
});
__publicField(this, "setEvent", (event) => {
this.state.previousEvent = this.state.event;
this.state.event = (0, import_store2.ref)(toEvent(event));
});
__publicField(this, "performExitEffects", (current, event) => {
const currentState = this.state.value;
if (currentState === "") return;
const stateNode = current ? this.getStateNode(current) : void 0;
this.stopActivities(currentState);
const _exit = determineActionsFn(stateNode?.exit, this.guardMap)(this.contextSnapshot, event, this.guardMeta);
const exitActions = toArray(_exit);
const afterExitActions = this.delayedEvents.get(currentState);
if (afterExitActions) {
exitActions.push(...afterExitActions);
}
this.executeActions(exitActions, event);
});
__publicField(this, "performEntryEffects", (next, event) => {
const stateNode = this.getStateNode(next);
const activities = toArray(stateNode?.activities);
this.createEveryActivities(stateNode?.every, (activity) => {
activities.unshift(activity);
});
if (activities.length > 0) {
this.executeActivities(event, activities);
}
const pickedActions = determineActionsFn(stateNode?.entry, this.guardMap)(
this.contextSnapshot,
event,
this.guardMeta
);
const entryActions = toArray(pickedActions);
const afterActions = this.getDelayedEventActions(next);
if (stateNode?.after && afterActions) {
this.delayedEvents.set(next, afterActions?.exits);
entryActions.push(...afterActions.entries);
}
this.executeActions(entryActions, event);
if (stateNode?.type === "final") {
this.state.done = true;
this.doneListeners.forEach((listener) => {
listener(this.stateSnapshot);
});
this.stop();
}
});
__publicField(this, "performTransitionEffects", (transitions, event) => {
const transition = this.determineTransition(transitions, event);
this.executeActions(transition?.actions, event);
});
/**
* Performs all the requires side-effects or reactions when
* we move from state A => state B.
*
* The Effect order:
* Exit actions (current state) => Transition actions => Go to state => Entry actions (next state)
*/
__publicField(this, "performStateChangeEffects", (current, next, event) => {
this.setEvent(event);
const changed = next.changed || next.reenter;
if (changed) {
this.performExitEffects(current, event);
}
this.performTransitionEffects(next.transition, event);
this.setState(next.target);
if (changed) {
this.performEntryEffects(next.target, event);
}
});
__publicField(this, "determineTransition", (transition, event) => {
const fn = determineTransitionFn(transition, this.guardMap);
return fn?.(this.contextSnapshot, event, this.guardMeta);
});
/**
* Function to send event to parent machine from spawned child
*/
__publicField(this, "sendParent", (evt) => {
if (!this.parent) {
invariant("[@zag-js/core > send-parent] Cannot send event to an unknown parent");
}
const event = toEvent(evt);
this.parent?.send(event);
});
__publicField(this, "log", (...args) => {
if (isDev() && this.options.debug) {
console.log(...args);
}
});
/**
* Function to send an event to current machine
*/
__publicField(this, "send", (evt) => {
const event = toEvent(evt);
this.transition(this.state.value, event);
});
__publicField(this, "transition", (state, evt) => {
const stateNode = isString(state) ? this.getStateNode(state) : state?.stateNode;
const event = toEvent(evt);
if (!stateNode && !this.config.on) {
const msg = this.status === "Stopped" /* Stopped */ ? "[@zag-js/core > transition] Cannot transition a stopped machine" : `[@zag-js/core > transition] State does not have a definition for \`state\`: ${state}, \`event\`: ${event.type}`;
warn(msg);
return;
}
const transitions = (
// @ts-expect-error - Fix this
stateNode?.on?.[event.type] ?? this.config.on?.[event.type]
);
const next = this.getNextStateInfo(transitions, event);
this.performStateChangeEffects(this.state.value, next, event);
return next.stateNode;
});
__publicField(this, "subscribe", (listener) => {
this.stateListeners.add(listener);
if (this.status === "Running" /* Running */) {
listener(this.stateSnapshot);
}
return () => {
this.stateListeners.delete(listener);
};
});
__publicField(this, "onDone", (listener) => {
this.doneListeners.add(listener);
return this;
});
__publicField(this, "onTransition", (listener) => {
this.stateListeners.add(listener);
if (this.status === "Running" /* Running */) {
listener(this.stateSnapshot);
}
return this;
});
this.config = structuredClone(config);
this.options = structuredClone(options ?? {});
this.id = this.config.id ?? `machine-${uuid()}`;
this.guardMap = this.options?.guards ?? {};
this.actionMap = this.options?.actions ?? {};
this.delayMap = this.options?.delays ?? {};
this.activityMap = this.options?.activities ?? {};
this.sync = this.options?.sync ?? false;
this.state = createProxy(this.config);
this.initialContext = (0, import_store2.snapshot)(this.state.context);
}
// immutable state value
get stateSnapshot() {
return cast((0, import_store2.snapshot)(this.state));
}
getState() {
return this.stateSnapshot;
}
// immutable context value
get contextSnapshot() {
return this.stateSnapshot.context;
}
/**
* A reference to the instance methods of the machine.
* Useful when spawning child machines and managing the communication between them.
*/
get self() {
const self = this;
return {
id: this.id,
send: this.send.bind(this),
sendParent: this.sendParent.bind(this),
sendChild: this.sendChild.bind(this),
stop: this.stop.bind(this),
stopChild: this.stopChild.bind(this),
spawn: this.spawn.bind(this),
stopActivity: this.stopActivity.bind(this),
get state() {
return self.stateSnapshot;
},
get initialContext() {
return self.initialContext;
},
get initialState() {
return self.initialState?.target ?? "";
}
};
}
get meta() {
return {
state: this.stateSnapshot,
guards: this.guardMap,
send: this.send.bind(this),
self: this.self,
initialContext: this.initialContext,
initialState: this.initialState?.target ?? "",
getState: () => this.stateSnapshot,
getAction: (key) => this.actionMap[key],
getGuard: (key) => this.guardMap[key]
};
}
get guardMeta() {
return {
state: this.stateSnapshot
};
}
get [Symbol.toStringTag]() {
return "Machine";
}
getHydrationState() {
const state = this.getState();
const computedKeys = Object.keys(this.config.computed ?? {});
return {
value: state.value,
context: omit(state.context, computedKeys),
tags: state.tags
};
}
};
var createMachine = (config, options) => new Machine(config, options);
var isMachine = (value) => {
return value instanceof Machine || value?.type === "machine" /* Machine */;
};
// src/merge-props.ts

@@ -896,6 +18,6 @@ var clsx = (...args) => args.map((str) => str?.trim?.()).filter(Boolean).join(" ");

var css = (a, b) => {
if (isString(a)) {
if (isString(b)) return `${a};${b}`;
if (utils.isString(a)) {
if (utils.isString(b)) return `${a};${b}`;
a = serialize(a);
} else if (isString(b)) {
} else if (utils.isString(b)) {
b = serialize(b);

@@ -910,3 +32,3 @@ }

if (key.startsWith("on") && typeof result[key] === "function" && typeof props[key] === "function") {
result[key] = callAll(props[key], result[key]);
result[key] = utils.callAll(props[key], result[key]);
continue;

@@ -932,16 +54,75 @@ }

}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Machine,
choose,
createMachine,
deepMerge,
guards,
isMachine,
mergeProps,
proxy,
ref,
snapshot,
subscribe
});
//# sourceMappingURL=index.js.map
function memo(getDeps, fn, opts) {
let deps = [];
let result;
return (depArgs) => {
const newDeps = getDeps(depArgs);
const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => !utils.isEqual(deps[index], dep));
if (!depsChanged) return result;
deps = newDeps;
result = fn(...newDeps);
opts?.onChange?.(result);
return result;
};
}
// src/create-machine.ts
function createGuards() {
return {
and: (...guards) => {
return function andGuard(params) {
return guards.every((str) => params.guard(str));
};
},
or: (...guards) => {
return function orGuard(params) {
return guards.some((str) => params.guard(str));
};
},
not: (guard) => {
return function notGuard(params) {
return !params.guard(guard);
};
}
};
}
function createMachine(config) {
return config;
}
function setup() {
return {
guards: createGuards(),
createMachine: (config) => {
return createMachine(config);
},
choose: (transitions) => {
return function chooseFn({ choose }) {
return choose(transitions)?.actions;
};
}
};
}
function createScope(props) {
const getRootNode = () => props.getRootNode?.() ?? document;
const getDoc = () => domQuery.getDocument(getRootNode());
const getWin = () => getDoc().defaultView ?? window;
const getActiveElementFn = () => domQuery.getActiveElement(getRootNode());
const isActiveElement = (elem) => elem === getActiveElementFn();
const getById = (id) => getRootNode().getElementById(id);
return {
...props,
getRootNode,
getDoc,
getWin,
getActiveElement: getActiveElementFn,
isActiveElement,
getById
};
}
exports.createGuards = createGuards;
exports.createMachine = createMachine;
exports.createScope = createScope;
exports.memo = memo;
exports.mergeProps = mergeProps;
exports.setup = setup;
{
"name": "@zag-js/core",
"version": "0.0.0-dev-20240723090825",
"version": "0.0.0-v1-beta-20250220125322",
"description": "A minimal implementation of xstate fsm for UI machines",

@@ -19,4 +19,3 @@ "keywords": [

"files": [
"dist",
"src"
"dist"
],

@@ -30,8 +29,7 @@ "publishConfig": {

"dependencies": {
"klona": "2.0.6",
"@zag-js/store": "0.0.0-dev-20240723090825"
"@zag-js/utils": "0.0.0-v1-beta-20250220125322",
"@zag-js/dom-query": "0.0.0-v1-beta-20250220125322"
},
"devDependencies": {
"clean-package": "2.2.0",
"@zag-js/utils": "0.0.0-dev-20240723090825"
"clean-package": "2.2.0"
},

@@ -52,6 +50,6 @@ "clean-package": "../../clean-package.config.json",

"build": "tsup",
"test": "jest --config ../../jest.config.js --rootDir . --passWithNoTests",
"lint": "eslint src --ext .ts,.tsx",
"test": "vitest --passWithNoTests",
"lint": "eslint src",
"typecheck": "tsc --noEmit"
}
}

@@ -106,3 +106,3 @@ # @zag-js/core

- `tags`: the tags associated with this state
- `done`: whehter the machine that reached its final state
- `done`: whether the machine that reached its final state
- `context`: the current context value

@@ -109,0 +109,0 @@ - `matches(...)`: a function used to test whether the current state matches one or more state values

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet