summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-09-05 13:20:48 -0700
committerLi Haoyi <haoyi@dropbox.com>2014-09-05 13:20:48 -0700
commitcf9b1e5dc81d4c3a30a26cb18e38f7db03460ef4 (patch)
tree8df706e2ebcbab222e898d30dea71fdef0b419ca
parent020885615083203808a3ea7ab3181cedf9a48331 (diff)
downloadworkbench-cf9b1e5dc81d4c3a30a26cb18e38f7db03460ef4.tar.gz
workbench-cf9b1e5dc81d4c3a30a26cb18e38f7db03460ef4.tar.bz2
workbench-cf9b1e5dc81d4c3a30a26cb18e38f7db03460ef4.zip
Workbench is now pure-scala
-rw-r--r--build.sbt3
-rw-r--r--client/src/main/scala/workbench/WorkbenchClient.scala (renamed from client/src/main/scala/workbench/Main.scala)57
-rw-r--r--example/src/main/scala/example/ScalaJSExample.scala3
-rw-r--r--src/main/scala/workbench/Server.scala28
-rw-r--r--workbench_template.js71
5 files changed, 55 insertions, 107 deletions
diff --git a/build.sbt b/build.sbt
index 852e777..6bb8ec3 100644
--- a/build.sbt
+++ b/build.sbt
@@ -9,7 +9,7 @@ val defaultSettings = Seq(
lazy val root = project.in(file(".")).settings(defaultSettings:_*).settings(
name := "workbench",
- version := "0.1.6-SNAPSHOT",
+ version := "0.1.6",
organization := "com.lihaoyi",
scalaVersion := "2.10.4",
sbtPlugin := true,
@@ -53,7 +53,6 @@ lazy val client = project.in(file("client"))
.settings(
libraryDependencies ++= Seq(
"org.scala-lang.modules.scalajs" %%% "scalajs-dom" % "0.6",
- "org.scala-lang.modules" %% "scala-async" % "0.9.2",
"com.lihaoyi" %%% "autowire" % "0.2.3",
"com.lihaoyi" %%% "upickle" % "0.2.3"
)
diff --git a/client/src/main/scala/workbench/Main.scala b/client/src/main/scala/workbench/WorkbenchClient.scala
index 7f63da6..c67d4c6 100644
--- a/client/src/main/scala/workbench/Main.scala
+++ b/client/src/main/scala/workbench/WorkbenchClient.scala
@@ -3,7 +3,6 @@ import upickle._
import org.scalajs.dom
import org.scalajs.dom.extensions._
import upickle.{Reader, Writer, Js}
-
import scala.scalajs.js
import scala.scalajs.js.annotation.JSExport
import scalajs.concurrent.JSExecutionContext.Implicits.runNow
@@ -12,32 +11,47 @@ object WireServer extends autowire.Server[Js.Value, upickle.Reader, upickle.Writ
def write[Result: Writer](r: Result) = upickle.writeJs(r)
def read[Result: Reader](p: Js.Value) = upickle.readJs[Result](p)
def wire(parsed: Js.Arr): Unit = {
- WireServer.route[Api](Main).apply(
- autowire.Core.Request(
- parsed(0).asInstanceOf[Js.Arr].value.collect{case Js.Str(s) => s},
- parsed(1).value.asInstanceOf[Map[String, Js.Value]]
- )
+ val Js.Arr(path, args: Js.Obj) = parsed
+
+ val req = new Request(
+ upickle.readJs[Seq[String]](path),
+ args.value.toMap
)
+ WireServer.route[Api](WorkbenchClient).apply(req)
}
}
@JSExport
-object Main extends Api{
+object WorkbenchClient extends Api{
+ val shadowBody = dom.document.body.cloneNode(deep = true)
+ var interval = 1000
+ var success = false
+ @JSExport
def main(bootSnippet: String, host: String, port: Int): Unit = {
- def rec(): Unit = {
- val f = Ajax.get(s"http://$host:$port/notifications")
-
- f.onSuccess { case data =>
- val parsed = json.read(data.responseText).asInstanceOf[Js.Arr]
- WireServer.wire(parsed)
- rec()
- } (runNow)
- ()
+ Ajax.post(s"http://$host:$port/notifications").onComplete{
+ case util.Success(data) =>
+ if (!success) println("Workbench connected")
+ success = true
+ interval = 1000
+ json.read(data.responseText)
+ .asInstanceOf[Js.Arr]
+ .value
+ .foreach(v => WireServer.wire(v.asInstanceOf[Js.Arr]))
+ main(bootSnippet, host, port)
+ case util.Failure(e) =>
+ if (!success) println("Workbench disconnected " + e)
+ success = false
+ interval = math.min(interval * 2, 30000)
+ dom.setTimeout(() => main(bootSnippet, host, port), interval)
}
- rec()
}
-
- override def clear(): Unit = ???
+ override def clear(): Unit = {
+ dom.document.asInstanceOf[js.Dynamic].body = shadowBody.cloneNode(true)
+ for(i <- 0 until 100000){
+ dom.clearTimeout(i)
+ dom.clearInterval(i)
+ }
+ }
override def reload(): Unit = {
dom.console.log("Reloading page...")
@@ -49,16 +63,15 @@ object Main extends Api{
var loaded = false
tag.setAttribute("src", path)
-
bootSnippet.foreach{ bootSnippet =>
tag.onreadystatechange = (e: dom.Event) => {
- dom.console.log("Post-run reboot")
if (!loaded) {
- dom.console.log("Post-run reboot go!")
+ dom.console.log("Post-run reboot")
js.eval(bootSnippet)
}
loaded = true
}
+ tag.asInstanceOf[js.Dynamic].onload = tag.onreadystatechange
}
dom.document.head.appendChild(tag)
}
diff --git a/example/src/main/scala/example/ScalaJSExample.scala b/example/src/main/scala/example/ScalaJSExample.scala
index 7222143..bab193b 100644
--- a/example/src/main/scala/example/ScalaJSExample.scala
+++ b/example/src/main/scala/example/ScalaJSExample.scala
@@ -7,7 +7,8 @@ case class Point(x: Int, y: Int){
def +(p: Point) = Point(x + p.x, y + p.y)
def /(d: Int) = Point(x / d, y / d)
}
-
+// Seems like you need this for sbt ~fastOptJS to work
+// mkdir ~/.sbt/0.13/plugins/target/scala-2.10/sbt-0.13/classes
@JSExport
object ScalaJSExample {
val ctx = dom.document
diff --git a/src/main/scala/workbench/Server.scala b/src/main/scala/workbench/Server.scala
index 96ac736..bec88b6 100644
--- a/src/main/scala/workbench/Server.scala
+++ b/src/main/scala/workbench/Server.scala
@@ -14,13 +14,13 @@ import scala.concurrent.Future
class Server(url: String, port: Int, bootSnippet: String) extends SimpleRoutingApp{
implicit val system = ActorSystem(
- "SystemLol",
+ "Workbench-System",
config = ConfigFactory.load(ActorSystem.getClass.getClassLoader),
classLoader = ActorSystem.getClass.getClassLoader
)
object Wire extends autowire.Client[Js.Value, upickle.Reader, upickle.Writer]{
def doCall(req: Request): Future[Js.Value] = {
- pubSub ! Js.Arr(Js.Str(req.path.mkString(".")), Js.Obj(req.args.toSeq:_*))
+ pubSub ! Js.Arr(upickle.writeJs(req.path), Js.Obj(req.args.toSeq:_*))
Future.successful(Js.Null)
}
def write[Result: Writer](r: Result) = upickle.writeJs(r)
@@ -63,19 +63,25 @@ class Server(url: String, port: Int, bootSnippet: String) extends SimpleRoutingA
get {
path("workbench.js") {
complete {
- IO.readStream(
- getClass.getClassLoader
- .getResourceAsStream("client-opt.js")
- ) + s"\nMain.main(${upickle.write(bootSnippet)}, ${upickle.write(url)}, ${upickle.write(port)})"
+ val body = IO.readStream(
+ getClass.getClassLoader.getResourceAsStream("client-opt.js")
+ )
+ s"""
+ (function(){
+ $body
+
+ WorkbenchClient().main(${upickle.write(bootSnippet)}, ${upickle.write(url)}, ${upickle.write(port)})
+ }).call(this)
+ """
}
} ~
- getFromDirectory(".")
+ getFromDirectory(".")
} ~
- post {
- path("notifications") { ctx =>
- pubSub ! ctx.responder
- }
+ post {
+ path("notifications") { ctx =>
+ pubSub ! ctx.responder
}
+ }
}
def kill() = {
system.shutdown()
diff --git a/workbench_template.js b/workbench_template.js
deleted file mode 100644
index a16e638..0000000
--- a/workbench_template.js
+++ /dev/null
@@ -1,71 +0,0 @@
-(function(){
- var shadowBody = null
- var bootSnippet = "<bootSnippet>"
- window.onload = function(){
- shadowBody = document.body.cloneNode(true)
- start()
- }
- window.addEventListener("keydown", function (event) {
- if(event.keyCode==13 && event.ctrlKey && event.altKey && event.shiftKey) {
- clear()
- eval(bootSnippet)
- }
- })
- function clear(){
- document.body = shadowBody.cloneNode(true)
- for(var i = 0; i < 99999; i++){
- clearTimeout(i)
- clearInterval(i)
- }
- }
-
- var start = function(){
- var req = new XMLHttpRequest()
-
- req.open("POST", "http://<host>:<port>/notifications")
-
- req.onload = function(){
- if (req.status != 200){
- setTimeout(function(){start()}, 1000)
- }else{
- var dataList = JSON.parse(req.responseText)
- for(var i = 0; i < dataList.length; i++){
-
- var data = dataList[i]
- if (data[0] == "reload") {
- console.log("Reloading page...")
- location.reload()
- }
- if (data[0] == "clear"){
- clear()
- }
- if (data[0] == "run"){
- var tag = document.createElement("script")
- var loaded = false
-
- tag.setAttribute("src", data[1])
-
- var bootSnippet = data[2]
- if (bootSnippet){
- tag.onreadystatechange = tag.onload = function() {
- console.log("Post-run reboot")
- if (!loaded) {
- console.log("Post-run reboot go!")
- eval(bootSnippet)
- }
- loaded = true
- };
- }
- document.head.appendChild(tag)
- }
- if (data[0] == "boot"){
- eval(bootSnippet)
- }
- if (data[0] == "print") console[data[1]](data[2])
- }
- start()
- }
- }
- req.send()
- }
-})()