Fix server change generator

This commit is contained in:
2025-02-02 12:41:06 +03:00
parent 4071f2c9cd
commit 63a79a59cd
27 changed files with 139 additions and 640 deletions

View File

@@ -3,8 +3,8 @@
package space.kscience.visionforge.gdml.demo
import androidx.compose.runtime.*
import bootstrap.Container
import bootstrap.Icon
import app.softwork.bootstrapcompose.Container
import app.softwork.bootstrapcompose.Icon
import org.jetbrains.compose.web.ExperimentalComposeWebApi
import org.jetbrains.compose.web.attributes.InputType
import org.jetbrains.compose.web.attributes.name

View File

@@ -3,12 +3,10 @@ package space.kscience.visionforge.gdml.demo
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.Style
import org.jetbrains.compose.web.renderComposable
import org.w3c.dom.Document
import space.kscience.dataforge.context.Context
import space.kscience.gdml.GdmlShowCase
import space.kscience.visionforge.Colors
import space.kscience.visionforge.gdml.toVision
import space.kscience.visionforge.html.Application
import space.kscience.visionforge.html.VisionForgeStyles
import space.kscience.visionforge.html.startApplication
import space.kscience.visionforge.solid.ambientLight
@@ -16,46 +14,39 @@ import space.kscience.visionforge.solid.invoke
import space.kscience.visionforge.solid.three.ThreePlugin
private class GDMLDemoApp : Application {
fun main() = startApplication { document ->
val context = Context("gdml-demo") {
plugin(ThreePlugin)
}
override fun start(document: Document, state: Map<String, Any>) {
val element = document.getElementById("application") ?: error("Element with id 'application' not found on page")
val element = document.getElementById("application") ?: error("Element with id 'application' not found on page")
val vision = GdmlShowCase.cubes().toVision().apply {
ambientLight {
color(Colors.white)
}
}
renderComposable(element) {
Style(VisionForgeStyles)
Style {
"html" {
height(100.percent)
}
"body" {
height(100.percent)
display(DisplayStyle.Flex)
alignItems(AlignItems.Stretch)
}
"#application" {
width(100.percent)
display(DisplayStyle.Flex)
alignItems(AlignItems.Stretch)
}
}
GDMLApp(context, vision)
val vision = GdmlShowCase.cubes().toVision().apply {
ambientLight {
color(Colors.white)
}
}
}
fun main() {
startApplication(::GDMLDemoApp)
}
renderComposable(element) {
Style(VisionForgeStyles)
Style {
"html" {
height(100.percent)
}
"body" {
height(100.percent)
display(DisplayStyle.Flex)
alignItems(AlignItems.Stretch)
}
"#application" {
width(100.percent)
display(DisplayStyle.Flex)
alignItems(AlignItems.Stretch)
}
}
GDMLApp(context, vision)
}
}

View File

@@ -47,7 +47,6 @@ kscience {
}
jsMain {
implementation(projects.visionforgeThreejs)
//implementation(devNpm("webpack-bundle-analyzer", "4.4.0"))
}
}
kotlin {

View File

@@ -54,7 +54,7 @@ kotlin {
val jsMain by getting {
dependencies {
implementation(projects.visionforgeThreejs)
compileOnly(npm("webpack-bundle-analyzer","4.5.0"))
// compileOnly(npm("webpack-bundle-analyzer","4.5.0"))
}
}

View File

@@ -19,7 +19,7 @@ import java.awt.Desktop
import java.nio.file.Path
public suspend fun makeVisionFile(
public fun makeVisionFile(
path: Path? = null,
title: String = "VisionForge page",
resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,

View File

@@ -3,17 +3,22 @@ import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
plugins {
id("space.kscience.gradle.mpp")
alias(spclibs.plugins.ktor)
application
// alias(spclibs.plugins.ktor)
}
group = "center.sciprog"
kscience {
// useSerialization {
// json()
// }
jvm{
withJava()
binaries {
executable {
mainClass.set("ru.mipt.npm.sat.SatServerKt")
}
}
}
jvmMain{
implementation("io.ktor:ktor-server-cio")
@@ -22,10 +27,4 @@ kscience {
}
}
group = "center.sciprog"
kotlin.explicitApi = ExplicitApiMode.Disabled
application {
mainClass.set("ru.mipt.npm.sat.SatServerKt")
}
kotlin.explicitApi = ExplicitApiMode.Disabled

View File

@@ -1,19 +1,17 @@
package space.kscience.visionforge.solid.demo
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.w3c.dom.Document
import space.kscience.visionforge.html.Application
import space.kscience.visionforge.html.startApplication
import space.kscience.visionforge.solid.x
import space.kscience.visionforge.solid.y
import kotlin.random.Random
private class ThreeDemoApp : Application {
override fun start(document: Document, state: Map<String, Any>) {
fun main() {
startApplication { document ->
val element = document.getElementById("demo") ?: error("Element with id 'demo' not found on page")
ThreeDemoGrid(element).run {
@@ -30,7 +28,7 @@ private class ThreeDemoApp : Application {
}
}
launch {
GlobalScope.launch {
while (isActive) {
delay(500)
boxes.forEach { box ->
@@ -41,8 +39,4 @@ private class ThreeDemoApp : Application {
}
}
}
}
fun main() {
startApplication(::ThreeDemoApp)
}

View File

@@ -2,7 +2,6 @@
package space.kscience.plotly.models
import com.benasher44.uuid.uuid4
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import space.kscience.dataforge.meta.*
@@ -13,6 +12,7 @@ import space.kscience.dataforge.names.NameToken
import space.kscience.dataforge.names.asName
import space.kscience.plotly.*
import space.kscience.visionforge.AbstractVision
import space.kscience.visionforge.Vision
import kotlin.js.JsName
import kotlin.properties.ReadOnlyProperty
@@ -718,11 +718,11 @@ public class Hoverlabel : Scheme() {
/**
* A base class for Plotly traces
*
* @param uid an unique identifier for this trace
* @param uid a unique identifier for this trace
*/
@Serializable
public open class Trace(
@Transient internal val uid: NameToken = NameToken("trace", uuid4().leastSignificantBits.toString(16))
@Transient internal val uid: NameToken = NameToken("trace", Vision.randomId())
) : AbstractVision(), MutableMetaProvider, MetaRepr {
override fun get(name: Name): MutableMeta? = properties.get(name)

View File

@@ -1,7 +1,7 @@
package space.kscience.visionforge.plotly
import io.ktor.server.cio.CIO
import io.ktor.server.engine.ApplicationEngine
import io.ktor.server.engine.EmbeddedServer
import io.ktor.server.engine.embeddedServer
import io.ktor.server.http.content.staticResources
import io.ktor.server.routing.routing
@@ -27,7 +27,7 @@ public fun Plotly.servePage(
title: String = "VisionForge Plotly page",
port: Int = 7777,
visionPage: HtmlVisionFragment
): ApplicationEngine = embeddedServer(CIO, port = port) {
): EmbeddedServer<*, *> = embeddedServer(CIO, port = port) {
routing {
staticResources("js", "js", null)
}
@@ -51,7 +51,7 @@ public fun Plotly.serve(
port: Int = 7777,
config: PlotlyConfig = PlotlyConfig(),
makePlot: suspend Plot.() -> Unit,
): ApplicationEngine = embeddedServer(CIO, port = port) {
): EmbeddedServer<*, *> = embeddedServer(CIO, port = port) {
routing {
staticResources("js", "js", null)
}

View File

@@ -62,7 +62,7 @@ include(
":visionforge-jupyter:visionforge-jupyter-common",
":plotly",
":plotly:plotlykt-core",
":plotly:plotly-kt-server",
":plotly:plotlykt-server",
":plotly:plotlykt-script",
":plotly:examples",
// ":plotly:examples:fx-demo",

View File

@@ -1,38 +0,0 @@
package space.kscience.dataforge.meta
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.NameToken
import space.kscience.dataforge.names.plus
/**
* A [Meta] child proxy that creates required nodes on write
*/
public class MutableMetaProxy(
public val upstream: MutableMeta,
public val proxyName: Name
) : MutableMeta {
override val items: Map<NameToken, MutableMeta>
get() = upstream[proxyName]?.items ?: emptyMap()
override var value: Value?
get() = upstream[proxyName]?.value
set(value) {
upstream[proxyName] = value
}
override fun getOrCreate(name: Name): MutableMeta = upstream.getOrCreate(proxyName + name)
override fun set(name: Name, node: Meta?) {
set(proxyName + name, node)
}
override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta)
override fun hashCode(): Int = Meta.hashCode(this)
override fun toString(): String = Meta.toString(this)
}

View File

@@ -62,21 +62,6 @@ public data class VisionChange(
public fun VisionChange.isEmpty(): Boolean = vision == null && properties == null && children == null
//@Serializable
//public sealed interface ChangeVisionEvent : VisionEvent
//
//@Serializable
//@SerialName("sepProperties")
//public data class SetVisionPropertiesEvent(val properties: Meta) : ChangeVisionEvent
//
//@Serializable
//@SerialName("setChild")
//public data class SetVisionChildEvent(val nameToken: NameToken, val vision: Vision?) : ChangeVisionEvent
//
//@Serializable
//@SerialName("setRoot")
//public data class SetRootVisionEvent(val vision: Vision) : ChangeVisionEvent
/**
* An update for a [Vision]
@@ -159,31 +144,9 @@ public class VisionChangeCollector : MutableVisionContainer<Vision> {
public fun collect(visionManager: VisionManager): VisionChange = VisionChange(
vision = vision?.deepCopy(visionManager),
properties = properties,
children = children.mapValues { it.value.collect(visionManager) }
properties = properties.takeIf { !it.isEmpty() },
children = children.takeIf { !it.isEmpty() }?.mapValues { it.value.collect(visionManager) }
)
// private fun build(visionManager: VisionManager): VisionChange = VisionChange(
// vision,
// if (propertyChange.isEmpty()) null else propertyChange,
// if (children.isEmpty()) null else children.mapValues { it.value.build(visionManager) }
// )
//
// /**
// * Isolate collected changes by creating detached copies of given visions
// */
// public fun deepCopy(visionManager: VisionManager): VisionChange = VisionChange(
// vision?.deepCopy(visionManager),
// if (propertyChange.isEmpty()) null else propertyChange.seal(),
// if (children.isEmpty()) null else children.mapValues { it.value.deepCopy(visionManager) }
// )
//
// /**
// * Transform current change directly to Json string without protective copy
// */
// public fun toJsonString(visionManager: VisionManager): String = visionManager.encodeToString(
// build(visionManager)
// )
}
public operator fun VisionChangeCollector.get(name: Name): VisionChangeCollector? = when (name.length) {
@@ -214,9 +177,20 @@ public fun Vision.flowChanges(
coroutineScope {
val collector = VisionChangeCollector()
val mutex = Mutex()
eventFlow.onEach {
collector.consumeEvent(it)
}.launchIn(this)
fun collectVisionEvents(vision: Vision, prefix: Name) {
vision.eventFlow.onEach {
val event = if (prefix.isEmpty()) it else VisionEventForChild(prefix, it)
collector.consumeEvent(event)
}.launchIn(this)
if (vision is VisionGroup<*>) {
vision.visions.forEach { (token, child) ->
collectVisionEvents(child, prefix + token)
}
}
}
collectVisionEvents(this@flowChanges, Name.EMPTY)
if (sendInitial) {
//Send initial vision state

View File

@@ -112,6 +112,7 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta), Vision {
useArrayPolymorphism = false
ignoreUnknownKeys = true
explicitNulls = false
encodeDefaults = false
}
private val visionSerializer: PolymorphicSerializer<Vision> = PolymorphicSerializer(Vision::class)

View File

@@ -1,21 +0,0 @@
# Module visionforge-plotly
## Usage
## Artifact:
The Maven coordinates of this project are `space.kscience:visionforge-plotly:0.4.2`.
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:visionforge-plotly:0.4.2")
}
```

View File

@@ -1,44 +0,0 @@
public final class space/kscience/visionforge/plotly/PlotlyPlugin : space/kscience/visionforge/VisionPlugin {
public static final field Companion Lspace/kscience/visionforge/plotly/PlotlyPlugin$Companion;
public fun <init> ()V
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
}
public final class space/kscience/visionforge/plotly/PlotlyPlugin$Companion : space/kscience/dataforge/context/PluginFactory {
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/visionforge/plotly/PlotlyPlugin;
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
}
public final class space/kscience/visionforge/plotly/VisionOfPlotly : space/kscience/visionforge/Vision {
public static final field Companion Lspace/kscience/visionforge/plotly/VisionOfPlotly$Companion;
public fun <init> (Lspace/kscience/plotly/Plot;)V
public fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;
public final fun getMeta ()Lspace/kscience/dataforge/meta/MutableMeta;
public fun getParent ()Lspace/kscience/visionforge/Vision;
public final fun getPlot ()Lspace/kscience/plotly/Plot;
public fun getProperties ()Lspace/kscience/visionforge/MutableVisionProperties;
public fun setParent (Lspace/kscience/visionforge/Vision;)V
}
public synthetic class space/kscience/visionforge/plotly/VisionOfPlotly$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lspace/kscience/visionforge/plotly/VisionOfPlotly$$serializer;
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/visionforge/plotly/VisionOfPlotly;
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/visionforge/plotly/VisionOfPlotly;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}
public final class space/kscience/visionforge/plotly/VisionOfPlotly$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class space/kscience/visionforge/plotly/VisionOfPlotlyKt {
public static final fun asVision (Lspace/kscience/plotly/Plot;)Lspace/kscience/visionforge/plotly/VisionOfPlotly;
public static final fun plotly (Lspace/kscience/visionforge/html/VisionOutput;Lspace/kscience/plotly/PlotlyConfig;Lkotlin/jvm/functions/Function1;)Lspace/kscience/visionforge/plotly/VisionOfPlotly;
public static synthetic fun plotly$default (Lspace/kscience/visionforge/html/VisionOutput;Lspace/kscience/plotly/PlotlyConfig;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/plotly/VisionOfPlotly;
}

View File

@@ -1,15 +0,0 @@
plugins {
id("space.kscience.gradle.mpp")
}
kscience {
jvm()
js {
binaries.library()
}
dependencies {
api(projects.visionforgeCore)
api(projects.plotly.plotlyktCore)
}
useSerialization()
}

View File

@@ -1,29 +0,0 @@
package space.kscience.visionforge.plotly
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.polymorphic
import kotlinx.serialization.modules.subclass
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginFactory
import space.kscience.dataforge.context.PluginTag
import space.kscience.dataforge.meta.Meta
import space.kscience.visionforge.Vision
import space.kscience.visionforge.VisionPlugin
public expect class PlotlyPlugin : VisionPlugin {
override val tag: PluginTag
override val visionSerializersModule: SerializersModule
public companion object : PluginFactory<PlotlyPlugin>{
override fun build(context: Context, meta: Meta): PlotlyPlugin
override val tag: PluginTag
}
}
internal val plotlySerializersModule = SerializersModule {
polymorphic(Vision::class) {
subclass(VisionOfPlotly.serializer())
}
}

View File

@@ -1,87 +0,0 @@
package space.kscience.visionforge.plotly
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.launch
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import space.kscience.dataforge.meta.*
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
import space.kscience.dataforge.names.Name
import space.kscience.plotly.Plot
import space.kscience.plotly.Plotly
import space.kscience.plotly.PlotlyConfig
import space.kscience.visionforge.MutableVisionProperties
import space.kscience.visionforge.Vision
import space.kscience.visionforge.VisionBuilder
import space.kscience.visionforge.html.VisionOutput
@Serializable
@SerialName("vision.plotly")
public class VisionOfPlotly private constructor(
@Serializable(MutableMetaSerializer::class) public val meta: MutableMeta,
) : Vision {
public constructor(plot: Plot) : this(plot.meta)
@Transient
public val plot: Plot = Plot(meta.asObservable())
@Transient
override var parent: Vision? = null
@Transient
override val properties: MutableVisionProperties = object : MutableVisionProperties {
override val own: Meta get() = plot.meta
override val changes = callbackFlow {
plot.meta.onChange(this) {
launch {
send(it)
}
}
awaitClose {
plot.meta.removeListener(this)
}
}
override fun invalidate(propertyName: Name) {
//do nothing, updates to source already counted
// manager?.context?.launch {
// changes.emit(propertyName)
// }
}
override fun getValue(name: Name, inherit: Boolean?, includeStyles: Boolean?): Value? = plot.meta[name]?.value
override fun set(name: Name, item: Meta?, notify: Boolean) {
plot.meta[name] = item
if (notify) invalidate(name)
}
override fun setValue(name: Name, value: Value?, notify: Boolean) {
plot.meta[name] = value
if (notify) invalidate(name)
}
override val descriptor: MetaDescriptor get() = plot.descriptor
}
override val descriptor: MetaDescriptor = Plot.descriptor
}
public fun Plot.asVision(): VisionOfPlotly = VisionOfPlotly(this)
/**
* Embed a dynamic plotly plot in a vision
*/
@VisionBuilder
public inline fun VisionOutput.plotly(
config: PlotlyConfig = PlotlyConfig(),
block: Plot.() -> Unit,
): VisionOfPlotly {
requirePlugin(PlotlyPlugin)
meta = config.meta
return VisionOfPlotly(Plotly.plot(block))
}

View File

@@ -1,110 +0,0 @@
package space.kscience.visionforge.plotly
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.meta.Value
import space.kscience.plotly.Plotly
import space.kscience.plotly.layout
import space.kscience.plotly.models.*
import space.kscience.visionforge.visionManager
import kotlin.test.Test
import kotlin.test.assertEquals
class VisionOfPlotlyTest {
@Test
fun conversion() {
val trace1 = Violin {
text("sample length: 32")
marker {
line {
width = 2
color("#bebada")
}
symbol = Symbol.valueOf("line-ns")
}
orientation = Orientation.h
hoveron = ViolinHoveron.`points+kde`
meanline {
visible = true
}
legendgroup = "F"
scalegroup = "F"
points = ViolinPoints.all
pointpos = 1.2
jitter = 0
box {
visible = true
}
scalemode = ViolinScaleMode.count
showlegend = false
side = ViolinSide.positive
y0 = Value.of(0)
line {
color("#bebada")
}
name = "F"
x(10.07, 34.83, 10.65, 12.43, 24.08, 13.42, 12.48, 29.8, 14.52, 11.38,
20.27, 11.17, 12.26, 18.26, 8.51, 10.33, 14.15, 13.16, 17.47, 27.05, 16.43,
8.35, 18.64, 11.87, 19.81, 43.11, 13.0, 12.74, 13.0, 16.4, 16.47, 18.78)
}
val trace2 = Violin {
text("sample length: 30")
marker {
line {
width = 2
color("#8dd3c7")
}
symbol = Symbol.valueOf("line-ns")
}
orientation = Orientation.h
hoveron = ViolinHoveron.`points+kde`
meanline {
visible = true
}
legendgroup = "M"
scalegroup = "M"
points = ViolinPoints.all
pointpos = -1.2
jitter = 0
box {
visible = true
}
scalemode = ViolinScaleMode.count
showlegend = false
side = ViolinSide.negative
y0 = Value.of(0)
line {
color("#8dd3c7")
}
name = "M"
x(27.2, 22.76, 17.29, 19.44, 16.66, 32.68, 15.98, 13.03, 18.28, 24.71,
21.16, 11.69, 14.26, 15.95, 8.52, 22.82, 19.08, 16.0, 34.3, 41.19, 9.78,
7.51, 28.44, 15.48, 16.58, 7.56, 10.34, 13.51, 18.71, 20.53)
}
val plot = Plotly.plot {
traces(trace1, trace2)
layout {
width = 800
height = 800
title = "Advanced Violin Plot"
}
}
val vision = VisionOfPlotly(plot)
val context = Context {
plugin(PlotlyPlugin)
}
val serialized = context.visionManager.encodeToString(vision)
val deserialized: VisionOfPlotly = context.visionManager.decodeFromString(serialized) as VisionOfPlotly
println(deserialized.plot.meta)
assertEquals(62, deserialized.plot.data.sumOf { it.x.doubles.size})
assertEquals("Advanced Violin Plot", deserialized.plot.layout.title)
}
}

View File

@@ -1,49 +0,0 @@
package space.kscience.visionforge.plotly
import kotlinx.serialization.modules.SerializersModule
import org.w3c.dom.Element
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginFactory
import space.kscience.dataforge.context.PluginTag
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName
import space.kscience.plotly.PlotlyConfig
import space.kscience.plotly.plot
import space.kscience.visionforge.Vision
import space.kscience.visionforge.VisionPlugin
import space.kscience.visionforge.html.ElementVisionRenderer
import space.kscience.visionforge.html.JsVisionClient
public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer {
public val visionClient: JsVisionClient by require(JsVisionClient)
actual override val tag: PluginTag get() = Companion.tag
actual override val visionSerializersModule: SerializersModule get() = plotlySerializersModule
override fun rateVision(vision: Vision): Int = when (vision) {
is VisionOfPlotly -> ElementVisionRenderer.DEFAULT_RATING
else -> ElementVisionRenderer.ZERO_RATING
}
override fun render(element: Element, name: Name, vision: Vision, meta: Meta) {
val plot = (vision as? VisionOfPlotly)?.plot ?: error("VisionOfPlotly expected but ${vision::class} found")
val config = PlotlyConfig.read(meta)
element.plot(config, plot)
}
override fun toString(): String = "Plotly"
override fun content(target: String): Map<Name, Any> = when (target) {
ElementVisionRenderer.TYPE -> mapOf("plotly".asName() to this)
else -> super.content(target)
}
public actual companion object : PluginFactory<PlotlyPlugin> {
actual override val tag: PluginTag = PluginTag("vision.plotly.js", PluginTag.DATAFORGE_GROUP)
actual override fun build(context: Context, meta: Meta): PlotlyPlugin = PlotlyPlugin()
}
}

View File

@@ -1,22 +0,0 @@
package space.kscience.visionforge.plotly
import kotlinx.serialization.modules.SerializersModule
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginFactory
import space.kscience.dataforge.context.PluginTag
import space.kscience.dataforge.meta.Meta
import space.kscience.visionforge.VisionPlugin
public actual class PlotlyPlugin : VisionPlugin() {
actual override val tag: PluginTag get() = Companion.tag
actual override val visionSerializersModule: SerializersModule get() = plotlySerializersModule
public actual companion object : PluginFactory<PlotlyPlugin> {
actual override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP)
actual override fun build(context: Context, meta: Meta): PlotlyPlugin = PlotlyPlugin()
}
}

View File

@@ -7,6 +7,7 @@ import io.ktor.http.path
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.application.log
import io.ktor.server.application.pluginOrNull
import io.ktor.server.engine.ConnectorType
import io.ktor.server.engine.EngineConnectorConfig
import io.ktor.server.html.respondHtml
@@ -102,7 +103,9 @@ public fun Application.serveVisionData(
configuration: VisionRoute,
resolveVision: (Name) -> Vision?,
) {
install(WebSockets)
if (pluginOrNull(WebSockets) == null) {
install(WebSockets)
}
routing {
route(configuration.route) {
//TODO do more precise CORS policy
@@ -208,7 +211,8 @@ public fun Application.visionPage(
embedData = configuration.dataMode == VisionRoute.Mode.EMBED,
fetchDataUrl = if (configuration.dataMode != VisionRoute.Mode.EMBED) {
url {
this.protocol = if (schema == ConnectorType.HTTPS) URLProtocol.HTTPS else URLProtocol.HTTP
this.protocol =
if (schema == ConnectorType.HTTPS) URLProtocol.HTTPS else URLProtocol.HTTP
this.host = host
this.port = port
path(route, "data")

View File

@@ -12,10 +12,7 @@ import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import space.kscience.dataforge.meta.Laminate
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MutableMeta
import space.kscience.dataforge.meta.MutableMetaProxy
import space.kscience.dataforge.meta.*
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
import space.kscience.dataforge.names.*
import space.kscience.dataforge.provider.Path
@@ -112,85 +109,37 @@ public class SolidReference(
return if (listOfMeta.all { it == null }) null else Laminate(listOfMeta)
}
//
// override val properties: MutableVisionProperties by lazy {
// object : AbstractVisionProperties(this, propertiesInternal) {
//
// override fun getValue(name: Name, inherit: Boolean?, includeStyles: Boolean?): Value? {
// if (name == Vision.STYLE_KEY) {
// return buildList {
// own.getValue(Vision.STYLE_KEY)?.list?.forEach {
// add(it)
// }
// prototype.styles.forEach {
// add(it.asValue())
// }
// }.distinct().asValue()
// }
// //1. resolve own properties
// own.getValue(name)?.let { return it }
//
// val descriptor = descriptor?.get(name)
// val inheritFlag = inherit ?: descriptor?.inherited ?: false
// val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true
//
// //2. Resolve prototype onw properties
// prototype.properties.own.getValue(name)?.let { return it }
//
// if (stylesFlag) {
// //3. own styles
// own.getValue(Vision.STYLE_KEY)?.list?.forEach { styleName ->
// getStyle(styleName.string)?.getValue(name)?.let { return it }
// }
// //4. prototype styles
// prototype.getStyleProperty(name)?.value?.let { return it }
// }
//
// if (inheritFlag) {
// //5. own inheritance
// parent?.properties?.getValue(name, inheritFlag, includeStyles)?.let { return it }
// //6. prototype inheritance
// prototype.parent?.properties?.getValue(name, inheritFlag, includeStyles)?.let { return it }
// }
//
// return descriptor?.defaultValue
// }
//
//
// override fun invalidate(propertyName: Name) {
// //send update signal
// @OptIn(DelicateCoroutinesApi::class)
// (manager?.context ?: GlobalScope).launch {
// changesInternal.emit(propertyName)
// }
//
// // update styles
// if (propertyName == Vision.STYLE_KEY) {
// styles.asSequence()
// .mapNotNull { getStyle(it) }
// .flatMap { it.items.asSequence() }
// .distinctBy { it.key }
// .forEach {
// invalidate(it.key.asName())
// }
// }
// }
// }
// }
//
// val items: VisionChildren
// get() = object : VisionChildren {
// override val parent: Vision get() = this@SolidReference
//
// override val keys: Set<NameToken> get() = prototype.children?.keys ?: emptySet()
//
// override val changes: Flow<Name> get() = emptyFlow()
//
// override fun get(token: NameToken): SolidReferenceChild? {
// if (token !in (prototype.children?.keys ?: emptySet())) return null
// return SolidReferenceChild(this@SolidReference, this@SolidReference, token.asName())
// }
// }
override fun writeProperty(
name: Name,
inherited: Boolean,
useStyles: Boolean
): MutableMeta {
val mutable = properties.getOrCreate(name)
val default = buildList {
//2. Resolve prototype own properties
add(prototype.properties[name])
if (useStyles) {
//3. own styles
add(getStyleProperty(name))
//4. prototype styles
add(prototype.getStyleProperty(name))
}
if (inherited) {
//5. own inheritance
add(parent?.readProperty(name, inherited, useStyles))
//6. prototype inheritance
add(prototype.parent?.readProperty(name, inherited, useStyles))
}
add(descriptor.defaultNode[name])
}
return mutable.withDefault { name ->
default.firstNotNullOfOrNull { it[name] }
}
}
public companion object {
public const val REFERENCE_CHILD_PROPERTY_PREFIX: String = "@child"
@@ -221,7 +170,38 @@ private class SolidReferenceChild(
VisionPropertyChangedEvent(it.propertyName.cutFirst(), it.propertyValue)
}
override val properties: MutableMeta = MutableMetaProxy(owner.properties, childToken.asName())
override val properties: MutableMeta = owner.properties.view(childToken.asName())
override fun writeProperty(
name: Name,
inherited: Boolean,
useStyles: Boolean
): MutableMeta {
val mutable = properties.getOrCreate(name)
val default = buildList {
//2. Resolve prototype own properties
add(prototype.properties[name])
if (useStyles) {
//3. own styles
add(getStyleProperty(name))
//4. prototype styles
add(prototype.getStyleProperty(name))
}
if (inherited) {
//5. own inheritance
add(parent?.readProperty(name, inherited, useStyles))
//6. prototype inheritance
add(prototype.parent?.readProperty(name, inherited, useStyles))
}
add(descriptor.defaultNode[name])
}
return mutable.withDefault { name ->
default.firstNotNullOfOrNull { it[name] }
}
}
override fun readProperty(
name: Name,
@@ -259,34 +239,6 @@ private class SolidReferenceChild(
SolidReferenceChild(owner, this, childName + key)
} ?: emptyMap()
// @Transient
// override val properties: MutableVisionProperties = object : MutableVisionProperties {
// override val descriptor: MetaDescriptor get() = this@SolidReferenceChild.descriptor
//
// override val own: MutableMeta by lazy { owner.properties[childToken(childName).asName()] }
//
// override fun getValue(
// name: Name,
// inherit: Boolean?,
// includeStyles: Boolean?,
// ): Value? = own.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles)
//
// override fun set(name: Name, item: Meta?, notify: Boolean) {
// own[name] = item
// }
//
// override fun setValue(name: Name, value: Value?, notify: Boolean) {
// own.setValue(name, value)
// }
//
// override val changes: Flow<Name>
// get() = owner.properties.changes.filter { it.startsWith(childToken(childName)) }
//
// override fun invalidate(propertyName: Name) {
// owner.properties.invalidate(childPropertyName(childName, propertyName))
// }
// }
companion object {
private fun childToken(childName: Name): NameToken =

View File

@@ -33,6 +33,6 @@ kscience {
jsMain {
api(projects.visionforgeThreejs)
compileOnly(npm("webpack-bundle-analyzer", "4.5.0"))
// compileOnly(npm("webpack-bundle-analyzer", "4.5.0"))
}
}