Skip to content

Instantly share code, notes, and snippets.

@myguidingstar-zz
Created October 9, 2014 22:41
Show Gist options
  • Save myguidingstar-zz/8997f862e4016159c749 to your computer and use it in GitHub Desktop.
Save myguidingstar-zz/8997f862e4016159c749 to your computer and use it in GitHub Desktop.
(ns cljs.repl.foxx
(:require [clojure.string :as string]
[clojure.java.io :as io]
[cljs.analyzer :as ana]
[cljs.repl :as repl]
[cljs.env :as env]
[clj-http.client :as client]
[cheshire.core :refer [parse-string]]
[cemerick.piggieback :as piggieback])
(:import cljs.repl.IJavaScriptEnv))
(defn js-eval [env filename line code]
(let [{:keys [foxx-url]} env]
(let [result-string (:body (client/put foxx-url {:body code}))]
(parse-string result-string true))))
(defn foxx-setup [repl-env]
(let [env (ana/empty-env)]
(env/with-compiler-env (or (::env/compiler repl-env) (env/default-compiler-env))
(repl/load-file repl-env "cljs/core.cljs")
(swap! (:loaded-libs repl-env) conj "cljs.core")
(repl/evaluate-form repl-env env "<cljs repl>"
'(ns cljs.user))
(repl/evaluate-form repl-env env "<cljs repl>"
'(set! cljs.core/*print-fn* (.-log (js/require "console")))))))
(defn foxx-eval [repl-env filename line js]
(let [result (js-eval repl-env filename line js)]
(if-let [error (:error result)]
{:status :exception :value (:stack error)}
{:status :success :value (:result result)})))
(defn load-javascript [repl-env ns url]
(let [missing (remove #(contains? @(:loaded-libs repl-env) %) ns)]
(when (seq missing)
(js-eval repl-env (.toString url) 1 (slurp url))
(swap! (:loaded-libs repl-env) (partial apply conj) missing))))
(defn foxx-tear-down [repl-env])
(defn load-resource
"Load a JS file from the classpath into the REPL environment."
[env filename]
(let [resource (io/resource filename)]
(assert resource (str "Can't find " filename " in classpath"))
(js-eval env filename 1 (slurp resource))))
(defrecord FoxxEnv []
repl/IJavaScriptEnv
(-setup [this]
(foxx-setup this))
(-evaluate [this filename line js]
(foxx-eval this filename line js))
(-load [this ns url]
(load-javascript this ns url))
(-tear-down [this]
(foxx-tear-down this)))
(defn repl-env
"Create a Node.js REPL environment."
[& {:as opts}]
(let [base (io/resource "goog/base.js")
deps (io/resource "goog/deps.js")
compiler (env/default-compiler-env)
new-repl-env (merge (FoxxEnv.)
{:foxx-url (:foxx-url opts)
:loaded-libs (atom #{})
:optimizations :simple,
::env/compiler compiler})]
;; workaround: build makes a copy of target, but repl does not call it
(swap! compiler assoc :target :nodejs)
(assert base "Can't find goog/base.js in classpath")
(assert deps "Can't find goog/deps.js in classpath")
(load-resource new-repl-env "goog/base.js")
(load-resource new-repl-env "goog/deps.js")
new-repl-env))
(defn run-node-repl [foxx-url]
(repl/repl (repl-env :foxx-url foxx-url)))
(defn nrepl-env [foxx-url]
(doto (repl-env :foxx-url foxx-url) (foxx-setup)))
(defn run-node-nrepl [foxx-url]
(piggieback/cljs-repl :repl-env (nrepl-env foxx-url)))
(defproject cljs.repl.foxx "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.6.0"]
[org.bodil/cljs-noderepl "0.1.11"]
[com.cemerick/piggieback "0.1.3"]
[org.clojure/clojurescript "0.0-2356"]
[clj-http "1.0.0"]])
@myguidingstar-zz
Copy link
Author

 (PUT app "/eval" [] {code :request-body}
       (json* (try #js {:result (js/eval code)}
                   (catch :default e
                     #js {:name (.-name e)
                          :message (.-message e)
                          :stack (.-stack e)}))))
  (PUT app "/eval-verbose" [] {code :request-body}
       (log "Got code: " code)
       (json* (try (let [result (js/eval code)]
                     ;; (log "Result: " result)
                     #js {:result result})
                   (catch :default e
                     (log "Error: " (.-name e) (.-message e))
                     #js {:name (.-name e)
                          :message (.-message e)
                          :stack (.-stack e)}))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment