Options
All
  • Public
  • Public/Protected
  • All
Menu

Type Parameters

  • mDT

Hierarchy

  • Machine

Index

Constructors

Properties

Accessors

Methods

Constructors

Properties

_action_interner: Interner
_actions: Map<string, Map<string, number>>
_active_state_style: Partial<JssmStateDeclaration>
_after_hooks: Map<string, HookHandler<mDT>>
_after_mapping: Map<string, [string, number]>
_allow_islands: JssmAllowIslands
_any_action_hook: HookHandler<mDT>
_any_transition_hook: HookHandler<mDT>
_arrange_declaration: string[][]
_arrange_end_declaration: string[][]
_arrange_start_declaration: string[][]
_boundary_depth: number
_boundary_depth_limit: number
_clear_timeout_source: ((h: any) => void)

Type declaration

    • (h: any): void
    • Parameters

      • h: any

      Returns void

_code_allows_override: JssmAllowsOverride
_config_allows_override: JssmAllowsOverride
_create_started: number
_created: number
_data?: mDT
_default_graph_config: JssmGraphConfig
_default_properties: Map<string, any>
_default_size?: JssmDefaultSize
_default_transition_config: JssmTransitionConfig
_dot_preamble: string
_edge_id_by_action_pair: Map<number, number>
_edge_id_by_pair: Map<number, number>
_edge_map: Map<string, Map<string, number>>
_edge_to_ids: number[]
_edges: JssmTransition<string, mDT>[]
_end_state_style: Partial<JssmStateDeclaration>
_end_states: Set<string>
_entry_hooks: Map<number, HookHandler<mDT>>
_event_handlers: Map<JssmEventName, Set<JssmEventEntry<any, any>>>
_event_listener_count: number
_everything_hook: EverythingHookHandler<mDT>
_exit_hooks: Map<number, HookHandler<mDT>>
_failed_outputs: Set<string>
_firing_error: boolean
_flow: "up" | "right" | "down" | "left"
_forced_transition_hook: HookHandler<mDT>
_fsl_version?: string
_global_action_hooks: Map<number, HookHandler<mDT>>
_graph_layout: JssmLayout
_group_hooks: JssmGroupHooks
_group_metadata: Map<string, Partial<JssmStateDeclaration>>
_group_order: string[]
_group_registry: JssmGroupRegistry
_has_after_hooks: boolean
_has_basic_hooks: boolean
_has_entry_hooks: boolean
_has_exit_hooks: boolean
_has_forced_transitions: boolean
_has_global_action_hooks: boolean
_has_hooks: boolean
_has_named_hooks: boolean
_has_post_basic_hooks: boolean
_has_post_entry_hooks: boolean
_has_post_exit_hooks: boolean
_has_post_global_action_hooks: boolean
_has_post_hooks: boolean
_has_post_named_hooks: boolean
_has_post_transition_hooks: boolean
_has_transition_hooks: boolean
_history: JssmHistory<mDT>
_history_length: number
_hooked_state_style: Partial<JssmStateDeclaration>
_hooks: Map<number, HookHandler<mDT>>
_instance_name: string
_machine_author?: string[]
_machine_comment?: string
_machine_contributor?: string[]
_machine_definition?: string
_machine_language?: string
_machine_license?: string
_machine_name?: string
_machine_version?: string
_main_transition_hook: HookHandler<mDT>
_named_hooks: Map<number, Map<number, HookHandler<mDT>>>
_named_transitions: Map<string, number>
_npm_name?: string
_outbound_edge_ids: Map<string, number[]>
_post_any_action_hook: HookHandler<mDT>
_post_any_transition_hook: HookHandler<mDT>
_post_entry_hooks: Map<number, HookHandler<mDT>>
_post_everything_hook: PostEverythingHookHandler<mDT>
_post_exit_hooks: Map<number, HookHandler<mDT>>
_post_forced_transition_hook: HookHandler<mDT>
_post_global_action_hooks: Map<number, HookHandler<mDT>>
_post_hooks: Map<number, HookHandler<mDT>>
_post_main_transition_hook: HookHandler<mDT>
_post_named_hooks: Map<number, Map<number, HookHandler<mDT>>>
_post_standard_transition_hook: HookHandler<mDT>
_pre_everything_hook: EverythingHookHandler<mDT>
_pre_post_everything_hook: PostEverythingHookHandler<mDT>
_property_keys: Set<string>
_raw_state_declaration?: <internal>.Object[]
_required_properties: Set<string>
_reverse_action_targets: Map<string, Map<string, number>>
_reverse_actions: Map<string, Map<string, number>>
_rng: JssmRng
_rng_seed: number
_standard_transition_hook: HookHandler<mDT>
_start_state_style: Partial<JssmStateDeclaration>
_start_states: Set<string>
_state: string
_state_declarations: Map<string, JssmStateDeclaration>
_state_hooks: JssmStateHooks
_state_id: number
_state_interner: Interner
_state_labels: Map<string, string>
_state_properties: Map<string, any>
_state_property_first_state: Map<string, string>
_state_to_groups: Map<string, Set<string>>
_states: Map<string, JssmGenericState>
_static_state_config_cache: Map<string, Partial<JssmStateDeclaration>>
_terminal_state_style: Partial<JssmStateDeclaration>
_themes: ("default" | "ocean" | "modern" | "plain" | "bold")[]
_time_source: (() => number)

Type declaration

    • (): number
    • Returns number

_timeout_handle: number
_timeout_source: ((Function: any, number: any) => number)

Type declaration

    • (Function: any, number: any): number
    • Parameters

      • Function: any
      • number: any

      Returns number

_timeout_target: string
_timeout_target_time: number

Accessors

  • Get the style for the active state. Does not include composition from an applied theme, or things from the underlying base stylesheet; only the modifications applied by this machine.

    const light = sm`a -> b;`;
    console.log(light.active_state_style);
    // {}

    const light = sm`a -> b; active_state: { shape: circle; };`;
    console.log(light.active_state_style);
    // { shape: 'circle' }

    Returns Partial<JssmStateDeclaration>

    The JssmStateConfig for the active state.

  • Return the effective island policy for this machine. true means disconnected components are allowed (the default), false requires a single connected component, and 'with_start' allows islands only when every component contains at least one start state.

    Returns JssmAllowIslands

    The island policy stored in the machine.

  • Check if a machine allows overriding state and data. Resolves the combined effect of code and config permissions — config may not be less strict than code.

    Returns JssmAllowsOverride

    The effective override permission.

  • get create_start_time(): number
  • Get the timestamp when construction began (before parsing).

    Returns number

    The start-of-construction timestamp as a number.

  • get creation_date(): Date
  • Get the creation date of this machine as a Date object.

    Returns Date

    A Date representing when the machine was created.

  • get creation_timestamp(): number
  • Get the creation timestamp (milliseconds since epoch).

    Returns number

    The timestamp as a number.

  • Get the end state style. Does not include composition from an applied theme, or things from the underlying base stylesheet; only the modifications applied by this machine.

    End states are defined in the directive end_states, and are distinct from terminal states. End states are voluntary successful endpoints for a process. Terminal states are states that cannot be exited. By example, most error states are terminal states, but not end states. Also, since some end states can be exited and are determined by hooks, such as recursive or iterative nodes, there is such a thing as an end state that is not a terminal state.

    const light = sm`a -> b;`;
    console.log(light.standard_state_style);
    // {}

    const light = sm`a -> b; end_state: { shape: circle; };`;
    console.log(light.standard_state_style);
    // { shape: 'circle' }

    Returns Partial<JssmStateDeclaration>

    The JssmStateConfig for end states.

  • get history(): [string, mDT][]
  • Get a truncated history of the recent states and data of the machine. Turned off by default; configure with .from('...', {data: 5}) by length, or set .history_length at runtime.

    History does not contain the current state. If you want that, call .history_inclusive instead.

    const foo = jssm.from(
    "a 'next' -> b 'next' -> c 'next' -> d 'next' -> e;",
    { history: 3 }
    );

    foo.action('next');
    foo.action('next');
    foo.action('next');
    foo.action('next');

    foo.history; // [ ['b',undefined], ['c',undefined], ['d',undefined] ]

    Notice that the machine's current state, e, is not in the returned list.

    Returns [string, mDT][]

  • get history_inclusive(): [string, mDT][]
  • Get a truncated history of the recent states and data of the machine, including the current state. Turned off by default; configure with .from('...', {data: 5}) by length, or set .history_length at runtime.

    History inclusive contains the current state. If you only want past states, call .history instead.

    The list returned will be one longer than the history buffer kept, as the history buffer kept gets the current state added to it to produce this list.

    const foo = jssm.from(
    "a 'next' -> b 'next' -> c 'next' -> d 'next' -> e;",
    { history: 3 }
    );

    foo.action('next');
    foo.action('next');
    foo.action('next');
    foo.action('next');

    foo.history_inclusive; // [ ['b',undefined], ['c',undefined], ['d',undefined], ['e',undefined] ]

    Notice that the machine's current state, e, is in the returned list.

    Returns [string, mDT][]

  • get history_length(): number
  • set history_length(to: number): void
  • Find out how long a history this machine is keeping. Defaults to zero. Settable directly.

    const foo = jssm.from("a -> b;");
    foo.history_length; // 0

    const bar = jssm.from("a -> b;", { history: 3 });
    foo.history_length; // 3
    foo.history_length = 5;
    foo.history_length; // 5

    Returns number

  • Find out how long a history this machine is keeping. Defaults to zero. Settable directly.

    const foo = jssm.from("a -> b;");
    foo.history_length; // 0

    const bar = jssm.from("a -> b;", { history: 3 });
    foo.history_length; // 3
    foo.history_length = 5;
    foo.history_length; // 5

    Parameters

    • to: number

    Returns void

  • Get the hooked state style. Does not include composition from an applied theme, or things from the underlying base stylesheet; only the modifications applied by this machine.

    The hooked style is only applied to nodes which have a named hook in the graph. Open hooks set through the external API aren't graphed, because that would be literally every node.

    const light = sm`a -> b;`;
    console.log(light.hooked_state_style);
    // {}

    const light = sm`a -> b; hooked_state: { shape: circle; };`;
    console.log(light.hooked_state_style);
    // { shape: 'circle' }

    Returns Partial<JssmStateDeclaration>

    The JssmStateConfig for hooked states.

  • get rng_seed(): number
  • set rng_seed(to: number): void
  • Get the current RNG seed used for probabilistic transitions.

    Returns number

    The numeric seed value.

  • Set the RNG seed. Pass undefined to reseed from the current time. Resets the internal PRNG so subsequent probabilistic operations use the new seed.

    Parameters

    • to: number

      The seed value, or undefined for time-based seeding.

    Returns void

    The numeric seed value.

  • Get the standard style for a single state. Does not include composition from an applied theme, or things from the underlying base stylesheet; only the modifications applied by this machine.

    const light = sm`a -> b;`;
    console.log(light.standard_state_style);
    // {}

    const light = sm`a -> b; state: { shape: circle; };`;
    console.log(light.standard_state_style);
    // { shape: 'circle' }

    Returns Partial<JssmStateDeclaration>

    The JssmStateConfig for standard states.

  • Get the start state style. Does not include composition from an applied theme, or things from the underlying base stylesheet; only the modifications applied by this machine.

    Start states are defined by the directive start_states, or in absentia, are the first mentioned state.

    const light = sm`a -> b;`;
    console.log(light.start_state_style);
    // {}

    const light = sm`a -> b; start_state: { shape: circle; };`;
    console.log(light.start_state_style);
    // { shape: 'circle' }

    Returns Partial<JssmStateDeclaration>

    The JssmStateConfig for start states.

  • Get the terminal state style. Does not include composition from an applied theme, or things from the underlying base stylesheet; only the modifications applied by this machine.

    Terminal state styles are automatically determined by the machine. Any state without a valid exit transition is terminal.

    const light = sm`a -> b;`;
    console.log(light.terminal_state_style);
    // {}

    const light = sm`a -> b; terminal_state: { shape: circle; };`;
    console.log(light.terminal_state_style);
    // { shape: 'circle' }

    Returns Partial<JssmStateDeclaration>

    The JssmStateConfig for terminal states.

  • get themes(): "default" | "ocean" | "modern" | "plain" | "bold" | ("default" | "ocean" | "modern" | "plain" | "bold")[]
  • set themes(to: "default" | "ocean" | "modern" | "plain" | "bold" | ("default" | "ocean" | "modern" | "plain" | "bold")[]): void
  • Get the active theme(s) for this machine. Always stored as an array internally; the union return type exists for setter compatibility.

    Returns "default" | "ocean" | "modern" | "plain" | "bold" | ("default" | "ocean" | "modern" | "plain" | "bold")[]

    The current theme or array of themes.

  • Set the active theme(s). Accepts a single theme name or an array.

    Parameters

    • to: "default" | "ocean" | "modern" | "plain" | "bold" | ("default" | "ocean" | "modern" | "plain" | "bold")[]

      A theme name or array of theme names to apply.

    Returns void

    The current theme or array of themes.

  • get uses_actions(): boolean
  • Whether any actions are defined on this machine.

    Returns boolean

    true if the machine has at least one action.

  • get uses_forced_transitions(): boolean
  • Whether any forced (~>) transitions exist in this machine.

    Returns boolean

    true if at least one forced transition is defined.

Methods

  • Folds the static tiers 1–5 of the unified config cascade for a state, plus — when active is set — the active-state THEME layers, which historically sit just below the per-state config so that a state foo : { … } block still overrides a theme's active styling. The user active_state : { … } overlay (tier 6) is NOT applied here; it is layered on top by resolve_state_config so it wins over per-state config.

    Tiers, folded least-specific → most-specific with {@link merge_state_config} (later wins, never throwing on a cross-tier key collision):

    1. theme defaults — base_theme.state, then each selected theme's .state block.
    2. default_state_config (the implicit state : { … } root over every state).
    3. static per-kind defaults selected by structural kind — terminal, then start, then end — each contributing its base_theme.<kind>, selected themes' .<kind>, and the machine's default_<kind>_state_config. When active, the active-state theme layers (base_theme.active and each selected theme's .active) are folded here too.
    4. group metadata, depth-ordered outer→inner (see _groups_by_depth), each group's RAW { declarations } already condensed at construction.
    5. the per-state state foo : { … } config.
    internal

    Parameters

    • state: string

      The state to resolve config for.

    • active: boolean

      Whether to include the active-state theme layers (true only for the machine's currently-occupied state).

    Returns Partial<JssmStateDeclaration>

    The composited tiers-1–5 JssmStateConfig for the state.

  • Dispatch an event to every registered subscriber in registration order. Filters are checked first; non-matching handlers are skipped without invoking the handler. Exceptions thrown by a handler are caught and re-emitted as an error event so subsequent handlers still run.

    Re-entry into the error event itself is guarded — if an error handler throws, the new exception is swallowed rather than rebroadcast to avoid an infinite loop.

    When exactly one subscriber is registered the common case avoids the Array.from(set) snapshot allocation by capturing the lone entry into a local first — equivalent to a 1-element snapshot but allocation-free. The general path still snapshots for re-entrancy safety.

    internal

    Type Parameters

    Parameters

    Returns void

  • _fire_boundary_actions(prev_state: string, next_state: string): void
  • Fire the FSL boundary-hook actions for a single, already-committed state change. In FSL, do is a synonym for action, so on enter &g do 'X'; means "when the machine crosses INTO group g, dispatch machine action X" — and likewise on exit / plain-state subjects. This is the runtime that fires those parked hooks.

    Crossing semantics (statechart convention — exits before enters):

    1. prev_groups / next_groups are the deep (transitive) group sets of the old and new states, from _state_to_groups.
    2. Exits fire first: every group in prev_groups \ next_groups with an onExit, plus the plain prev_state's onExit (when the state name actually changed).
    3. Enters fire next: every group in next_groups \ prev_groups with an onEnter, plus the plain next_state's onEnter (when the state name changed).
    4. A group present in BOTH sets is a transition within that group and fires neither of its boundary hooks. prev_state === next_state fires nothing at all.
    5. "Fire its action" is this.action(label). If that action is not valid from the current state, action is a safe no-op (returns false) — an inapplicable boundary action never throws.
    6. Multi-membership and nesting both fan out naturally: a state in groups A and B fires both; crossing an inner and an outer boundary fires both levels.

    Because firing an action can drive a further transition (which crosses more boundaries, which fires more actions), this is a bounded run-to-completion: _boundary_depth tracks the live cascade depth and a cascade deeper than _boundary_depth_limit throws a JssmError rather than overflowing the stack or hanging. The limit defaults to 100 and is configurable via the boundary_depth_limit constructor option.

    throws

    {JssmError} If cascaded boundary firing exceeds _boundary_depth_limit (a probable infinite loop).

    see

    action

    see

    transition_impl

    internal

    Parameters

    • prev_state: string

      The state the machine was in before this commit.

    • next_state: string

      The state the machine is in now (already committed).

    Returns void

  • _fire_hook_rejection(hook_name: string, fromState: string, newState: string, fromAction: string, oldData: mDT, newData: mDT, wasForced: boolean): void
  • Fire a 'rejection' event caused by a hook vetoing a pending transition. Extracted from the per-call closures inside transition_impl so that it is allocated once at class-definition time rather than on every hooked transition.

    see

    transition_impl

    see

    _fire

    internal

    Parameters

    • hook_name: string

      Name of the hook that rejected (e.g. 'exit').

    • fromState: string

      State the machine was in when the transition was attempted; used as the from field of the rejection event.

    • newState: string

      State that would have been entered had the hook passed; used as the to field of the rejection event.

    • fromAction: string

      Action name when the transition was initiated by an action call; undefined for plain state transitions.

    • oldData: mDT

      Machine data at the moment the transition was attempted, before any hook mutations.

    • newData: mDT

      The next_data value passed to the transition call.

    • wasForced: boolean

      Whether the transition was attempted via force_transition.

    Returns void

  • Invoke a single event-handler entry, respecting its filter, once-removal semantics, and the error re-fire / recursion-guard logic. Extracted so _fire can share identical behavior between the size-1 fast-path and the general snapshotted loop.

    internal

    Type Parameters

    Parameters

    • entry: JssmEventEntry<mDT, Ev>

      The subscriber descriptor to invoke.

    • set: Set<JssmEventEntry<any, any>>

      The live Set that owns entry; needed for once-removal.

    • name: Ev

      The event name being dispatched (used in error re-fires).

    • detail: JssmEventDetailMap<mDT>[Ev]

      The event payload forwarded to the handler.

    Returns void

  • _groups_by_depth(state: string): string[]
  • Orders the groups a state belongs to by nesting depth for the config cascade — outermost first, innermost last — so that, folded in order, the innermost (nearest / smallest {@link membership_distance}) group's metadata wins. Equal-distance groups are ordered by group declaration order, so a later-declared group of the same depth wins the tie.

    Concretely: groups are sorted by descending membership distance (largest distance applied first / wins least), and for equal distances by ascending declaration index (later index applied last / wins most).

    internal

    Parameters

    • state: string

      The state whose containing groups are being ordered.

    Returns string[]

    The containing group names, ordered for outer→inner folding (the last entry wins).

  • Reads the condensed per-state style fields (color, shape, …) out of a state's declaration into a fresh JssmStateConfig — the tier-5 "state foo : { … }" contribution of the config cascade. A state with no declaration yields an all-undefined config (which contributes nothing once folded with {@link merge_state_config}).

    internal

    Parameters

    • state: string

      The state whose per-state declared style is wanted.

    Returns Partial<JssmStateDeclaration>

    The per-state style config (fields may be undefined).

  • Returns the list of resolved theme implementations for this machine, in the order they should layer (outer/base-most first). Each declared theme name is mapped through {@link theme_mapping}; unknown names are skipped.

    The list is reversed relative to declaration order to match the historical layering of style_for: a later-declared theme layers under an earlier-declared one.

    internal

    Returns JssmBaseTheme[]

    The resolved JssmBaseTheme stack, base-most first.

  • Remove one event-subscription entry from its set and keep Machine._event_listener_count in sync. The count is decremented only when the entry was actually present, so calling a stale unsubscribe closure (or removing an already-fired once entry) is idempotent and cannot drive the count negative.

    internal

    Parameters

    Returns void

  • Validate a HookDescription before registration. Every hook needs a handler function, and each kind's identifying spatial fields (from/to/action) must be exactly those set_hook reads for that kind — present when required, absent otherwise. This turns a mis-shaped descriptor into a thrown error instead of a silently dead hook keyed on undefined (e.g. an exit hook handed to instead of from, #734).

    throws

    JssmError if the kind is unknown, the handler is not a function, a required field is missing, or an inapplicable field is present.

    example

    const m = sma -> b;; // an exit hook is keyed by from, so supplying to is rejected: expect(() => m.set_hook({ kind: 'exit', to: 'a', handler: () => true })).toThrow();

    Parameters

    Returns void

  • action(actionName: string, newData?: mDT): boolean
  • Instruct the machine to complete an action. Synonym for do.

    const light = sm`red 'next' -> green 'next' -> yellow 'next' -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`;

    light.state(); // 'red'
    light.action('next'); // true
    light.state(); // 'green'

    Parameters

    • actionName: string

      The action to engage

    • Optional newData: mDT

      The data change to insert during the action

    Returns boolean

    true if the action was valid and the transition occurred, false otherwise.

  • actions(whichState?: string): string[]
  • List all actions available from this state. Please note that the order of the actions is not guaranteed.

    import { sm } from 'jssm';

    const machine = sm`
    red 'next' -> green 'next' -> yellow 'next' -> red;
    [red yellow green] 'shutdown' ~> off 'start' -> red;
    `;

    console.log( machine.state() ); // logs 'red'
    console.log( machine.actions() ); // logs ['next', 'shutdown']

    machine.action('next'); // true
    console.log( machine.state() ); // logs 'green'
    console.log( machine.actions() ); // logs ['next', 'shutdown']

    machine.action('shutdown'); // true
    console.log( machine.state() ); // logs 'off'
    console.log( machine.actions() ); // logs ['start']

    machine.action('start'); // true
    console.log( machine.state() ); // logs 'red'
    console.log( machine.actions() ); // logs ['next', 'shutdown']

    Parameters

    • whichState: string = ...

      The state whose actions to list. Defaults to the current state.

    Returns string[]

    An array of action names available from the given state.

  • all_action_label_chars(): readonly { from: string; to: string }[]
  • List the character ranges accepted inside a single-quoted FSL action label without escaping. Space is allowed; the apostrophe ' is explicitly excluded since it terminates the label.

    example

    import { sm } from 'jssm'; const m = sma -> b;; m.all_action_label_chars().some(r => ' ' >= r.from && ' ' <= r.to); // => true m.all_action_label_chars().some(r => "'" >= r.from && "'" <= r.to); // => false

    Returns readonly { from: string; to: string }[]

    An array of {from, to} inclusive character ranges.

  • all_state_name_chars(): readonly { from: string; to: string }[]
  • List the character ranges accepted by the FSL grammar in any but the first position of a state name (atom). Each entry is an inclusive {from, to} range of single Unicode characters.

    example

    import { sm } from 'jssm'; const m = sma -> b;; m.all_state_name_chars().some(r => '+' >= r.from && '+' <= r.to); // => true

    Returns readonly { from: string; to: string }[]

    An array of {from, to} inclusive character ranges.

  • all_state_name_first_chars(): readonly { from: string; to: string }[]
  • List the character ranges accepted by the FSL grammar in the first position of a state name (atom). Narrower than all_state_name_chars: notably omits +, (, ), &, #, @.

    example

    import { sm } from 'jssm'; const m = sma -> b;; m.all_state_name_first_chars().some(r => '+' >= r.from && '+' <= r.to); // => false

    Returns readonly { from: string; to: string }[]

    An array of {from, to} inclusive character ranges.

  • all_themes(): ("default" | "ocean" | "modern" | "plain" | "bold")[]
  • List all available theme names.

    Returns ("default" | "ocean" | "modern" | "plain" | "bold")[]

    An array of theme name strings.

  • auto_set_state_timeout(): void
  • If the current state has an after timeout configured, schedule it. Called internally after each transition.

    Returns void

  • clear_state_timeout(): void
  • Cancel any pending state timeout. Safe to call when no timeout is active.

    Returns void

  • Get the full transition object for an action from the current state.

    throws

    {JssmError} If the action is not available from the current state.

    Parameters

    • action: string

      The action name.

    Returns JssmTransition<string, mDT>

    The JssmTransition object.

  • current_action_for(action: string): number
  • Get the edge index for an action from the current state. Interned dispatch: resolves via the numeric (action, from) index — unknown action names miss without throwing.

    Parameters

    • action: string

      The action name.

    Returns number

    The edge index, or undefined if the action is not available.

  • current_state_timeout(): [string, number]
  • Get the configured after timeout for the current state, if any.

    Returns [string, number]

    A [targetState, delayMs] tuple, or undefined.

  • data(): mDT
  • Get the current data of a machine.

    import * as jssm from 'jssm';

    const lswitch = jssm.from('on <=> off;', {data: 1});
    console.log( lswitch.data() ); // 1

    Returns mDT

    A deep clone of the machine's current data value.

  • Get the consolidated graph: {} default-config block: the ordered, de-duplicated { key, value }[] list of graph-scope style items. The compiler folds the deprecated top-level graph keywords (graph_bg_colorbackground-color, plus graph_layout, theme, flow, dot_preamble) into this list first, then lets an explicit graph: {} block win on key conflict. The viz layer projects the graph-meaningful keys onto graph-scope Graphviz attributes (e.g. background-colorbgcolor).

    import { sm } from 'jssm';
    sm`a -> b; graph: { background-color: #ffffff; };`.default_graph_config();
    // [ { key: 'background-color', value: '#ffffffff' } ]
    see

    default_transition_config

    Returns JssmGraphConfig

    The graph-config item list, or undefined if the machine has no graph config (no graph: {} block and no deprecated graph keyword).

  • Get the render-size hint for the machine's visualization. Set via the FSL default_size directive. Returns undefined when not present.

    The three FSL forms each produce a different subset of fields:

    • default_size: 800;{ width: 800 }
    • default_size: 800 600;{ width: 800, height: 600 }
    • default_size: height 600;{ height: 600 }

    This is a hint, not a hard constraint. Renderers may ignore it.

    see

    npm_name

    Returns JssmDefaultSize

    The size-hint object, or undefined if not set.

  • Get the consolidated transition: {} default-config block: the ordered, de-duplicated { key, value }[] list of edge-default style items compiled from a transition: {} block (e.g. transition: { color: blue; }). The viz layer projects this onto a Graphviz edge [ … ] default statement so every edge inherits it.

    import { sm } from 'jssm';
    sm`a -> b; transition: { color: blue; };`.default_transition_config();
    // [ { key: 'color', value: '#0000ffff' } ]
    see

    default_graph_config

    Returns JssmTransitionConfig

    The transition-config item list, or undefined if the machine declared no transition: {} block.

  • display_text(state: string): string
  • Get whatever the node should show as text.

    Currently, this means to get the label for a given state, if any; otherwise to return the node's name. However, this definition is expected to grow with time, and it is currently considered ill-advised to manually parse this text.

    See also label_for.

    import * as jssm from 'jssm';

    const lswitch = jssm.from('a -> b; state a: { label: "Foo!"; };');
    console.log( lswitch.display_text('a') ); // 'Foo!'
    console.log( lswitch.display_text('b') ); // 'b'

    Parameters

    • state: string

      The state to get display text for.

    Returns string

    The label if one exists, otherwise the state's name.

  • do(actionName: string, newData?: mDT): boolean
  • Instruct the machine to complete an action. Synonym for action.

    const light = sm`
    off 'start' -> red;
    red 'next' -> green 'next' -> yellow 'next' -> red;
    [red yellow green] 'shutdown' ~> off;
    `;

    light.state(); // 'off'
    light.do('start'); // true
    light.state(); // 'red'
    light.do('next'); // true
    light.state(); // 'green'
    light.do('next'); // true
    light.state(); // 'yellow'
    light.do('dance'); // !! false - no such action
    light.state(); // 'yellow'
    light.do('start'); // !! false - yellow does not have the action start
    light.state(); // 'yellow'

    Parameters

    • actionName: string

      The action to engage

    • Optional newData: mDT

      The data change to insert during the action

    Returns boolean

    true if the action was valid and the transition occurred, false otherwise.

  • dot_preamble(): string
  • Get the Graphviz DOT preamble string, injected before the graph body during visualization. Set via the FSL dot_preamble directive.

    Returns string

    The preamble string.

  • edges_between(from: string, to: string): JssmTransition<string, mDT>[]
  • Get all edges between two states (there can be multiple with different actions).

    Parameters

    • from: string

      Source state name.

    • to: string

      Target state name.

    Returns JssmTransition<string, mDT>[]

    An array of matching JssmTransition objects.

  • failed_outputs(): string[]
  • Get the set of states declared as failure outputs for this machine. Returns an array of state labels, or an empty array when none were declared. A state in this list means the machine is in a failure condition when it occupies that state.

    see

    is_failed_output to test a single state

    see

    is_failed to test the current state

    Returns string[]

  • flow(): "up" | "right" | "down" | "left"
  • Get the flow direction for graph layout (e.g. 'right', 'down'). Set via the FSL flow directive.

    Returns "up" | "right" | "down" | "left"

    The current flow direction.

  • force_transition(newState: string, newData?: mDT): boolean
  • Instruct the machine to complete a forced transition (which will reject if called with a normal transition call.)

    const light = sm`red -> green -> yellow -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`;

    light.state(); // 'red'
    light.transition('off'); // false
    light.state(); // 'red'
    light.force_transition('off'); // true
    light.state(); // 'off'

    Parameters

    • newState: string

      The state to switch to

    • Optional newData: mDT

      The data change to insert during the transition

    Returns boolean

    true if a transition (forced or otherwise) existed and occurred, false otherwise.

  • fsl_version(): string
  • Get the FSL language version this machine was compiled under.

    Returns string

    The FSL version string.

  • get_transition_by_state_names(from: string, to: string): number
  • Look up a transition's edge index by source and target state names.

    Parameters

    • from: string

      Source state name.

    • to: string

      Target state name.

    Returns number

    The edge index in the edges array, or undefined if no such transition exists.

  • go(newState: string, newData?: mDT): boolean
  • Instruct the machine to complete a transition. Synonym for transition.

    const light = sm`red -> green -> yellow -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`;

    light.state(); // 'red'
    light.go('green'); // true
    light.state(); // 'green'

    Parameters

    • newState: string

      The state to switch to

    • Optional newData: mDT

      The data change to insert during the transition

    Returns boolean

    true if the transition was legal and occurred, false otherwise.

  • graph_layout(): string
  • Get the graph layout direction (e.g. 'LR', 'TB'). Set via the FSL graph_layout directive.

    Returns string

    The layout string, or the default if not set.

  • groups(): string[]
  • Lists all declared group names, in source declaration order. The order matches the order the &group : [ … ]; declarations appear in the FSL, and is the same order used to break depth-specificity ties in the config cascade. Machines that declare no groups return an empty array.

    import { sm } from 'jssm';

    const m = sm`&first : [a]; &second : [b]; a -> b;`;
    m.groups(); // [ 'first', 'second' ]
    see

    groupsOf

    see

    statesIn

    Returns string[]

    The declared group names, in declaration order.

  • groupsOf(state: string): Set<string>
  • Lists every group that transitively contains a given state. Membership is deep — direct, nested, and spread sub-group containment all count — and the result is the precomputed inverse-index entry for the state, so the lookup is constant-time. A state that belongs to no group (or a state name that appears in no group) yields an empty Set.

    import { sm } from 'jssm';

    const m = sm`&inner : [a]; &outer : [&inner b]; a -> b;`;
    m.groupsOf('a'); // Set { 'inner', 'outer' } — deep through &inner
    m.groupsOf('b'); // Set { 'outer' }
    m.groupsOf('z'); // Set {} — not in any group
    see

    isIn

    see

    groups

    Parameters

    • state: string

      The state whose containing groups are wanted.

    Returns Set<string>

    A Set of every group name transitively containing state; empty when state belongs to no group.

  • has_completes(): boolean
  • Check whether any state in the machine is complete.

    Returns boolean

    true if at least one state is complete.

  • Is at least one observational hook bound to the given target (megaspec §12)? The query is read exactly as in Machine.hooks_on. An optional phase narrows the test to pre- or post-transition hooks only; omitted, either phase satisfies it.

    const m = sm`a -> b;`;
    m.has_hook('b'); // false
    m.hook_entry('b', () => true);
    m.has_hook('b'); // true
    m.has_hook('b', 'post'); // false (the entry hook is pre-phase)

    Parameters

    Returns boolean

    true when a matching hook exists.

  • has_state(whichState: string): boolean
  • Check whether the machine knows a given state.

    import * as jssm from 'jssm';

    const lswitch = jssm.from('on <=> off;');

    console.log( lswitch.has_state('off') ); // true
    console.log( lswitch.has_state('dance') ); // false

    Parameters

    • whichState: string

      The state to be checked for existence.

    Returns boolean

    true if the state exists, false otherwise.

  • has_terminals(): boolean
  • Check whether any state in the machine is terminal.

    Returns boolean

    true if at least one state has no exits.

  • has_unenterables(): boolean
  • Check whether any state in the machine is unenterable.

    Returns boolean

    true if at least one state has no incoming transitions.

  • Register a pre-transition hook on a specific edge. Fires before transitioning from from to to. If the handler returns false, the transition is blocked.

    const m = sm`a -> b -> c;`;
    m.hook('a', 'b', () => console.log('a->b'));

    Parameters

    • from: string

      Source state name.

    • to: string

      Target state name.

    • handler: HookHandler<mDT>

      Callback invoked before the transition.

    Returns Machine<mDT>

    this for chaining.

  • hook_action(from: string, to: string, action: string, handler: HookHandler<mDT>): Machine<mDT>
  • Register a pre-transition hook on a specific action-labeled edge.

    Parameters

    • from: string

      Source state name.

    • to: string

      Target state name.

    • action: string

      The action label that triggers this hook.

    • handler: HookHandler<mDT>

      Callback invoked before the transition.

    Returns Machine<mDT>

    this for chaining.

  • Register a hook that fires when a state's after timer elapses — the delay-over companion to a after 5s -> b; style time transitions. It does NOT fire when the state is entered or left by ordinary dispatch; use hook_entry / hook_exit for those. (Versions through 5.143.28 also spuriously fired it on entering the state, the jssm side of StoneCypher/fsl#1327.)

    example

    const m = sma after 1000 -> b; a -> c; c -> a;; let calls = 0; m.hook_after('a', () => { calls += 1; }); m.go('c'); m.go('a'); // ordinary dispatch never fires it; only the timer elapsing does: calls; // => 0 m.clear_state_timeout();

    see

    hook_entry

    see

    hook_exit

    see

    set_state_timeout

    Parameters

    • from: string

      The state whose after timer is being watched.

    • handler: HookHandler<mDT>

      Callback invoked when the timer fires, just before the timed transition is taken; informational — its outcome cannot reject the transition.

    Returns Machine<mDT>

    this for chaining.

  • Register a pre-transition hook on any action-driven transition.

    Parameters

    • handler: HookHandler<mDT>

      Callback invoked before any action transition.

    Returns Machine<mDT>

    this for chaining.

  • Register a pre-transition hook on any transition regardless of kind.

    Parameters

    • handler: HookHandler<mDT>

      Callback invoked before every transition.

    Returns Machine<mDT>

    this for chaining.

  • Register a hook that fires when entering a specific state.

    Parameters

    • to: string

      The state being entered.

    • handler: HookHandler<mDT>

      Callback invoked on entry.

    Returns Machine<mDT>

    this for chaining.

  • Register a pre-transition hook that fires after all other pre-hooks on every transition. If the handler returns false, the transition is blocked. The handler receives an EverythingHookContext whose hook_name is 'everything'.

    const m = sm`a -> b -> c;`;
    m.hook_everything(({ hook_name }) => {
    console.log(`${hook_name} fired`);
    return true;
    });

    Parameters

    Returns Machine<mDT>

    this for chaining.

  • Register a hook that fires when leaving a specific state.

    Parameters

    • from: string

      The state being exited.

    • handler: HookHandler<mDT>

      Callback invoked on exit.

    Returns Machine<mDT>

    this for chaining.

  • Register a pre-transition hook on any forced (~>) transition.

    Parameters

    • handler: HookHandler<mDT>

      Callback invoked before any forced transition.

    Returns Machine<mDT>

    this for chaining.

  • Register a pre-transition hook on any edge triggered by a specific action.

    Parameters

    • action: string

      The action name to hook.

    • handler: HookHandler<mDT>

      Callback invoked before any transition with this action.

    Returns Machine<mDT>

    this for chaining.

  • Register a pre-transition hook on any main-path (=>) transition.

    Parameters

    • handler: HookHandler<mDT>

      Callback invoked before any main transition.

    Returns Machine<mDT>

    this for chaining.

  • Register a post-transition hook that fires after all other post-hooks on every transition. Cannot block the transition. The handler receives an EverythingHookContext whose hook_name is 'post everything'.

    const m = sm`a -> b -> c;`;
    m.hook_post_everything(({ hook_name }) => {
    console.log(`${hook_name} fired`);
    });

    Parameters

    Returns Machine<mDT>

    this for chaining.

  • Register a pre-transition hook that fires before all other pre-hooks on every transition. If the handler returns false, the transition is blocked. The handler receives an EverythingHookContext whose hook_name is 'pre everything'.

    const m = sm`a -> b -> c;`;
    m.hook_pre_everything(({ hook_name }) => {
    console.log(`${hook_name} fired`);
    return true;
    });

    Parameters

    Returns Machine<mDT>

    this for chaining.

  • Register a post-transition hook that fires before all other post-hooks on every transition. Cannot block the transition. The handler receives an EverythingHookContext whose hook_name is 'pre post everything'.

    const m = sm`a -> b -> c;`;
    m.hook_pre_post_everything(({ hook_name }) => {
    console.log(`${hook_name} fired`);
    });

    Parameters

    Returns Machine<mDT>

    this for chaining.

  • Generate the uniform observational-hook registry — every currently registered hook projected onto a normalized (kind, target, phase) row (megaspec §12, → #1357). The registry is generated on demand by walking the concrete per-kind storage tables rather than maintained as a second copy, so it can never drift from the tables Machine.set_hook actually dispatches into. It is the single source of truth behind the introspection accessors (Machine.has_hook, Machine.hooks_on) and the hooked_state viz styling.

    Targets are normalized: edge hooks become { scope: 'edge', from, to } (named hooks add action), entry/exit/after become { scope: 'state' }, global-action hooks become { scope: 'action' }, and the any-*, transition-class, and everything observers become { scope: 'global' }.

    const m = sm`a 'go' -> b;`;
    m.hook_entry('b', () => true);
    m.hook_registry();
    // => [ { kind: 'entry', phase: 'pre', target: { scope: 'state', state: 'b' } } ]

    Returns HookRegistryEntry[]

    Every registered hook as a HookRegistryEntry, in a stable table-walk order (pre-phase tables first, then post-phase).

  • Register a pre-transition hook on any standard (->) transition.

    Parameters

    • handler: HookHandler<mDT>

      Callback invoked before any legal transition.

    Returns Machine<mDT>

    this for chaining.

  • Return every registry entry observing the given target (megaspec §12). The query selects the target shape:

    • a bare state name matches entry/exit/after hooks on that state, its state-boundary hooks, and every edge hook touching it (from or to),
    • a { from, to, action? } edge matches edge hooks on that transition (optionally narrowed to the named action),
    • a { action } action matches global-action and named-edge hooks carrying that action,
    • a { group } group matches that group's boundary hooks (group hooks are matched by name only and do not propagate to member states).
    const m = sm`a 'go' -> b;`;
    m.hook_entry('b', () => true);
    m.hooks_on('b').length; // 1
    m.hooks_on({ from: 'a', to: 'b' }); // [] (no edge hook registered)

    Parameters

    Returns HookRegistryEntry[]

    The matching HookRegistryEntry rows (possibly empty).

  • instance_name(): string
  • Get the instance name of this machine, if one was assigned at creation.

    Returns string

    The instance name string, or undefined.

  • isIn(groupName: string): boolean
  • Reports whether the machine's CURRENT state is a transitive member of a named group. Membership is deep: a state counts as in groupName if it belongs to that group directly, or via any nested (&child) or spread (...&child) sub-group, at any depth. An undeclared group simply has no members, so this returns false rather than throwing.

    import { sm } from 'jssm';

    const m = sm`&busy : [working]; idle 'go' -> working;`;
    m.isIn('busy'); // false — current state is 'idle'
    m.action('go');
    m.isIn('busy'); // true — current state is now 'working'
    m.isIn('nonesuch'); // false — undeclared group has no members
    see

    groupsOf

    see

    statesIn

    Parameters

    • groupName: string

      The group to test the current state against.

    Returns boolean

    true if the current state is a transitive member of groupName.

  • is_complete(): boolean
  • Check whether the current state is complete (every exit has an action).

    Returns boolean

    true if the current state is complete.

  • is_end_state(whichState: string): boolean
  • Check whether a given state is a valid start state (either because it was explicitly named as such, or because it was the first mentioned state.)

    import { sm, is_end_state } from 'jssm';

    const example = sm`a -> b;`;

    console.log( final_test.is_start_state('a') ); // false
    console.log( final_test.is_start_state('b') ); // true

    const example = sm`end_states: [a b]; a -> b;`;

    console.log( final_test.is_start_state('a') ); // true
    console.log( final_test.is_start_state('b') ); // true

    Parameters

    • whichState: string

      The name of the state to check

    Returns boolean

  • is_failed(): boolean
  • Check whether the machine is currently in a failure state — that is, whether its current state is one of the declared failed_outputs.

    see

    failed_outputs for the full failure-output set

    see

    is_failed_output to test an arbitrary state

    Returns boolean

  • is_failed_output(whichState: string): boolean
  • Check whether a given state is declared as a failure output.

    see

    failed_outputs for the full failure-output set

    see

    is_failed to test the current state

    Parameters

    • whichState: string

      The name of the state to check

    Returns boolean

  • is_final(): boolean
  • Check whether the current state is final (either has no exits or is marked complete.)

    import { sm, is_final } from 'jssm';

    const final_test = sm`first -> second;`;

    console.log( final_test.is_final() ); // false
    state.transition('second');
    console.log( final_test.is_final() ); // true

    Returns boolean

  • is_start_state(whichState: string): boolean
  • Check whether a given state is a valid start state (either because it was explicitly named as such, or because it was the first mentioned state.)

    import { sm, is_start_state } from 'jssm';

    const example = sm`a -> b;`;

    console.log( final_test.is_start_state('a') ); // true
    console.log( final_test.is_start_state('b') ); // false

    const example = sm`start_states: [a b]; a -> b;`;

    console.log( final_test.is_start_state('a') ); // true
    console.log( final_test.is_start_state('b') ); // true

    Parameters

    • whichState: string

      The name of the state to check

    Returns boolean

  • is_terminal(): boolean
  • Check whether the current state is terminal (has no exits).

    Returns boolean

    true if the current state has zero exits.

  • is_unenterable(whichState: string): boolean
  • Check whether a state has no incoming transitions (unreachable after start).

    throws

    {JssmError} If the state does not exist.

    Parameters

    • whichState: string

      The state to check.

    Returns boolean

    true if the state has zero entrances.

  • known_prop(prop_name: string): boolean
  • Check whether a given string is a known property's name.

    const example = sm`property foo default 1; a->b;`;

    example.known_prop('foo'); // true
    example.known_prop('bar'); // false

    Parameters

    • prop_name: string

      The relevant property name to look up

    Returns boolean

  • known_props(): string[]
  • List all known property names. If you'd also like values, use props instead. The order of the properties is not defined, and the properties generally will not be sorted.

    const m = sm`property color default "grey"; property size default 1; a -> b;`;

    m.known_props(); // ['color', 'size']

    Returns string[]

    An array of all property name strings defined on this machine.

  • label_for(state: string): string
  • Get the label for a given state, if any; return undefined otherwise.

    import * as jssm from 'jssm';

    const lswitch = jssm.from('a -> b; state a: { label: "Foo!"; };');
    console.log( lswitch.label_for('a') ); // 'Foo!'
    console.log( lswitch.label_for('b') ); // undefined

    See also display_text.

    Parameters

    • state: string

      The state to get the label for.

    Returns string

    The label string, or undefined if no label is set.

  • list_actions(): string[]
  • List all distinct action names defined anywhere in the machine.

    Returns string[]

    An array of action name strings.

  • Lists all edges of a machine.

    import { sm } from 'jssm';

    const lswitch = sm`on 'toggle' <=> 'toggle' off;`;

    lswitch.list_edges();
    [
    {
    from: 'on',
    to: 'off',
    kind: 'main',
    forced_only: false,
    main_path: true,
    action: 'toggle'
    },
    {
    from: 'off',
    to: 'on',
    kind: 'main',
    forced_only: false,
    main_path: true,
    action: 'toggle'
    }
    ]

    Returns JssmTransition<string, mDT>[]

    An array of all JssmTransition edge objects.

  • list_entrances(whichState?: string): string[]
  • List all entrances attached to the current state. Please note that the order of the list is not defined. This list includes both unforced and forced entrances; if this isn't desired, consider {@link list_unforced_entrances} or {@link list_forced_entrances} as appropriate.

    import { sm } from 'jssm';

    const light = sm`red 'next' -> green 'next' -> yellow 'next' -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`;

    light.state(); // 'red'
    light.list_entrances(); // [ 'yellow', 'off' ]

    Parameters

    • whichState: string = ...

      The state whose entrances to have listed

    Returns string[]

  • list_exit_actions(whichState?: string): string[]
  • List all action names available as exits from a given state.

    Returns the empty array (does not throw) when whichState exists but has no action-named exits — including terminal states, states whose only exits are plain -> transitions, and states in machines that use no actions at all. Only nonexistent states cause a throw.

    throws

    {JssmError} If the state does not exist.

    example

    const m = sma 'go' -> b; b -> c;; m.list_exit_actions('a'); // => ['go'] m.list_exit_actions('b'); // => [] m.list_exit_actions('c'); // => [] expect(() => m.list_exit_actions('z')).toThrow();

    Parameters

    • whichState: string = ...

      The state to inspect. Defaults to the current state.

    Returns string[]

    An array of action name strings, possibly empty.

  • list_exits(whichState?: string): string[]
  • List all exits attached to the current state. Please note that the order of the list is not defined. This list includes both unforced and forced exits; if this isn't desired, consider {@link list_unforced_exits} or {@link list_forced_exits} as appropriate.

    import { sm } from 'jssm';

    const light = sm`red 'next' -> green 'next' -> yellow 'next' -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`;

    light.state(); // 'red'
    light.list_exits(); // [ 'green', 'off' ]

    Parameters

    • whichState: string = ...

      The state whose exits to have listed

    Returns string[]

  • list_named_transitions(): Map<string, number>
  • Get the map of named transitions (transitions with explicit names).

    Returns Map<string, number>

    A Map from transition name to edge index.

  • list_states_having_action(whichState: string): string[]
  • List all states that have a specific action attached. Please note that the order of the states is not guaranteed.

    import { sm } from 'jssm';

    const machine = sm`
    red 'next' -> green 'next' -> yellow 'next' -> red;
    [red yellow green] 'shutdown' ~> off 'start' -> red;
    `;

    console.log( machine.list_states_having_action('next') ); // ['red', 'green', 'yellow']
    console.log( machine.list_states_having_action('start') ); // ['off']

    Parameters

    • whichState: string

      The action to be checked for associated states

    Returns string[]

  • List all transitions attached to the current state, sorted by entrance and exit. The order of each sublist is not defined. A node could appear in both lists.

    import { sm } from 'jssm';

    const light = sm`red 'next' -> green 'next' -> yellow 'next' -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`;

    light.state(); // 'red'
    light.list_transitions(); // { entrances: [ 'yellow', 'off' ], exits: [ 'green', 'off' ] }

    Parameters

    • whichState: string = ...

      The state whose transitions to have listed

    Returns JssmTransitionList

  • lookup_transition_for(from: string, to: string): JssmTransition<string, mDT>
  • Look up the full transition object for a given source→target pair.

    Parameters

    • from: string

      Source state name.

    • to: string

      Target state name.

    Returns JssmTransition<string, mDT>

    The JssmTransition object, or undefined if none exists.

  • machine_author(): string[]
  • Get the machine's author list. Set via the FSL machine_author directive.

    Returns string[]

    An array of author name strings.

  • machine_comment(): string
  • Get the machine's comment string. Set via the FSL machine_comment directive.

    Returns string

    The comment string.

  • machine_contributor(): string[]
  • Get the machine's contributor list. Set via the FSL machine_contributor directive.

    Returns string[]

    An array of contributor name strings.

  • machine_definition(): string
  • Get the machine's definition string. Set via the FSL machine_definition directive.

    Returns string

    The definition string.

  • machine_language(): string
  • Get the machine's natural language as an ISO 639-1 code. Set via the FSL machine_language directive, which accepts a language name or code, or a BCP-47 tag whose region subtag is dropped (en-us -> en). Unrecognized values resolve to undefined.

    Returns string

    The ISO 639-1 language code (e.g. 'en'), or undefined if the supplied value did not resolve to a known language.

  • machine_license(): string
  • Get the machine's license string. Set via the FSL machine_license directive.

    Returns string

    The license string.

  • machine_name(): string
  • Get the machine's name. Set via the FSL machine_name directive.

    Returns string

    The machine name string.

  • machine_version(): string
  • Get the machine's version string. Set via the FSL machine_version directive.

    Returns string

    The version string.

  • npm_name(): string
  • Get the npm package name associated with the machine. Set via the FSL npm_name directive. Returns undefined when not present.

    see

    machine_name

    Returns string

    The npm package name string, or undefined.

  • Remove a previously-registered event handler. Match is by reference — the same function value passed to Machine.on or Machine.once. Returns true if a subscription was found and removed, false otherwise.

    const fn = (e: any) => console.log(e);
    m.on('transition', fn);
    m.off('transition', fn); // true
    m.off('transition', fn); // false

    Type Parameters

    Parameters

    • name: Ev

      The event name.

    • handler: JssmEventHandler<mDT, Ev>

      The handler reference to remove.

    Returns boolean

    true if removed, false if no match was registered.

  • Subscribe to a typed observation event. Hooks (set_hook and friends) intercept and may cancel a transition; events fire alongside the same state-machine moments but cannot influence the outcome. This is the surface most users actually want for "tell me when state changes".

    Handlers run synchronously, in registration order. A throwing handler does not block subsequent handlers — its exception is caught and re-emitted as an error event whose detail names the original event and the offending handler.

    const m = sm`a -> b -> c;`;

    m.on('transition', e => console.log(`${e.from} -> ${e.to}`));
    m.on('entry', { state: 'b' }, e => console.log(`entered ${e.state}`));

    const off = m.on('transition', () => {});
    off(); // unsubscribe
    see

    Machine.off

    see

    Machine.once

    Type Parameters

    • Ev extends JssmEventName

      The event name (drives the detail type).

    Parameters

    Returns JssmUnsubscribe

    A function that unsubscribes when called.

  • Type Parameters

    Parameters

    Returns JssmUnsubscribe

  • override(newState: string, newData?: mDT): void
  • Replace the current state and data with no regard to the graph.

    import { sm } from 'jssm';

    const machine = sm`a -> b -> c;`;
    console.log( machine.state() ); // 'a'

    machine.go('b');
    machine.go('c');
    console.log( machine.state() ); // 'c'

    machine.override('a');
    console.log( machine.state() ); // 'a'

    Parameters

    • newState: string
    • Optional newData: mDT

    Returns void

  • Post-transition hook on a specific edge. Fires after the transition from from to to has completed. Cannot block the transition.

    Parameters

    • from: string

      Source state name.

    • to: string

      Target state name.

    • handler: HookHandler<mDT>

      Callback invoked after the transition.

    Returns Machine<mDT>

    this for chaining.

  • post_hook_action(from: string, to: string, action: string, handler: HookHandler<mDT>): Machine<mDT>
  • Post-transition hook on a specific action-labeled edge.

    Parameters

    • from: string

      Source state name.

    • to: string

      Target state name.

    • action: string

      The action label.

    • handler: HookHandler<mDT>

      Callback invoked after the transition.

    Returns Machine<mDT>

    this for chaining.

  • Post-transition hook on any action-driven transition.

    Parameters

    • handler: HookHandler<mDT>

      Callback invoked after any action transition.

    Returns Machine<mDT>

    this for chaining.

  • Post-transition hook on any transition regardless of kind.

    Parameters

    • handler: HookHandler<mDT>

      Callback invoked after every transition.

    Returns Machine<mDT>

    this for chaining.

  • Post-transition hook that fires after entering a specific state.

    Parameters

    • to: string

      The state that was entered.

    • handler: HookHandler<mDT>

      Callback invoked after entry.

    Returns Machine<mDT>

    this for chaining.

  • Post-transition hook that fires after leaving a specific state.

    Parameters

    • from: string

      The state that was exited.

    • handler: HookHandler<mDT>

      Callback invoked after exit.

    Returns Machine<mDT>

    this for chaining.

  • Post-transition hook on any forced (~>) transition.

    Parameters

    • handler: HookHandler<mDT>

      Callback invoked after any forced transition.

    Returns Machine<mDT>

    this for chaining.

  • Post-transition hook on any edge triggered by a specific action.

    Parameters

    • action: string

      The action name.

    • handler: HookHandler<mDT>

      Callback invoked after any transition with this action.

    Returns Machine<mDT>

    this for chaining.

  • Post-transition hook on any main-path (=>) transition.

    Parameters

    • handler: HookHandler<mDT>

      Callback invoked after any main transition.

    Returns Machine<mDT>

    this for chaining.

  • Post-transition hook on any standard (->) transition.

    Parameters

    • handler: HookHandler<mDT>

      Callback invoked after any legal transition.

    Returns Machine<mDT>

    this for chaining.

  • probabilistic_histo_walk(n: number): Map<string, number>
  • Take n probabilistic steps and return a histograph of how many times each state was visited.

    Parameters

    • n: number

      Number of steps to walk.

    Returns Map<string, number>

    A Map from state name to visit count.

  • probabilistic_transition(): boolean
  • Take a single random transition from the current state, weighted by edge probabilities.

    Returns boolean

    true if a transition was taken, false otherwise.

  • probabilistic_walk(n: number): string[]
  • Take n consecutive probabilistic transitions and return the sequence of states visited (before each transition).

    Parameters

    • n: number

      Number of steps to walk.

    Returns string[]

    An array of state names visited during the walk.

  • probable_action_exits(whichState?: string): any[]
  • List all action exits from a state with their probabilities.

    throws

    {JssmError} If the state does not exist.

    Parameters

    • whichState: string = ...

      The state to inspect. Defaults to the current state.

    Returns any[]

    An array of { action, probability } objects.

  • Get the transitions available from a state for use by the probabilistic walk system.

    If any exit declares a probability, only those probability-bearing exits are returned, so that non-probability peers cannot dilute the declared distribution. If no exit declares a probability, every legal (non-forced) exit is returned, which weighted_rand_select treats as equal weight. Forced-only exits (~>) are always excluded, since they cannot be taken by an ordinary transition() call.

    Fixes StoneCypher/fsl#1325, in which the function previously returned every exit unconditionally — including forced-only exits and exits with no probability, which distorted the weighted distribution.

    throws

    {JssmError} If the state does not exist.

    Parameters

    • whichState: string

      The state to inspect.

    Returns JssmTransition<string, mDT>[]

    An array of JssmTransition edges exiting the state, filtered as described above. May be empty.

  • prop(name: string): any
  • Get the current value of a given property name. Checks the current state's properties first, then falls back to the global default. Returns undefined if neither exists. For a throwing variant, see strict_prop.

    const m = sm`property color default "grey"; a -> b;
    state b: { property color "blue"; };`;

    m.prop('color'); // 'grey' (default, because state is 'a')
    m.go('b');
    m.prop('color'); // 'blue' (state 'b' overrides the default)
    m.prop('size'); // undefined (no such property)

    Parameters

    • name: string

      The relevant property name to look up.

    Returns any

    The value behind the prop name, or undefined if not defined.

  • props(): object
  • Get the current value of every prop, as an object. If no current definition exists for a prop — that is, if the prop was defined without a default and the current state also doesn't define the prop — then that prop will be listed in the returned object with a value of undefined.

    const traffic_light = sm`

    property can_go default true;
    property hesitate default true;
    property stop_first default false;

    Off -> Red => Green => Yellow => Red;
    [Red Yellow Green] ~> [Off FlashingRed];
    FlashingRed -> Red;

    state Red: { property stop_first true; property can_go false; };
    state Off: { property stop_first true; };
    state FlashingRed: { property stop_first true; };
    state Green: { property hesitate false; };

    `;

    traffic_light.state(); // Off
    traffic_light.props(); // { can_go: true, hesitate: true, stop_first: true; }

    traffic_light.go('Red');
    traffic_light.props(); // { can_go: false, hesitate: true, stop_first: true; }

    traffic_light.go('Green');
    traffic_light.props(); // { can_go: true, hesitate: false, stop_first: false; }

    Returns object

    An object mapping every known property name to its current value (or undefined if the property has no default and the current state doesn't define it).

  • Remove a previously-registered hook described by a HookDescription. Match is by kind + identifying keys (from/to/action/etc.), not by handler reference — there is one hook per slot in the registry, so the description uniquely identifies which one to clear. Fires a hook-removal event for inspector tools.

    This is the symmetric counterpart of Machine.set_hook for the event-bridging use case (#638). Reasoning about hooks via observation events requires being able to observe their disappearance too.

    const m = sm`a -> b;`;
    const fn = () => true;
    m.set_hook({ kind: 'hook', from: 'a', to: 'b', handler: fn });
    m.remove_hook({ kind: 'hook', from: 'a', to: 'b', handler: fn });

    Parameters

    • HookDesc: HookDescription<mDT>

      A hook descriptor identifying the hook to remove.

    Returns boolean

    true if a hook was removed, false otherwise.

  • Resolves the full unified style/config cascade for a state — the runtime successor to the ad-hoc layer merge style_for used to perform.

    For any state OTHER than the current one, this returns the memoized static resolution (tiers 1–5; see _compose_state_config) — theme → default_state_config → per-kind defaults → depth-ordered group metadata → per-state config. The cache is keyed by state and never invalidated, since those tiers do not depend on which state is current.

    For the machine's CURRENTLY-occupied state the result is recomputed each call (never cached) and additionally carries the dynamic active_state layers: the active-state THEME layers fold in just below the per-state config (tier 3-active), and the user active_state : { … } overlay folds in LAST (tier 6), on top of everything, so it wins over per-state config. Every fold uses {@link merge_state_config}, so a key set at a lower tier is overridden — never rejected — by a higher one.

    import { sm } from 'jssm';

    const m = sm`&busy : [working]; idle 'go' -> working; state &busy : { color: orange; };`;
    m.resolve_state_config('working').color; // '#ffa500ff' — from group &busy
    see

    style_for

    Parameters

    • state: string

      The state to compute the composite config for.

    Returns Partial<JssmStateDeclaration>

    The fully composited JssmStateConfig for the state, including the active overlay when the state is current.

  • Serialize the current machine, including all defining state but not the machine string, to a structure. This means you will need the machine string to recreate (to not waste repeated space;) if you want the machine string embedded, call {@link serialize_with_string} instead.

    Parameters

    • Optional comment: string

      An optional comment string to embed in the serialized output for identification or debugging.

    Returns JssmSerialization<mDT>

    A JssmSerialization object containing the machine's current state, data, and timestamp.

  • set_state_timeout(next_state: string, after_time: number): void
  • Schedule an automatic transition to next_state after after_time milliseconds. Only one timeout may be active at a time.

    throws

    {JssmError} If a timeout is already pending.

    Parameters

    • next_state: string

      The state to transition to when the timer fires.

    • after_time: number

      Delay in milliseconds.

    Returns void

  • Convenience method to create a new machine from a tagged template literal. Equivalent to calling the top-level sm function.

    Parameters

    • template_strings: TemplateStringsArray

      The template string array.

    • Rest ...remainder: any[]

      Interpolated values.

    Returns Machine<mDT>

    A new Machine instance.

  • state(): string
  • Get the current state of a machine.

    import * as jssm from 'jssm';

    const lswitch = jssm.from('on <=> off;');
    console.log( lswitch.state() ); // 'on'

    lswitch.transition('off');
    console.log( lswitch.state() ); // 'off'

    Returns string

    The current state name.

  • state_has_hooks(state: string): boolean
  • Does the given state carry any observational hook — i.e. should it receive the hooked_state viz styling? True when an entry/exit/after hook is bound to the state, any edge hook touches it, or the state has its own boundary hook. Group-boundary hooks do not count here — they are matched by group only and never propagate to member states. Powers the hooked styling layer in Machine.resolve_state_config; replaces the long-stubbed has_hooks placeholder (megaspec §12).

    const m = sm`a -> b;`;
    m.state_has_hooks('a'); // false
    m.hook_exit('a', () => true);
    m.state_has_hooks('a'); // true

    Parameters

    • state: string

      The state to test.

    Returns boolean

    true when the state is observed by at least one hook.

  • state_is_complete(whichState: string): boolean
  • Check whether a specific state is complete (every exit has an action).

    throws

    {JssmError} If the state does not exist.

    Parameters

    • whichState: string

      The state to check.

    Returns boolean

    true if the state is complete.

  • state_is_final(whichState: string): boolean
  • Check whether a given state is final (either has no exits or is marked complete.)

    import { sm, state_is_final } from 'jssm';

    const final_test = sm`first -> second;`;

    console.log( final_test.state_is_final('first') ); // false
    console.log( final_test.state_is_final('second') ); // true

    Parameters

    • whichState: string

      The name of the state to check for finality

    Returns boolean

  • state_is_terminal(whichState: string): boolean
  • Check whether a specific state is terminal (has no exits).

    throws

    {JssmError} If the state does not exist.

    Parameters

    • whichState: string

      The state to check.

    Returns boolean

    true if the state has zero exits.

  • state_timeout_for(which_state: string): [string, number]
  • Get the configured after timeout for a given state, if any.

    Parameters

    • which_state: string

      The state to look up.

    Returns [string, number]

    A [targetState, delayMs] tuple, or undefined if no timeout is configured for that state.

  • states(): string[]
  • List all the states known by the machine. Please note that the order of these states is not guaranteed.

    import * as jssm from 'jssm';

    const lswitch = jssm.from('on <=> off;');
    console.log( lswitch.states() ); // ['on', 'off']

    Returns string[]

    An array of all state names in the machine.

  • statesIn(groupName: string): string[]
  • Lists every state that is a transitive member of a named group — the flattened membership of the group, descending through nested and spread sub-groups, in member-declaration order.

    import { sm } from 'jssm';

    const m = sm`&inner : [a b]; &outer : [&inner c]; a -> b -> c;`;
    m.statesIn('outer'); // [ 'a', 'b', 'c' ]
    m.statesIn('inner'); // [ 'a', 'b' ]
    throws

    {JssmError} If groupName is not a declared group.

    see

    groups

    see

    groupsOf

    Parameters

    • groupName: string

      The group whose transitive member states are wanted.

    Returns string[]

    The transitive member states of groupName, in declaration order.

  • strict_prop(name: string): any
  • Get the current value of a given property name. If missing on the state and without a global default, throws a JssmError, unlike prop, which would return undefined instead.

    const m = sm`property color default "grey"; a -> b;`;

    m.strict_prop('color'); // 'grey'
    m.strict_prop('size'); // throws JssmError
    throws

    {JssmError} If the property is not defined on the current state and has no default.

    Parameters

    • name: string

      The relevant property name to look up.

    Returns any

    The value behind the prop name.

  • Gets the composite style for a specific node — the public viz entry point, now a thin wrapper over the unified config cascade in resolve_state_config.

    The order of composition runs least-specific to most-specific: theme defaults, then the default_state_config root, then per-kind defaults (terminal, start, end), then depth-ordered group metadata (inner groups winning over outer), then the per-state config, and finally — for the current state only — the active overlay. Last wins at every tier.

    see

    resolve_state_config

    Parameters

    • state: string

      The state to compute the composite style for.

    Returns Partial<JssmStateDeclaration>

    The fully composited JssmStateConfig for the given state.

  • transition(newState: string, newData?: mDT): boolean
  • Instruct the machine to complete a transition. Synonym for go.

    const light = sm`
    off 'start' -> red;
    red 'next' -> green 'next' -> yellow 'next' -> red;
    [red yellow green] 'shutdown' ~> off;
    `;

    light.state(); // 'off'
    light.go('red'); // true
    light.state(); // 'red'
    light.go('green'); // true
    light.state(); // 'green'
    light.go('blue'); // !! false - no such state
    light.state(); // 'green'
    light.go('red'); // !! false - green may not go directly to red, only to yellow
    light.state(); // 'green'

    Parameters

    • newState: string

      The state to switch to

    • Optional newData: mDT

      The data change to insert during the transition

    Returns boolean

    true if the transition was legal and occurred, false otherwise.

  • transition_impl(newStateOrAction: string, newData: mDT, wasForced: boolean, wasAction: boolean): boolean
  • Shared transition core used by transition, force_transition, and action. Runs validation, fires the full hook pipeline (pre- everything, any-action, after, any-transition, exit, named, basic, edge-type, entry, everything), commits the new state if nothing rejected, and returns whether the transition succeeded.

    Not meant for external use. Call one of the public wrappers instead:

    • transition for an ordinary legal transition
    • force_transition to bypass the legality check
    • action to dispatch by action name rather than target state
    remarks

    Known sharp edges, carried over from the original // TODO comments:

    • The forced-ness behavior needs to be cleaned up a lot here.
    • The callbacks are not fully correct across the forced / action / plain cases and should be revisited.
    • When multiple edges exist between two states with different kind values, only the first edge's kind is used to pick the edge-type hook.
    internal

    Parameters

    • newStateOrAction: string

      The target state name (for a plain or forced transition) or the action name (when wasAction is true).

    • newData: mDT

      Optional replacement machine data to install alongside the transition. Hooks may further override this via complex results.

    • wasForced: boolean

      true if the caller invoked force_transition, in which case legality is checked against valid_force_transition rather than valid_transition.

    • wasAction: boolean

      true if the caller invoked action, in which case newStateOrAction is an action name and the target state is looked up via the current action edge.

    Returns boolean

    true if the transition was valid and every hook passed; false if the transition was invalid or any hook rejected.

  • valid_action(action: string, _newData?: mDT): boolean
  • Check whether an action is available from the current state.

    Parameters

    • action: string

      The action name to check.

    • Optional _newData: mDT

      Reserved for future data validation.

    Returns boolean

    true if the action can be taken.

  • valid_force_transition(newState: string, _newData?: mDT): boolean
  • Check whether a forced transition to a given state exists from the current state.

    Parameters

    • newState: string

      The target state.

    • Optional _newData: mDT

      Reserved for future data validation.

    Returns boolean

    true if a forced (or any) transition exists.

  • valid_transition(newState: string, _newData?: mDT): boolean
  • Check whether a transition to a given state is legal (non-forced) from the current state.

    Parameters

    • newState: string

      The target state.

    • Optional _newData: mDT

      Reserved for future data validation.

    Returns boolean

    true if the transition is legal.

Generated using TypeDoc