jssm 5.79.18 → 5.81.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es6/jssm.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // whargarbl lots of these return arrays could/should be sets
2
2
  import { reduce as reduce_to_639 } from 'reduce-to-639-1';
3
3
  import { circular_buffer } from 'circular_buffer_js';
4
+ import { base_state_style, base_start_state_style, base_end_state_style, base_terminal_state_style, base_active_state_style } from './jssm_base_stylesheet';
4
5
  import { seq, unique, find_repeated, weighted_rand_select, weighted_sample_select, histograph, weighted_histo_key, array_box_if_string, name_bind_prop_and_state, hook_name, named_hook_name } from './jssm_util';
5
6
  import * as constants from './jssm_constants';
6
7
  const { shapes, gviz_shapes, named_colors } = constants;
@@ -271,7 +272,7 @@ function makeTransition(this_se, from, to, isRight, _wasList, _wasIndex) {
271
272
  * ```typescript
272
273
  * import { sm } from 'jssm';
273
274
  *
274
- * const switch = sm`on <=> off;`;
275
+ * const lswitch = sm`on <=> off;`;
275
276
  * ```
276
277
  *
277
278
  * Method {@link from}:
@@ -379,7 +380,9 @@ function compile_rule_handler(rule) {
379
380
  'graph_layout', 'start_states', 'end_states', 'machine_name', 'machine_version',
380
381
  'machine_comment', 'machine_author', 'machine_contributor', 'machine_definition',
381
382
  'machine_reference', 'machine_license', 'fsl_version', 'state_config', 'theme',
382
- 'flow', 'dot_preamble'
383
+ 'flow', 'dot_preamble', 'default_state_config', 'default_start_state_config',
384
+ 'default_end_state_config', 'default_hooked_state_config',
385
+ 'default_active_state_config', 'default_terminal_state_config'
383
386
  ];
384
387
  if (tautologies.includes(rule.key)) {
385
388
  return { agg_as: rule.key, val: rule.value };
@@ -421,7 +424,7 @@ function compile_rule_handler(rule) {
421
424
  * ```typescript
422
425
  * import { sm } from 'jssm';
423
426
  *
424
- * const switch = sm`on <=> off;`;
427
+ * const lswitch = sm`on <=> off;`;
425
428
  * ```
426
429
  *
427
430
  * Method {@link from}:
@@ -462,7 +465,13 @@ function compile(tree) {
462
465
  arrange_declaration: [],
463
466
  arrange_start_declaration: [],
464
467
  arrange_end_declaration: [],
465
- machine_version: []
468
+ machine_version: [],
469
+ default_state_config: [],
470
+ default_active_state_config: [],
471
+ default_hooked_state_config: [],
472
+ default_terminal_state_config: [],
473
+ default_start_state_config: [],
474
+ default_end_state_config: [],
466
475
  };
467
476
  tree.map((tr) => {
468
477
  const rule = compile_rule_handler(tr), agg_as = rule.agg_as, val = rule.val; // TODO FIXME no any
@@ -475,8 +484,9 @@ function compile(tree) {
475
484
  const assembled_transitions = [].concat(...results['transition']);
476
485
  const result_cfg = {
477
486
  start_states: results.start_states.length ? results.start_states : [assembled_transitions[0].from],
487
+ end_states: results.end_states,
478
488
  transitions: assembled_transitions,
479
- state_property: []
489
+ state_property: [],
480
490
  };
481
491
  const oneOnlyKeys = [
482
492
  'graph_layout', 'machine_name', 'machine_version', 'machine_comment',
@@ -495,7 +505,10 @@ function compile(tree) {
495
505
  });
496
506
  ['arrange_declaration', 'arrange_start_declaration', 'arrange_end_declaration',
497
507
  'machine_author', 'machine_contributor', 'machine_reference',
498
- 'state_declaration', 'property_definition'].map((multiKey) => {
508
+ 'state_declaration', 'property_definition', 'default_state_config',
509
+ 'default_start_state_config', 'default_end_state_config',
510
+ 'default_hooked_state_config', 'default_terminal_state_config',
511
+ 'default_active_state_config'].map((multiKey) => {
499
512
  if (results[multiKey].length) {
500
513
  result_cfg[multiKey] = results[multiKey];
501
514
  }
@@ -552,8 +565,8 @@ function transfer_state_properties(state_decl) {
552
565
  case 'corners':
553
566
  state_decl.corners = d.value;
554
567
  break;
555
- case 'linestyle':
556
- state_decl.linestyle = d.value;
568
+ case 'line-style':
569
+ state_decl.lineStyle = d.value;
557
570
  break;
558
571
  case 'text-color':
559
572
  state_decl.textColor = d.value;
@@ -561,6 +574,9 @@ function transfer_state_properties(state_decl) {
561
574
  case 'background-color':
562
575
  state_decl.backgroundColor = d.value;
563
576
  break;
577
+ case 'state-label':
578
+ state_decl.stateLabel = d.value;
579
+ break;
564
580
  case 'border-color':
565
581
  state_decl.borderColor = d.value;
566
582
  break;
@@ -572,10 +588,80 @@ function transfer_state_properties(state_decl) {
572
588
  });
573
589
  return state_decl;
574
590
  }
591
+ function state_style_condense(jssk) {
592
+ const state_style = {};
593
+ if (Array.isArray(jssk)) {
594
+ jssk.forEach((key, i) => {
595
+ if (typeof key !== 'object') {
596
+ throw new JssmError(this, `invalid state item ${i} in state_style_condense list: ${JSON.stringify(key)}`);
597
+ }
598
+ switch (key.key) {
599
+ case 'shape':
600
+ if (state_style.shape !== undefined) {
601
+ throw new JssmError(this, `cannot redefine 'shape' in state_style_condense, already defined`);
602
+ }
603
+ state_style.shape = key.value;
604
+ break;
605
+ case 'color':
606
+ if (state_style.color !== undefined) {
607
+ throw new JssmError(this, `cannot redefine 'color' in state_style_condense, already defined`);
608
+ }
609
+ state_style.color = key.value;
610
+ break;
611
+ case 'text-color':
612
+ if (state_style.textColor !== undefined) {
613
+ throw new JssmError(this, `cannot redefine 'text-color' in state_style_condense, already defined`);
614
+ }
615
+ state_style.textColor = key.value;
616
+ break;
617
+ case 'corners':
618
+ if (state_style.corners !== undefined) {
619
+ throw new JssmError(this, `cannot redefine 'corners' in state_style_condense, already defined`);
620
+ }
621
+ state_style.corners = key.value;
622
+ break;
623
+ case 'line-style':
624
+ if (state_style.lineStyle !== undefined) {
625
+ throw new JssmError(this, `cannot redefine 'line-style' in state_style_condense, already defined`);
626
+ }
627
+ state_style.lineStyle = key.value;
628
+ break;
629
+ case 'background-color':
630
+ if (state_style.backgroundColor !== undefined) {
631
+ throw new JssmError(this, `cannot redefine 'background-color' in state_style_condense, already defined`);
632
+ }
633
+ state_style.backgroundColor = key.value;
634
+ break;
635
+ case 'state-label':
636
+ if (state_style.stateLabel !== undefined) {
637
+ throw new JssmError(this, `cannot redefine 'state-label' in state_style_condense, already defined`);
638
+ }
639
+ state_style.stateLabel = key.value;
640
+ break;
641
+ case 'border-color':
642
+ if (state_style.borderColor !== undefined) {
643
+ throw new JssmError(this, `cannot redefine 'border-color' in state_style_condense, already defined`);
644
+ }
645
+ state_style.borderColor = key.value;
646
+ break;
647
+ default:
648
+ // TODO do that <never> trick to assert this list is complete
649
+ throw new JssmError(this, `unknown state style key in condense: ${key.key}`);
650
+ }
651
+ });
652
+ }
653
+ else if (jssk === undefined) {
654
+ // do nothing, undefined is legal and means we should return the empty container above
655
+ }
656
+ else {
657
+ throw new JssmError(this, 'state_style_condense received a non-array');
658
+ }
659
+ return state_style;
660
+ }
575
661
  // TODO add a lotta docblock here
576
662
  class Machine {
577
663
  // whargarbl this badly needs to be broken up, monolith master
578
- constructor({ start_states, complete = [], transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, state_declaration, property_definition, state_property, fsl_version, dot_preamble = undefined, arrange_declaration = [], arrange_start_declaration = [], arrange_end_declaration = [], theme = 'default', flow = 'down', graph_layout = 'dot', instance_name, history, data }) {
664
+ constructor({ start_states, end_states = [], complete = [], transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, state_declaration, property_definition, state_property, fsl_version, dot_preamble = undefined, arrange_declaration = [], arrange_start_declaration = [], arrange_end_declaration = [], theme = 'default', flow = 'down', graph_layout = 'dot', instance_name, history, data, default_state_config, default_active_state_config, default_hooked_state_config, default_terminal_state_config, default_start_state_config, default_end_state_config }) {
579
665
  this._instance_name = instance_name;
580
666
  this._state = start_states[0];
581
667
  this._states = new Map();
@@ -586,6 +672,8 @@ class Machine {
586
672
  this._actions = new Map();
587
673
  this._reverse_actions = new Map();
588
674
  this._reverse_action_targets = new Map(); // todo
675
+ this._start_states = new Set(start_states);
676
+ this._end_states = new Set(end_states); // todo consider what to do about incorporating complete too
589
677
  this._machine_author = array_box_if_string(machine_author);
590
678
  this._machine_comment = machine_comment;
591
679
  this._machine_contributor = array_box_if_string(machine_contributor);
@@ -644,8 +732,16 @@ class Machine {
644
732
  this._default_properties = new Map();
645
733
  this._state_properties = new Map();
646
734
  this._required_properties = new Set();
735
+ this._state_style = state_style_condense(default_state_config);
736
+ this._active_state_style = state_style_condense(default_active_state_config);
737
+ this._hooked_state_style = state_style_condense(default_hooked_state_config);
738
+ this._terminal_state_style = state_style_condense(default_terminal_state_config);
739
+ this._start_state_style = state_style_condense(default_start_state_config);
740
+ this._end_state_style = state_style_condense(default_end_state_config);
647
741
  this._history_length = history || 0;
648
742
  this._history = new circular_buffer(this._history_length);
743
+ this._state_labels = new Map();
744
+ // consolidate the state declarations
649
745
  if (state_declaration) {
650
746
  state_declaration.map((state_decl) => {
651
747
  if (this._state_declarations.has(state_decl.state)) { // no repeats
@@ -654,6 +750,17 @@ class Machine {
654
750
  this._state_declarations.set(state_decl.state, transfer_state_properties(state_decl));
655
751
  });
656
752
  }
753
+ // walk the decls for labels; aggregate them when found
754
+ [...this._state_declarations].map(sd => {
755
+ const [key, decl] = sd, labelled = decl.declarations.filter(d => d.key === 'state-label');
756
+ if (labelled.length > 1) {
757
+ throw new JssmError(this, `state ${key} may only have one state-label; has ${labelled.length}`);
758
+ }
759
+ if (labelled.length === 1) {
760
+ this._state_labels.set(key, labelled[0].value);
761
+ }
762
+ });
763
+ // walk the transitions
657
764
  transitions.map((tr) => {
658
765
  if (tr.from === undefined) {
659
766
  throw new JssmError(this, `transition must define 'from': ${JSON.stringify(tr)}`);
@@ -805,11 +912,11 @@ class Machine {
805
912
  * ```typescript
806
913
  * import * as jssm from 'jssm';
807
914
  *
808
- * const switch = jssm.from('on <=> off;');
809
- * console.log( switch.state() ); // 'on'
915
+ * const lswitch = jssm.from('on <=> off;');
916
+ * console.log( lswitch.state() ); // 'on'
810
917
  *
811
- * switch.transition('off');
812
- * console.log( switch.state() ); // 'off'
918
+ * lswitch.transition('off');
919
+ * console.log( lswitch.state() ); // 'off'
813
920
  * ```
814
921
  *
815
922
  * @typeparam mDT The type of the machine data member; usually omitted
@@ -818,13 +925,23 @@ class Machine {
818
925
  state() {
819
926
  return this._state;
820
927
  }
821
- /* whargarbl todo major
822
- when we reimplement this, reintroduce this change to the is_final call
823
-
824
- is_changing(): boolean {
825
- return true; // todo whargarbl
826
- }
827
- */
928
+ /*********
929
+ *
930
+ * Get the label for a given state, if any; return `undefined` otherwise.
931
+ *
932
+ * ```typescript
933
+ * import * as jssm from 'jssm';
934
+ *
935
+ * const lswitch = jssm.from('a -> b; state a: { label: "Foo!"; };');
936
+ * console.log( lswitch.label_for('a') ); // 'Foo!'
937
+ * ```
938
+ *
939
+ * @typeparam mDT The type of the machine data member; usually omitted
940
+ *
941
+ */
942
+ label_for(state) {
943
+ return this._state_labels.get(state);
944
+ }
828
945
  /*********
829
946
  *
830
947
  * Get the current data of a machine.
@@ -832,8 +949,8 @@ class Machine {
832
949
  * ```typescript
833
950
  * import * as jssm from 'jssm';
834
951
  *
835
- * const switch = jssm.from('on <=> off;', {data: 1});
836
- * console.log( switch.data() ); // 1
952
+ * const lswitch = jssm.from('on <=> off;', {data: 1});
953
+ * console.log( lswitch.data() ); // 1
837
954
  * ```
838
955
  *
839
956
  * @typeparam mDT The type of the machine data member; usually omitted
@@ -842,13 +959,6 @@ class Machine {
842
959
  data() {
843
960
  return this._data;
844
961
  }
845
- /* whargarbl todo major
846
- when we reimplement this, reintroduce this change to the is_final call
847
-
848
- is_changing(): boolean {
849
- return true; // todo whargarbl
850
- }
851
- */
852
962
  // NEEDS_DOCS
853
963
  /*********
854
964
  *
@@ -1008,6 +1118,60 @@ class Machine {
1008
1118
  known_props() {
1009
1119
  return [...this._property_keys];
1010
1120
  }
1121
+ /********
1122
+ *
1123
+ * Check whether a given state is a valid start state (either because it was
1124
+ * explicitly named as such, or because it was the first mentioned state.)
1125
+ *
1126
+ * ```typescript
1127
+ * import { sm, is_start_state } from 'jssm';
1128
+ *
1129
+ * const example = sm`a -> b;`;
1130
+ *
1131
+ * console.log( final_test.is_start_state('a') ); // true
1132
+ * console.log( final_test.is_start_state('b') ); // false
1133
+ *
1134
+ * const example = sm`start_states: [a b]; a -> b;`;
1135
+ *
1136
+ * console.log( final_test.is_start_state('a') ); // true
1137
+ * console.log( final_test.is_start_state('b') ); // true
1138
+ * ```
1139
+ *
1140
+ * @typeparam mDT The type of the machine data member; usually omitted
1141
+ *
1142
+ * @param whichState The name of the state to check
1143
+ *
1144
+ */
1145
+ is_start_state(whichState) {
1146
+ return this._start_states.has(whichState);
1147
+ }
1148
+ /********
1149
+ *
1150
+ * Check whether a given state is a valid start state (either because it was
1151
+ * explicitly named as such, or because it was the first mentioned state.)
1152
+ *
1153
+ * ```typescript
1154
+ * import { sm, is_end_state } from 'jssm';
1155
+ *
1156
+ * const example = sm`a -> b;`;
1157
+ *
1158
+ * console.log( final_test.is_start_state('a') ); // false
1159
+ * console.log( final_test.is_start_state('b') ); // true
1160
+ *
1161
+ * const example = sm`end_states: [a b]; a -> b;`;
1162
+ *
1163
+ * console.log( final_test.is_start_state('a') ); // true
1164
+ * console.log( final_test.is_start_state('b') ); // true
1165
+ * ```
1166
+ *
1167
+ * @typeparam mDT The type of the machine data member; usually omitted
1168
+ *
1169
+ * @param whichState The name of the state to check
1170
+ *
1171
+ */
1172
+ is_end_state(whichState) {
1173
+ return this._end_states.has(whichState);
1174
+ }
1011
1175
  /********
1012
1176
  *
1013
1177
  * Check whether a given state is final (either has no exits or is marked
@@ -1028,7 +1192,7 @@ class Machine {
1028
1192
  *
1029
1193
  */
1030
1194
  state_is_final(whichState) {
1031
- return ((this.state_is_terminal(whichState)) && (this.state_is_complete(whichState)));
1195
+ return ((this.state_is_terminal(whichState)) || (this.state_is_complete(whichState)));
1032
1196
  }
1033
1197
  /********
1034
1198
  *
@@ -1036,7 +1200,7 @@ class Machine {
1036
1200
  * `complete`.)
1037
1201
  *
1038
1202
  * ```typescript
1039
- * import { sm, state_is_final } from 'jssm';
1203
+ * import { sm, is_final } from 'jssm';
1040
1204
  *
1041
1205
  * const final_test = sm`first -> second;`;
1042
1206
  *
@@ -1134,8 +1298,8 @@ class Machine {
1134
1298
  * ```typescript
1135
1299
  * import * as jssm from 'jssm';
1136
1300
  *
1137
- * const switch = jssm.from('on <=> off;');
1138
- * console.log( switch.states() ); // ['on', 'off']
1301
+ * const lswitch = jssm.from('on <=> off;');
1302
+ * console.log( lswitch.states() ); // ['on', 'off']
1139
1303
  * ```
1140
1304
  *
1141
1305
  * @typeparam mDT The type of the machine data member; usually omitted
@@ -1160,10 +1324,10 @@ class Machine {
1160
1324
  * ```typescript
1161
1325
  * import * as jssm from 'jssm';
1162
1326
  *
1163
- * const switch = jssm.from('on <=> off;');
1327
+ * const lswitch = jssm.from('on <=> off;');
1164
1328
  *
1165
- * console.log( switch.has_state('off') ); // true
1166
- * console.log( switch.has_state('dance') ); // false
1329
+ * console.log( lswitch.has_state('off') ); // true
1330
+ * console.log( lswitch.has_state('dance') ); // false
1167
1331
  * ```
1168
1332
  *
1169
1333
  * @typeparam mDT The type of the machine data member; usually omitted
@@ -2003,6 +2167,237 @@ class Machine {
2003
2167
  action(actionName, newData) {
2004
2168
  return this.transition_impl(actionName, newData, false, true);
2005
2169
  }
2170
+ /********
2171
+ *
2172
+ * Get the standard style for a single state. ***Does not*** include
2173
+ * composition from an applied theme, or things from the underlying base
2174
+ * stylesheet; only the modifications applied by this machine.
2175
+ *
2176
+ * ```typescript
2177
+ * const light = sm`a -> b;`;
2178
+ * console.log(light.standard_state_style);
2179
+ * // {}
2180
+ *
2181
+ * const light = sm`a -> b; state: { shape: circle; };`;
2182
+ * console.log(light.standard_state_style);
2183
+ * // { shape: 'circle' }
2184
+ * ```
2185
+ *
2186
+ * @typeparam mDT The type of the machine data member; usually omitted
2187
+ *
2188
+ */
2189
+ get standard_state_style() {
2190
+ return this._state_style;
2191
+ }
2192
+ /********
2193
+ *
2194
+ * Get the hooked state style. ***Does not*** include
2195
+ * composition from an applied theme, or things from the underlying base
2196
+ * stylesheet; only the modifications applied by this machine.
2197
+ *
2198
+ * The hooked style is only applied to nodes which have a named hook in the
2199
+ * graph. Open hooks set through the external API aren't graphed, because
2200
+ * that would be literally every node.
2201
+ *
2202
+ * ```typescript
2203
+ * const light = sm`a -> b;`;
2204
+ * console.log(light.hooked_state_style);
2205
+ * // {}
2206
+ *
2207
+ * const light = sm`a -> b; hooked_state: { shape: circle; };`;
2208
+ * console.log(light.hooked_state_style);
2209
+ * // { shape: 'circle' }
2210
+ * ```
2211
+ *
2212
+ * @typeparam mDT The type of the machine data member; usually omitted
2213
+ *
2214
+ */
2215
+ get hooked_state_style() {
2216
+ return this._hooked_state_style;
2217
+ }
2218
+ /********
2219
+ *
2220
+ * Get the start state style. ***Does not*** include composition from an
2221
+ * applied theme, or things from the underlying base stylesheet; only the
2222
+ * modifications applied by this machine.
2223
+ *
2224
+ * Start states are defined by the directive `start_states`, or in absentia,
2225
+ * are the first mentioned state.
2226
+ *
2227
+ * ```typescript
2228
+ * const light = sm`a -> b;`;
2229
+ * console.log(light.start_state_style);
2230
+ * // {}
2231
+ *
2232
+ * const light = sm`a -> b; start_state: { shape: circle; };`;
2233
+ * console.log(light.start_state_style);
2234
+ * // { shape: 'circle' }
2235
+ * ```
2236
+ *
2237
+ * @typeparam mDT The type of the machine data member; usually omitted
2238
+ *
2239
+ */
2240
+ get start_state_style() {
2241
+ return this._start_state_style;
2242
+ }
2243
+ /********
2244
+ *
2245
+ * Get the end state style. ***Does not*** include
2246
+ * composition from an applied theme, or things from the underlying base
2247
+ * stylesheet; only the modifications applied by this machine.
2248
+ *
2249
+ * End states are defined in the directive `end_states`, and are distinct
2250
+ * from terminal states. End states are voluntary successful endpoints for a
2251
+ * process. Terminal states are states that cannot be exited. By example,
2252
+ * most error states are terminal states, but not end states. Also, since
2253
+ * some end states can be exited and are determined by hooks, such as
2254
+ * recursive or iterative nodes, there is such a thing as an end state that
2255
+ * is not a terminal state.
2256
+ *
2257
+ * ```typescript
2258
+ * const light = sm`a -> b;`;
2259
+ * console.log(light.standard_state_style);
2260
+ * // {}
2261
+ *
2262
+ * const light = sm`a -> b; end_state: { shape: circle; };`;
2263
+ * console.log(light.standard_state_style);
2264
+ * // { shape: 'circle' }
2265
+ * ```
2266
+ *
2267
+ * @typeparam mDT The type of the machine data member; usually omitted
2268
+ *
2269
+ */
2270
+ get end_state_style() {
2271
+ return this._end_state_style;
2272
+ }
2273
+ /********
2274
+ *
2275
+ * Get the terminal state style. ***Does not*** include
2276
+ * composition from an applied theme, or things from the underlying base
2277
+ * stylesheet; only the modifications applied by this machine.
2278
+ *
2279
+ * Terminal state styles are automatically determined by the machine. Any
2280
+ * state without a valid exit transition is terminal.
2281
+ *
2282
+ * ```typescript
2283
+ * const light = sm`a -> b;`;
2284
+ * console.log(light.terminal_state_style);
2285
+ * // {}
2286
+ *
2287
+ * const light = sm`a -> b; terminal_state: { shape: circle; };`;
2288
+ * console.log(light.terminal_state_style);
2289
+ * // { shape: 'circle' }
2290
+ * ```
2291
+ *
2292
+ * @typeparam mDT The type of the machine data member; usually omitted
2293
+ *
2294
+ */
2295
+ get terminal_state_style() {
2296
+ return this._terminal_state_style;
2297
+ }
2298
+ /********
2299
+ *
2300
+ * Get the style for the active state. ***Does not*** include
2301
+ * composition from an applied theme, or things from the underlying base
2302
+ * stylesheet; only the modifications applied by this machine.
2303
+ *
2304
+ * ```typescript
2305
+ * const light = sm`a -> b;`;
2306
+ * console.log(light.active_state_style);
2307
+ * // {}
2308
+ *
2309
+ * const light = sm`a -> b; active_state: { shape: circle; };`;
2310
+ * console.log(light.active_state_style);
2311
+ * // { shape: 'circle' }
2312
+ * ```
2313
+ *
2314
+ * @typeparam mDT The type of the machine data member; usually omitted
2315
+ *
2316
+ */
2317
+ get active_state_style() {
2318
+ return this._active_state_style;
2319
+ }
2320
+ /********
2321
+ *
2322
+ * Gets the composite style for a specific node by individually imposing the
2323
+ * style layers on a given object, after determining which layers are
2324
+ * appropriate.
2325
+ *
2326
+ * The order of composition is base, then theme, then user content. Each
2327
+ * item in the stack will be composited independently. First, the base state
2328
+ * style, then the theme state style, then the user state style.
2329
+ *
2330
+ * After the three state styles, we'll composite the hooked styles; then the
2331
+ * terminal styles; then the start styles; then the end styles; finally, the
2332
+ * active styles. Remember, last wins.
2333
+ *
2334
+ * The base state style must exist. All other styles are optional.
2335
+ *
2336
+ * @typeparam mDT The type of the machine data member; usually omitted
2337
+ *
2338
+ */
2339
+ style_for(state) {
2340
+ // basic state style
2341
+ const layers = [base_state_style];
2342
+ // if (theme.state_style) { layers.push(theme.state_style); }
2343
+ if (this._state_style) {
2344
+ layers.push(this._state_style);
2345
+ }
2346
+ /*
2347
+ // hooked state style
2348
+ if (this.has_hooks(state)) {
2349
+ layers.push(base_hooked_state_style);
2350
+ // if (theme.hooked_state_style) { layers.push(theme.hooked_state_style); }
2351
+ if (this._hooked_state_style) { layers.push(this._hooked_state_style); }
2352
+ }
2353
+ */
2354
+ // terminal state style
2355
+ if (this.state_is_terminal(state)) {
2356
+ layers.push(base_terminal_state_style);
2357
+ // if (theme.terminal_state_style) { layers.push(theme.terminal_state_style); }
2358
+ if (this._terminal_state_style) {
2359
+ layers.push(this._terminal_state_style);
2360
+ }
2361
+ }
2362
+ // start state style
2363
+ if (this.is_start_state(state)) {
2364
+ layers.push(base_start_state_style);
2365
+ // if (theme.start_state_style) { layers.push(theme.start_state_style); }
2366
+ if (this._start_state_style) {
2367
+ layers.push(this._start_state_style);
2368
+ }
2369
+ }
2370
+ // end state style
2371
+ if (this.is_end_state(state)) {
2372
+ layers.push(base_end_state_style);
2373
+ // if (theme.end_state_style) { layers.push(theme.end_state_style); }
2374
+ if (this._end_state_style) {
2375
+ layers.push(this._end_state_style);
2376
+ }
2377
+ }
2378
+ // active state style
2379
+ if (this.state() === state) {
2380
+ layers.push(base_active_state_style);
2381
+ // if (theme.active_state_style) { layers.push(theme.active_state_style); }
2382
+ if (this._active_state_style) {
2383
+ layers.push(this._active_state_style);
2384
+ }
2385
+ }
2386
+ const individual_style = {}, decl = this._state_declarations.get(state);
2387
+ individual_style.color = decl === null || decl === void 0 ? void 0 : decl.color;
2388
+ individual_style.textColor = decl === null || decl === void 0 ? void 0 : decl.textColor;
2389
+ individual_style.borderColor = decl === null || decl === void 0 ? void 0 : decl.borderColor;
2390
+ individual_style.backgroundColor = decl === null || decl === void 0 ? void 0 : decl.backgroundColor;
2391
+ individual_style.lineStyle = decl === null || decl === void 0 ? void 0 : decl.lineStyle;
2392
+ individual_style.corners = decl === null || decl === void 0 ? void 0 : decl.corners;
2393
+ individual_style.shape = decl === null || decl === void 0 ? void 0 : decl.shape;
2394
+ layers.push(individual_style);
2395
+ return layers.reduce((acc, cur) => {
2396
+ const composite_state = acc;
2397
+ Object.keys(cur).forEach(key => { var _a; return composite_state[key] = (_a = cur[key]) !== null && _a !== void 0 ? _a : composite_state[key]; });
2398
+ return composite_state;
2399
+ }, {});
2400
+ }
2006
2401
  /********
2007
2402
  *
2008
2403
  * Instruct the machine to complete an action. Synonym for {@link action}.
@@ -2173,7 +2568,7 @@ class Machine {
2173
2568
  * ```typescript
2174
2569
  * import * as jssm from 'jssm';
2175
2570
  *
2176
- * const switch = jssm.from('on <=> off;');
2571
+ * const lswitch = jssm.from('on <=> off;');
2177
2572
  * ```
2178
2573
  *
2179
2574
  * @typeparam mDT The type of the machine data member; usually omitted
@@ -2208,7 +2603,7 @@ function sm(template_strings, ...remainder /* , arguments */) {
2208
2603
  * ```typescript
2209
2604
  * import * as jssm from 'jssm';
2210
2605
  *
2211
- * const switch = jssm.from('on <=> off;');
2606
+ * const lswitch = jssm.from('on <=> off;');
2212
2607
  * ```
2213
2608
  *
2214
2609
  * @typeparam mDT The type of the machine data member; usually omitted
@@ -2277,4 +2672,4 @@ function deserialize(machine_string, ser) {
2277
2672
  }
2278
2673
  export { version, transfer_state_properties, Machine, deserialize, make, wrap_parse as parse, compile, sm, from, arrow_direction, arrow_left_kind, arrow_right_kind,
2279
2674
  // WHARGARBL TODO these should be exported to a utility library
2280
- seq, unique, find_repeated, weighted_rand_select, histograph, weighted_sample_select, weighted_histo_key, constants, shapes, gviz_shapes, named_colors, is_hook_rejection, is_hook_complex_result, abstract_hook_step };
2675
+ seq, unique, find_repeated, weighted_rand_select, histograph, weighted_sample_select, weighted_histo_key, constants, shapes, gviz_shapes, named_colors, is_hook_rejection, is_hook_complex_result, abstract_hook_step, state_style_condense };
@@ -0,0 +1,10 @@
1
+ import { JssmStateConfig } from './jssm_types';
2
+ declare const base_state_style: JssmStateConfig;
3
+ declare const base_active_state_style: JssmStateConfig;
4
+ declare const base_terminal_state_style: JssmStateConfig;
5
+ declare const base_active_terminal_state_style: JssmStateConfig;
6
+ declare const base_start_state_style: JssmStateConfig;
7
+ declare const base_active_start_state_style: JssmStateConfig;
8
+ declare const base_end_state_style: JssmStateConfig;
9
+ declare const base_active_end_state_style: JssmStateConfig;
10
+ export { base_state_style, base_active_state_style, base_terminal_state_style, base_active_terminal_state_style, base_start_state_style, base_active_start_state_style, base_end_state_style, base_active_end_state_style };