jed / lave

eval in reverse: stringifying all the stuff that JSON.stringify won't
MIT License
896 stars 19 forks source link

Support symbols #10

Open jed opened 8 years ago

gnestor commented 8 years ago

+1

I get the following error when trying:

lave(<ReactComponent text="This is a class component" />)
/Users/grant/Sites/dia/magic-console/node_modules/lave/index.js:77
  if (value < 0) {
      ^
TypeError: Cannot convert a Symbol value to a number
at getExpression (/Users/grant/Sites/dia/magic-console/node_modules/lave/index.js:77:11)
at getExpression (/Users/grant/Sites/dia/magic-console/node_modules/lave/index.js:269:25)
at lave (/Users/grant/Sites/dia/magic-console/node_modules/lave/index.js:13:20)
at Object.<anonymous> (lave.js:30:43)
at Module._compile (module.js:413:34)
at loader (/usr/local/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:134:5)
at Object.require.extensions.(anonymous function) [as .js] (/usr/local/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:144:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
gnestor commented 8 years ago

You can reproduce using this Tonic notebook: https://tonicdev.com/gnestor/lave-react-element/1.0.0

jed commented 8 years ago

Hey there @gnestor, thanks for the issue! The problem appears to be that you are using JSX, which unfortunately, is not valid JavaScript.

gnestor commented 8 years ago

However, in the example in Tonic, I am using React.createElement, so what's being passed to lave is valid JS, not JSX:

var lave = require('lave')
var React = require('react')
var ReactDOM = require('react-dom')

class ReactComponent extends React.Component {
  render() {
    return <span>{this.props.text}</span>
  }
}
var element = React.createElement(ReactComponent,  {text: 'This is a React element'})
var ast = lave(element)
console.log(element, ast)

I think this "Cannot convert a Symbol value to a number" error refers to the $$typeof: Symbol.for('react.element') property that is added to React element objects.

jed commented 8 years ago

I would love to add support for symbols soon, but can't imagine this will work, for it would assume that React doesn't use any closures (which means that not even lave could stringify it).

gnestor commented 8 years ago

@jed if you wouldn't mind explaining the problem here, I would love to help. If I understand you correctly, if an value/expression involves closures, you can't stringified it using lave? However, circular references are ok? I've tried to stringify React classes using a lot of different methods with no luck yet for ES6 class components (ES5 composite class components and stateless components work).

jed commented 8 years ago

@gnestor: that's exactly right. lave works by crawling every property of a given object, and since closures are not properties, they cannot be crawled.