jssm 5.72.5 → 5.73.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/CHANGELOG.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- 931 merges; 120 releases; Changlogging the last 10 commits; Full changelog at [CHANGELOG.long.md](CHANGELOG.long.md)
5
+ 933 merges; 122 releases; Changlogging the last 10 commits; Full changelog at [CHANGELOG.long.md](CHANGELOG.long.md)
6
6
 
7
7
 
8
8
 
@@ -12,7 +12,7 @@ All notable changes to this project will be documented in this file.
12
12
 
13
13
  Published tags:
14
14
 
15
- <a href="#5__72__3">5.72.3</a>, <a href="#5__72__2">5.72.2</a>, <a href="#5__72__1">5.72.1</a>, <a href="#5__72__0">5.72.0</a>, <a href="#5__71__1">5.71.1</a>, <a href="#5__71__0">5.71.0</a>, <a href="#5__70__36">5.70.36</a>, <a href="#5__70__35">5.70.35</a>, <a href="#5__70__34">5.70.34</a>, <a href="#5__70__33">5.70.33</a>, <a href="#5__70__32">5.70.32</a>, <a href="#5__70__31">5.70.31</a>, <a href="#5__70__30">5.70.30</a>, <a href="#5__70__29">5.70.29</a>, <a href="#5__70__28">5.70.28</a>, <a href="#5__70__27">5.70.27</a>, <a href="#5__70__26">5.70.26</a>, <a href="#5__70__25">5.70.25</a>, <a href="#5__70__24">5.70.24</a>, <a href="#5__70__23">5.70.23</a>, <a href="#5__70__22">5.70.22</a>, <a href="#5__70__21">5.70.21</a>, <a href="#5__70__20">5.70.20</a>, <a href="#5__70__19">5.70.19</a>, <a href="#5__70__18">5.70.18</a>, <a href="#5__70__16">5.70.16</a>, <a href="#5__70__15">5.70.15</a>, <a href="#5__70__14">5.70.14</a>, <a href="#5__70__13">5.70.13</a>, <a href="#5__70__12">5.70.12</a>, <a href="#5__70__11">5.70.11</a>, <a href="#5__70__10">5.70.10</a>, <a href="#5__70__9">5.70.9</a>, <a href="#5__70__8">5.70.8</a>, <a href="#5__70__7">5.70.7</a>, <a href="#5__70__6">5.70.6</a>, <a href="#5__70__5">5.70.5</a>, <a href="#5__70__4">5.70.4</a>, <a href="#5__70__3">5.70.3</a>, <a href="#5__70__2">5.70.2</a>, <a href="#5__70__1">5.70.1</a>, <a href="#5__70__0">5.70.0</a>, <a href="#5__69__4">5.69.4</a>, <a href="#5__69__3">5.69.3</a>, <a href="#5__69__2">5.69.2</a>, <a href="#5__69__0">5.69.0</a>, <a href="#5__68__0">5.68.0</a>, <a href="#5__67__2">5.67.2</a>, <a href="#5__67__0">5.67.0</a>, <a href="#5__66__0">5.66.0</a>, <a href="#5__65__14">5.65.14</a>, <a href="#5__65__12">5.65.12</a>, <a href="#5__65__11">5.65.11</a>, <a href="#5__65__10">5.65.10</a>, <a href="#5__65__9">5.65.9</a>, <a href="#5__65__8">5.65.8</a>, <a href="#5__65__7">5.65.7</a>, <a href="#5__65__5">5.65.5</a>, <a href="#5__65__4">5.65.4</a>, <a href="#5__65__3">5.65.3</a>, <a href="#5__65__2">5.65.2</a>, <a href="#5__65__1">5.65.1</a>, <a href="#5__65__0">5.65.0</a>, <a href="#5__64__2">5.64.2</a>, <a href="#5__64__1">5.64.1</a>, <a href="#5__64__0">5.64.0</a>, <a href="#5__63__0">5.63.0</a>, <a href="#5__62__0">5.62.0</a>, <a href="#5__61__4">5.61.4</a>, <a href="#5__61__3">5.61.3</a>, <a href="#5__61__2">5.61.2</a>, <a href="#5__61__1">5.61.1</a>, <a href="#5__60__4">5.60.4</a>, <a href="#5__60__3">5.60.3</a>, <a href="#5__60__0">5.60.0</a>, <a href="#5__59__1">5.59.1</a>, <a href="#5__59__0">5.59.0</a>, <a href="#5__58__1">5.58.1</a>, <a href="#5__58__0">5.58.0</a>, <a href="#5__57__1">5.57.1</a>, <a href="#5__57__0">5.57.0</a>, <a href="#5__56__2">5.56.2</a>, <a href="#5__56__1">5.56.1</a>, <a href="#5__55__0">5.55.0</a>, <a href="#5__54__0">5.54.0</a>, <a href="#5__53__0">5.53.0</a>, <a href="#5__52__0">5.52.0</a>, <a href="#5__51__0">5.51.0</a>, <a href="#5__50__0">5.50.0</a>, <a href="#5__49__0">5.49.0</a>, <a href="#5__48__0">5.48.0</a>, <a href="#5__47__0">5.47.0</a>, <a href="#5__46__0">5.46.0</a>, <a href="#5__45__2">5.45.2</a>, <a href="#5__45__0">5.45.0</a>, <a href="#5__44__0">5.44.0</a>, <a href="#5__43__2">5.43.2</a>, <a href="#v5__42__0">v5.42.0</a>, <a href="#5__42__0">5.42.0</a>, <a href="#v5__41__15">v5.41.15</a>, <a href="#5__41__15">5.41.15</a>, <a href="#v5__41__14">v5.41.14</a>, <a href="#5__41__14">5.41.14</a>, <a href="#v5__41__12">v5.41.12</a>, <a href="#5__41__12">5.41.12</a>, <a href="#v5__41__10">v5.41.10</a>, <a href="#5__41__10">5.41.10</a>, <a href="#v5__41__9">v5.41.9</a>, <a href="#5__41__9">5.41.9</a>, <a href="#v5__41__8">v5.41.8</a>, <a href="#5__41__8">5.41.8</a>, <a href="#v5__41__7">v5.41.7</a>, <a href="#v5__41__2">v5.41.2</a>, <a href="#v5__41__1">v5.41.1</a>, <a href="#v5__32__14">v5.32.14</a>, <a href="#5__14__0">5.14.0</a>, <a href="#5__12__0">5.12.0</a>, <a href="#5__11__12">5.11.12</a>, <a href="#5__11__1">5.11.1</a>, <a href="#5__11__0">5.11.0</a>
15
+ <a href="#5__72__5">5.72.5</a>, <a href="#5__72__4">5.72.4</a>, <a href="#5__72__3">5.72.3</a>, <a href="#5__72__2">5.72.2</a>, <a href="#5__72__1">5.72.1</a>, <a href="#5__72__0">5.72.0</a>, <a href="#5__71__1">5.71.1</a>, <a href="#5__71__0">5.71.0</a>, <a href="#5__70__36">5.70.36</a>, <a href="#5__70__35">5.70.35</a>, <a href="#5__70__34">5.70.34</a>, <a href="#5__70__33">5.70.33</a>, <a href="#5__70__32">5.70.32</a>, <a href="#5__70__31">5.70.31</a>, <a href="#5__70__30">5.70.30</a>, <a href="#5__70__29">5.70.29</a>, <a href="#5__70__28">5.70.28</a>, <a href="#5__70__27">5.70.27</a>, <a href="#5__70__26">5.70.26</a>, <a href="#5__70__25">5.70.25</a>, <a href="#5__70__24">5.70.24</a>, <a href="#5__70__23">5.70.23</a>, <a href="#5__70__22">5.70.22</a>, <a href="#5__70__21">5.70.21</a>, <a href="#5__70__20">5.70.20</a>, <a href="#5__70__19">5.70.19</a>, <a href="#5__70__18">5.70.18</a>, <a href="#5__70__16">5.70.16</a>, <a href="#5__70__15">5.70.15</a>, <a href="#5__70__14">5.70.14</a>, <a href="#5__70__13">5.70.13</a>, <a href="#5__70__12">5.70.12</a>, <a href="#5__70__11">5.70.11</a>, <a href="#5__70__10">5.70.10</a>, <a href="#5__70__9">5.70.9</a>, <a href="#5__70__8">5.70.8</a>, <a href="#5__70__7">5.70.7</a>, <a href="#5__70__6">5.70.6</a>, <a href="#5__70__5">5.70.5</a>, <a href="#5__70__4">5.70.4</a>, <a href="#5__70__3">5.70.3</a>, <a href="#5__70__2">5.70.2</a>, <a href="#5__70__1">5.70.1</a>, <a href="#5__70__0">5.70.0</a>, <a href="#5__69__4">5.69.4</a>, <a href="#5__69__3">5.69.3</a>, <a href="#5__69__2">5.69.2</a>, <a href="#5__69__0">5.69.0</a>, <a href="#5__68__0">5.68.0</a>, <a href="#5__67__2">5.67.2</a>, <a href="#5__67__0">5.67.0</a>, <a href="#5__66__0">5.66.0</a>, <a href="#5__65__14">5.65.14</a>, <a href="#5__65__12">5.65.12</a>, <a href="#5__65__11">5.65.11</a>, <a href="#5__65__10">5.65.10</a>, <a href="#5__65__9">5.65.9</a>, <a href="#5__65__8">5.65.8</a>, <a href="#5__65__7">5.65.7</a>, <a href="#5__65__5">5.65.5</a>, <a href="#5__65__4">5.65.4</a>, <a href="#5__65__3">5.65.3</a>, <a href="#5__65__2">5.65.2</a>, <a href="#5__65__1">5.65.1</a>, <a href="#5__65__0">5.65.0</a>, <a href="#5__64__2">5.64.2</a>, <a href="#5__64__1">5.64.1</a>, <a href="#5__64__0">5.64.0</a>, <a href="#5__63__0">5.63.0</a>, <a href="#5__62__0">5.62.0</a>, <a href="#5__61__4">5.61.4</a>, <a href="#5__61__3">5.61.3</a>, <a href="#5__61__2">5.61.2</a>, <a href="#5__61__1">5.61.1</a>, <a href="#5__60__4">5.60.4</a>, <a href="#5__60__3">5.60.3</a>, <a href="#5__60__0">5.60.0</a>, <a href="#5__59__1">5.59.1</a>, <a href="#5__59__0">5.59.0</a>, <a href="#5__58__1">5.58.1</a>, <a href="#5__58__0">5.58.0</a>, <a href="#5__57__1">5.57.1</a>, <a href="#5__57__0">5.57.0</a>, <a href="#5__56__2">5.56.2</a>, <a href="#5__56__1">5.56.1</a>, <a href="#5__55__0">5.55.0</a>, <a href="#5__54__0">5.54.0</a>, <a href="#5__53__0">5.53.0</a>, <a href="#5__52__0">5.52.0</a>, <a href="#5__51__0">5.51.0</a>, <a href="#5__50__0">5.50.0</a>, <a href="#5__49__0">5.49.0</a>, <a href="#5__48__0">5.48.0</a>, <a href="#5__47__0">5.47.0</a>, <a href="#5__46__0">5.46.0</a>, <a href="#5__45__2">5.45.2</a>, <a href="#5__45__0">5.45.0</a>, <a href="#5__44__0">5.44.0</a>, <a href="#5__43__2">5.43.2</a>, <a href="#v5__42__0">v5.42.0</a>, <a href="#5__42__0">5.42.0</a>, <a href="#v5__41__15">v5.41.15</a>, <a href="#5__41__15">5.41.15</a>, <a href="#v5__41__14">v5.41.14</a>, <a href="#5__41__14">5.41.14</a>, <a href="#v5__41__12">v5.41.12</a>, <a href="#5__41__12">5.41.12</a>, <a href="#v5__41__10">v5.41.10</a>, <a href="#5__41__10">5.41.10</a>, <a href="#v5__41__9">v5.41.9</a>, <a href="#5__41__9">5.41.9</a>, <a href="#v5__41__8">v5.41.8</a>, <a href="#5__41__8">5.41.8</a>, <a href="#v5__41__7">v5.41.7</a>, <a href="#v5__41__2">v5.41.2</a>, <a href="#v5__41__1">v5.41.1</a>, <a href="#v5__32__14">v5.32.14</a>, <a href="#5__14__0">5.14.0</a>, <a href="#5__12__0">5.12.0</a>, <a href="#5__11__12">5.11.12</a>, <a href="#5__11__1">5.11.1</a>, <a href="#5__11__0">5.11.0</a>
16
16
 
17
17
 
18
18
 
@@ -22,7 +22,44 @@ Published tags:
22
22
 
23
23
  &nbsp;
24
24
 
25
- ## [Untagged] - 6/25/2022 8:12:11 AM
25
+ <a name="5__72__5" />
26
+
27
+ ## [5.72.5] - 6/25/2022 11:07:29 AM
28
+
29
+ Commit [f1a61f1e967df66b87f2b6b39f75636659f496e9](https://github.com/StoneCypher/jssm/commit/f1a61f1e967df66b87f2b6b39f75636659f496e9)
30
+
31
+ Author: `John Haugeland <stonecypher@gmail.com>`
32
+
33
+ Merges [dc3096f, 751c5fd]
34
+
35
+ * Merge pull request #503 from StoneCypher/AttemptToCaptureTestResults
36
+ * Captures test results, fixes StoneCypher/fsl#944, tools readme, fixes StoneCypher/fsl#736
37
+
38
+
39
+
40
+
41
+ &nbsp;
42
+
43
+ &nbsp;
44
+
45
+ ## [Untagged] - 6/25/2022 11:04:20 AM
46
+
47
+ Commit [751c5fd0cc8c9751331e664e8f51af34f736ce31](https://github.com/StoneCypher/jssm/commit/751c5fd0cc8c9751331e664e8f51af34f736ce31)
48
+
49
+ Author: `John Haugeland <stonecypher@gmail.com>`
50
+
51
+ * Captures test results, fixes StoneCypher/fsl#944, tools readme, fixes StoneCypher/fsl#736
52
+
53
+
54
+
55
+
56
+ &nbsp;
57
+
58
+ &nbsp;
59
+
60
+ <a name="5__72__4" />
61
+
62
+ ## [5.72.4] - 6/25/2022 8:12:11 AM
26
63
 
27
64
  Commit [dc3096f064e58ea616899b12d3d25c973f326c1c](https://github.com/StoneCypher/jssm/commit/dc3096f064e58ea616899b12d3d25c973f326c1c)
28
65
 
@@ -141,34 +178,4 @@ Author: `John Haugeland <stonecypher@gmail.com>`
141
178
  Merges [b0cbe1c, d52217a]
142
179
 
143
180
  * Merge pull request #501 from StoneCypher/MovingToAbstractHooks
144
- * Moving to abstract hooks
145
-
146
-
147
-
148
-
149
- &nbsp;
150
-
151
- &nbsp;
152
-
153
- ## [Untagged] - 6/24/2022 7:44:55 PM
154
-
155
- Commit [d52217ab9dde2a5746cd0704597d337362057024](https://github.com/StoneCypher/jssm/commit/d52217ab9dde2a5746cd0704597d337362057024)
156
-
157
- Author: `John Haugeland <stonecypher@gmail.com>`
158
-
159
- * Basic conversion to abstract hooks complete; fixes StoneCypher/fsl#931
160
-
161
-
162
-
163
-
164
- &nbsp;
165
-
166
- &nbsp;
167
-
168
- ## [Untagged] - 6/24/2022 7:36:27 PM
169
-
170
- Commit [adfa9069ba5e78d8a227896a5f7e14a8f4b80117](https://github.com/StoneCypher/jssm/commit/adfa9069ba5e78d8a227896a5f7e14a8f4b80117)
171
-
172
- Author: `John Haugeland <stonecypher@gmail.com>`
173
-
174
- * the conversion continues
181
+ * Moving to abstract hooks
package/README.md CHANGED
@@ -18,14 +18,14 @@ Please edit the file it's derived from, instead: `./src/md/readme_base.md`
18
18
 
19
19
 
20
20
 
21
- * Generated for version 5.72.5 at 6/25/2022, 10:53:38 AM
21
+ * Generated for version 5.73.0 at 6/27/2022, 2:27:29 AM
22
22
 
23
23
  -->
24
24
  # jssm
25
25
 
26
26
  Easy. Small. Fast. TS, es6, es5. Node, Browser. 100% coverage. Property
27
27
  tests. Fuzz tests. Language tests for a dozen languages and emoji. Easy to
28
- share online. Easy to embed. ***4,611 tests***.
28
+ share online. Easy to embed. ***4,617 tests***.
29
29
 
30
30
  Readable, useful state machines as one-liner strings.
31
31
 
@@ -1,4 +1,5 @@
1
1
  declare type StateType = string;
2
+ import { circular_buffer } from 'circular_buffer_js';
2
3
  import { JssmGenericState, JssmGenericConfig, JssmTransition, JssmTransitionList, // JssmTransitionRule,
3
4
  JssmMachineInternalState, JssmParseTree, JssmStateDeclaration, JssmArrow, JssmArrowDirection, JssmArrowKind, JssmLayout, FslDirection, FslTheme, HookDescription, HookHandler, HookContext, HookResult, HookComplexResult } from './jssm_types';
4
5
  import { seq, weighted_rand_select, weighted_sample_select, histograph, weighted_histo_key } from './jssm_util';
@@ -233,7 +234,9 @@ declare class Machine<mDT> {
233
234
  _main_transition_hook: HookHandler<mDT> | undefined;
234
235
  _forced_transition_hook: HookHandler<mDT> | undefined;
235
236
  _any_transition_hook: HookHandler<mDT> | undefined;
236
- constructor({ start_states, complete, transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, state_declaration, fsl_version, dot_preamble, arrange_declaration, arrange_start_declaration, arrange_end_declaration, theme, flow, graph_layout, instance_name, data }: JssmGenericConfig<mDT>);
237
+ _history: circular_buffer<[StateType, mDT]>;
238
+ _history_length: number;
239
+ constructor({ start_states, complete, transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, state_declaration, fsl_version, dot_preamble, arrange_declaration, arrange_start_declaration, arrange_end_declaration, theme, flow, graph_layout, instance_name, history, data }: JssmGenericConfig<mDT>);
237
240
  /********
238
241
  *
239
242
  * Internal method for fabricating states. Not meant for external use.
@@ -551,6 +554,88 @@ declare class Machine<mDT> {
551
554
  hook_exit(from: string, handler: HookHandler<mDT>): Machine<mDT>;
552
555
  edges_between(from: string, to: string): JssmTransition<mDT>[];
553
556
  transition_impl(newStateOrAction: StateType, newData: mDT | undefined, wasForced: boolean, wasAction: boolean): boolean;
557
+ /*********
558
+ *
559
+ * Get a truncated history of the recent states and data of the machine.
560
+ * Turned off by default; configure with `.from('...', {data: 5})` by length,
561
+ * or set `.history_length` at runtime.
562
+ *
563
+ * History *does not contain the current state*. If you want that, call
564
+ * `.history_inclusive` instead.
565
+ *
566
+ * ```typescript
567
+ * const foo = jssm.from(
568
+ * "a 'next' -> b 'next' -> c 'next' -> d 'next' -> e;",
569
+ * { history: 3 }
570
+ * );
571
+ *
572
+ * foo.action('next');
573
+ * foo.action('next');
574
+ * foo.action('next');
575
+ * foo.action('next');
576
+ *
577
+ * foo.history; // [ ['b',undefined], ['c',undefined], ['d',undefined] ]
578
+ * ```
579
+ *
580
+ * Notice that the machine's current state, `e`, is not in the returned list.
581
+ *
582
+ * @typeparam mDT The type of the machine data member; usually omitted
583
+ *
584
+ */
585
+ get history(): [string, mDT][];
586
+ /*********
587
+ *
588
+ * Get a truncated history of the recent states and data of the machine,
589
+ * including the current state. Turned off by default; configure with
590
+ * `.from('...', {data: 5})` by length, or set `.history_length` at runtime.
591
+ *
592
+ * History inclusive contains the current state. If you only want past
593
+ * states, call `.history` instead.
594
+ *
595
+ * The list returned will be one longer than the history buffer kept, as the
596
+ * history buffer kept gets the current state added to it to produce this
597
+ * list.
598
+ *
599
+ * ```typescript
600
+ * const foo = jssm.from(
601
+ * "a 'next' -> b 'next' -> c 'next' -> d 'next' -> e;",
602
+ * { history: 3 }
603
+ * );
604
+ *
605
+ * foo.action('next');
606
+ * foo.action('next');
607
+ * foo.action('next');
608
+ * foo.action('next');
609
+ *
610
+ * foo.history_inclusive; // [ ['b',undefined], ['c',undefined], ['d',undefined], ['e',undefined] ]
611
+ * ```
612
+ *
613
+ * Notice that the machine's current state, `e`, is in the returned list.
614
+ *
615
+ * @typeparam mDT The type of the machine data member; usually omitted
616
+ *
617
+ */
618
+ get history_inclusive(): [string, mDT][];
619
+ /*********
620
+ *
621
+ * Find out how long a history this machine is keeping. Defaults to zero.
622
+ * Settable directly.
623
+ *
624
+ * ```typescript
625
+ * const foo = jssm.from("a -> b;");
626
+ * foo.history_length; // 0
627
+ *
628
+ * const bar = jssm.from("a -> b;", { history: 3 });
629
+ * foo.history_length; // 3
630
+ * foo.history_length = 5;
631
+ * foo.history_length; // 5
632
+ * ```
633
+ *
634
+ * @typeparam mDT The type of the machine data member; usually omitted
635
+ *
636
+ */
637
+ get history_length(): number;
638
+ set history_length(to: number);
554
639
  /********
555
640
  *
556
641
  * Instruct the machine to complete an action.
package/dist/es6/jssm.js CHANGED
@@ -1,5 +1,6 @@
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
+ import { circular_buffer } from 'circular_buffer_js';
3
4
  import { seq, weighted_rand_select, weighted_sample_select, histograph, weighted_histo_key, array_box_if_string, hook_name, named_hook_name } from './jssm_util';
4
5
  import { shapes, gviz_shapes, named_colors } from './jssm_constants';
5
6
  import { parse } from './jssm-dot';
@@ -534,7 +535,7 @@ function transfer_state_properties(state_decl) {
534
535
  // TODO add a lotta docblock here
535
536
  class Machine {
536
537
  // whargarbl this badly needs to be broken up, monolith master
537
- constructor({ start_states, complete = [], transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, state_declaration, fsl_version, dot_preamble = undefined, arrange_declaration = [], arrange_start_declaration = [], arrange_end_declaration = [], theme = 'default', flow = 'down', graph_layout = 'dot', instance_name, data }) {
538
+ constructor({ start_states, complete = [], transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, state_declaration, fsl_version, dot_preamble = undefined, arrange_declaration = [], arrange_start_declaration = [], arrange_end_declaration = [], theme = 'default', flow = 'down', graph_layout = 'dot', instance_name, history, data }) {
538
539
  this._instance_name = instance_name;
539
540
  this._state = start_states[0];
540
541
  this._states = new Map();
@@ -582,6 +583,8 @@ class Machine {
582
583
  this._any_transition_hook = undefined;
583
584
  this._standard_transition_hook = undefined;
584
585
  this._data = data;
586
+ this._history_length = history || 0;
587
+ this._history = new circular_buffer(this._history_length);
585
588
  if (state_declaration) {
586
589
  state_declaration.map((state_decl) => {
587
590
  if (this._state_declarations.has(state_decl.state)) { // no repeats
@@ -1426,6 +1429,9 @@ class Machine {
1426
1429
  update_fields(outcome);
1427
1430
  }
1428
1431
  // all hooks passed! let's now establish the result
1432
+ if (this._history_length) {
1433
+ this._history.shove([this._state, this._data]);
1434
+ }
1429
1435
  this._state = newState;
1430
1436
  if (data_changed) {
1431
1437
  this._data = hook_args.data;
@@ -1434,6 +1440,9 @@ class Machine {
1434
1440
  // or without hooks
1435
1441
  }
1436
1442
  else {
1443
+ if (this._history_length) {
1444
+ this._history.shove([this._state, this._data]);
1445
+ }
1437
1446
  this._state = newState;
1438
1447
  return true;
1439
1448
  }
@@ -1443,6 +1452,99 @@ class Machine {
1443
1452
  return false;
1444
1453
  }
1445
1454
  }
1455
+ /*********
1456
+ *
1457
+ * Get a truncated history of the recent states and data of the machine.
1458
+ * Turned off by default; configure with `.from('...', {data: 5})` by length,
1459
+ * or set `.history_length` at runtime.
1460
+ *
1461
+ * History *does not contain the current state*. If you want that, call
1462
+ * `.history_inclusive` instead.
1463
+ *
1464
+ * ```typescript
1465
+ * const foo = jssm.from(
1466
+ * "a 'next' -> b 'next' -> c 'next' -> d 'next' -> e;",
1467
+ * { history: 3 }
1468
+ * );
1469
+ *
1470
+ * foo.action('next');
1471
+ * foo.action('next');
1472
+ * foo.action('next');
1473
+ * foo.action('next');
1474
+ *
1475
+ * foo.history; // [ ['b',undefined], ['c',undefined], ['d',undefined] ]
1476
+ * ```
1477
+ *
1478
+ * Notice that the machine's current state, `e`, is not in the returned list.
1479
+ *
1480
+ * @typeparam mDT The type of the machine data member; usually omitted
1481
+ *
1482
+ */
1483
+ get history() {
1484
+ return this._history.toArray();
1485
+ }
1486
+ /*********
1487
+ *
1488
+ * Get a truncated history of the recent states and data of the machine,
1489
+ * including the current state. Turned off by default; configure with
1490
+ * `.from('...', {data: 5})` by length, or set `.history_length` at runtime.
1491
+ *
1492
+ * History inclusive contains the current state. If you only want past
1493
+ * states, call `.history` instead.
1494
+ *
1495
+ * The list returned will be one longer than the history buffer kept, as the
1496
+ * history buffer kept gets the current state added to it to produce this
1497
+ * list.
1498
+ *
1499
+ * ```typescript
1500
+ * const foo = jssm.from(
1501
+ * "a 'next' -> b 'next' -> c 'next' -> d 'next' -> e;",
1502
+ * { history: 3 }
1503
+ * );
1504
+ *
1505
+ * foo.action('next');
1506
+ * foo.action('next');
1507
+ * foo.action('next');
1508
+ * foo.action('next');
1509
+ *
1510
+ * foo.history_inclusive; // [ ['b',undefined], ['c',undefined], ['d',undefined], ['e',undefined] ]
1511
+ * ```
1512
+ *
1513
+ * Notice that the machine's current state, `e`, is in the returned list.
1514
+ *
1515
+ * @typeparam mDT The type of the machine data member; usually omitted
1516
+ *
1517
+ */
1518
+ get history_inclusive() {
1519
+ const ret = this._history.toArray();
1520
+ ret.push([this.state(), this.data()]);
1521
+ return ret;
1522
+ }
1523
+ /*********
1524
+ *
1525
+ * Find out how long a history this machine is keeping. Defaults to zero.
1526
+ * Settable directly.
1527
+ *
1528
+ * ```typescript
1529
+ * const foo = jssm.from("a -> b;");
1530
+ * foo.history_length; // 0
1531
+ *
1532
+ * const bar = jssm.from("a -> b;", { history: 3 });
1533
+ * foo.history_length; // 3
1534
+ * foo.history_length = 5;
1535
+ * foo.history_length; // 5
1536
+ * ```
1537
+ *
1538
+ * @typeparam mDT The type of the machine data member; usually omitted
1539
+ *
1540
+ */
1541
+ get history_length() {
1542
+ return this._history_length;
1543
+ }
1544
+ set history_length(to) {
1545
+ this._history_length = to;
1546
+ this._history.resize(to, true);
1547
+ }
1446
1548
  /********
1447
1549
  *
1448
1550
  * Instruct the machine to complete an action.
@@ -102,6 +102,7 @@ declare type JssmGenericConfig<DataType> = {
102
102
  data?: DataType;
103
103
  nodes?: Array<StateType>;
104
104
  check?: JssmStatePermitterMaybeArray<DataType>;
105
+ history?: number;
105
106
  min_exits?: number;
106
107
  max_exits?: number;
107
108
  allow_islands?: false;
@@ -1,2 +1,2 @@
1
- const version = "5.72.5";
1
+ const version = "5.73.0";
2
2
  export { version };