Refactor jupyter integratin

This commit is contained in:
Alexander Nozik 2023-07-19 22:25:32 +03:00
parent 04b4a12946
commit 8b25761dc6
28 changed files with 264 additions and 190 deletions

View File

@ -13,7 +13,7 @@ val fxVersion by extra("11")
allprojects { allprojects {
group = "space.kscience" group = "space.kscience"
version = "0.3.0-dev-10" version = "0.3.0-dev-11"
} }
subprojects { subprojects {

View File

@ -47,12 +47,11 @@ kotlin {
val commonMain by getting { val commonMain by getting {
dependencies { dependencies {
implementation(projects.visionforgeSolid) implementation(projects.visionforgeSolid)
implementation(projects.visionforgeGdml)
implementation(projects.visionforgePlotly) implementation(projects.visionforgePlotly)
implementation(projects.visionforgeMarkdown) implementation(projects.visionforgeMarkdown)
implementation(projects.visionforgeTables) implementation(projects.visionforgeTables)
implementation(projects.cernRootLoader) implementation(projects.cernRootLoader)
implementation(projects.jupyter) implementation(projects.visionforgeJupyter.visionforgeJupyterCommon)
} }
} }
@ -66,6 +65,8 @@ kotlin {
val jvmMain by getting { val jvmMain by getting {
dependencies { dependencies {
implementation("io.ktor:ktor-server-cio:${spclibs.versions.ktor.get()}")
implementation(projects.visionforgeGdml)
implementation(projects.visionforgeServer) implementation(projects.visionforgeServer)
implementation(spclibs.logback.classic) implementation(spclibs.logback.classic)
implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6") implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6")

View File

@ -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
}

View File

@ -2,15 +2,11 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": null,
"metadata": { "metadata": {
"tags": [], "tags": [],
"pycharm": { "pycharm": {
"is_executing": true "is_executing": true
},
"ExecuteTime": {
"end_time": "2023-05-29T15:22:37.933397300Z",
"start_time": "2023-05-29T15:22:37.913872100Z"
} }
}, },
"outputs": [], "outputs": [],
@ -18,57 +14,23 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": null,
"metadata": { "metadata": {},
"ExecuteTime": { "outputs": [],
"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"
]
}
],
"source": [ "source": [
"vf.startServer()" "vf.startServer()"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": null,
"metadata": { "metadata": {
"collapsed": false, "collapsed": false,
"jupyter": { "jupyter": {
"outputs_hidden": false "outputs_hidden": false
},
"ExecuteTime": {
"end_time": "2023-05-29T15:22:51.410680600Z",
"start_time": "2023-05-29T15:22:51.250779400Z"
} }
}, },
"outputs": [ "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"
]
}
],
"source": [ "source": [
"import kotlinx.coroutines.*\n", "import kotlinx.coroutines.*\n",
"import kotlin.random.Random\n", "import kotlin.random.Random\n",

View File

@ -1,5 +1,5 @@
import space.kscience.dataforge.misc.DFExperimental 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.markup.MarkupPlugin
import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.plotly.PlotlyPlugin
import space.kscience.visionforge.ring.ThreeWithControlsPlugin import space.kscience.visionforge.ring.ThreeWithControlsPlugin
@ -12,5 +12,5 @@ fun main() = runVisionClient {
plugin(PlotlyPlugin) plugin(PlotlyPlugin)
plugin(MarkupPlugin) plugin(MarkupPlugin)
plugin(TableVisionJsPlugin) plugin(TableVisionJsPlugin)
plugin(VFNotebookPlugin) plugin(VFNotebookClient)
} }

View File

@ -8,13 +8,15 @@ kscience {
// useSerialization { // useSerialization {
// json() // json()
// } // }
useKtor()
dependencies{ dependencies{
implementation("io.ktor:ktor-server-cio")
implementation(projects.visionforgeThreejs.visionforgeThreejsServer) 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 { application {
mainClass.set("ru.mipt.npm.sat.SatServerKt") mainClass.set("ru.mipt.npm.sat.SatServerKt")

View File

@ -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")
}
```

View File

@ -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)
}

View File

@ -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<Gdml> { gdmlModel ->
handler.produceHtml {
vision { gdmlModel.toVision() }
}
}
}
}

View File

@ -1,3 +0,0 @@
const ringConfig = require('@jetbrains/ring-ui/webpack.config').config;
config.module.rules.push(...ringConfig.module.rules)

View File

@ -64,6 +64,6 @@ include(
":demo:playground", ":demo:playground",
// ":demo:plotly-fx", // ":demo:plotly-fx",
":demo:js-playground", ":demo:js-playground",
":jupyter", ":visionforge-jupyter",
":jupyter:visionforge-jupyter-gdml" ":visionforge-jupyter:visionforge-jupyter-common"
) )

View File

@ -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 = { public fun styleSheetHeader(href: String, block: LINK.() -> Unit = {}): HtmlFragment = {
link { link {

View File

@ -5,6 +5,7 @@ plugins {
description = "Common visionforge jupyter module" description = "Common visionforge jupyter module"
kscience { kscience {
useKtor()
jvm() jvm()
js() js()
jupyterLibrary() jupyterLibrary()
@ -12,6 +13,7 @@ kscience {
api(projects.visionforgeCore) api(projects.visionforgeCore)
} }
dependencies(jvmMain){ dependencies(jvmMain){
api("io.ktor:ktor-server-cio")
api(projects.visionforgeServer) api(projects.visionforgeServer)
} }
} }

View File

@ -13,7 +13,7 @@ import space.kscience.visionforge.renderAllVisionsById
import space.kscience.visionforge.renderAllVisionsIn import space.kscience.visionforge.renderAllVisionsIn
@JsExport @JsExport
public class VFNotebookPlugin : AbstractPlugin() { public class VFNotebookClient : AbstractPlugin() {
private val client by require(VisionClient) private val client by require(VisionClient)
public fun renderAllVisionsIn(element: Element) { public fun renderAllVisionsIn(element: Element) {
@ -39,8 +39,8 @@ public class VFNotebookPlugin : AbstractPlugin() {
override val tag: PluginTag get() = Companion.tag override val tag: PluginTag get() = Companion.tag
@Suppress("NON_EXPORTABLE_TYPE") @Suppress("NON_EXPORTABLE_TYPE")
public companion object : PluginFactory<VFNotebookPlugin> { public companion object : PluginFactory<VFNotebookClient> {
override fun build(context: Context, meta: Meta): VFNotebookPlugin = VFNotebookPlugin() override fun build(context: Context, meta: Meta): VFNotebookClient = VFNotebookClient()
override val tag: PluginTag = PluginTag(name = "vision.notebook", group = PluginTag.DATAFORGE_GROUP) override val tag: PluginTag = PluginTag(name = "vision.notebook", group = PluginTag.DATAFORGE_GROUP)
} }

View File

@ -16,9 +16,7 @@ import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.context.ContextAware
import space.kscience.dataforge.context.info import space.kscience.dataforge.context.info
import space.kscience.dataforge.context.logger import space.kscience.dataforge.context.logger
import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.*
import space.kscience.dataforge.meta.int
import space.kscience.dataforge.meta.string
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.visionforge.Vision import space.kscience.visionforge.Vision
import space.kscience.visionforge.VisionManager 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.html.visionFragment
import space.kscience.visionforge.server.VisionRoute import space.kscience.visionforge.server.VisionRoute
import space.kscience.visionforge.server.serveVisionData import space.kscience.visionforge.server.serveVisionData
import space.kscience.visionforge.visionManager
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.random.Random import kotlin.random.Random
import kotlin.random.nextUInt import kotlin.random.nextUInt
@ -41,9 +38,14 @@ internal fun TagConsumer<*>.renderScriptForId(id: String) {
/** /**
* A handler class that includes a server and common utilities * 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 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 html(block: TagConsumer<*>.() -> Unit): MimeTypedResult = HTML(createHTML().apply(block).finalize())
public fun getProperty(name: String): TypedMeta<*>? = configuration[name] ?: context.properties[name]
public fun startServer( public fun startServer(
host: String = context.properties["visionforge.host"].string ?: "localhost", host: String = getProperty("visionforge.host").string ?: "localhost",
port: Int = context.properties["visionforge.port"].int ?: VisionRoute.DEFAULT_PORT, port: Int = getProperty("visionforge.port").int ?: VisionRoute.DEFAULT_PORT,
): MimeTypedResult = html { ): MimeTypedResult = html {
if (engine != null) { if (engine != null) {
p { p {

View File

@ -18,12 +18,12 @@ import kotlin.random.nextUInt
* A base class for different Jupyter VF integrations * A base class for different Jupyter VF integrations
*/ */
@DFExperimental @DFExperimental
public abstract class VFIntegrationBase( public abstract class VisionForgeIntegration(
public val visionManager: VisionManager, public val visionManager: VisionManager,
) : JupyterIntegration(), ContextAware { ) : JupyterIntegration(), ContextAware {
override val context: Context get() = visionManager.context 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() protected abstract fun Builder.afterLoaded()
@ -33,13 +33,15 @@ public abstract class VFIntegrationBase(
declare("VisionForge" to handler, "vf" to handler) declare("VisionForge" to handler, "vf" to handler)
} }
onShutdown { onShutdown {
handler.stopServer() handler.stopServer()
} }
import( import(
"kotlinx.html.*", "kotlinx.html.*",
"space.kscience.visionforge.html.*" "space.kscience.visionforge.html.*",
"space.kscience.visionforge.jupyter.*"
) )
render<HtmlFragment> { fragment -> render<HtmlFragment> { fragment ->
@ -54,7 +56,6 @@ public abstract class VFIntegrationBase(
handler.produceHtml { handler.produceHtml {
vision(vision) vision(vision)
} }
} }
render<VisionPage> { page -> render<VisionPage> { page ->
@ -94,3 +95,11 @@ public abstract class VFIntegrationBase(
afterLoaded() afterLoaded()
} }
} }
/**
* Create a standalone page in the notebook
*/
public fun VisionForge.page(
pageHeaders: Map<String, HtmlFragment> = emptyMap(),
content: HtmlVisionFragment
): VisionPage = VisionPage(visionManager, pageHeaders, content)

View File

@ -11,11 +11,14 @@ import space.kscience.visionforge.html.VisionOfHtmlForm
public class HtmlFormFragment internal constructor( public class HtmlFormFragment internal constructor(
public val vision: VisionOfHtmlForm, public val vision: VisionOfHtmlForm,
public val formBody: HtmlFragment, public val formBody: HtmlFragment,
){ ) {
public val values: Meta? get() = vision.values public val values: Meta? get() = vision.values
public operator fun get(valueName: String): Meta? = values?.get(valueName) 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 { public fun HtmlFormFragment(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment {
val realId = id ?: "form[${builder.hashCode().toUInt()}]" val realId = id ?: "form[${builder.hashCode().toUInt()}]"
return HtmlFormFragment(VisionOfHtmlForm(realId)) { return HtmlFormFragment(VisionOfHtmlForm(realId)) {
@ -25,3 +28,7 @@ public fun HtmlFormFragment(id: String? = null, builder: FORM.() -> Unit): HtmlF
} }
} }
} }
public fun VisionForge.form(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment =
HtmlFormFragment(id, builder)

View File

@ -2,10 +2,11 @@ plugins {
id("space.kscience.gradle.mpp") id("space.kscience.gradle.mpp")
} }
description = "Jupyter api artifact for GDML rendering" description = "Jupyter api artifact including all common modules"
kscience { kscience {
fullStack("js/gdml-jupyter.js", fullStack(
"js/visionforge-jupyter-common.js",
jsConfig = { useCommonJs() } jsConfig = { useCommonJs() }
) { ) {
commonWebpackConfig { commonWebpackConfig {
@ -16,21 +17,24 @@ kscience {
} }
} }
dependencies{ dependencies {
implementation(projects.visionforgeSolid) implementation(projects.visionforgeSolid)
implementation(projects.jupyter) implementation(projects.visionforgePlotly)
implementation(projects.visionforgeTables)
implementation(projects.visionforgeMarkdown)
implementation(projects.visionforgeJupyter)
} }
dependencies(jvmMain){ jvmMain {
implementation(projects.visionforgeGdml) implementation(projects.visionforgeGdml)
} }
dependencies(jsMain){ jsMain {
implementation(projects.visionforgeThreejs)
implementation(projects.ui.ring) implementation(projects.ui.ring)
implementation(projects.visionforgeThreejs)
} }
jupyterLibrary("space.kscience.visionforge.gdml.jupyter.GdmlForJupyter") jupyterLibrary("space.kscience.visionforge.jupyter.JupyterCommonIntegration")
} }
readme { readme {

View File

@ -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)
}

View File

@ -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 org.jetbrains.kotlinx.jupyter.api.libraries.resources
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import space.kscience.gdml.Gdml import space.kscience.gdml.Gdml
import space.kscience.plotly.Plot import space.kscience.plotly.Plot
import space.kscience.tables.*
import space.kscience.visionforge.gdml.toVision 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.PlotlyPlugin
import space.kscience.visionforge.plotly.asVision import space.kscience.visionforge.plotly.asVision
import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.Solids
import space.kscience.visionforge.tables.TableVisionPlugin
import space.kscience.visionforge.tables.toVision
import space.kscience.visionforge.visionManager import space.kscience.visionforge.visionManager
@DFExperimental @DFExperimental
internal class VisionForgePlayGroundForJupyter : VFIntegrationBase( public class JupyterCommonIntegration : VisionForgeIntegration(CONTEXT.visionManager) {
Context("VisionForge") {
plugin(Solids)
plugin(PlotlyPlugin)
}.visionManager
) {
override fun Builder.afterLoaded() { override fun Builder.afterLoaded() {
resources { resources {
js("VisionForge") { js("three") {
classPath("js/visionforge-playground.js") classPath("js/visionforge-jupyter-common.js")
} }
} }
import( import(
"space.kscience.gdml.*", "space.kscience.gdml.*",
"space.kscience.plotly.*",
"space.kscience.plotly.models.*",
"space.kscience.visionforge.solid.*", "space.kscience.visionforge.solid.*",
"space.kscience.tables.*",
"space.kscience.dataforge.meta.*",
) )
render<Gdml> { gdmlModel -> render<Gdml> { gdmlModel ->
handler.produceHtml { handler.produceHtml {
vision { gdmlModel.toVision() } vision { gdmlModel.toVision() }
} }
} }
render<Table<*>> { table ->
handler.produceHtml {
vision { table.toVision() }
}
}
render<Plot> { plot -> render<Plot> { plot ->
handler.produceHtml { handler.produceHtml {
vision { plot.asVision() } 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)
}
}
} }

View File

@ -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: {}
}
]
}
)

View File

@ -6,7 +6,7 @@ kscience{
useKtor() useKtor()
dependencies { dependencies {
api(projects.visionforgeCore) 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-html-builder")
api("io.ktor:ktor-server-websockets") api("io.ktor:ktor-server-websockets")
implementation("io.ktor:ktor-server-cors") implementation("io.ktor:ktor-server-cors")

View File

@ -2,7 +2,6 @@ package space.kscience.visionforge.server
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.cio.*
import io.ktor.server.engine.* import io.ktor.server.engine.*
import io.ktor.server.html.* import io.ktor.server.html.*
import io.ktor.server.http.content.* import io.ktor.server.http.content.*

View File

@ -246,6 +246,6 @@ public var Solid.scaleZ: Number by float(Z_SCALE_KEY, 1f)
/** /**
* Add rotation with given [angle] relative to given [axis] * 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 quaternion = Quaternion.fromRotation(angle, axis)*quaternion
} }

View File

@ -99,3 +99,8 @@ public inline fun MutableVisionContainer<Solid>.solidGroup(
name: String, name: String,
action: SolidGroup.() -> Unit = {}, action: SolidGroup.() -> Unit = {},
): SolidGroup = solidGroup(name.parseAsName(), action) ): SolidGroup = solidGroup(name.parseAsName(), action)
/**
* Create a [SolidGroup] using given configuration [block]
*/
public inline fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block)

View File

@ -9,9 +9,9 @@ kscience {
js { js {
useCommonJs() useCommonJs()
binaries.library() binaries.library()
browser{ browser {
commonWebpackConfig{ commonWebpackConfig {
cssSupport{ cssSupport {
enabled.set(true) enabled.set(true)
} }
} }
@ -21,13 +21,13 @@ kscience {
api(projects.visionforgeCore) api(projects.visionforgeCore)
api("space.kscience:tables-kt:${tablesVersion}") api("space.kscience:tables-kt:${tablesVersion}")
} }
dependencies(jsMain){ dependencies(jsMain) {
implementation(npm("tabulator-tables", "5.0.1")) implementation(npm("tabulator-tables", "5.4.4"))
implementation(npm("@types/tabulator-tables", "5.0.1")) implementation(npm("@types/tabulator-tables", "5.4.8"))
} }
useSerialization() useSerialization()
} }
readme{ readme {
maturity = space.kscience.gradle.Maturity.PROTOTYPE maturity = space.kscience.gradle.Maturity.PROTOTYPE
} }

View File

@ -86,6 +86,11 @@ public fun Table<String>.toVision(): VisionOfTable = toVision { (it ?: "").asVal
@JvmName("numberTableToVision") @JvmName("numberTableToVision")
public fun Table<Number>.toVision(): VisionOfTable = toVision { (it ?: Double.NaN).asValue() } public fun Table<Number>.toVision(): VisionOfTable = toVision { (it ?: Double.NaN).asValue() }
@JvmName("anyTableToVision")
public fun Table<Any?>.toVision(): VisionOfTable = toVision {
(it as? Number)?.asValue() ?: it?.toString()?.asValue() ?: Null
}
@DFExperimental @DFExperimental
public inline fun VisionOutput.table( public inline fun VisionOutput.table(
vararg headers: ColumnHeader<Value>, vararg headers: ColumnHeader<Value>,