From 8b25761dc6a37cd51413641e8374c85707497c53 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 19 Jul 2023 22:25:32 +0300 Subject: [PATCH] Refactor jupyter integratin --- build.gradle.kts | 2 +- demo/playground/build.gradle.kts | 5 +- demo/playground/notebooks/common-demo.ipynb | 104 ++++++++++++++++++ demo/playground/notebooks/dynamic-demo.ipynb | 50 +-------- .../src/jsMain/kotlin/playgroundMain.kt | 4 +- demo/sat-demo/build.gradle.kts | 6 +- jupyter/visionforge-jupyter-gdml/README.md | 32 ------ .../src/jsMain/kotlin/gdmlJupyter.kt | 12 -- .../src/jvmMain/kotlin/GdmlForJupyter.kt | 38 ------- .../webpack.config.d/01.ring.js | 3 - settings.gradle.kts | 4 +- .../kscience/visionforge/html/VisionPage.kt | 2 +- {jupyter => visionforge-jupyter}/README.md | 0 .../build.gradle.kts | 2 + .../src/jsMain/kotlin/VFNotebookClient.kt | 6 +- .../src/jvmMain/kotlin/VisionForge.kt | 22 ++-- .../jvmMain/kotlin/VisionForgeIntegration.kt | 19 +++- .../src/jvmMain/kotlin/forms.kt | 11 +- .../build.gradle.kts | 22 ++-- .../src/jsMain/kotlin/commonJupyter.kt | 17 +++ .../kotlin/JupyterCommonIntegration.kt | 40 ++++--- .../webpack.config.d/01.ring.js | 24 ++++ visionforge-server/build.gradle.kts | 2 +- .../visionforge/server/VisionServer.kt | 1 - .../space/kscience/visionforge/solid/Solid.kt | 2 +- .../kscience/visionforge/solid/SolidGroup.kt | 5 + visionforge-tables/build.gradle.kts | 14 +-- .../visionforge/tables/VisionOfTable.kt | 5 + 28 files changed, 264 insertions(+), 190 deletions(-) create mode 100644 demo/playground/notebooks/common-demo.ipynb delete mode 100644 jupyter/visionforge-jupyter-gdml/README.md delete mode 100644 jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt delete mode 100644 jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt delete mode 100644 jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js rename {jupyter => visionforge-jupyter}/README.md (100%) rename {jupyter => visionforge-jupyter}/build.gradle.kts (86%) rename jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt => visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt (90%) rename jupyter/src/jvmMain/kotlin/VFForNotebook.kt => visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt (88%) rename jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt => visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt (85%) rename {jupyter => visionforge-jupyter}/src/jvmMain/kotlin/forms.kt (82%) rename {jupyter/visionforge-jupyter-gdml => visionforge-jupyter/visionforge-jupyter-common}/build.gradle.kts (53%) create mode 100644 visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt rename demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt => visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt (51%) create mode 100644 visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js diff --git a/build.gradle.kts b/build.gradle.kts index 8997eeda..73f03bbd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-10" + version = "0.3.0-dev-11" } subprojects { diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index ddc1d6a8..77dd565e 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -47,12 +47,11 @@ kotlin { val commonMain by getting { dependencies { implementation(projects.visionforgeSolid) - implementation(projects.visionforgeGdml) implementation(projects.visionforgePlotly) implementation(projects.visionforgeMarkdown) implementation(projects.visionforgeTables) implementation(projects.cernRootLoader) - implementation(projects.jupyter) + implementation(projects.visionforgeJupyter.visionforgeJupyterCommon) } } @@ -66,6 +65,8 @@ kotlin { val jvmMain by getting { dependencies { + implementation("io.ktor:ktor-server-cio:${spclibs.versions.ktor.get()}") + implementation(projects.visionforgeGdml) implementation(projects.visionforgeServer) implementation(spclibs.logback.classic) implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6") diff --git a/demo/playground/notebooks/common-demo.ipynb b/demo/playground/notebooks/common-demo.ipynb new file mode 100644 index 00000000..73409ae7 --- /dev/null +++ b/demo/playground/notebooks/common-demo.ipynb @@ -0,0 +1,104 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "@file:Repository(\"*mavenLocal\")\n", + "@file:Repository(\"https://repo.kotlin.link\")\n", + "@file:Repository(\"https://maven.pkg.jetbrains.space/spc/p/sci/dev\")\n", + "@file:DependsOn(\"space.kscience:visionforge-jupyter-common-jvm:0.3.0-dev-11\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + ":classpath" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "vf.startServer()" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "import space.kscience.visionforge.plotly.plotly\n", + "\n", + "vf.page {\n", + " h1 { +\"AAA\" }\n", + " vision {\n", + " solid {\n", + " ambientLight()\n", + " box(100, 100, 200)\n", + "\n", + " sphere(100) {\n", + " x = 300\n", + " }\n", + " }\n", + " }\n", + "\n", + " vision {\n", + " plotly {\n", + " scatter {\n", + " x(1, 2, 3, 1)\n", + " y(1, 2, 3, 4)\n", + " }\n", + " }\n", + " }\n", + "}" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [], + "metadata": { + "collapsed": false + } + } + ], + "metadata": { + "kernelspec": { + "display_name": "Kotlin", + "language": "kotlin", + "name": "kotlin" + }, + "language_info": { + "name": "kotlin", + "version": "1.8.20", + "mimetype": "text/x-kotlin", + "file_extension": ".kt", + "pygments_lexer": "kotlin", + "codemirror_mode": "text/x-kotlin", + "nbconvert_exporter": "" + }, + "ktnbPluginMetadata": { + "isAddProjectLibrariesToClasspath": false + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/demo/playground/notebooks/dynamic-demo.ipynb b/demo/playground/notebooks/dynamic-demo.ipynb index 41289185..ac70b4c2 100644 --- a/demo/playground/notebooks/dynamic-demo.ipynb +++ b/demo/playground/notebooks/dynamic-demo.ipynb @@ -2,15 +2,11 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "tags": [], "pycharm": { "is_executing": true - }, - "ExecuteTime": { - "end_time": "2023-05-29T15:22:37.933397300Z", - "start_time": "2023-05-29T15:22:37.913872100Z" } }, "outputs": [], @@ -18,57 +14,23 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": { - "ExecuteTime": { - "end_time": "2023-05-29T15:22:50.486483300Z", - "start_time": "2023-05-29T15:22:50.457485500Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Line_2.jupyter.kts (1:1 - 3) Unresolved reference: vf" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "vf.startServer()" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false - }, - "ExecuteTime": { - "end_time": "2023-05-29T15:22:51.410680600Z", - "start_time": "2023-05-29T15:22:51.250779400Z" } }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Line_3.jupyter.kts (1:16 - 26) Unresolved reference: coroutines\n", - "Line_3.jupyter.kts (4:1 - 7) Unresolved reference: Plotly\n", - "Line_3.jupyter.kts (5:5 - 12) Unresolved reference: scatter\n", - "Line_3.jupyter.kts (6:9 - 10) Unresolved reference: x\n", - "Line_3.jupyter.kts (7:9 - 10) Unresolved reference: y\n", - "Line_3.jupyter.kts (8:12 - 14) Unresolved reference: vf\n", - "Line_3.jupyter.kts (9:13 - 15) Unresolved reference: vf\n", - "Line_3.jupyter.kts (10:23 - 31) Unresolved reference: isActive\n", - "Line_3.jupyter.kts (11:21 - 26) Unresolved reference: delay\n", - "Line_3.jupyter.kts (12:21 - 22) Unresolved reference: y" - ] - } - ], + "outputs": [], "source": [ "import kotlinx.coroutines.*\n", "import kotlin.random.Random\n", diff --git a/demo/playground/src/jsMain/kotlin/playgroundMain.kt b/demo/playground/src/jsMain/kotlin/playgroundMain.kt index 8e259d48..feff4de1 100644 --- a/demo/playground/src/jsMain/kotlin/playgroundMain.kt +++ b/demo/playground/src/jsMain/kotlin/playgroundMain.kt @@ -1,5 +1,5 @@ import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.jupyter.VFNotebookPlugin +import space.kscience.visionforge.jupyter.VFNotebookClient import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.ring.ThreeWithControlsPlugin @@ -12,5 +12,5 @@ fun main() = runVisionClient { plugin(PlotlyPlugin) plugin(MarkupPlugin) plugin(TableVisionJsPlugin) - plugin(VFNotebookPlugin) + plugin(VFNotebookClient) } \ No newline at end of file diff --git a/demo/sat-demo/build.gradle.kts b/demo/sat-demo/build.gradle.kts index 6afadf27..5e881b63 100644 --- a/demo/sat-demo/build.gradle.kts +++ b/demo/sat-demo/build.gradle.kts @@ -8,13 +8,15 @@ kscience { // useSerialization { // json() // } + useKtor() dependencies{ + implementation("io.ktor:ktor-server-cio") implementation(projects.visionforgeThreejs.visionforgeThreejsServer) - implementation("ch.qos.logback:logback-classic:1.4.5") + implementation(spclibs.logback.classic) } } -group = "ru.mipt.npm" +group = "center.sciprog" application { mainClass.set("ru.mipt.npm.sat.SatServerKt") diff --git a/jupyter/visionforge-jupyter-gdml/README.md b/jupyter/visionforge-jupyter-gdml/README.md deleted file mode 100644 index cae8af86..00000000 --- a/jupyter/visionforge-jupyter-gdml/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Module visionforge-jupyter-gdml - -Jupyter api artifact for GDML rendering - -## Usage - -## Artifact: - -The Maven coordinates of this project are `space.kscience:visionforge-jupyter-gdml:0.2.0`. - -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:visionforge-jupyter-gdml:0.2.0' -} -``` -**Gradle Kotlin DSL:** -```kotlin -repositories { - maven("https://repo.kotlin.link") - mavenCentral() -} - -dependencies { - implementation("space.kscience:visionforge-jupyter-gdml:0.2.0") -} -``` diff --git a/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt b/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt deleted file mode 100644 index d4ee507e..00000000 --- a/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt +++ /dev/null @@ -1,12 +0,0 @@ -package space.kscience.visionforge.gdml.jupyter - -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.ring.ThreeWithControlsPlugin -import space.kscience.visionforge.runVisionClient - -@DFExperimental -@JsExport -public fun main(): Unit = runVisionClient { - plugin(ThreeWithControlsPlugin) -} - diff --git a/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt b/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt deleted file mode 100644 index 0d55be2e..00000000 --- a/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt +++ /dev/null @@ -1,38 +0,0 @@ -package space.kscience.visionforge.gdml.jupyter - -import org.jetbrains.kotlinx.jupyter.api.libraries.resources -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.gdml.Gdml -import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.jupyter.VFIntegrationBase -import space.kscience.visionforge.solid.Solids -import space.kscience.visionforge.visionManager - -@DFExperimental -internal class GdmlForJupyter : VFIntegrationBase( - Context("GDML") { - plugin(Solids) - }.visionManager -) { - - override fun Builder.afterLoaded() { - - resources { - js("three") { - classPath("js/gdml-jupyter.js") - } - } - - import( - "space.kscience.gdml.*", - "space.kscience.visionforge.gdml.jupyter.*" - ) - - render { gdmlModel -> - handler.produceHtml { - vision { gdmlModel.toVision() } - } - } - } -} diff --git a/jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js b/jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js deleted file mode 100644 index 41da041c..00000000 --- a/jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js +++ /dev/null @@ -1,3 +0,0 @@ -const ringConfig = require('@jetbrains/ring-ui/webpack.config').config; - -config.module.rules.push(...ringConfig.module.rules) \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index e9e3deba..31119a06 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -64,6 +64,6 @@ include( ":demo:playground", // ":demo:plotly-fx", ":demo:js-playground", - ":jupyter", - ":jupyter:visionforge-jupyter-gdml" + ":visionforge-jupyter", + ":visionforge-jupyter:visionforge-jupyter-common" ) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt index de18ced5..f92454f0 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt @@ -26,7 +26,7 @@ public data class VisionPage( } /** - * Use css with given stylesheet link as a global header for all pages. + * Use css with the given stylesheet link as a global header for all pages. */ public fun styleSheetHeader(href: String, block: LINK.() -> Unit = {}): HtmlFragment = { link { diff --git a/jupyter/README.md b/visionforge-jupyter/README.md similarity index 100% rename from jupyter/README.md rename to visionforge-jupyter/README.md diff --git a/jupyter/build.gradle.kts b/visionforge-jupyter/build.gradle.kts similarity index 86% rename from jupyter/build.gradle.kts rename to visionforge-jupyter/build.gradle.kts index 5808f287..ed4ab76d 100644 --- a/jupyter/build.gradle.kts +++ b/visionforge-jupyter/build.gradle.kts @@ -5,6 +5,7 @@ plugins { description = "Common visionforge jupyter module" kscience { + useKtor() jvm() js() jupyterLibrary() @@ -12,6 +13,7 @@ kscience { api(projects.visionforgeCore) } dependencies(jvmMain){ + api("io.ktor:ktor-server-cio") api(projects.visionforgeServer) } } diff --git a/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt similarity index 90% rename from jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt rename to visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt index f6a37f23..24304136 100644 --- a/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt +++ b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt @@ -13,7 +13,7 @@ import space.kscience.visionforge.renderAllVisionsById import space.kscience.visionforge.renderAllVisionsIn @JsExport -public class VFNotebookPlugin : AbstractPlugin() { +public class VFNotebookClient : AbstractPlugin() { private val client by require(VisionClient) public fun renderAllVisionsIn(element: Element) { @@ -39,8 +39,8 @@ public class VFNotebookPlugin : AbstractPlugin() { override val tag: PluginTag get() = Companion.tag @Suppress("NON_EXPORTABLE_TYPE") - public companion object : PluginFactory { - override fun build(context: Context, meta: Meta): VFNotebookPlugin = VFNotebookPlugin() + public companion object : PluginFactory { + override fun build(context: Context, meta: Meta): VFNotebookClient = VFNotebookClient() override val tag: PluginTag = PluginTag(name = "vision.notebook", group = PluginTag.DATAFORGE_GROUP) } diff --git a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt similarity index 88% rename from jupyter/src/jvmMain/kotlin/VFForNotebook.kt rename to visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt index 50619e44..0a538a3e 100644 --- a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt @@ -16,9 +16,7 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.context.info import space.kscience.dataforge.context.logger -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.int -import space.kscience.dataforge.meta.string +import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager @@ -26,7 +24,6 @@ import space.kscience.visionforge.html.HtmlVisionFragment import space.kscience.visionforge.html.visionFragment import space.kscience.visionforge.server.VisionRoute import space.kscience.visionforge.server.serveVisionData -import space.kscience.visionforge.visionManager import kotlin.coroutines.CoroutineContext import kotlin.random.Random import kotlin.random.nextUInt @@ -41,9 +38,14 @@ internal fun TagConsumer<*>.renderScriptForId(id: String) { /** * A handler class that includes a server and common utilities */ -public class VFForNotebook(override val context: Context) : ContextAware, CoroutineScope { +public class VisionForge( + public val visionManager: VisionManager, + meta: Meta = Meta.EMPTY, +) : ContextAware, CoroutineScope { - public val visionManager: VisionManager = context.visionManager + override val context: Context get() = visionManager.context + + public val configuration: ObservableMutableMeta = meta.toMutableMeta() private var counter = 0 @@ -61,9 +63,11 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout public fun html(block: TagConsumer<*>.() -> Unit): MimeTypedResult = HTML(createHTML().apply(block).finalize()) + public fun getProperty(name: String): TypedMeta<*>? = configuration[name] ?: context.properties[name] + public fun startServer( - host: String = context.properties["visionforge.host"].string ?: "localhost", - port: Int = context.properties["visionforge.port"].int ?: VisionRoute.DEFAULT_PORT, + host: String = getProperty("visionforge.host").string ?: "localhost", + port: Int = getProperty("visionforge.port").int ?: VisionRoute.DEFAULT_PORT, ): MimeTypedResult = html { if (engine != null) { p { @@ -141,4 +145,4 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout public fun form(builder: FORM.() -> Unit): HtmlFormFragment = HtmlFormFragment("form[${counter++}]", builder = builder) -} \ No newline at end of file +} diff --git a/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt similarity index 85% rename from jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt rename to visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt index bf6322e9..3029ef32 100644 --- a/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt @@ -18,12 +18,12 @@ import kotlin.random.nextUInt * A base class for different Jupyter VF integrations */ @DFExperimental -public abstract class VFIntegrationBase( +public abstract class VisionForgeIntegration( public val visionManager: VisionManager, ) : JupyterIntegration(), ContextAware { override val context: Context get() = visionManager.context - protected val handler: VFForNotebook = VFForNotebook(visionManager.context) + protected val handler: VisionForge = VisionForge(visionManager) protected abstract fun Builder.afterLoaded() @@ -33,13 +33,15 @@ public abstract class VFIntegrationBase( declare("VisionForge" to handler, "vf" to handler) } + onShutdown { handler.stopServer() } import( "kotlinx.html.*", - "space.kscience.visionforge.html.*" + "space.kscience.visionforge.html.*", + "space.kscience.visionforge.jupyter.*" ) render { fragment -> @@ -54,7 +56,6 @@ public abstract class VFIntegrationBase( handler.produceHtml { vision(vision) } - } render { page -> @@ -93,4 +94,12 @@ public abstract class VFIntegrationBase( afterLoaded() } -} \ No newline at end of file +} + +/** + * Create a standalone page in the notebook + */ +public fun VisionForge.page( + pageHeaders: Map = emptyMap(), + content: HtmlVisionFragment +): VisionPage = VisionPage(visionManager, pageHeaders, content) \ No newline at end of file diff --git a/jupyter/src/jvmMain/kotlin/forms.kt b/visionforge-jupyter/src/jvmMain/kotlin/forms.kt similarity index 82% rename from jupyter/src/jvmMain/kotlin/forms.kt rename to visionforge-jupyter/src/jvmMain/kotlin/forms.kt index bccce2e7..fe072887 100644 --- a/jupyter/src/jvmMain/kotlin/forms.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/forms.kt @@ -11,11 +11,14 @@ import space.kscience.visionforge.html.VisionOfHtmlForm public class HtmlFormFragment internal constructor( public val vision: VisionOfHtmlForm, public val formBody: HtmlFragment, -){ +) { public val values: Meta? get() = vision.values public operator fun get(valueName: String): Meta? = values?.get(valueName) } +/** + * Top level function to create a form + */ public fun HtmlFormFragment(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment { val realId = id ?: "form[${builder.hashCode().toUInt()}]" return HtmlFormFragment(VisionOfHtmlForm(realId)) { @@ -24,4 +27,8 @@ public fun HtmlFormFragment(id: String? = null, builder: FORM.() -> Unit): HtmlF builder() } } -} \ No newline at end of file +} + + +public fun VisionForge.form(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment = + HtmlFormFragment(id, builder) \ No newline at end of file diff --git a/jupyter/visionforge-jupyter-gdml/build.gradle.kts b/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts similarity index 53% rename from jupyter/visionforge-jupyter-gdml/build.gradle.kts rename to visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts index 5a67459e..c71b33d0 100644 --- a/jupyter/visionforge-jupyter-gdml/build.gradle.kts +++ b/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts @@ -2,10 +2,11 @@ plugins { id("space.kscience.gradle.mpp") } -description = "Jupyter api artifact for GDML rendering" +description = "Jupyter api artifact including all common modules" kscience { - fullStack("js/gdml-jupyter.js", + fullStack( + "js/visionforge-jupyter-common.js", jsConfig = { useCommonJs() } ) { commonWebpackConfig { @@ -16,21 +17,24 @@ kscience { } } - dependencies{ + dependencies { implementation(projects.visionforgeSolid) - implementation(projects.jupyter) + implementation(projects.visionforgePlotly) + implementation(projects.visionforgeTables) + implementation(projects.visionforgeMarkdown) + implementation(projects.visionforgeJupyter) } - dependencies(jvmMain){ + jvmMain { implementation(projects.visionforgeGdml) } - dependencies(jsMain){ - implementation(projects.visionforgeThreejs) + jsMain { implementation(projects.ui.ring) + implementation(projects.visionforgeThreejs) } - - jupyterLibrary("space.kscience.visionforge.gdml.jupyter.GdmlForJupyter") + + jupyterLibrary("space.kscience.visionforge.jupyter.JupyterCommonIntegration") } readme { diff --git a/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt new file mode 100644 index 00000000..e5fb4edd --- /dev/null +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt @@ -0,0 +1,17 @@ +package space.kscience.visionforge.gdml.jupyter + +import space.kscience.visionforge.jupyter.VFNotebookClient +import space.kscience.visionforge.markup.MarkupPlugin +import space.kscience.visionforge.plotly.PlotlyPlugin +import space.kscience.visionforge.ring.ThreeWithControlsPlugin +import space.kscience.visionforge.runVisionClient +import space.kscience.visionforge.tables.TableVisionJsPlugin + +public fun main(): Unit = runVisionClient { + plugin(ThreeWithControlsPlugin) + plugin(PlotlyPlugin) + plugin(MarkupPlugin) + plugin(TableVisionJsPlugin) + plugin(VFNotebookClient) +} + diff --git a/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt similarity index 51% rename from demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt rename to visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt index 0b87e06d..6bca7036 100644 --- a/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt @@ -1,46 +1,52 @@ -package space.kscience.visionforge.examples +package space.kscience.visionforge.jupyter +import kotlinx.html.* import org.jetbrains.kotlinx.jupyter.api.libraries.resources import space.kscience.dataforge.context.Context import space.kscience.dataforge.misc.DFExperimental import space.kscience.gdml.Gdml import space.kscience.plotly.Plot +import space.kscience.tables.* import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.jupyter.VFIntegrationBase +import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.plotly.asVision import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.tables.TableVisionPlugin +import space.kscience.visionforge.tables.toVision import space.kscience.visionforge.visionManager + @DFExperimental -internal class VisionForgePlayGroundForJupyter : VFIntegrationBase( - Context("VisionForge") { - plugin(Solids) - plugin(PlotlyPlugin) - }.visionManager -) { +public class JupyterCommonIntegration : VisionForgeIntegration(CONTEXT.visionManager) { override fun Builder.afterLoaded() { + resources { - js("VisionForge") { - classPath("js/visionforge-playground.js") + js("three") { + classPath("js/visionforge-jupyter-common.js") } } import( "space.kscience.gdml.*", - "space.kscience.plotly.*", - "space.kscience.plotly.models.*", "space.kscience.visionforge.solid.*", + "space.kscience.tables.*", + "space.kscience.dataforge.meta.*", ) - render { gdmlModel -> handler.produceHtml { vision { gdmlModel.toVision() } } } + render> { table -> + handler.produceHtml { + vision { table.toVision() } + } + } + render { plot -> handler.produceHtml { vision { plot.asVision() } @@ -48,4 +54,12 @@ internal class VisionForgePlayGroundForJupyter : VFIntegrationBase( } } + public companion object { + private val CONTEXT: Context = Context("Jupyter-common") { + plugin(Solids) + plugin(PlotlyPlugin) + plugin(TableVisionPlugin) + plugin(MarkupPlugin) + } + } } diff --git a/visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js b/visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js new file mode 100644 index 00000000..cfb15cb8 --- /dev/null +++ b/visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js @@ -0,0 +1,24 @@ +const ringConfig = require('@jetbrains/ring-ui/webpack.config').config; + +const path = require('path'); + +config.module.rules.push(...ringConfig.module.rules) + +config.module.rules.push( + { + test: /\.css$/, + exclude: [ + path.resolve(__dirname, "../../node_modules/@jetbrains/ring-ui") + ], + use: [ + { + loader: 'style-loader', + options: {} + }, + { + loader: 'css-loader', + options: {} + } + ] + } +) \ No newline at end of file diff --git a/visionforge-server/build.gradle.kts b/visionforge-server/build.gradle.kts index a4a7d848..00331969 100644 --- a/visionforge-server/build.gradle.kts +++ b/visionforge-server/build.gradle.kts @@ -6,7 +6,7 @@ kscience{ useKtor() dependencies { api(projects.visionforgeCore) - api("io.ktor:ktor-server-cio") + api("io.ktor:ktor-server-host-common") api("io.ktor:ktor-server-html-builder") api("io.ktor:ktor-server-websockets") implementation("io.ktor:ktor-server-cors") diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 84a87a65..47c5db84 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.server import io.ktor.http.* import io.ktor.server.application.* -import io.ktor.server.cio.* import io.ktor.server.engine.* import io.ktor.server.html.* import io.ktor.server.http.content.* diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index c58b849d..8b719b54 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -246,6 +246,6 @@ public var Solid.scaleZ: Number by float(Z_SCALE_KEY, 1f) /** * Add rotation with given [angle] relative to given [axis] */ -public fun Solid.rotate(angle: Angle, axis: DoubleVector3D) = with(QuaternionField) { +public fun Solid.rotate(angle: Angle, axis: DoubleVector3D): Unit = with(QuaternionField) { quaternion = Quaternion.fromRotation(angle, axis)*quaternion } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index f601a30e..791bb0c9 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -99,3 +99,8 @@ public inline fun MutableVisionContainer.solidGroup( name: String, action: SolidGroup.() -> Unit = {}, ): SolidGroup = solidGroup(name.parseAsName(), action) + +/** + * Create a [SolidGroup] using given configuration [block] + */ +public inline fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block) \ No newline at end of file diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index 23d77912..cf813e6e 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -9,9 +9,9 @@ kscience { js { useCommonJs() binaries.library() - browser{ - commonWebpackConfig{ - cssSupport{ + browser { + commonWebpackConfig { + cssSupport { enabled.set(true) } } @@ -21,13 +21,13 @@ kscience { api(projects.visionforgeCore) api("space.kscience:tables-kt:${tablesVersion}") } - dependencies(jsMain){ - implementation(npm("tabulator-tables", "5.0.1")) - implementation(npm("@types/tabulator-tables", "5.0.1")) + dependencies(jsMain) { + implementation(npm("tabulator-tables", "5.4.4")) + implementation(npm("@types/tabulator-tables", "5.4.8")) } useSerialization() } -readme{ +readme { maturity = space.kscience.gradle.Maturity.PROTOTYPE } \ No newline at end of file diff --git a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt index 20332974..3e4f9da8 100644 --- a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt +++ b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt @@ -86,6 +86,11 @@ public fun Table.toVision(): VisionOfTable = toVision { (it ?: "").asVal @JvmName("numberTableToVision") public fun Table.toVision(): VisionOfTable = toVision { (it ?: Double.NaN).asValue() } +@JvmName("anyTableToVision") +public fun Table.toVision(): VisionOfTable = toVision { + (it as? Number)?.asValue() ?: it?.toString()?.asValue() ?: Null +} + @DFExperimental public inline fun VisionOutput.table( vararg headers: ColumnHeader,