From 9db9bad5242f635d4a69db3dca4caeeb6013af1e Mon Sep 17 00:00:00 2001 From: John Haugeland Date: Sun, 15 May 2022 07:25:27 -0700 Subject: [PATCH 1/2] Base error object, fixes StoneCypher/fsl#752 --- benchmark/results/general.chart.html | 14 +-- benchmark/results/general.json | 126 +++++++++++++-------------- dist/es6/jssm.js | 15 +++- dist/es6/jssm_error.d.ts | 4 + dist/es6/jssm_error.js | 8 ++ dist/es6/version.js | 2 +- dist/jssm.es5.cjs.js | 2 +- dist/jssm.es5.cjs.nonmin.js | 14 ++- dist/jssm.es5.iife.js | 2 +- dist/jssm.es5.iife.nonmin.js | 14 ++- docs/docs/classes/Machine.html | 2 +- docs/docs/modules.html | 2 +- jssm_error.d.ts | 4 + package.json | 2 +- src/ts/jssm.ts | 33 ++++++- src/ts/jssm_error.ts | 17 ++++ src/ts/version.ts | 2 +- 17 files changed, 177 insertions(+), 86 deletions(-) create mode 100644 dist/es6/jssm_error.d.ts create mode 100644 dist/es6/jssm_error.js create mode 100644 jssm_error.d.ts create mode 100644 src/ts/jssm_error.ts diff --git a/benchmark/results/general.chart.html b/benchmark/results/general.chart.html index 29ed3ba7..0a6e9972 100644 --- a/benchmark/results/general.chart.html +++ b/benchmark/results/general.chart.html @@ -28,7 +28,7 @@
- +
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class Machine<mDT>

Type parameters

  • mDT

Hierarchy

  • Machine

Index

Constructors

Properties

Methods

Constructors

  • new Machine<mDT>(__namedParameters: JssmGenericConfig<mDT>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • __namedParameters: JssmGenericConfig<mDT>

    Returns Machine<mDT>

Properties

_actions: Map<string, Map<string, number>>
_any_action_hook: Function
_any_transition_hook: Function
_arrange_declaration: string[][]
_arrange_end_declaration: string[][]
_arrange_start_declaration: string[][]
_dot_preamble: string
_edge_map: Map<string, Map<string, number>>
_edges: JssmTransition<mDT>[]
_entry_hooks: Map<string, Function>
_exit_hooks: Map<string, Function>
_flow: FslDirection
_forced_transition_hook: Function
_fsl_version?: string
_global_action_hooks: Map<string, Function>
_graph_layout: JssmLayout
_has_basic_hooks: boolean
_has_entry_hooks: boolean
_has_exit_hooks: boolean
_has_global_action_hooks: boolean
_has_hooks: boolean
_has_named_hooks: boolean
_has_transition_hooks: boolean
_hooks: Map<string, Function>
_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: Function
_named_hooks: Map<string, Function>
_named_transitions: Map<string, number>
_raw_state_declaration?: Object[]
_reverse_action_targets: Map<string, Map<string, number>>
_reverse_actions: Map<string, Map<string, number>>
_standard_transition_hook: Function
_state: string
_state_declarations: Map<string, JssmStateDeclaration>
_states: Map<string, JssmGenericState>
_theme: FslTheme

Methods

  • _new_state(state_config: JssmGenericState): string
  • Parameters

    • state_config: JssmGenericState

    Returns string

  • action(actionName: string, newData?: mDT): boolean
  • Parameters

    • actionName: string
    • Optional newData: mDT

    Returns boolean

  • actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • current_action_edge_for(action: string): JssmTransition<mDT>
  • Parameters

    • action: string

    Returns JssmTransition<mDT>

  • current_action_for(action: string): number
  • Parameters

    • action: string

    Returns number

  • dot_preamble(): string
  • edges_between(from: string, to: string): JssmTransition<mDT>[]
  • Parameters

    • from: string
    • to: string

    Returns JssmTransition<mDT>[]

  • flow(): FslDirection
  • force_transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • fsl_version(): string
  • get_transition_by_state_names(from: string, to: string): number
  • Parameters

    • from: string
    • to: string

    Returns number

  • graph_layout(): string
  • has_completes(): boolean
  • has_state(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • has_terminals(): boolean
  • has_unenterables(): boolean
  • hook(from: string, to: string, handler: Function): Machine<mDT>
  • hook_action(from: string, to: string, action: string, handler: Function): Machine<mDT>
  • Parameters

    • from: string
    • to: string
    • action: string
    • handler: Function

    Returns Machine<mDT>

  • hook_any_action(handler: Function): Machine<mDT>
  • hook_any_transition(handler: Function): Machine<mDT>
  • hook_entry(to: string, handler: Function): Machine<mDT>
  • hook_exit(from: string, handler: Function): Machine<mDT>
  • hook_forced_transition(handler: Function): Machine<mDT>
  • hook_global_action(action: string, handler: Function): Machine<mDT>
  • hook_main_transition(handler: Function): Machine<mDT>
  • hook_standard_transition(handler: Function): Machine<mDT>
  • instance_name(): string
  • is_complete(): boolean
  • is_final(): boolean
  • is_terminal(): boolean
  • is_unenterable(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • list_actions(): string[]
  • list_edges(): JssmTransition<mDT>[]
  • list_entrances(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exit_actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exits(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_named_transitions(): Map<string, number>
  • list_states_having_action(whichState: string): string[]
  • Parameters

    • whichState: string

    Returns string[]

  • list_transitions(whichState?: string): JssmTransitionList
  • Parameters

    • whichState: string = ...

    Returns JssmTransitionList

  • lookup_transition_for(from: string, to: string): JssmTransition<mDT>
  • Parameters

    • from: string
    • to: string

    Returns JssmTransition<mDT>

  • machine_author(): string[]
  • machine_comment(): string
  • machine_contributor(): string[]
  • machine_definition(): string
  • machine_language(): string
  • machine_license(): string
  • machine_name(): string
  • machine_state(): JssmMachineInternalState<mDT>
  • Returns JssmMachineInternalState<mDT>

  • machine_version(): string
  • probabilistic_histo_walk(n: number): Map<string, number>
  • Parameters

    • n: number

    Returns Map<string, number>

  • probabilistic_transition(): boolean
  • probabilistic_walk(n: number): string[]
  • Parameters

    • n: number

    Returns string[]

  • probable_action_exits(whichState?: string): any[]
  • Parameters

    • whichState: string = ...

    Returns any[]

  • probable_exits_for(whichState: string): JssmTransition<mDT>[]
  • Parameters

    • whichState: string

    Returns JssmTransition<mDT>[]

  • raw_state_declarations(): Object[]
  • set_hook(HookDesc: HookDescription): void
  • Parameters

    • HookDesc: HookDescription

    Returns void

  • sm(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • state(): string
  • state_declaration(which: string): JssmStateDeclaration
  • Parameters

    • which: string

    Returns JssmStateDeclaration

  • state_declarations(): Map<string, JssmStateDeclaration>
  • Returns Map<string, JssmStateDeclaration>

  • state_for(whichState: string): JssmGenericState
  • Parameters

    • whichState: string

    Returns JssmGenericState

  • state_is_complete(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_final(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_terminal(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • states(): string[]
  • theme(): FslTheme
  • transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • transition_impl(newStateOrAction: string, newData: mDT, wasForced: boolean, wasAction: boolean): boolean
  • Parameters

    • newStateOrAction: string
    • newData: mDT
    • wasForced: boolean
    • wasAction: boolean

    Returns boolean

  • valid_action(action: string, _newData?: mDT): boolean
  • Parameters

    • action: string
    • Optional _newData: mDT

    Returns boolean

  • valid_force_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

  • valid_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

Generated using TypeDoc

\ No newline at end of file +Machine | jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class Machine<mDT>

Type parameters

  • mDT

Hierarchy

  • Machine

Index

Constructors

Properties

Methods

Constructors

  • new Machine<mDT>(__namedParameters: JssmGenericConfig<mDT>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • __namedParameters: JssmGenericConfig<mDT>

    Returns Machine<mDT>

Properties

_actions: Map<string, Map<string, number>>
_any_action_hook: Function
_any_transition_hook: Function
_arrange_declaration: string[][]
_arrange_end_declaration: string[][]
_arrange_start_declaration: string[][]
_dot_preamble: string
_edge_map: Map<string, Map<string, number>>
_edges: JssmTransition<mDT>[]
_entry_hooks: Map<string, Function>
_exit_hooks: Map<string, Function>
_flow: FslDirection
_forced_transition_hook: Function
_fsl_version?: string
_global_action_hooks: Map<string, Function>
_graph_layout: JssmLayout
_has_basic_hooks: boolean
_has_entry_hooks: boolean
_has_exit_hooks: boolean
_has_global_action_hooks: boolean
_has_hooks: boolean
_has_named_hooks: boolean
_has_transition_hooks: boolean
_hooks: Map<string, Function>
_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: Function
_named_hooks: Map<string, Function>
_named_transitions: Map<string, number>
_raw_state_declaration?: Object[]
_reverse_action_targets: Map<string, Map<string, number>>
_reverse_actions: Map<string, Map<string, number>>
_standard_transition_hook: Function
_state: string
_state_declarations: Map<string, JssmStateDeclaration>
_states: Map<string, JssmGenericState>
_theme: FslTheme

Methods

  • _new_state(state_config: JssmGenericState): string
  • Parameters

    • state_config: JssmGenericState

    Returns string

  • action(actionName: string, newData?: mDT): boolean
  • Parameters

    • actionName: string
    • Optional newData: mDT

    Returns boolean

  • actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • current_action_edge_for(action: string): JssmTransition<mDT>
  • Parameters

    • action: string

    Returns JssmTransition<mDT>

  • current_action_for(action: string): number
  • Parameters

    • action: string

    Returns number

  • dot_preamble(): string
  • edges_between(from: string, to: string): JssmTransition<mDT>[]
  • Parameters

    • from: string
    • to: string

    Returns JssmTransition<mDT>[]

  • flow(): FslDirection
  • force_transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • fsl_version(): string
  • get_transition_by_state_names(from: string, to: string): number
  • Parameters

    • from: string
    • to: string

    Returns number

  • graph_layout(): string
  • has_completes(): boolean
  • has_state(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • has_terminals(): boolean
  • has_unenterables(): boolean
  • hook(from: string, to: string, handler: Function): Machine<mDT>
  • hook_action(from: string, to: string, action: string, handler: Function): Machine<mDT>
  • Parameters

    • from: string
    • to: string
    • action: string
    • handler: Function

    Returns Machine<mDT>

  • hook_any_action(handler: Function): Machine<mDT>
  • hook_any_transition(handler: Function): Machine<mDT>
  • hook_entry(to: string, handler: Function): Machine<mDT>
  • hook_exit(from: string, handler: Function): Machine<mDT>
  • hook_forced_transition(handler: Function): Machine<mDT>
  • hook_global_action(action: string, handler: Function): Machine<mDT>
  • hook_main_transition(handler: Function): Machine<mDT>
  • hook_standard_transition(handler: Function): Machine<mDT>
  • instance_name(): string
  • is_complete(): boolean
  • is_final(): boolean
  • is_terminal(): boolean
  • is_unenterable(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • list_actions(): string[]
  • list_edges(): JssmTransition<mDT>[]
  • list_entrances(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exit_actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exits(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_named_transitions(): Map<string, number>
  • list_states_having_action(whichState: string): string[]
  • Parameters

    • whichState: string

    Returns string[]

  • list_transitions(whichState?: string): JssmTransitionList
  • Parameters

    • whichState: string = ...

    Returns JssmTransitionList

  • lookup_transition_for(from: string, to: string): JssmTransition<mDT>
  • Parameters

    • from: string
    • to: string

    Returns JssmTransition<mDT>

  • machine_author(): string[]
  • machine_comment(): string
  • machine_contributor(): string[]
  • machine_definition(): string
  • machine_language(): string
  • machine_license(): string
  • machine_name(): string
  • machine_state(): JssmMachineInternalState<mDT>
  • Returns JssmMachineInternalState<mDT>

  • machine_version(): string
  • probabilistic_histo_walk(n: number): Map<string, number>
  • Parameters

    • n: number

    Returns Map<string, number>

  • probabilistic_transition(): boolean
  • probabilistic_walk(n: number): string[]
  • Parameters

    • n: number

    Returns string[]

  • probable_action_exits(whichState?: string): any[]
  • Parameters

    • whichState: string = ...

    Returns any[]

  • probable_exits_for(whichState: string): JssmTransition<mDT>[]
  • Parameters

    • whichState: string

    Returns JssmTransition<mDT>[]

  • raw_state_declarations(): Object[]
  • set_hook(HookDesc: HookDescription): void
  • Parameters

    • HookDesc: HookDescription

    Returns void

  • sm(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • state(): string
  • state_declaration(which: string): JssmStateDeclaration
  • Parameters

    • which: string

    Returns JssmStateDeclaration

  • state_declarations(): Map<string, JssmStateDeclaration>
  • Returns Map<string, JssmStateDeclaration>

  • state_for(whichState: string): JssmGenericState
  • Parameters

    • whichState: string

    Returns JssmGenericState

  • state_is_complete(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_final(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_terminal(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • states(): string[]
  • theme(): FslTheme
  • transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • transition_impl(newStateOrAction: string, newData: mDT, wasForced: boolean, wasAction: boolean): boolean
  • Parameters

    • newStateOrAction: string
    • newData: mDT
    • wasForced: boolean
    • wasAction: boolean

    Returns boolean

  • valid_action(action: string, _newData?: mDT): boolean
  • Parameters

    • action: string
    • Optional _newData: mDT

    Returns boolean

  • valid_force_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

  • valid_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/docs/modules.html b/docs/docs/modules.html index 903a32e1..ac3096af 100644 --- a/docs/docs/modules.html +++ b/docs/docs/modules.html @@ -1 +1 @@ -jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

jssm

Index

Variables

histograph: Function = ...
seq: Function = ...
version: string = "5.62.0"
weighted_histo_key: Function = ...
weighted_rand_select: Function = ...
weighted_sample_select: Function = ...

Functions

  • arrow_direction(arrow: JssmArrow): JssmArrowDirection
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowDirection

  • arrow_left_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • arrow_right_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • compile<mDT>(tree: JssmParseTree): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • tree: JssmParseTree

    Returns JssmGenericConfig<mDT>

  • from<mDT>(MachineAsString: string, ExtraConstructorFields?: Partial<JssmGenericConfig<mDT>>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • MachineAsString: string
    • Optional ExtraConstructorFields: Partial<JssmGenericConfig<mDT>>

    Returns Machine<mDT>

  • make<mDT>(plan: string): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • plan: string

    Returns JssmGenericConfig<mDT>

  • parse(input: string, options?: Object): any
  • Parameters

    • input: string
    • Optional options: Object

    Returns any

  • sm<mDT>(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • transfer_state_properties(state_decl: JssmStateDeclaration): JssmStateDeclaration
  • Parameters

    • state_decl: JssmStateDeclaration

    Returns JssmStateDeclaration

Generated using TypeDoc

\ No newline at end of file +jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

jssm

Index

Variables

histograph: Function = ...
seq: Function = ...
version: string = "5.63.0"
weighted_histo_key: Function = ...
weighted_rand_select: Function = ...
weighted_sample_select: Function = ...

Functions

  • arrow_direction(arrow: JssmArrow): JssmArrowDirection
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowDirection

  • arrow_left_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • arrow_right_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • compile<mDT>(tree: JssmParseTree): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • tree: JssmParseTree

    Returns JssmGenericConfig<mDT>

  • from<mDT>(MachineAsString: string, ExtraConstructorFields?: Partial<JssmGenericConfig<mDT>>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • MachineAsString: string
    • Optional ExtraConstructorFields: Partial<JssmGenericConfig<mDT>>

    Returns Machine<mDT>

  • make<mDT>(plan: string): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • plan: string

    Returns JssmGenericConfig<mDT>

  • parse(input: string, options?: Object): any
  • Parameters

    • input: string
    • Optional options: Object

    Returns any

  • sm<mDT>(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • transfer_state_properties(state_decl: JssmStateDeclaration): JssmStateDeclaration
  • Parameters

    • state_decl: JssmStateDeclaration

    Returns JssmStateDeclaration

Generated using TypeDoc

\ No newline at end of file diff --git a/jssm_error.d.ts b/jssm_error.d.ts new file mode 100644 index 00000000..810dd8dd --- /dev/null +++ b/jssm_error.d.ts @@ -0,0 +1,4 @@ +declare class JssmError extends Error { + constructor(machine: any, message: string); +} +export { JssmError }; diff --git a/package.json b/package.json index b247db1c..fe9e5980 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jssm", - "version": "5.62.0", + "version": "5.63.0", "engines": { "node": ">=10.0.0" }, diff --git a/src/ts/jssm.ts b/src/ts/jssm.ts index a72efc7a..906d7f04 100644 --- a/src/ts/jssm.ts +++ b/src/ts/jssm.ts @@ -37,16 +37,43 @@ import { -import { parse } from './jssm-dot'; // TODO FIXME WHARGARBL this could be post-typed +import { parse } from './jssm-dot'; +import { version } from './version'; // replaced from package.js in build -import { version } from './version'; // replaced from package.js in build + + + + +class JssmError extends Error { + + constructor(machine: Machine, message: string) { + + super(message); + this.name = 'JssmError'; + + } + +}; function xthrow(machine: Machine, message): never { - throw new Error(`${(machine.instance_name !== undefined)? `[[${machine.instance_name}]]: ` : ''}${message}${machine.state !== undefined? ` (at ${machine.state})` : ''}`); + + throw new JssmError( this, + `${ + (machine.instance_name !== undefined) + ? `[[${machine.instance_name}]]: ` + : '' + }${ + message + }${ + machine.state !== undefined + ? ` (at ${machine.state})` + : '' + }`); + } diff --git a/src/ts/jssm_error.ts b/src/ts/jssm_error.ts new file mode 100644 index 00000000..4f738e3c --- /dev/null +++ b/src/ts/jssm_error.ts @@ -0,0 +1,17 @@ + +class JssmError extends Error { + + constructor(machine: any, message: string) { + + super(message); + this.name = 'JssmError'; + + } + +}; + + + + + +export { JssmError }; diff --git a/src/ts/version.ts b/src/ts/version.ts index e74a82fd..588a8394 100644 --- a/src/ts/version.ts +++ b/src/ts/version.ts @@ -1,3 +1,3 @@ -const version: string = "5.62.0"; +const version: string = "5.63.0"; export { version }; From 53e95660d5dd587109acd91c7875192dd443ff57 Mon Sep 17 00:00:00 2001 From: John Haugeland Date: Sun, 15 May 2022 22:31:17 -0700 Subject: [PATCH 2/2] JssmError extension, fixes StoneCypher/fsl#755; instance name on error object, fixes StoneCypher/fsl#746; state at error time, fixes StoneCypher/fsl#742; target state at error time, fixes StoneCypher/fsl#743base message, fixes StoneCypher/fsl#741; materialized error, fixes StoneCypher/fsl#740 --- benchmark/results/general.chart.html | 14 +- benchmark/results/general.json | 136 ++++++++--------- dist/es6/jssm.js | 79 +++++----- dist/es6/jssm_error.d.ts | 6 +- dist/es6/jssm_error.js | 24 ++- dist/es6/jssm_types.d.ts | 5 +- dist/jssm.es5.cjs.js | 2 +- dist/jssm.es5.cjs.nonmin.js | 98 +++++++------ dist/jssm.es5.iife.js | 2 +- dist/jssm.es5.iife.nonmin.js | 98 +++++++------ docs/docs/classes/Machine.html | 2 +- docs/docs/modules.html | 2 +- jssm_error.d.ts | 6 +- jssm_types.d.ts | 5 +- src/ts/jssm.ts | 211 +++++++++++---------------- src/ts/jssm_error.ts | 44 +++++- src/ts/jssm_types.ts | 10 ++ src/ts/tests/error.spec.ts | 105 +++++++++++++ 18 files changed, 509 insertions(+), 340 deletions(-) create mode 100644 src/ts/tests/error.spec.ts diff --git a/benchmark/results/general.chart.html b/benchmark/results/general.chart.html index 0a6e9972..a45ff11c 100644 --- a/benchmark/results/general.chart.html +++ b/benchmark/results/general.chart.html @@ -28,7 +28,7 @@
- +
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class Machine<mDT>

Type parameters

  • mDT

Hierarchy

  • Machine

Index

Constructors

Properties

Methods

Constructors

  • new Machine<mDT>(__namedParameters: JssmGenericConfig<mDT>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • __namedParameters: JssmGenericConfig<mDT>

    Returns Machine<mDT>

Properties

_actions: Map<string, Map<string, number>>
_any_action_hook: Function
_any_transition_hook: Function
_arrange_declaration: string[][]
_arrange_end_declaration: string[][]
_arrange_start_declaration: string[][]
_dot_preamble: string
_edge_map: Map<string, Map<string, number>>
_edges: JssmTransition<mDT>[]
_entry_hooks: Map<string, Function>
_exit_hooks: Map<string, Function>
_flow: FslDirection
_forced_transition_hook: Function
_fsl_version?: string
_global_action_hooks: Map<string, Function>
_graph_layout: JssmLayout
_has_basic_hooks: boolean
_has_entry_hooks: boolean
_has_exit_hooks: boolean
_has_global_action_hooks: boolean
_has_hooks: boolean
_has_named_hooks: boolean
_has_transition_hooks: boolean
_hooks: Map<string, Function>
_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: Function
_named_hooks: Map<string, Function>
_named_transitions: Map<string, number>
_raw_state_declaration?: Object[]
_reverse_action_targets: Map<string, Map<string, number>>
_reverse_actions: Map<string, Map<string, number>>
_standard_transition_hook: Function
_state: string
_state_declarations: Map<string, JssmStateDeclaration>
_states: Map<string, JssmGenericState>
_theme: FslTheme

Methods

  • _new_state(state_config: JssmGenericState): string
  • Parameters

    • state_config: JssmGenericState

    Returns string

  • action(actionName: string, newData?: mDT): boolean
  • Parameters

    • actionName: string
    • Optional newData: mDT

    Returns boolean

  • actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • current_action_edge_for(action: string): JssmTransition<mDT>
  • Parameters

    • action: string

    Returns JssmTransition<mDT>

  • current_action_for(action: string): number
  • Parameters

    • action: string

    Returns number

  • dot_preamble(): string
  • edges_between(from: string, to: string): JssmTransition<mDT>[]
  • Parameters

    • from: string
    • to: string

    Returns JssmTransition<mDT>[]

  • flow(): FslDirection
  • force_transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • fsl_version(): string
  • get_transition_by_state_names(from: string, to: string): number
  • Parameters

    • from: string
    • to: string

    Returns number

  • graph_layout(): string
  • has_completes(): boolean
  • has_state(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • has_terminals(): boolean
  • has_unenterables(): boolean
  • hook(from: string, to: string, handler: Function): Machine<mDT>
  • hook_action(from: string, to: string, action: string, handler: Function): Machine<mDT>
  • Parameters

    • from: string
    • to: string
    • action: string
    • handler: Function

    Returns Machine<mDT>

  • hook_any_action(handler: Function): Machine<mDT>
  • hook_any_transition(handler: Function): Machine<mDT>
  • hook_entry(to: string, handler: Function): Machine<mDT>
  • hook_exit(from: string, handler: Function): Machine<mDT>
  • hook_forced_transition(handler: Function): Machine<mDT>
  • hook_global_action(action: string, handler: Function): Machine<mDT>
  • hook_main_transition(handler: Function): Machine<mDT>
  • hook_standard_transition(handler: Function): Machine<mDT>
  • instance_name(): string
  • is_complete(): boolean
  • is_final(): boolean
  • is_terminal(): boolean
  • is_unenterable(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • list_actions(): string[]
  • list_edges(): JssmTransition<mDT>[]
  • list_entrances(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exit_actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exits(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_named_transitions(): Map<string, number>
  • list_states_having_action(whichState: string): string[]
  • Parameters

    • whichState: string

    Returns string[]

  • list_transitions(whichState?: string): JssmTransitionList
  • Parameters

    • whichState: string = ...

    Returns JssmTransitionList

  • lookup_transition_for(from: string, to: string): JssmTransition<mDT>
  • Parameters

    • from: string
    • to: string

    Returns JssmTransition<mDT>

  • machine_author(): string[]
  • machine_comment(): string
  • machine_contributor(): string[]
  • machine_definition(): string
  • machine_language(): string
  • machine_license(): string
  • machine_name(): string
  • machine_state(): JssmMachineInternalState<mDT>
  • Returns JssmMachineInternalState<mDT>

  • machine_version(): string
  • probabilistic_histo_walk(n: number): Map<string, number>
  • Parameters

    • n: number

    Returns Map<string, number>

  • probabilistic_transition(): boolean
  • probabilistic_walk(n: number): string[]
  • Parameters

    • n: number

    Returns string[]

  • probable_action_exits(whichState?: string): any[]
  • Parameters

    • whichState: string = ...

    Returns any[]

  • probable_exits_for(whichState: string): JssmTransition<mDT>[]
  • Parameters

    • whichState: string

    Returns JssmTransition<mDT>[]

  • raw_state_declarations(): Object[]
  • set_hook(HookDesc: HookDescription): void
  • Parameters

    • HookDesc: HookDescription

    Returns void

  • sm(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • state(): string
  • state_declaration(which: string): JssmStateDeclaration
  • Parameters

    • which: string

    Returns JssmStateDeclaration

  • state_declarations(): Map<string, JssmStateDeclaration>
  • Returns Map<string, JssmStateDeclaration>

  • state_for(whichState: string): JssmGenericState
  • Parameters

    • whichState: string

    Returns JssmGenericState

  • state_is_complete(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_final(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_terminal(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • states(): string[]
  • theme(): FslTheme
  • transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • transition_impl(newStateOrAction: string, newData: mDT, wasForced: boolean, wasAction: boolean): boolean
  • Parameters

    • newStateOrAction: string
    • newData: mDT
    • wasForced: boolean
    • wasAction: boolean

    Returns boolean

  • valid_action(action: string, _newData?: mDT): boolean
  • Parameters

    • action: string
    • Optional _newData: mDT

    Returns boolean

  • valid_force_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

  • valid_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

Legend

  • Property
  • Method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file +Machine | jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class Machine<mDT>

Type parameters

  • mDT

Hierarchy

  • Machine

Index

Constructors

Properties

Methods

Constructors

  • new Machine<mDT>(__namedParameters: JssmGenericConfig<mDT>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • __namedParameters: JssmGenericConfig<mDT>

    Returns Machine<mDT>

Properties

_actions: Map<string, Map<string, number>>
_any_action_hook: Function
_any_transition_hook: Function
_arrange_declaration: string[][]
_arrange_end_declaration: string[][]
_arrange_start_declaration: string[][]
_dot_preamble: string
_edge_map: Map<string, Map<string, number>>
_edges: JssmTransition<mDT>[]
_entry_hooks: Map<string, Function>
_exit_hooks: Map<string, Function>
_flow: FslDirection
_forced_transition_hook: Function
_fsl_version?: string
_global_action_hooks: Map<string, Function>
_graph_layout: JssmLayout
_has_basic_hooks: boolean
_has_entry_hooks: boolean
_has_exit_hooks: boolean
_has_global_action_hooks: boolean
_has_hooks: boolean
_has_named_hooks: boolean
_has_transition_hooks: boolean
_hooks: Map<string, Function>
_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: Function
_named_hooks: Map<string, Function>
_named_transitions: Map<string, number>
_raw_state_declaration?: Object[]
_reverse_action_targets: Map<string, Map<string, number>>
_reverse_actions: Map<string, Map<string, number>>
_standard_transition_hook: Function
_state: string
_state_declarations: Map<string, JssmStateDeclaration>
_states: Map<string, JssmGenericState>
_theme: FslTheme

Methods

  • _new_state(state_config: JssmGenericState): string
  • Parameters

    • state_config: JssmGenericState

    Returns string

  • action(actionName: string, newData?: mDT): boolean
  • Parameters

    • actionName: string
    • Optional newData: mDT

    Returns boolean

  • actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • current_action_edge_for(action: string): JssmTransition<mDT>
  • Parameters

    • action: string

    Returns JssmTransition<mDT>

  • current_action_for(action: string): number
  • Parameters

    • action: string

    Returns number

  • dot_preamble(): string
  • edges_between(from: string, to: string): JssmTransition<mDT>[]
  • Parameters

    • from: string
    • to: string

    Returns JssmTransition<mDT>[]

  • flow(): FslDirection
  • force_transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • fsl_version(): string
  • get_transition_by_state_names(from: string, to: string): number
  • Parameters

    • from: string
    • to: string

    Returns number

  • graph_layout(): string
  • has_completes(): boolean
  • has_state(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • has_terminals(): boolean
  • has_unenterables(): boolean
  • hook(from: string, to: string, handler: Function): Machine<mDT>
  • hook_action(from: string, to: string, action: string, handler: Function): Machine<mDT>
  • Parameters

    • from: string
    • to: string
    • action: string
    • handler: Function

    Returns Machine<mDT>

  • hook_any_action(handler: Function): Machine<mDT>
  • hook_any_transition(handler: Function): Machine<mDT>
  • hook_entry(to: string, handler: Function): Machine<mDT>
  • hook_exit(from: string, handler: Function): Machine<mDT>
  • hook_forced_transition(handler: Function): Machine<mDT>
  • hook_global_action(action: string, handler: Function): Machine<mDT>
  • hook_main_transition(handler: Function): Machine<mDT>
  • hook_standard_transition(handler: Function): Machine<mDT>
  • instance_name(): string
  • is_complete(): boolean
  • is_final(): boolean
  • is_terminal(): boolean
  • is_unenterable(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • list_actions(): string[]
  • list_edges(): JssmTransition<mDT>[]
  • list_entrances(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exit_actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exits(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_named_transitions(): Map<string, number>
  • list_states_having_action(whichState: string): string[]
  • Parameters

    • whichState: string

    Returns string[]

  • list_transitions(whichState?: string): JssmTransitionList
  • Parameters

    • whichState: string = ...

    Returns JssmTransitionList

  • lookup_transition_for(from: string, to: string): JssmTransition<mDT>
  • Parameters

    • from: string
    • to: string

    Returns JssmTransition<mDT>

  • machine_author(): string[]
  • machine_comment(): string
  • machine_contributor(): string[]
  • machine_definition(): string
  • machine_language(): string
  • machine_license(): string
  • machine_name(): string
  • machine_state(): JssmMachineInternalState<mDT>
  • Returns JssmMachineInternalState<mDT>

  • machine_version(): string
  • probabilistic_histo_walk(n: number): Map<string, number>
  • Parameters

    • n: number

    Returns Map<string, number>

  • probabilistic_transition(): boolean
  • probabilistic_walk(n: number): string[]
  • Parameters

    • n: number

    Returns string[]

  • probable_action_exits(whichState?: string): any[]
  • Parameters

    • whichState: string = ...

    Returns any[]

  • probable_exits_for(whichState: string): JssmTransition<mDT>[]
  • Parameters

    • whichState: string

    Returns JssmTransition<mDT>[]

  • raw_state_declarations(): Object[]
  • set_hook(HookDesc: HookDescription): void
  • Parameters

    • HookDesc: HookDescription

    Returns void

  • sm(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • state(): string
  • state_declaration(which: string): JssmStateDeclaration
  • Parameters

    • which: string

    Returns JssmStateDeclaration

  • state_declarations(): Map<string, JssmStateDeclaration>
  • Returns Map<string, JssmStateDeclaration>

  • state_for(whichState: string): JssmGenericState
  • Parameters

    • whichState: string

    Returns JssmGenericState

  • state_is_complete(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_final(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_terminal(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • states(): string[]
  • theme(): FslTheme
  • transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • transition_impl(newStateOrAction: string, newData: mDT, wasForced: boolean, wasAction: boolean): boolean
  • Parameters

    • newStateOrAction: string
    • newData: mDT
    • wasForced: boolean
    • wasAction: boolean

    Returns boolean

  • valid_action(action: string, _newData?: mDT): boolean
  • Parameters

    • action: string
    • Optional _newData: mDT

    Returns boolean

  • valid_force_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

  • valid_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

Legend

  • Property
  • Method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/docs/modules.html b/docs/docs/modules.html index ac3096af..2ce19dbb 100644 --- a/docs/docs/modules.html +++ b/docs/docs/modules.html @@ -1 +1 @@ -jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

jssm

Index

Variables

histograph: Function = ...
seq: Function = ...
version: string = "5.63.0"
weighted_histo_key: Function = ...
weighted_rand_select: Function = ...
weighted_sample_select: Function = ...

Functions

  • arrow_direction(arrow: JssmArrow): JssmArrowDirection
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowDirection

  • arrow_left_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • arrow_right_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • compile<mDT>(tree: JssmParseTree): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • tree: JssmParseTree

    Returns JssmGenericConfig<mDT>

  • from<mDT>(MachineAsString: string, ExtraConstructorFields?: Partial<JssmGenericConfig<mDT>>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • MachineAsString: string
    • Optional ExtraConstructorFields: Partial<JssmGenericConfig<mDT>>

    Returns Machine<mDT>

  • make<mDT>(plan: string): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • plan: string

    Returns JssmGenericConfig<mDT>

  • parse(input: string, options?: Object): any
  • Parameters

    • input: string
    • Optional options: Object

    Returns any

  • sm<mDT>(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • transfer_state_properties(state_decl: JssmStateDeclaration): JssmStateDeclaration
  • Parameters

    • state_decl: JssmStateDeclaration

    Returns JssmStateDeclaration

Legend

  • Property
  • Method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file +jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

jssm

Index

Variables

histograph: Function = ...
seq: Function = ...
version: string = "5.63.0"
weighted_histo_key: Function = ...
weighted_rand_select: Function = ...
weighted_sample_select: Function = ...

Functions

  • arrow_direction(arrow: JssmArrow): JssmArrowDirection
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowDirection

  • arrow_left_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • arrow_right_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • compile<mDT>(tree: JssmParseTree): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • tree: JssmParseTree

    Returns JssmGenericConfig<mDT>

  • from<mDT>(MachineAsString: string, ExtraConstructorFields?: Partial<JssmGenericConfig<mDT>>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • MachineAsString: string
    • Optional ExtraConstructorFields: Partial<JssmGenericConfig<mDT>>

    Returns Machine<mDT>

  • make<mDT>(plan: string): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • plan: string

    Returns JssmGenericConfig<mDT>

  • parse(input: string, options?: Object): any
  • Parameters

    • input: string
    • Optional options: Object

    Returns any

  • sm<mDT>(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • transfer_state_properties(state_decl: JssmStateDeclaration): JssmStateDeclaration
  • Parameters

    • state_decl: JssmStateDeclaration

    Returns JssmStateDeclaration

Legend

  • Property
  • Method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/jssm_error.d.ts b/jssm_error.d.ts index 810dd8dd..1232f995 100644 --- a/jssm_error.d.ts +++ b/jssm_error.d.ts @@ -1,4 +1,8 @@ +import { JssmErrorExtendedInfo } from './jssm_types'; declare class JssmError extends Error { - constructor(machine: any, message: string); + message: string; + base_message: string; + requested_state: string | undefined; + constructor(machine: any, message: string, JEEI?: JssmErrorExtendedInfo); } export { JssmError }; diff --git a/jssm_types.d.ts b/jssm_types.d.ts index 65d34962..39d569ef 100644 --- a/jssm_types.d.ts +++ b/jssm_types.d.ts @@ -199,4 +199,7 @@ declare type ExitHook = { handler: HookHandler; }; declare type HookDescription = BasicHookDescription | HookDescriptionWithAction | GlobalActionHook | AnyActionHook | StandardTransitionHook | MainTransitionHook | ForcedTransitionHook | AnyTransitionHook | EntryHook | ExitHook; -export { JssmColor, JssmTransition, JssmTransitions, JssmTransitionList, JssmTransitionRule, JssmArrow, JssmArrowKind, JssmArrowDirection, JssmGenericConfig, JssmGenericState, JssmGenericMachine, JssmParseTree, JssmCompileSe, JssmCompileSeStart, JssmCompileRule, JssmPermitted, JssmPermittedOpt, JssmResult, JssmStateDeclaration, JssmStateDeclarationRule, JssmLayout, JssmParseFunctionType, JssmMachineInternalState, FslDirection, FslTheme, HookDescription, HookHandler }; +declare type JssmErrorExtendedInfo = { + requested_state?: StateType | undefined; +}; +export { JssmColor, JssmTransition, JssmTransitions, JssmTransitionList, JssmTransitionRule, JssmArrow, JssmArrowKind, JssmArrowDirection, JssmGenericConfig, JssmGenericState, JssmGenericMachine, JssmParseTree, JssmCompileSe, JssmCompileSeStart, JssmCompileRule, JssmPermitted, JssmPermittedOpt, JssmResult, JssmStateDeclaration, JssmStateDeclarationRule, JssmLayout, JssmParseFunctionType, JssmMachineInternalState, JssmErrorExtendedInfo, FslDirection, FslTheme, HookDescription, HookHandler }; diff --git a/src/ts/jssm.ts b/src/ts/jssm.ts index 906d7f04..b585ea55 100644 --- a/src/ts/jssm.ts +++ b/src/ts/jssm.ts @@ -37,44 +37,9 @@ import { -import { parse } from './jssm-dot'; -import { version } from './version'; // replaced from package.js in build - - - - - -class JssmError extends Error { - - constructor(machine: Machine, message: string) { - - super(message); - this.name = 'JssmError'; - - } - -}; - - - - - -function xthrow(machine: Machine, message): never { - - throw new JssmError( this, - `${ - (machine.instance_name !== undefined) - ? `[[${machine.instance_name}]]: ` - : '' - }${ - message - }${ - machine.state !== undefined - ? ` (at ${machine.state})` - : '' - }`); - -} +import { parse } from './jssm-dot'; +import { version } from './version'; // replaced from package.js in build +import { JssmError } from './jssm_error'; @@ -110,7 +75,7 @@ function arrow_direction(arrow: JssmArrow): JssmArrowDirection { return 'both'; default: - xthrow(this, `arrow_direction: unknown arrow type ${arrow}`); + throw new JssmError(undefined, `arrow_direction: unknown arrow type ${arrow}`); } @@ -152,7 +117,7 @@ function arrow_left_kind(arrow: JssmArrow): JssmArrowKind { return 'forced'; default: - xthrow(this, `arrow_direction: unknown arrow type ${arrow}`); + throw new JssmError(undefined, `arrow_direction: unknown arrow type ${arrow}`); } @@ -194,7 +159,7 @@ function arrow_right_kind(arrow: JssmArrow): JssmArrowKind { return 'forced'; default: - xthrow(this, `arrow_direction: unknown arrow type ${arrow}`); + throw new JssmError(undefined, `arrow_direction: unknown arrow type ${arrow}`); } @@ -226,13 +191,13 @@ function makeTransition( main_path: kind === 'main' }; - // if ((wasList !== undefined) && (wasIndex === undefined)) { xthrow(this, `Must have an index if transition was in a list"); } - // if ((wasIndex !== undefined) && (wasList === undefined)) { xthrow(this, `Must be in a list if transition has an index"); } + // if ((wasList !== undefined) && (wasIndex === undefined)) { throw new JssmError(undefined, `Must have an index if transition was in a list"); } + // if ((wasIndex !== undefined) && (wasList === undefined)) { throw new JssmError(undefined, `Must be in a list if transition has an index"); } /* if (typeof edge.to === 'object') { if (edge.to.key === 'cycle') { - if (wasList === undefined) { xthrow(this, "Must have a waslist if a to is type cycle"); } + if (wasList === undefined) { throw new JssmError(undefined, "Must have a waslist if a to is type cycle"); } const nextIndex = wrapBy(wasIndex, edge.to.value, wasList.length); edge.to = wasList[nextIndex]; } @@ -317,7 +282,7 @@ function compile_rule_handler(rule: JssmCompileSeStart): JssmCompileR } if (rule.key === 'state_declaration') { - if (!rule.name) { xthrow(this, 'State declarations must have a name'); } + if (!rule.name) { throw new JssmError(undefined, 'State declarations must have a name'); } return { agg_as: 'state_declaration', val: { state: rule.name, declarations: rule.value } }; } @@ -337,7 +302,7 @@ function compile_rule_handler(rule: JssmCompileSeStart): JssmCompileR return { agg_as: rule.key, val: rule.value }; } - xthrow(this, `compile_rule_handler: Unknown rule: ${JSON.stringify(rule)}`); + throw new JssmError(undefined, `compile_rule_handler: Unknown rule: ${JSON.stringify(rule)}`); } @@ -420,7 +385,7 @@ function compile(tree: JssmParseTree): JssmGenericConfig { oneOnlyKeys.map((oneOnlyKey: string) => { if (results[oneOnlyKey].length > 1) { - xthrow(this, + throw new JssmError(undefined, `May only have one ${oneOnlyKey} statement maximum: ${JSON.stringify(results[oneOnlyKey])}` ); } else { @@ -470,7 +435,7 @@ function transfer_state_properties(state_decl: JssmStateDeclaration): JssmStateD case 'background-color' : state_decl.backgroundColor = d.value; break; case 'border-color' : state_decl.borderColor = d.value; break; - default: xthrow(this, `Unknown state property: '${JSON.stringify(d)}'`); + default: throw new JssmError(undefined, `Unknown state property: '${JSON.stringify(d)}'`); } @@ -487,26 +452,26 @@ function transfer_state_properties(state_decl: JssmStateDeclaration): JssmStateD class Machine { - _state: StateType; - _states: Map; - _edges: Array>; - _edge_map: Map>; - _named_transitions: Map; - _actions: Map>; - _reverse_actions: Map>; - _reverse_action_targets: Map>; - - _machine_author?: Array; - _machine_comment?: string; - _machine_contributor?: Array; - _machine_definition?: string; - _machine_language?: string; - _machine_license?: string; - _machine_name?: string; - _machine_version?: string; - _fsl_version?: string; - _raw_state_declaration?: Array; - _state_declarations: Map; + _state : StateType; + _states : Map; + _edges : Array>; + _edge_map : Map>; + _named_transitions : Map; + _actions : Map>; + _reverse_actions : Map>; + _reverse_action_targets : Map>; + + _machine_author? : Array; + _machine_comment? : string; + _machine_contributor? : Array; + _machine_definition? : string; + _machine_language? : string; + _machine_license? : string; + _machine_name? : string; + _machine_version? : string; + _fsl_version? : string; + _raw_state_declaration? : Array; + _state_declarations : Map; _instance_name : string; @@ -556,38 +521,38 @@ class Machine { machine_version, state_declaration, fsl_version, - dot_preamble = undefined, - arrange_declaration = [], + dot_preamble = undefined, + arrange_declaration = [], arrange_start_declaration = [], - arrange_end_declaration = [], - theme = 'default', - flow = 'down', - graph_layout = 'dot', + arrange_end_declaration = [], + theme = 'default', + flow = 'down', + graph_layout = 'dot', instance_name }: JssmGenericConfig) { this._instance_name = instance_name; - this._state = start_states[0]; - this._states = new Map(); - this._state_declarations = new Map(); - this._edges = []; - this._edge_map = new Map(); - this._named_transitions = new Map(); - this._actions = new Map(); - this._reverse_actions = new Map(); + this._state = start_states[0]; + this._states = new Map(); + this._state_declarations = new Map(); + this._edges = []; + this._edge_map = new Map(); + this._named_transitions = new Map(); + this._actions = new Map(); + this._reverse_actions = new Map(); this._reverse_action_targets = new Map(); // todo - this._machine_author = array_box_if_string(machine_author); - this._machine_comment = machine_comment; - this._machine_contributor = array_box_if_string(machine_contributor); - this._machine_definition = machine_definition; - this._machine_language = machine_language; - this._machine_license = machine_license; - this._machine_name = machine_name; - this._machine_version = machine_version; + this._machine_author = array_box_if_string(machine_author); + this._machine_comment = machine_comment; + this._machine_contributor = array_box_if_string(machine_contributor); + this._machine_definition = machine_definition; + this._machine_language = machine_language; + this._machine_license = machine_license; + this._machine_name = machine_name; + this._machine_version = machine_version; this._raw_state_declaration = state_declaration || []; - this._fsl_version = fsl_version; + this._fsl_version = fsl_version; this._arrange_declaration = arrange_declaration; this._arrange_start_declaration = arrange_start_declaration; @@ -624,7 +589,7 @@ class Machine { state_declaration.map((state_decl: JssmStateDeclaration) => { if (this._state_declarations.has(state_decl.state)) { // no repeats - xthrow(this, `Added the same state declaration twice: ${JSON.stringify(state_decl.state)}`); + throw new JssmError(this, `Added the same state declaration twice: ${JSON.stringify(state_decl.state)}`); } this._state_declarations.set(state_decl.state, transfer_state_properties(state_decl)); @@ -635,8 +600,8 @@ class Machine { transitions.map((tr: JssmTransition) => { - if (tr.from === undefined) { xthrow(this, `transition must define 'from': ${JSON.stringify(tr)}`); } - if (tr.to === undefined) { xthrow(this, `transition must define 'to': ${JSON.stringify(tr)}`); } + if ( tr.from === undefined ) { throw new JssmError(this, `transition must define 'from': ${JSON.stringify(tr)}`); } + if ( tr.to === undefined ) { throw new JssmError(this, `transition must define 'to': ${JSON.stringify(tr)}`); } // get the cursors. what a mess const cursor_from: JssmGenericState @@ -657,7 +622,7 @@ class Machine { // guard against existing connections being re-added if (cursor_from.to.includes(tr.to)) { - xthrow(this, `already has ${JSON.stringify(tr.from)} to ${JSON.stringify(tr.to)}`); + throw new JssmError(this, `already has ${JSON.stringify(tr.from)} to ${JSON.stringify(tr.to)}`); } else { cursor_from.to.push(tr.to); cursor_to.from.push(tr.from); @@ -670,7 +635,7 @@ class Machine { // guard against repeating a transition name if (tr.name) { if (this._named_transitions.has(tr.name)) { - xthrow(this, `named transition "${JSON.stringify(tr.name)}" already created`); + throw new JssmError(this, `named transition "${JSON.stringify(tr.name)}" already created`); } else { this._named_transitions.set(tr.name, thisEdgeId); } @@ -697,7 +662,7 @@ class Machine { } if (actionMap.has(tr.from)) { - xthrow(this, `action ${JSON.stringify(tr.action)} already attached to origin ${JSON.stringify(tr.from)}`); + throw new JssmError(this, `action ${JSON.stringify(tr.action)} already attached to origin ${JSON.stringify(tr.from)}`); } else { actionMap.set(tr.from, thisEdgeId); } @@ -725,12 +690,12 @@ class Machine { const roActionMap = this._reverse_action_targets.get(tr.to); // wasteful - already did has - refactor if (roActionMap) { if (roActionMap.has(tr.action)) { - xthrow(this, `ro-action ${tr.to} already attached to action ${tr.action}`); + throw new JssmError(this, `ro-action ${tr.to} already attached to action ${tr.action}`); } else { roActionMap.set(tr.action, thisEdgeId); } } else { - xthrow(this, `should be impossible - flow doesn\'t know .set precedes .get yet again. severe error?'); + throw new JssmError(this, `should be impossible - flow doesn\'t know .set precedes .get yet again. severe error?'); } */ } @@ -742,7 +707,7 @@ class Machine { _new_state(state_config: JssmGenericState): StateType { if (this._states.has(state_config.name)) { - xthrow(this, `state ${JSON.stringify(state_config.name)} already exists`); + throw new JssmError(this, `state ${JSON.stringify(state_config.name)} already exists`); } this._states.set(state_config.name, state_config); @@ -837,16 +802,18 @@ class Machine { machine_state(): JssmMachineInternalState { return { - internal_state_impl_version: 1, - - actions: this._actions, - edge_map: this._edge_map, - edges: this._edges, - named_transitions: this._named_transitions, - reverse_actions: this._reverse_actions, - // reverse_action_targets : this._reverse_action_targets, - state: this._state, - states: this._states + + internal_state_impl_version : 1, + + actions : this._actions, + edge_map : this._edge_map, + edges : this._edges, + named_transitions : this._named_transitions, + reverse_actions : this._reverse_actions, + // reverse_action_targets : this._reverse_action_targets, + state : this._state, + states : this._states + }; } @@ -865,7 +832,7 @@ class Machine { state_for(whichState: StateType): JssmGenericState { const state: JssmGenericState = this._states.get(whichState); if (state) { return state; } - else { xthrow(this, `no such state ${JSON.stringify(state)}`); } + else { throw new JssmError(this, 'No such state', { requested_state: whichState }); } } has_state(whichState: StateType): boolean { @@ -940,7 +907,7 @@ class Machine { probable_exits_for(whichState: StateType): Array> { const wstate: JssmGenericState = this._states.get(whichState); - if (!(wstate)) { xthrow(this, `No such state ${JSON.stringify(whichState)} in probable_exits_for`); } + if (!(wstate)) { throw new JssmError(this, `No such state ${JSON.stringify(whichState)} in probable_exits_for`); } const wstate_to: Array = wstate.to, @@ -977,13 +944,13 @@ class Machine { actions(whichState: StateType = this.state()): Array { const wstate: Map = this._reverse_actions.get(whichState); if (wstate) { return Array.from(wstate.keys()); } - else { xthrow(this, `No such state ${JSON.stringify(whichState)}`); } + else { throw new JssmError(this, `No such state ${JSON.stringify(whichState)}`); } } list_states_having_action(whichState: StateType): Array { const wstate: Map = this._actions.get(whichState); if (wstate) { return Array.from(wstate.keys()); } - else { xthrow(this, `No such state ${JSON.stringify(whichState)}`); } + else { throw new JssmError(this, `No such state ${JSON.stringify(whichState)}`); } } // comeback @@ -997,7 +964,7 @@ class Machine { */ list_exit_actions(whichState: StateType = this.state()): Array { // these are mNT, not ?mNT const ra_base: Map = this._reverse_actions.get(whichState); - if (!(ra_base)) { xthrow(this, `No such state ${JSON.stringify(whichState)}`); } + if (!(ra_base)) { throw new JssmError(this, `No such state ${JSON.stringify(whichState)}`); } return Array.from(ra_base.values()) .map((edgeId: number): JssmTransition => this._edges[edgeId]) @@ -1007,7 +974,7 @@ class Machine { probable_action_exits(whichState: StateType = this.state()): Array { // these are mNT // TODO FIXME no any const ra_base: Map = this._reverse_actions.get(whichState); - if (!(ra_base)) { xthrow(this, `No such state ${JSON.stringify(whichState)}`); } + if (!(ra_base)) { throw new JssmError(this, `No such state ${JSON.stringify(whichState)}`); } return Array.from(ra_base.values()) .map((edgeId: number): JssmTransition => this._edges[edgeId]) @@ -1023,7 +990,7 @@ class Machine { // TODO FIXME test that is_unenterable on non-state throws is_unenterable(whichState: StateType): boolean { - if (!(this.has_state(whichState))) { xthrow(this, `No such state ${whichState}`); } + if (!(this.has_state(whichState))) { throw new JssmError(this, `No such state ${whichState}`); } return this.list_entrances(whichState).length === 0; } @@ -1039,7 +1006,7 @@ class Machine { // TODO FIXME test that state_is_terminal on non-state throws state_is_terminal(whichState: StateType): boolean { - if (!(this.has_state(whichState))) { xthrow(this, `No such state ${whichState}`); } + if (!(this.has_state(whichState))) { throw new JssmError(this, `No such state ${whichState}`); } return this.list_exits(whichState).length === 0; } @@ -1056,7 +1023,7 @@ class Machine { state_is_complete(whichState: StateType): boolean { const wstate: JssmGenericState = this._states.get(whichState); if (wstate) { return wstate.complete; } - else { xthrow(this, `No such state ${JSON.stringify(whichState)}`); } + else { throw new JssmError(this, `No such state ${JSON.stringify(whichState)}`); } } has_completes(): boolean { @@ -1130,7 +1097,7 @@ class Machine { break; default: - xthrow(this, `Unknown hook type ${(HookDesc as any).kind}, should be impossible`); + throw new JssmError(this, `Unknown hook type ${(HookDesc as any).kind}, should be impossible`); } } @@ -1238,7 +1205,7 @@ class Machine { // remove_hook(HookDesc: HookDescription) { - // xthrow(this, 'TODO: Should remove hook here'); + // throw new JssmError(this, 'TODO: Should remove hook here'); // } @@ -1444,7 +1411,7 @@ class Machine { current_action_edge_for(action: StateType): JssmTransition { const idx: number = this.current_action_for(action); - if ((idx === undefined) || (idx === null)) { xthrow(this, `No such action ${JSON.stringify(action)}`); } + if ((idx === undefined) || (idx === null)) { throw new JssmError(this, `No such action ${JSON.stringify(action)}`); } return this._edges[idx]; } diff --git a/src/ts/jssm_error.ts b/src/ts/jssm_error.ts index 4f738e3c..81c1a017 100644 --- a/src/ts/jssm_error.ts +++ b/src/ts/jssm_error.ts @@ -1,10 +1,48 @@ +import { JssmErrorExtendedInfo } from './jssm_types'; + + + + + class JssmError extends Error { - constructor(machine: any, message: string) { + message : string; + base_message : string; + requested_state : string | undefined; + + constructor(machine: any, message: string, JEEI?: JssmErrorExtendedInfo) { + + const { requested_state } = (JEEI === undefined) + ? { requested_state: undefined } + : JEEI; + + const follow_ups = []; + + if (machine) { + if (machine.state() !== undefined) { follow_ups.push(`at "${machine.state()}"`); } + } + + if (requested_state !== undefined) { follow_ups.push(`requested "${requested_state}"`); } + + const complex_msg = `${ + (machine?.instance_name() !== undefined) + ? `[[${machine.instance_name()}]]: ` + : '' + }${ + message + }${ + follow_ups.length + ? ` (${follow_ups.join(', ')})` + : '' + }`; + + super(complex_msg); - super(message); - this.name = 'JssmError'; + this.name = 'JssmError'; + this.message = complex_msg; + this.base_message = message; + this.requested_state = requested_state; } diff --git a/src/ts/jssm_types.ts b/src/ts/jssm_types.ts index 1d21550d..bac30535 100644 --- a/src/ts/jssm_types.ts +++ b/src/ts/jssm_types.ts @@ -386,6 +386,14 @@ type HookDescription +type JssmErrorExtendedInfo = { + requested_state? : StateType | undefined +}; + + + + + export { JssmColor, @@ -421,6 +429,8 @@ export { JssmMachineInternalState, + JssmErrorExtendedInfo, + FslDirection, FslTheme, diff --git a/src/ts/tests/error.spec.ts b/src/ts/tests/error.spec.ts new file mode 100644 index 00000000..be3b8c30 --- /dev/null +++ b/src/ts/tests/error.spec.ts @@ -0,0 +1,105 @@ + +import * as jssm from '../jssm'; +import { JssmError } from '../jssm_error'; + +const sm = jssm.sm; + + + + + +describe('Basic hooks on API callpoint', () => { + + + test('Creating an error should throw', () => { + + expect( () => { + const _foo = sm`a -FAIL> b;`; + }) + .toThrow(); + + } ); + + + test('Creating an error from the class makes a JssmError', () => { + + expect( () => { + try { + const _foo = sm`a -FAIL> b;`; + } catch (e) { + expect(e instanceof JssmError).toBe(true); + } + }) + + } ); + + + test('Creating an error from the machine makes a JssmError', () => { + + expect( () => { + try { + const foo = jssm.from('a->b;'); + foo.state_for('c'); + } catch (e) { + expect(e instanceof JssmError).toBe(true); + } + }) + + } ); + + + test('Creating an error directly from the class has the complex message as its emit', () => { + +// TODO + + expect( () => { const _foo = sm`a -FAIL> b;`; } ) + .toThrow( 'Expected \"{\", action label, arrow, nonneg number, or whitespace but \"-\" found.' ) + + } ); + + + test('Creating an error from the machine has the complex message as its emit', () => { + +// TODO + + expect( () => { + const _foo = sm`a -> b;`; + _foo.state_for('c'); + } ) + .toThrow( 'No such state (at "a", requested "c")' ) + + } ); + + + test('Creating an error from the machine has the complex message as its emit', () => { + + expect( () => { + const _foo = jssm.from(`a -> b;`, { instance_name: 'doug' }); + _foo.state_for('c'); + } ) + .toThrow( '[[doug]]: No such state (at "a", requested "c")' ) + + } ); + + + test('Machine errors drop the parenthetical without content', () => { + + expect( () => { jssm.arrow_direction('-a>' as any); } ) + .toThrow( 'arrow_direction: unknown arrow type -a>' ) + + } ); + + + test('Creating an error has undefined for a state when appropriate', () => { + + expect( () => { + try { + const _foo = sm`a -FAIL> b;`; + } catch (e) { + expect(e.state).toBe(undefined) + } + }) + + } ); + +});