jbeard4 / SCION

SCXML/Statecharts in JavaScript, moved to gitlab: https://gitlab.com/scion-scxml/scion
https://scion.scxml.io
Apache License 2.0
149 stars 29 forks source link

TypeError: chunk.charAt is not a function #378

Closed jonnermut closed 7 years ago

jonnermut commented 7 years ago

Seems that the scxml.documentStringToModel func is somehow broken?

This code in node (latest):

var scxml = require('scxml')

var xml = `<scxml 
    xmlns="http://www.w3.org/2005/07/scxml"
    version="1.0"
    profile="ecmascript"
    initial="draft">

    <state id="draft">
    </state>

</scxml>`

 scxml.documentStringToModel(xml, function(err, model) {
    if(err) {
        throw err;
    }
    console.log(model)
  })

gives the error:

bash-3.2$ node testInNode.js
/Volumes/TERA/Dropbox/code/scion-viz2/node_modules/sax/lib/sax.js:976
      result = chunk.charAt(i)
                     ^

TypeError: chunk.charAt is not a function
    at charAt (/Volumes/TERA/Dropbox/code/scion-viz2/node_modules/sax/lib/sax.js:976:22)
    at Object.write (/Volumes/TERA/Dropbox/code/scion-viz2/node_modules/sax/lib/sax.js:999:11)
    at transform (/Volumes/TERA/Dropbox/code/scion-viz2/node_modules/scxml/lib/compiler/scxml-to-scjson.js:296:12)
    at Object.documentStringToModel (/Volumes/TERA/Dropbox/code/scion-viz2/node_modules/scxml/lib/runtime/document-string-to-model.js:43:18)
    at Object.<anonymous> (/Volumes/TERA/Dropbox/code/scion-viz2/testInNode.js:15:8)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
bash-3.2$

It does the same thing in the browser. Using pathToModel seems to work ok.

jonnermut commented 7 years ago

ok, caused by a missing parameter in documentStringToModel (the doco on the front page is wrong)

jbeard4 commented 7 years ago

Thanks, I added the missing parameter to the README.

jonnermut commented 7 years ago

while I've got you... I'm having a lot of trouble actually getting a parsed statechart through that method - all I can seem to get are generated states.

For instance

var scxml = require('scxml')

var xml = `<scxml 
    xmlns="http://www.w3.org/2005/07/scxml"
    version="1.0"
    profile="ecmascript"
    initial="draft">

    <state id="draft">
    </state>

    <state id="secondState">
    </state>

</scxml>`

 scxml.documentStringToModel(null, xml, function(err, model) {
    if(err) {
        throw err;
    }

    console.log(JSON.stringify(model))

    var s = new scxml.scion.Statechart(model)

    // what can I use to get at the states?

  })

prints {"rootScripts":[],"module":{}}

And if I inspect in a debugger there doesnt seem to be any visible states in either model or s. I had previous code from an earlier version that would pass that model in to SCXML object (now Statechart), and list the states and transitions, how do you do that in the new API?

jbeard4 commented 7 years ago

The SCION API changed from version 2 to 3. Please now do the following:

scxml.documentStringToModel(null, xml, function(err, model) {
  model.prepare(function(err, fnModel) {

    if(err) throw err;

    //instantiate the interpreter
    var sc = new scxml.scion.Statechart(fnModel);
  });
})

model.prepare re-downloads and injects script tags without re-parsing the SCXML.

I will update SCION so that it validates the fnModel argument and throws an error if it is invalid. I have created an issue to track this here: https://github.com/jbeard4/SCION/issues/379

jonnermut commented 7 years ago

Thanks, that would have helped track it down. This was a copy and paste of previous code without closely checking the new examples.

Couple of questions, if I may;

  1. To get the states, I am using statechart_model.states.forEach and recursing through descendants. Is _model now private, given the underscore, and is there a better way to do this?
  2. Is there a way to relate the states and transitions back to the xml model? Eg a reference to the xml element that created the object? I'm guessing not given the compilation model. I guess states always have to have an id, so I can just look them up in a DOM, but transitions etc don't. The use case is I'm playing around with JointJS to make a drag-drop editor, where I want changes to the diagram to update the xml, and use that as the canonical source (not the json model etc).

Thinking about it, I'm probably confusing the parser/compiler/runtime parts of SCION. What I really want for the diagram editor is to parse the xml into a normalised JS form, and then be able to manipulate the JS form and have the xml updated, either automagically, or manually through a link back to the xml dom element. That use case doesn't look particularly practical in SCION, but it would be a shame to have to replicate the xml parsing in SCION to do this. Can you actually add states and transitions dynamically in SCION?

  1. From experimentation, it looks like custom attributes on elements are passed straight through, which is great. Is there any support for custom elements? For instance, this is an example from the spec:
<scxml:transition event="email.send">
  <my:email to="data('_event')/scxml:property[@name='email']"
            cc="data('_event')/scxml:property[@name='xmlcontent']/h:headers/h:cc"
            subject="data('_event')/scxml:property[@name='xmlcontent']/h:headers/h:subject"
            content="data('_event')/scxml:property[@name='content']"/>
</scxml:transition>

And states and transitions can have any custom elements in my understanding? The major use case for me is triggering reusable server actions, but I probably don't understand the scxml model well enough. Could possibly just use custom attributes on existing elements I guess.

jbeard4 commented 7 years ago

To get the states, I am using statechart_model.states.forEach and recursing through descendants. Is _model now private, given the underscore, and is there a better way to do this?

Actually, just use the following code:

let scjsonModel = fnModel()

jbeard4 commented 7 years ago

Is there a way to relate the states and transitions back to the xml model? Eg a reference to the xml element that created the object? I'm guessing not given the compilation model. I guess states always have to have an id, so I can just look them up in a DOM, but transitions etc don't.

You can use ids to map the states. Transitions can be mapped based on their parent state, and their order in the document.

jbeard4 commented 7 years ago

Can you actually add states and transitions dynamically in SCION?

You can add states and transitions dynamically to an SCJSON, but once that is used to instantiate a simulator, updating the states and transitions of the SCJSON is not supported.

jbeard4 commented 7 years ago

From experimentation, it looks like custom attributes on elements are passed straight through, which is great. Is there any support for custom elements?

This is not currently supported, but patches are welcome.