I am trying to give myself a JS repl. Having some success, but since I am just doing (js/eval <selectionText>), the evals are run in a context that is then forgotten, so I can’t define a variable in one evaluation and use it in the next one. Any ideas how to overcome this? Is there something in SCI that can facilitate it, @borkdude?
This should help somewhat I think:
(js/eval.apply js/globalThis #js ["var x = 1"])There is nothing in SCI that will help you evaluate JS
const won't work for defining global things using eval:
https://stackoverflow.com/a/50099981/6264
Thanks! Seems eval and the apply on globalThis work similarly. Both behave like this in this case at least. Very good to know about the const -> strict thing.
I did a similar thing in clerk, let me look it up
ah yes, you need to attach that function to the global object first:
(j/assoc! js/globalThis :global_eval (fn [x]
(js/eval.apply js/globalThis #js [x])))without j/:
(set! (.-global_eval js/globalThis) (fn [x] (js/eval.apply js/globalThis #js [x]))))and then call that js/global_eval function
I could get const declarations work using the node repl:
(defonce node-repl (.start repl))
(defn eval+ [code]
(p/create (fn [resolve reject]
(.eval node-repl
code
(.-context node-repl)
""
(fn [err, result]
(if err
(reject err)
(resolve result)))))))Progress. No top level await and no es6, yet. But for quick js experiments this is pretty useful already, I think.
in squint repl I hack around the limitation of eval + await by evaluating everything inside of a self-calling async anonymous function
but in that case, const etc won't work I guess
Maybe I could detect if there is a top level await there and then wrap it like that, with the limitation that it strict assignments will be scoped in those cases. But maybe that defeats the purpose…
or rewrite const to var ;)
only when it appears on the top level
dunno
I guess you need to evaluate everything in the scope of what file/module it is in as well
sounds like a mess
The evaluator knows which file thing are evaluated in. But maybe it mostly uses that for error messages. Idk. Maybe I could test that some way…
Rewriting the code sounds pretty difficult.
I mean, there are some tools to parse JS as an AST, then you could walk this by rewriting only the top level stuff and print it back to a string, but this sounds like a future rabbit-hole optimization ;)