summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-09-03 23:06:31 -0700
committerLi Haoyi <haoyi@dropbox.com>2014-09-03 23:06:31 -0700
commit2f96da023d9172deb646de9bd1cf0a05c4201df7 (patch)
tree8636cf8853fe0a8621587e4a9870230545f89f9c
parent424cc28d19f7e23cab6af9795a6c6a5c4adf5e3c (diff)
downloadworkbench-2f96da023d9172deb646de9bd1cf0a05c4201df7.tar.gz
workbench-2f96da023d9172deb646de9bd1cf0a05c4201df7.tar.bz2
workbench-2f96da023d9172deb646de9bd1cf0a05c4201df7.zip
lols
-rw-r--r--build.sbt20
-rw-r--r--client/src/main/scala/workbench/Main.scala76
-rw-r--r--example/project/build.sbt6
-rw-r--r--shared/main/scala/workbench/Shared.scala8
-rw-r--r--shared/src/main/scala/workbench/Shared.scala1
-rw-r--r--src/main/scala/workbench/Plugin.scala (renamed from plugin/src/main/scala/workbench/Plugin.scala)29
-rw-r--r--src/main/scala/workbench/Server.scala (renamed from plugin/src/main/scala/workbench/Server.scala)37
7 files changed, 128 insertions, 49 deletions
diff --git a/build.sbt b/build.sbt
index d6cb612..c92a713 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,14 +1,17 @@
import sbt.Keys._
+import scala.scalajs.sbtplugin.ScalaJSPlugin._
+import ScalaJSKeys._
val defaultSettings = Seq(
unmanagedSourceDirectories in Compile <+= baseDirectory(_ / "shared" / "main" / "scala"),
unmanagedSourceDirectories in Test <+= baseDirectory(_ / "shared" / "test" / "scala")
)
-lazy val plugin = project.in(file("plugin")).settings(defaultSettings:_*).settings(
+lazy val root = project.in(file(".")).settings(defaultSettings:_*).settings(
name := "workbench",
- version := "0.1.5",
+ version := "0.1.6-SNAPSHOT",
organization := "com.lihaoyi",
+ scalaVersion := "2.10.4",
sbtPlugin := true,
publishArtifact in Test := false,
publishTo := Some("releases" at "https://oss.sonatype.org/service/local/staging/deploy/maven2"),
@@ -32,12 +35,16 @@ lazy val plugin = project.in(file("plugin")).settings(defaultSettings:_*).settin
</developer>
</developers>
),
- (resources in Compile) := {(resources in Compile).value ++ (baseDirectory.value * "*.js").get},
+ (resources in Compile) += {
+ (fullOptJS in (client, Compile)).value
+ (artifactPath in (client, Compile, fullOptJS)).value
+ },
libraryDependencies ++= Seq(
"io.spray" % "spray-can" % "1.3.1",
"io.spray" % "spray-routing" % "1.3.1",
"com.typesafe.akka" %% "akka-actor" % "2.3.0",
- "com.lihaoyi" %% "upickle" % "0.2.1"
+ "com.lihaoyi" %% "autowire" % "0.2.3-SNAPSHOT",
+ "com.lihaoyi" %% "upickle" % "0.2.3-SNAPSHOT"
)
)
@@ -47,6 +54,7 @@ lazy val client = project.in(file("client"))
libraryDependencies ++= Seq(
"org.scala-lang.modules.scalajs" %%% "scalajs-dom" % "0.6",
"org.scala-lang.modules" %% "scala-async" % "0.9.2",
- "com.lihaoyi" %%% "upickle" % "0.2.1"
+ "com.lihaoyi" %%% "autowire" % "0.2.3-SNAPSHOT",
+ "com.lihaoyi" %%% "upickle" % "0.2.3-SNAPSHOT"
)
-) \ No newline at end of file
+)
diff --git a/client/src/main/scala/workbench/Main.scala b/client/src/main/scala/workbench/Main.scala
index 0b0cea7..7f63da6 100644
--- a/client/src/main/scala/workbench/Main.scala
+++ b/client/src/main/scala/workbench/Main.scala
@@ -1,10 +1,74 @@
-package workbench
+package com.lihaoyi.workbench
+import upickle._
+import org.scalajs.dom
import org.scalajs.dom.extensions._
-import async.Async._
-object Main{
- def main(bootSnippet: String, host: String, port: Int): Unit = async{
- while(true){
- val data = await(Ajax.get(s"http://$host:$port/notifications"))
+import upickle.{Reader, Writer, Js}
+
+import scala.scalajs.js
+import scala.scalajs.js.annotation.JSExport
+import scalajs.concurrent.JSExecutionContext.Implicits.runNow
+object WireServer extends autowire.Server[Js.Value, upickle.Reader, upickle.Writer]{
+
+ 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]]
+ )
+ )
+ }
+}
+@JSExport
+object Main extends Api{
+ 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)
+ ()
+ }
+ rec()
+ }
+
+
+ override def clear(): Unit = ???
+
+ override def reload(): Unit = {
+ dom.console.log("Reloading page...")
+ dom.location.reload()
+ }
+
+ override def run(path: String, bootSnippet: Option[String]): Unit = {
+ val tag = dom.document.createElement("script")
+ 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!")
+ js.eval(bootSnippet)
+ }
+ loaded = true
+ }
+ }
+ dom.document.head.appendChild(tag)
+ }
+
+ override def print(level: String, msg: String): Unit = {
+ level match {
+ case "error" => dom.console.error(msg)
+ case "warn" => dom.console.warn(msg)
+ case "info" => dom.console.info(msg)
+ case "log" => dom.console.log(msg)
}
}
} \ No newline at end of file
diff --git a/example/project/build.sbt b/example/project/build.sbt
index 24009f8..4871695 100644
--- a/example/project/build.sbt
+++ b/example/project/build.sbt
@@ -1,6 +1,4 @@
-addSbtPlugin("org.scala-lang.modules.scalajs" % "scalajs-sbt-plugin" % "0.5.3")
+addSbtPlugin("org.scala-lang.modules.scalajs" % "scalajs-sbt-plugin" % "0.5.4")
-lazy val root = project.in( file(".") ).dependsOn(
- file("../..")
-) \ No newline at end of file
+lazy val root = project.in(file(".")).dependsOn(file("../..")) \ No newline at end of file
diff --git a/shared/main/scala/workbench/Shared.scala b/shared/main/scala/workbench/Shared.scala
new file mode 100644
index 0000000..da202b4
--- /dev/null
+++ b/shared/main/scala/workbench/Shared.scala
@@ -0,0 +1,8 @@
+package com.lihaoyi.workbench
+
+trait Api{
+ def clear(): Unit
+ def reload(): Unit
+ def print(level: String, msg: String): Unit
+ def run(path: String, bootSnippet: Option[String]): Unit
+} \ No newline at end of file
diff --git a/shared/src/main/scala/workbench/Shared.scala b/shared/src/main/scala/workbench/Shared.scala
deleted file mode 100644
index be0ee43..0000000
--- a/shared/src/main/scala/workbench/Shared.scala
+++ /dev/null
@@ -1 +0,0 @@
-package workbench
diff --git a/plugin/src/main/scala/workbench/Plugin.scala b/src/main/scala/workbench/Plugin.scala
index 3a434e8..8e122fe 100644
--- a/plugin/src/main/scala/workbench/Plugin.scala
+++ b/src/main/scala/workbench/Plugin.scala
@@ -1,3 +1,9 @@
+package com.lihaoyi.workbench
+import sbt._
+import sbt.Keys._
+import autowire._
+import upickle.Js
+import scala.concurrent.ExecutionContext.Implicits.global
object Plugin extends sbt.Plugin {
val refreshBrowsers = taskKey[Unit]("Sends a message to all connected web pages asking them to refresh the page")
@@ -9,8 +15,6 @@ object Plugin extends sbt.Plugin {
val bootSnippet = settingKey[String]("piece of javascript to make things happen")
val updatedJS = taskKey[List[String]]("Provides the addresses of the JS files that have changed")
-
-
val workbenchSettings = Seq(
localUrl := ("localhost", 12345),
updatedJS := {
@@ -36,9 +40,9 @@ object Plugin extends sbt.Plugin {
val clientLogger = FullLogger{
new Logger {
def log(level: Level.Value, message: => String) =
- if(level >= Level.Info) server.value msg Seq("print", level.toString, message)
- def success(message: => String) = server.value msg Seq("print", "info", message)
- def trace(t: => Throwable) = server.value msg Seq("print", "error", t.toString)
+ if(level >= Level.Info) server.value.Wire[Api].print(level.toString, message).call()
+ def success(message: => String) = server.value.Wire[Api].print("info", message).call()
+ def trace(t: => Throwable) = server.value.Wire[Api].print("error", t.toString).call()
}
}
clientLogger.setSuccessEnabled(true)
@@ -47,22 +51,17 @@ object Plugin extends sbt.Plugin {
},
refreshBrowsers := {
streams.value.log.info("workbench: Reloading Pages...")
- server.value msg Seq("reload")
+ server.value.Wire[Api].reload().call()
},
updateBrowsers := {
val changed = updatedJS.value
// There is no point in clearing the browser if no js files have changed.
if (changed.length > 0) {
- server.value msg Seq("clear")
+ server.value.Wire[Api].clear().call()
- changed.foreach {
- path =>
- streams.value.log.info("workbench: Refreshing " + path)
- server.value msg Seq(
- "run",
- path,
- bootSnippet.value
- )
+ changed.foreach { path =>
+ streams.value.log.info("workbench: Refreshing " + path)
+ server.value.Wire[Api].run(path, Some(bootSnippet.value)).call()
}
}
},
diff --git a/plugin/src/main/scala/workbench/Server.scala b/src/main/scala/workbench/Server.scala
index b9773a7..96ac736 100644
--- a/plugin/src/main/scala/workbench/Server.scala
+++ b/src/main/scala/workbench/Server.scala
@@ -5,19 +5,28 @@ import com.typesafe.config.ConfigFactory
import sbt.IO
import spray.routing.SimpleRoutingApp
import akka.actor.ActorDSL._
-import scala.Some
-import upickle.{Writer, Json, Js}
+
+import upickle.{Reader, Writer, Js}
import spray.http.{AllOrigins, HttpResponse}
import spray.http.HttpHeaders.`Access-Control-Allow-Origin`
import concurrent.duration._
+import scala.concurrent.Future
+
class Server(url: String, port: Int, bootSnippet: String) extends SimpleRoutingApp{
implicit val system = ActorSystem(
"SystemLol",
config = ConfigFactory.load(ActorSystem.getClass.getClassLoader),
classLoader = ActorSystem.getClass.getClassLoader
)
-
- val pubSub = actor(new Actor{
+ 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:_*))
+ Future.successful(Js.Null)
+ }
+ def write[Result: Writer](r: Result) = upickle.writeJs(r)
+ def read[Result: Reader](p: Js.Value) = upickle.readJs[Result](p)
+ }
+ private val pubSub = actor(new Actor{
var waitingActor: Option[ActorRef] = None
var queuedMessages = List[Js.Value]()
case object Clear
@@ -37,15 +46,15 @@ class Server(url: String, port: Int, bootSnippet: String) extends SimpleRoutingA
waitingActor = Some(a)
case (a: ActorRef, None, msgs) =>
- respond(a, Json.write(Js.Array(msgs)))
+ respond(a, upickle.json.write(Js.Arr(msgs:_*)))
queuedMessages = Nil
- case (msg: Js.Array, None, msgs) =>
+ case (msg: Js.Arr, None, msgs) =>
queuedMessages = msg :: msgs
- case (msg: Js.Array, Some(a), Nil) =>
- respond(a, Json.write(Js.Array(Seq(msg))))
+ case (msg: Js.Arr, Some(a), Nil) =>
+ respond(a, upickle.json.write(Js.Arr(msg)))
waitingActor = None
case (Clear, Some(a), Nil) =>
- respond(a, Json.write(Js.Array(Nil)))
+ respond(a, upickle.json.write(Js.Arr()))
waitingActor = None
}
})
@@ -56,10 +65,8 @@ class Server(url: String, port: Int, bootSnippet: String) extends SimpleRoutingA
complete {
IO.readStream(
getClass.getClassLoader
- .getResourceAsStream("workbench_template.js")
- ).replace("<host>", url)
- .replace("<port>", port.toString)
- .replace("<bootSnippet>", bootSnippet)
+ .getResourceAsStream("client-opt.js")
+ ) + s"\nMain.main(${upickle.write(bootSnippet)}, ${upickle.write(url)}, ${upickle.write(port)})"
}
} ~
getFromDirectory(".")
@@ -70,10 +77,6 @@ class Server(url: String, port: Int, bootSnippet: String) extends SimpleRoutingA
}
}
}
-
- def msg[T: Writer](t: T) = {
- pubSub ! upickle.writeJs(t)
- }
def kill() = {
system.shutdown()
}