I could use a hand; Trying to learn how to use js ...
# javascript
g
I could use a hand; Trying to learn how to use js modules in my kotlin JS apps for browser. I'm stuck on defining this lamba part; all untested just trying to get off the ground:
Copy code
@JsModule("grapesjs")
external class Grapes {
    fun init(lambda: () -> Unit): Grapes = definedExternally
}

class WebEditorViewController {
    val grapes = Grapes().init {
        val container = "#gjs"
        val fromElement = true
    }
}
And here is what the actual JS is supposed to look like, from the hello world examples
Copy code
const editor = grapesjs.init({
  container: '#gjs',
  fromElement: true,
  height: '300px',
  width: 'auto',
  storageManager: false,
  panels: { defaults: [] },
});
hmmm... just realized that's a json in the second screenshot not CSS or other... I should be able to form a json with klaxon if I recall
Any input appreciated... wondering if this is really practical, you'd need to create a wrapper for most everything. Isn't there a way to auto-generate a wrapper?
So when I do this, with implementation(npm("grapesjs")), do I still need to include the CSS and JS (and potentially others in different packages) in the resources folder or are they included automatically and how?
hmmm... would I still need to include script("") pathing and static routes in the Ktor backend? this npm thing has always confused me... ATM I am using js and css libs from the resources folder.
t
Grapes - external object (not class)
g
ok... guess that makes sense kinda... not sure why though
a
Copy code
external interface Panels {
  var defaults: Array<dynamic>
}

external interface GrapesInit {
  var container: String
  var fromElement: Boolean
  var height: String
  var width: String
  var storageManager: Boolean
  var panels: Panels
}

@JsModule("grapesjs")
external object Grapes {
  fun init(param: GrapesInit)
}

//usage

val editor = Grapes.init(jsObject{
  container = "#gjs"
  . . .
})
g
Thanks, this should help. I haven't gotten klaxon to work, starting to think it only works in JVM backend kotlin
hmm... jsObject isn't json. is that from java FX? not familiar with it
hmm... jsObject is JVM but this is front end KotlinJS
a
actually jsObject is for KotlinJs
g
what's teh dependancy string?
a
its in kotlin-stdlib-js, its a lambda in KotlinJs that you can use to construct plain javascript objects from kotlin js
I mean, its a function that takes a lambda and used to construct Javascript objects
g
can't seem to find klaxon or this jsObject... this is strange
Copy code
implementation(kotlin("stdlib-js"))
This seems to work fine
Copy code
implementation("com.beust:klaxon:5.2")
Can't access klaxon or that jsObject. strange
hmm... maybe replaced with js {}
r
jsObject
is not in stdlib, it's in kotlin-extensions: https://github.com/JetBrains/kotlin-wrappers/tree/master/kotlin-extensions
and klaxon is jvm library, you can't use it in Kotlin/JS
g
okay, that explains that, lol... no where on the readMe does it say JVM... might as well use gson
hard to beleive no front end JSON parser... or is there?
r
kotlinx.serialization is multiplatform
but for using library like this grapes, you don't need json parser
g
Thanks Robert, you are the Obi Wan of Kotlin... I wish I had used KVision now you clearly know your junk.... how hard would it be to migrate to KVision? Yeah, I know I'll need one eventually... so I think I'll drop klaxon for the kotlinx one you recommended, since I can use in front and back. As always, thanks
r
Unfortunately KVision won't help you lot if you want to use grapes.js, because you will have to declare exactly the same external interfaces with objects, functions and methods. But it surely can help with a lot of other useful features, because it contains ready to use bindings for a lot of different js libraries.
g
Yeah, I saw react looks inherent in it.
I used angularJS more
It really seems like there should be a way to automatically create a Kotlin wrapper from any JS file.
r
they are working on it - its called
dukat
but is still very immature
g
COOLLLLL... typing is probably an issue, lol. thanks man, will check that out.
hmmmm.... that looks like typescript to kotlin converter
r
yep, it is
g
So how would you get from JS to TS
r
the idea is to convert typescript bindings for js libraries
most js libraries have such bindings on https://definitelytyped.org/
the goal is to automatically create kotlin wrappers when you add a npm dependency, based on definitelytyped repository typescript code
it will be officially available in Kotlin 1.4
g
ah, I meant they should be able to automatically generate biddings just by looking at the JS file... like what you guys just helped me with, seems automate-able... Wonder who writes all the typescript bindings, and how do you locate them, is there one for grape?
r
but do not expect miracles ;-)
there are none https://github.com/artf/grapesjs/issues/1759 they are working on this as well
g
wow, maybe they can do kotlin's at the same time, lol. Hell, really all we are talking about here is typing right? I realize kotlin is strongly typed, but couldn't you automatically create really fast ANY typed biddings and then maybe a config file to manually assign?
honestly my biggest goal is writting an entire web app in one language, typing has it's advantages and disadvantages, but I really don't care for web dev... I guess I'd say web development should be untyped if I had to pick because it's such a high level thing. Where as programming firmware should be typed... don't want to send a 240V signal ment for solenoid to your front end display... seen it
I think kotlin should add untyped keyword to var/val.... I think conversion might be auto possible then? No idea, just brain dumbing... brb
r
it does have untyped
it's called
dynamic
g
• Wow cool... my brain is telling me js to kotlin autoconversion would be easy if you eliminate typing needs of kotlin, but my brain is often wrong.
r
you don't really need bindings if you just want to use js libraries
but in general when working with
dynamic
you loose what Kotlin is really about, so it could just make no sense
you need to find your own way
dynamic is good enough for some simple things, like in this example app, when I just want to use hammer.js library for two swipe event listeners https://github.com/rjaros/kvision-examples/blob/2d4f800c85bce4513a645bacd393c6213dfe8b5c/pokedex/src/main/kotlin/com/example/App.kt#L69
no need to create any external objects - just write some simple untyped code
g
hmmm... interesting; not sure how that works... require just checks to make sure its included and returns it... it being I presume a giant java function or module with everything included. Then it pretty much becomoes like js... fascinating, no IDE errors:
Not sure why Kotlin or the IDE can't look that up and comfirm those functions don't exist... but I guess everything is in a contstant state of evolution... like literally everything, lol
a
Not really, require returns dynamic. A dynamic type literally turns off kotlin typesafe system and let you type what you are sure is there. It is important for js interopability
g
hmm...Interesting... Well I guess type safe is generally the recommended approach, integrates better with stuff... so I guess I should use it. Learning lots though, thanks,
So if I include an NPM dependency and wire it up like this, what happens to the original dependency? Can I delete it from my resources folder? Is it webpacked up together with my code or does it stay separated somewhere (resources again maybe)? Do I still need to included the everything in ktor,respondHTML blocks i.e. :
Copy code
link("/libs/grapesjs/css/grapes.min.css","stylesheet")
script(src = "/libs/grapesjs/js/grapes.min.js") {}
or is it included in my own MyProject.js
a
If you use
require
webpack will handle the rest. So no need to include them
g
Okay, I gotta read more on webpack require, much of this is new to me... tools have exploded in numbers, spent too many years focusing on algorthyms and data = (. Just FYI, my first ktor page... I guess will be my only one, where id=content gets cleared and populated from the front end.
Copy code
get("demo") {
    call.respondHtml {
        //TODO: Ad new HTML5 footer
        head {
            link("/libs/metro/css/metro-all.min.css","stylesheet")
            link("/libs/grapesjs/css/grapes.min.css","stylesheet")
        }
        body("h-100") {
            div("h-100") {
                id = "content"
                attributes["style"] = "min-height=100%"
                +loadingString()
            }

            script(src = "/libs/three.js/js/three.min.js") {}
            script(src = "/libs/metro/js/metro.min.js") {}
            script(src = "/libs/grapesjs/js/grapes.min.js") {}
            script(src = "/PipelineDXP.js") {}
        }
    }
}
okay, so I can remove grapes here now I suspect
a
You can remove grapes there, but leave the css
g
understood, can I delete both files from my resources folder? webpack or DCE tasks are getting slow
a
Depends on your setup. If your using npm for frontend then yes, you can delete grapes from resources. If not, then you shouldn't
g
yeah, trying to do what's recommend... learning, starting off new project right... npm seems to be recommend, also allows version control from gradle which is cool.
Any idea what I'm doing wrong here:
Copy code
val metro4 = kotlinext.js.require("metro4")

fun main() {
    document.addEventListener("DOMContentLoaded", {
        demoTableAndProjection()
    })
}
a
If you are not using
metro4
KotlinDCE will chew it up for breakfast. Put your require inside main
g
Copy code
fun main() {
    val metro4 = kotlinext.js.require("metro4")
    document.addEventListener("DOMContentLoaded", {
        demoWebEditor()
    })
}
How do I path to the css associated with it?
grape seemed easier to npm-ize
a
you can just use forward strokes. Say
kotlinext.js.require("metro4/path/to/styles.css")
But this will work if you have configured css modules for webpack
g
hmm... interesting grapes is out of resources entirely, there is js and css in that package. somehow the css is being served up and I presume the JS is burried in my produced js file. That's the only reference to it I need:
Copy code
link("/libs/grapesjs/css/grapes.min.css","stylesheet")
Plus the adapter yall helped me make. So I guess perhaps it might be configured by default
Time for a break, long day. Gonna push this stuff. Tomorrow try to remove those other two, three.js and metro4... guess three would be easier so that will be first