All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.kotlin.com.intuit.playerui.j2v8.bridge.V8Node.kt Maven / Gradle / Ivy

There is a newer version: 0.10.0-next.5
Show newest version
package com.intuit.playerui.j2v8.bridge

import com.eclipsesource.v8.V8
import com.eclipsesource.v8.V8Array
import com.eclipsesource.v8.V8Function
import com.eclipsesource.v8.V8Object
import com.eclipsesource.v8.V8Value
import com.intuit.playerui.core.bridge.Invokable
import com.intuit.playerui.core.bridge.Node
import com.intuit.playerui.core.bridge.NodeWrapper
import com.intuit.playerui.core.bridge.runtime.Runtime
import com.intuit.playerui.core.bridge.serialization.format.RuntimeFormat
import com.intuit.playerui.j2v8.extensions.evaluateInJSThreadBlocking
import com.intuit.playerui.j2v8.extensions.evaluateInJSThreadIfDefinedBlocking
import com.intuit.playerui.j2v8.extensions.handleValue
import com.intuit.playerui.j2v8.extensions.mapUndefinedToNull
import com.intuit.playerui.j2v8.extensions.toInvokable
import com.intuit.playerui.j2v8.extensions.toList
import com.intuit.playerui.j2v8.extensions.toNode
import com.intuit.playerui.j2v8.getV8Value
import kotlinx.serialization.DeserializationStrategy

/** Pseudo constructor to create a [Node] from a [V8Object] */
public fun Runtime.Node(obj: V8Object): Node = V8Node(obj, this)

internal class V8Node(override val v8Object: V8Object, override val runtime: Runtime) : Node, V8ObjectWrapper {

    override val format: RuntimeFormat get() = runtime.format

    override val keys: Set by lazy {
        v8Object.evaluateInJSThreadIfDefinedBlocking(runtime) {
            keys.filter { v8Object.get(it) != V8.getUndefined() }.toSet()
        } ?: emptySet()
    }

    override val size: Int by lazy {
        keys.size
    }

    override val entries: Set> by lazy {
        keys.associateWith { get(it) }.entries
    }

    override val values: List by lazy {
        keys.map(::get)
    }

    override fun containsKey(key: String): Boolean = keys.contains(key)

    override fun containsValue(value: Any?): Boolean = values.contains(value)

    override fun isEmpty(): Boolean = size == 0

    // Getter APIs
    override operator fun get(key: String): Any? = v8Object.evaluateInJSThreadIfDefinedBlocking(runtime) {
        get(key).handleValue(format)
    }

    override fun  getInvokable(key: String, deserializationStrategy: DeserializationStrategy): Invokable? = v8Object.evaluateInJSThreadIfDefinedBlocking(runtime) {
        get(key) as? V8Function
    }?.toInvokable(format, v8Object, deserializationStrategy)

    override fun  getFunction(key: String): Invokable? = v8Object.evaluateInJSThreadIfDefinedBlocking(runtime) {
        get(key) as? V8Function
    }?.toInvokable(format, v8Object, null)

    override fun getList(key: String): List<*>? = v8Object.evaluateInJSThreadIfDefinedBlocking(runtime) {
        get(key) as? V8Array
    }?.toList(format)

    override fun getObject(key: String): Node? = v8Object.evaluateInJSThreadIfDefinedBlocking(runtime) {
        get(key) as? V8Object
    }?.toNode(format)

    override fun  getSerializable(key: String, deserializer: DeserializationStrategy): T? = v8Object.evaluateInJSThreadBlocking(runtime) {
        getV8Value([email protected], key).mapUndefinedToNull()?.let {
            format.decodeFromRuntimeValue(deserializer, it)
        }
    }

    override fun  deserialize(deserializer: DeserializationStrategy): T = format.decodeFromRuntimeValue(deserializer, v8Object)

    override fun isReleased(): Boolean = v8Object.isReleased

    override fun isUndefined() = v8Object.isUndefined

    override fun nativeReferenceEquals(other: Any?): Boolean = when (other) {
        is NodeWrapper -> nativeReferenceEquals(other.node)
        is V8ObjectWrapper -> nativeReferenceEquals(other.v8Object)
        is V8Object -> v8Object.evaluateInJSThreadBlocking(runtime) {
            v8Object.strictEquals(other)
        }
        else -> false
    }

    override fun equals(other: Any?): Boolean = when (other) {
        is Map<*, *> -> keys == other.keys && keys.all {
            get(it) == other[it]
        }
        is NodeWrapper -> equals(other.node)
        is V8ObjectWrapper -> equals(other.v8Object)
        is V8Object -> equals(V8Node(other, runtime))
        else -> false
    }

    override fun hashCode(): Int = v8Object.evaluateInJSThreadBlocking(runtime) { hashCode() }

    override fun toString(): String = v8Object.evaluateInJSThreadIfDefinedBlocking(runtime) {
        keys.associate { it to get(it) }.toString()
    } ?: emptyMap().toString()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy