scala-js-dom icon indicating copy to clipboard operation
scala-js-dom copied to clipboard

Replace docs with mdoc

Open zetashift opened this issue 1 year ago • 16 comments

Improves and replaces https://github.com/scala-js/scala-js-dom/pull/741

zetashift avatar Feb 19 '23 23:02 zetashift

Running docs/mdoc gives me the following error (while it didn't in my previous effort):

[error] stack trace is suppressed; run last docs / Compile / managedResources for the full ou
tput
[error] (docs / Compile / managedResources) sbt.internal.util.Init$RuntimeUndefined: References to undefined settings at runtime.
[error] ScopedKey(Scope(Select(ProjectRef(file:/home/rishi/dev/scala/new/scala-js-dom/,jsdocs)), Select(ConfigKey(compile)), Zero, Zero),fullClasspath) referenced from setting(ScopedKey(Scope(Select(ProjectRef(file:/home/rishi/dev/scala/new/scala-js-dom/,docs)), Select(ConfigKey(compile)), Zero, Zero),resourceGenerators)) at LinePosition((mdoc.MdocPlugin.projectSettings) MdocPlugin.scala,111)
[error] ScopedKey(Scope(Select(ProjectRef(file:/home/rishi/dev/scala/new/scala-js-dom/,jsdocs)), Select(ConfigKey(compile)), Zero, Zero),scalacOptions) referenced from setting(ScopedKey(Scope(Select(ProjectRef(file:/home/rishi/dev/scala/new/scala-js-dom/,docs)), Select(ConfigKey(compile)), Zero, Zero),resourceGenerators)) at LinePosition((mdoc.MdocPlugin.projectSettings) MdocPlugin.scala,111)
[error] Total time: 1 s, completed Feb 20, 2023, 12:27:59 AM

zetashift avatar Feb 19 '23 23:02 zetashift

We now have our first runnable demo!

Things to do

  • Is the current way of making a demo good enough?
    • if so change all the other demos as well
  • style the page
  • hook it up to CI/CD things

zetashift avatar Feb 20 '23 00:02 zetashift

So the current websocket demo that's commented out, makes mdoc crash with the following:

info: Compiling 1 file to /home/rishi/dev/scala/scala-js-dom/mdocs/target/mdoc
error:
  Could not generate function for JS function: Found a non-private field value input$3 in final <synthetic> class anonfun$echoWebSocket$1$2 extends scala.scalajs.js.Function with scala.scalajs.js.Function1 {
  final def apply(arg1: org.scalajs.dom.Event): Unit = anonfun$echoWebSocket$1$2.this.input$3.onkeyup_=({
    (new <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1>(anonfun$echoWebSocket$1$2.this): scala.scalajs.js.Function1)
  });
  final <bridge> <artifact> def apply(arg1: Object): Object = {
    anonfun$echoWebSocket$1$2.this.apply(arg1.$asInstanceOf[org.scalajs.dom.Event]());
    scala.runtime.BoxedUnit.UNIT
  };
  <synthetic> <paramaccessor> val input$3: org.scalajs.dom.HTMLInputElement = _;
  <synthetic> <paramaccessor> val socket$1: org.scalajs.dom.WebSocket = _;
  def <init>(input$3: org.scalajs.dom.HTMLInputElement, socket$1: org.scalajs.dom.WebSocket): <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1> = {
    anonfun$echoWebSocket$1$2.this.input$3 = input$3;
    anonfun$echoWebSocket$1$2.this.socket$1 = socket$1;
    anonfun$echoWebSocket$1$2.super.<init>(scala.collection.immutable.Nil);
    ()
  }
}
     while compiling: readme.md
        during phase: jscode
     library version: version 2.13.6
    compiler version: version 2.13.6
  reconstructed args: -deprecation -feature -unchecked -Wconf:cat=feature:w -Wconf:cat=deprecation:w -Wconf:cat=unchecked:w -Wconf:cat=deprecation:w -Wconf:cat=deprecation:ws -Wconf:cat=feature:ws -Wconf:cat=optimizer:ws -Wunused:imports -Wunused:patvars -Wunused:locals -Wunused:implicits -classpath /home/rishi/dev/scala/scala-js-dom/mdocs-js/target/scala-2.13/classes:/home/rishi/dev/scala/scala-js-dom/dom/target/scala-2.13/classes:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.6/scala-library-2.13.6.jar:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-js/scalajs-library_2.13/1.7.1/scalajs-library_2.13-1.7.1.jar -Xmaxerrs -1 -Xmaxwarns -1 -Xplugin:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-js/scalajs-compiler_2.13.6/1.7.1/scalajs-compiler_2.13.6-1.7.1.jar -Xplugin:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.13.6/4.6.0/semanticdb-scalac_2.13.6-4.6.0.jar -Yrangepos -Ydelambdafy:inline -P:semanticdb:targetroot:/home/rishi/dev/scala/scala-js-dom/mdocs-js/target/scala-2.13/meta

  last tree to typer: TypeTree(class Event)
       tree position: line 140 of readme.md
            tree tpe: org.scalajs.dom.Event
              symbol: class Event in package dom
   symbol definition: class Event extends Object (a ClassSymbol)
      symbol package: org.scalajs.dom
       symbol owners: class Event
           call site: <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1> in package <empty>

== Source file context for tree position ==

   137 }
   138 @_root_.scala.scalajs.js.annotation.JSExportTopLevel("mdoc_js_run13")
   139 def run13(node: _root_.org.scalajs.dom.html.Element): Unit = {
   140 document.getElementById("demo7-btn").addEventListener("click", (ev: Event) => {
   141   changeColor(document.getElementById("demo7-text").asInstanceOf[html.Div])
   142 })
   143 }
error: Error while emitting readme.md

  Could not generate function for JS function: Found a non-private field value input$3 in final <synthetic> class anonfun$echoWebSocket$1$2 extends scala.scalajs.js.Function with scala.scalajs.js.Function1 {
  final def apply(arg1: org.scalajs.dom.Event): Unit = anonfun$echoWebSocket$1$2.this.input$3.onkeyup_=({
    (new <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1>(anonfun$echoWebSocket$1$2.this): scala.scalajs.js.Function1)
  });
  final <bridge> <artifact> def apply(arg1: Object): Object = {
    anonfun$echoWebSocket$1$2.this.apply(arg1.$asInstanceOf[org.scalajs.dom.Event]());
    scala.runtime.BoxedUnit.UNIT
  };
  <synthetic> <paramaccessor> val input$3: org.scalajs.dom.HTMLInputElement = _;
  <synthetic> <paramaccessor> val socket$1: org.scalajs.dom.WebSocket = _;
  def <init>(input$3: org.scalajs.dom.HTMLInputElement, socket$1: org.scalajs.dom.WebSocket): <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1> = {
    anonfun$echoWebSocket$1$2.this.input$3 = input$3;
    anonfun$echoWebSocket$1$2.this.socket$1 = socket$1;
    anonfun$echoWebSocket$1$2.super.<init>(scala.collection.immutable.Nil);
    ()
  }
}
     while compiling: readme.md
        during phase: jscode
     library version: version 2.13.6
    compiler version: version 2.13.6
  reconstructed args: -deprecation -feature -unchecked -Wconf:cat=feature:w -Wconf:cat=deprecation:w -Wconf:cat=unchecked:w -Wconf:cat=deprecation:w -Wconf:cat=deprecation:ws -Wconf:cat=feature:ws -Wconf:cat=optimizer:ws -Wunused:imports -Wunused:patvars -Wunused:locals -Wunused:implicits -classpath /home/rishi/dev/scala/scala-js-dom/mdocs-js/target/scala-2.13/classes:/home/rishi/dev/scala/scala-js-dom/dom/target/scala-2.13/classes:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.6/scala-library-2.13.6.jar:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-js/scalajs-library_2.13/1.7.1/scalajs-library_2.13-1.7.1.jar -Xmaxerrs -1 -Xmaxwarns -1 -Xplugin:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-js/scalajs-compiler_2.13.6/1.7.1/scalajs-compiler_2.13.6-1.7.1.jar -Xplugin:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.13.6/4.6.0/semanticdb-scalac_2.13.6-4.6.0.jar -Yrangepos -Ydelambdafy:inline -P:semanticdb:targetroot:/home/rishi/dev/scala/scala-js-dom/mdocs-js/target/scala-2.13/meta

  last tree to typer: TypeTree(class Event)
       tree position: line 140 of readme.md
            tree tpe: org.scalajs.dom.Event
              symbol: class Event in package dom
   symbol definition: class Event extends Object (a ClassSymbol)
      symbol package: org.scalajs.dom
       symbol owners: class Event
           call site: <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1> in package <empty>

== Source file context for tree position ==

   137 }
   138 @_root_.scala.scalajs.js.annotation.JSExportTopLevel("mdoc_js_run13")
   139 def run13(node: _root_.org.scalajs.dom.html.Element): Unit = {
   140 document.getElementById("demo7-btn").addEventListener("click", (ev: Event) => {
   141   changeColor(document.getElementById("demo7-text").asInstanceOf[html.Div])
   142 })
   143 }
warning: readme.md:198:1: local method echoWebSocket in method run11 is never used
def echoWebSocket(input: html.Input, pre: html.Pre) = {

zetashift avatar Feb 27 '23 19:02 zetashift

Is that reproducible outside of mdoc?

sjrd avatar Feb 27 '23 20:02 sjrd

Is that reproducible outside of mdoc?

I don't think so:

I tried the following:

//> using platform "scala-js"
//> using scala "3.2.2"
//> using dep "org.scala-js::scalajs-dom::2.4.0"

import org.scalajs.dom.*

@main def echo() =
  val echo = "wss://echo.websocket.org"
  val socket = new WebSocket(echo)

  socket.onmessage = (e: MessageEvent) => println(e.data.toString)
  socket.onopen = (e: Event) => println("Connected")

And it compiles fine

zetashift avatar Feb 27 '23 21:02 zetashift

It seems to be an mdoc thing:

This works:

def addInput(input: html.Input, socket: WebSocket) = {
  input.onkeyup = (e: Event) => socket.send(input.value)
}

def echoWebSocket(input: html.Input, pre: html.Pre) = {
  val echo = "wss://echo.websocket.org"
  val socket = new WebSocket(echo)
  socket.onmessage = {
    (e: MessageEvent) =>
      pre.textContent +=
        e.data.toString
  }

  socket.onopen = (e: Event) => addInput(input, socket)
}

But this doesn't work(notice that everything in onopen is defined in the function body):

def echoWebSocket(input: html.Input, pre: html.Pre) = {
  val echo = "wss://echo.websocket.org"
  val socket = new WebSocket(echo)
  socket.onmessage = {
    (e: MessageEvent) =>
      pre.textContent +=
        e.data.toString
  }

  socket.onopen = { (e: Event) =>
    input.addEventListener("onkeyup", { (e: Event) =>
      socket.send(input.value)
    })
  }
}

EDIT: will try to report this to mdoc with an easier to follow example :P

zetashift avatar Feb 27 '23 22:02 zetashift

@armanbilge The content for the readme is now reviewable, all the examples are "interactive". I removed the websocket example because the websocket echo server is not working (they shut it down). And it had mdoc troubles anyway. But I did save my progress here in case we find an alternative websocket server. From googling around I couldn't find a replacement.

Things to do:

  • figure out the whole CI/CD deploy thing
  • I have no idea how to style the eventual page that will because the docs

zetashift avatar Mar 11 '23 20:03 zetashift

I removed the websocket example because the websocket echo server is not working

there's a new one from postman you can use, see https://http4s.github.io/http4s-dom/websocket.html

I can look into CI deploy and styling :)

Thanks for all your work on this!!

armanbilge avatar Mar 11 '23 20:03 armanbilge

there's a new one from postman you can use, see https://http4s.github.io/http4s-dom/websocket.html

Actually I found that one in my quest for example servers, but it didn't work for me, it gave back a 101 switching protocols. But this probably means I did something wrong lol, I'll get on it tomorrow again

zetashift avatar Mar 11 '23 21:03 zetashift

One other idea I had along these lines, is that we can deploy the rendered markdown and JS to a branch on this repo. Then the scala-js-website repo could include that as git submodule, so it's deployed as part of the scala-js.org site. We can setup dependabot to automatically open PRs on scala-js-website when there are changes to the site here. Depends what @sjrd thinks of this, of course :)

What is supposed to be the benefit of publishing inside scala-js.org as opposed to the GH Pages of this repo? It seems like a lot of infrastructure for a questionable benefit.

sjrd avatar Mar 17 '23 12:03 sjrd

It seems like a lot of infrastructure

Well, depends who you ask :)

The only "infrastructure" I'm proposing is (1) a git submodule and (2) ~ 3 lines of dependabot YAML.

The alternative is that we maintain all the "infrastructure" to configure and deploy a fully-styled site from this repository. In comparison it seems like a lot more work, at least to me!

armanbilge avatar Mar 17 '23 15:03 armanbilge

Yea I was also unsure about the run buttons, but since the current docs has them, I didn't even think about just removing them lol.

As for the infrastructure, at first the git submodule sounded like a lot of things as well, because well, weaving in a git submodule into another repo sounds like a lot of work. But reading your explanation it does sound like less work? Handling all the infra here does seem like starting from scratch.

zetashift avatar Mar 19 '23 12:03 zetashift

weaving in a git submodule into another repo sounds like a lot of work

git submodule add https://github.com/scala-js/scala-js-dom

Then we add a dependabot config like this: https://github.com/typelevel/cats-effect/blob/fb35b3f85d03cb5d33eb5e12ceb4d3f179346783/.github/dependabot.yml#L3-L8

All this would be doing is placing the index.md with our docs as a page in the scala-js.org website. It would basically be the same if we just manually copied that page in.

armanbilge avatar Mar 19 '23 12:03 armanbilge

I opened a PR against scala-js-website showing how my proposal would work.

  • https://github.com/scala-js/scala-js-website/pull/609

armanbilge avatar Mar 29 '23 05:03 armanbilge

I opened a PR against scala-js-website showing how my proposal would work.

* [Add scala-js-dom docs as submodule scala-js-website#609](https://github.com/scala-js/scala-js-website/pull/609)

That does look quite simple, nice! Let's see if sjrd agrees :P

zetashift avatar Mar 29 '23 15:03 zetashift

@sjrd polite bump? :)

armanbilge avatar May 11 '23 15:05 armanbilge