Check if a machine allows overriding state and data.
Check if the code that built the machine allows overriding state and data.
Check if the machine config allows overriding state and data.
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' }
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.
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.
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
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
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' }
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' }
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' }
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' }
Internal method for fabricating states. Not meant for external use.
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'
The action to engage
The data change to insert during the action
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']
The state whose actions to have listed
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
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'
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'
The action to engage
The data change to insert during the action
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'
The state to switch to
The data change to insert during the transition
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'
The state to switch to
The data change to insert during the transition
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
The state to be checked for extance
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
The name of the state to check
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
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
The name of the state to check
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
The relevant property name to look up
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.
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.
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'
}
]
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' ]
The state whose entrances to have listed
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' ]
The state whose exits to have listed
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']
The action to be checked for associated states
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' ] }
The state whose transitions to have listed
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'
Get the current value of a given property name.
The relevant property name to look up
The value behind the prop name. Because functional props are evaluated as getters, this can be anything.
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; }
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.
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'
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
The name of the state to check for finality
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']
Get the current value of a given property name. If missing on the state
and without a global default, throw, unlike prop, which would
return undefined
instead.
The relevant property name to look up
The value behind the prop name. Because functional props are evaluated as getters, this can be anything.
Gets the composite style for a specific node by individually imposing the style layers on a given object, after determining which layers are appropriate.
The order of composition is base, then theme, then user content. Each item in the stack will be composited independently. First, the base state style, then the theme state style, then the user state style.
After the three state styles, we'll composite the hooked styles; then the terminal styles; then the start styles; then the end styles; finally, the active styles. Remember, last wins.
The base state style must exist. All other styles are optional.
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'
The state to switch to
The data change to insert during the transition
Generated using TypeDoc
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.