From 791328b08dbc0fce25435adef4fdd1d3212ecfbc Mon Sep 17 00:00:00 2001 From: John Haugeland Date: Sun, 7 May 2017 15:25:38 -0700 Subject: [PATCH] Rudimentary demo page in place. Browserify now exporting. Basic API. --- package.json | 4 +- src/demo/index.html | 18 +++++++ src/demo/style.css | 2 + src/js/jssm-tests.js | 13 ++--- src/js/jssm-types.js | 115 ++++++++++++++++++++++++++++++----------- src/js/jssm.js | 119 ++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 227 insertions(+), 44 deletions(-) create mode 100644 src/demo/index.html create mode 100644 src/demo/style.css diff --git a/package.json b/package.json index 4206cfbb..0f7388db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jssm", - "version": "0.5.1", + "version": "0.6.0", "description": "A Javascript state machine with a simple API. Well tested, and typed with Flowtype. MIT License.", "main": "dist/jssm.es5.browserified.js", "scripts": { @@ -9,7 +9,7 @@ "babel": "babel src/js -d build/", "setver": "node ./set_version.js", "rename": "node -e \"require('fs').renameSync('./build/jssm.js', './build/jssm.es5.js');\"", - "pack": "browserify build/jssm.es5.js > build/jssm.es5.amd.js", + "pack": "browserify -r ./build/jssm.es5.js:jssm -o build/jssm.es5.amd.js", "make": "npm run clean && npm run babel && npm run rename && npm run setver && npm run pack", "flow": "flow", "eslint": "eslint src/js/jssm.js", diff --git a/src/demo/index.html b/src/demo/index.html new file mode 100644 index 00000000..de387b82 --- /dev/null +++ b/src/demo/index.html @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/demo/style.css b/src/demo/style.css new file mode 100644 index 00000000..5f53ee6c --- /dev/null +++ b/src/demo/style.css @@ -0,0 +1,2 @@ +html, body { padding: 0; margin: 0; border: 0; font-family: helvetica neue, helvetica, arial, sans-serif; } +body { padding: 2em; } \ No newline at end of file diff --git a/src/js/jssm-tests.js b/src/js/jssm-tests.js index b1701a28..0e567b27 100644 --- a/src/js/jssm-tests.js +++ b/src/js/jssm-tests.js @@ -9,16 +9,8 @@ const jssm = require('../../build/jssm.es5.js'); test('build-set version number is present', t => t.is(typeof jssm.version, 'string')); -// build 200 tests that delay up to 3 sec each. completes in 3 sec because they're all -// being run in parallel - const seq = upTo => new Array(upTo).fill(false).map( (_,i) => i ); -/* -seq(200).map(i => test(`Delay test ${i}`, t => - new Promise( (res, rej) => setTimeout(() => { t.true(); res('res'); }, Math.random() * 3000))) ); -*/ - @@ -27,10 +19,13 @@ function promise_delay(how_long, f) { return new Promise( (resolve, reject) => setTimeout( () => { resolve(f()); }, how_long ) ); } +// todo whargarbl get rid of this nonsense before 1.0 seq(3000).map(i => - test(`Delay test ${i}`, t => promise_delay(Math.random() * 5000, () => { t.is(1,1); return 'res'; })) + test(`Delay test ${i}`, t => promise_delay(Math.random() * 1500, () => { t.is(1,1); return 'res'; })) ); +// p_test('text', 'expected', test()); + diff --git a/src/js/jssm-types.js b/src/js/jssm-types.js index 3bb4b6aa..be6f70e3 100644 --- a/src/js/jssm-types.js +++ b/src/js/jssm-types.js @@ -5,42 +5,85 @@ -type JssmEdgePermitter = (OldState: NT, NewState: NT, OldData: DT, NewData: DT) => boolean; -type JssmEdgePermitterDef = JssmEdgePermitter | Array< JssmEdgePermitter >; - -type JssmEdge = { - from : NT, - to : NT, - name? : string, - valid? : JssmEdgePermitterDef, // validate this edge's transition; usually about data - likelihood? : number, // for stoch modelling - usual? : NT // most common exit, for graphing; likelihood overrides -}; +type JssmSuccess = { success: true }; +type JssmFailure = { success: false, error: mixed }; +type JssmIncomplete = { success: 'incomplete' }; +type JssmResult = JssmSuccess | JssmFailure | JssmIncomplete; + + + + +type ARD = 'allow' | 'require' | 'disallow'; + + + -type JssmEdges = Array< JssmEdge >; +type JssmTransitionPermitter = (OldState: NT, NewState: NT, OldData: DT, NewData: DT) => boolean; +type JssmTransitionPermitterMaybeArray = JssmTransitionPermitter | Array< JssmTransitionPermitter >; -type JssmStatePermitter = (OldState: NT, NewState: NT, OldData: DT, NewData: DT) => boolean; -type JssmStatePermitterDef = JssmStatePermitter | Array< JssmStatePermitter >; + +type JssmStatePermitter = (OldState: NT, NewState: NT, OldData: DT, NewData: DT) => boolean; +type JssmStatePermitterMaybeArray = JssmStatePermitter | Array< JssmStatePermitter >; type JssmGenericMachine = { - name? : string, - state : NT, - data? : DT, - nodes? : Array, - edges : JssmEdges, - valid? : JssmStatePermitterDef, + name? : string, + state : NT, + data? : DT, + nodes? : Array, + transitions : JssmTransitions, + valid? : JssmStatePermitterMaybeArray, + + min_transitions? : number, + max_transitions? : number, + + allow_empty? : boolean, + allow_islands? : boolean, + allow_force? : boolean + +}; + + - min_edges? : number, - max_edges? : number, - allow_empty? : boolean, - allow_islands? : boolean, - allow_force? : boolean + +type JssmTransition = { + from : NT, + to : NT, + name? : string, + action? : string, + valid? : JssmTransitionPermitterMaybeArray, // validate this edge's transition; usually about data + likelihood? : number, // for stoch modelling, would like to constrain to [0..1], dunno how + usual? : '' // most common exit, for graphing; likelihood overrides +}; + +type JssmTransitions = Array< JssmTransition >; + + + + + +type JssmGenericConfig = { + + initial_state : NT, + + transitions : JssmTransitions, + + name? : string, + data? : mixed, + nodes? : Array, // uncommon + valid? : JssmStatePermitterMaybeArray, + +//locked? : bool = true, + min_exits? : number, + max_exits? : number, + allow_islands? : false, + allow_force? : false, + actions? : ARD }; @@ -49,6 +92,7 @@ type JssmGenericMachine = { type JssmMachine = JssmGenericMachine; +type JssmConfig = JssmGenericConfig; @@ -56,17 +100,26 @@ type JssmMachine = JssmGenericMachine; export type { - JssmEdgePermitter, - JssmEdgePermitterDef, + JssmResult, + JssmSuccess, + JssmFailure, + JssmIncomplete, + + ARD, - JssmEdge, - JssmEdges, + JssmTransitionPermitter, + JssmTransitionPermitterMaybeArray, + + JssmTransition, + JssmTransitions, JssmStatePermitter, - JssmStatePermitterDef, + JssmStatePermitterMaybeArray, JssmGenericMachine, - JssmMachine + JssmMachine, + + JssmConfig }; diff --git a/src/js/jssm.js b/src/js/jssm.js index 1c4789b7..56f1b7b9 100644 --- a/src/js/jssm.js +++ b/src/js/jssm.js @@ -1,7 +1,7 @@ // @flow -import type { JssmMachine } from './jssm-types'; +import type { JssmMachine, JssmConfig, JssmTransitions } from './jssm-types'; const version = null; // replaced from package.js in build @@ -10,13 +10,128 @@ const version = null; // replaced from package.js in build const new_machine = (props:mixed) : JssmMachine => { - return {state:'1', edges: []}; // whargarbl this should not work + return {state:'1', transitions: []}; // whargarbl this should not work }; +class jssm { + + + constructor({ transitions } : JssmConfig) { + + transitions.map(tr => { + console.log(`hook up ${JSON.stringify(tr)}`); + }); + + } + + + + state() : string { + return ''; // todo whargarbl + } + + machine_state() : mixed { + return {}; // todo whargarbl + } + + + nodes() : Array { // todo whargarbl + return []; // todo whargarbl + } + + transitions() : Array { // todo whargarbl + return []; // todo whargarbl + } + + named_transitions() : Array { // todo whargarbl + return []; // todo whargarbl + } + + actions() : Array { // todo whargarbl + return []; // todo whargarbl + } + + + transitions_for(whichNode : string) : Array { // todo whargarbl + return []; // todo whargarbl + } + + entrances_for(whichNode : string) : Array { // todo whargarbl + return []; // todo whargarbl + } + + exits_for(whichNode : string) : Array { // todo whargarbl + return []; // todo whargarbl + } + + + actions_for(whichNode : string) : Array { // todo whargarbl + return []; // todo whargarbl + } + + action_entrances_for(whichNode : string) : Array { // todo whargarbl + return []; // todo whargarbl + } + + action_exits_for(whichNode : string) : Array { // todo whargarbl + return []; // todo whargarbl + } + + + is_unenterable(whichNode : string) : boolean { + return this.entrances_for(whichNode).length === 0; + } + + has_unenterables() : boolean { + return this.nodes.some(this.is_unenterable); + } + + + is_terminal(whichNode : string) : boolean { + return this.exits_for(whichNode).length === 0; + } + + has_terminals() : boolean { + return this.nodes.some(this.is_terminal); + } + + + action(name : string, new_data? : mixed) : boolean { + return false; // todo whargarbl + } + + transition(newNode : string, new_data? : mixed) : boolean { + return false; // todo whargarbl + } + + force_transition(newNode : string, new_data? : mixed) : boolean { + return false; // todo whargarbl + } + + + valid_action(action : string, new_data : mixed) : boolean { + return false; // todo whargarbl + } + + valid_transition(newNode : string, new_data : mixed) : boolean { + return false; // todo whargarbl + } + + valid_force_transition(newNode : string, new_data : mixed) : boolean { + return false; // todo whargarbl + } + + +} + + + + + export { new_machine,