jssm 5.79.0 → 5.79.3

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.
@@ -253,6 +253,7 @@ declare class Machine<mDT> {
253
253
  _property_keys: Set<string>;
254
254
  _default_properties: Map<string, any>;
255
255
  _state_properties: Map<string, any>;
256
+ _required_properties: Set<string>;
256
257
  _history: JssmHistory<mDT>;
257
258
  _history_length: number;
258
259
  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, arrange_declaration, arrange_start_declaration, arrange_end_declaration, theme, flow, graph_layout, instance_name, history, data }: JssmGenericConfig<mDT>);
@@ -312,6 +313,23 @@ declare class Machine<mDT> {
312
313
  *
313
314
  */
314
315
  prop(name: string): any;
316
+ /*********
317
+ *
318
+ * Get the current value of a given property name. If missing on the state
319
+ * and without a global default, throw, unlike {@link prop}, which would
320
+ * return `undefined` instead.
321
+ *
322
+ * ```typescript
323
+ *
324
+ * ```
325
+ *
326
+ * @param name The relevant property name to look up
327
+ *
328
+ * @returns The value behind the prop name. Because functional props are
329
+ * evaluated as getters, this can be anything.
330
+ *
331
+ */
332
+ strict_prop(name: string): any;
315
333
  /*********
316
334
  *
317
335
  * Get the current value of every prop, as an object. If no current definition
package/dist/es6/jssm.js CHANGED
@@ -353,12 +353,14 @@ function compile_rule_handler(rule) {
353
353
  }
354
354
  // manually rehandled to make `undefined` as a property safe
355
355
  if (rule.key === 'property_definition') {
356
+ const ret = { agg_as: 'property_definition', val: { name: rule.name } };
356
357
  if (rule.hasOwnProperty('default_value')) {
357
- return { agg_as: 'property_definition', val: { name: rule.name, default_value: rule.default_value } };
358
+ ret.val.default_value = rule.default_value;
358
359
  }
359
- else {
360
- return { agg_as: 'property_definition', val: { name: rule.name } };
360
+ if (rule.hasOwnProperty('required')) {
361
+ ret.val.required = rule.required;
361
362
  }
363
+ return ret;
362
364
  }
363
365
  // state properties are in here
364
366
  if (rule.key === 'state_declaration') {
@@ -503,7 +505,6 @@ function compile(tree) {
503
505
  sd.declarations.forEach(decl => {
504
506
  if (decl.key === 'state_property') {
505
507
  const label = name_bind_prop_and_state(decl.name, sd.state);
506
- console.log(`Bind ${sd.state}:${decl.name} as ${label}`);
507
508
  if (result_cfg.state_property.findIndex(c => c.name === label) !== -1) {
508
509
  throw new JssmError(undefined, `A state may only bind a property once (${sd.state} re-binds ${decl.name})`);
509
510
  }
@@ -641,6 +642,7 @@ class Machine {
641
642
  this._property_keys = new Set();
642
643
  this._default_properties = new Map();
643
644
  this._state_properties = new Map();
645
+ this._required_properties = new Set();
644
646
  this._history_length = history || 0;
645
647
  this._history = new circular_buffer(this._history_length);
646
648
  if (state_declaration) {
@@ -744,6 +746,9 @@ class Machine {
744
746
  if (pr.hasOwnProperty('default_value')) {
745
747
  this._default_properties.set(pr.name, pr.default_value);
746
748
  }
749
+ if (pr.hasOwnProperty('required') && (pr.required === true)) {
750
+ this._required_properties.add(pr.name);
751
+ }
747
752
  });
748
753
  }
749
754
  if (Array.isArray(state_property)) {
@@ -751,6 +756,32 @@ class Machine {
751
756
  this._state_properties.set(sp.name, sp.default_value);
752
757
  });
753
758
  }
759
+ // done building, do checks
760
+ this._state_properties.forEach((_value, key) => {
761
+ const inside = JSON.parse(key);
762
+ if (Array.isArray(inside)) {
763
+ const j_property = inside[0];
764
+ if (typeof j_property === 'string') {
765
+ const j_state = inside[1];
766
+ if (typeof j_state === 'string') {
767
+ if (!(this.known_prop(j_property))) {
768
+ throw new JssmError(this, `State "${j_state}" has property "${j_property}" which is not globally declared`);
769
+ }
770
+ }
771
+ }
772
+ }
773
+ });
774
+ this._required_properties.forEach(dp_key => {
775
+ if (this._default_properties.has(dp_key)) {
776
+ throw new JssmError(this, `The property "${dp_key}" is required, but also has a default; these conflict`);
777
+ }
778
+ this.states().forEach(s => {
779
+ const bound_name = name_bind_prop_and_state(dp_key, s);
780
+ if (!(this._state_properties.has(bound_name))) {
781
+ throw new JssmError(this, `State "${s}" is missing required property "${dp_key}"`);
782
+ }
783
+ });
784
+ });
754
785
  }
755
786
  /********
756
787
  *
@@ -845,6 +876,35 @@ class Machine {
845
876
  }
846
877
  }
847
878
  // NEEDS_DOCS
879
+ /*********
880
+ *
881
+ * Get the current value of a given property name. If missing on the state
882
+ * and without a global default, throw, unlike {@link prop}, which would
883
+ * return `undefined` instead.
884
+ *
885
+ * ```typescript
886
+ *
887
+ * ```
888
+ *
889
+ * @param name The relevant property name to look up
890
+ *
891
+ * @returns The value behind the prop name. Because functional props are
892
+ * evaluated as getters, this can be anything.
893
+ *
894
+ */
895
+ strict_prop(name) {
896
+ const bound_name = name_bind_prop_and_state(name, this.state());
897
+ if (this._state_properties.has(bound_name)) {
898
+ return this._state_properties.get(bound_name);
899
+ }
900
+ else if (this._default_properties.has(name)) {
901
+ return this._default_properties.get(name);
902
+ }
903
+ else {
904
+ throw new JssmError(this, `Strictly requested a prop '${name}' which doesn't exist on current state '${this.state()}' and has no default`);
905
+ }
906
+ }
907
+ // NEEDS_DOCS
848
908
  // COMEBACK add prop_map, sparse_props and strict_props to doc text when implemented
849
909
  /*********
850
910
  *
@@ -38,6 +38,7 @@ declare type JssmSerialization<DataType> = {
38
38
  declare type JssmPropertyDefinition = {
39
39
  name: string;
40
40
  default_value?: any;
41
+ required?: boolean;
41
42
  };
42
43
  declare type JssmTransitionPermitter<DataType> = (OldState: StateType, NewState: StateType, OldData: DataType, NewData: DataType) => boolean;
43
44
  declare type JssmTransitionPermitterMaybeArray<DataType> = JssmTransitionPermitter<DataType> | Array<JssmTransitionPermitter<DataType>>;
@@ -173,6 +174,7 @@ declare type JssmCompileSeStart<DataType> = {
173
174
  name?: string;
174
175
  state?: string;
175
176
  default_value?: any;
177
+ required?: boolean;
176
178
  };
177
179
  declare type JssmParseTree = Array<JssmCompileSeStart<StateType>>;
178
180
  declare type JssmParseFunctionType = (string: any) => JssmParseTree;
@@ -1,2 +1,2 @@
1
- const version = "5.79.0";
1
+ const version = "5.79.3";
2
2
  export { version };