This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-11-03
Channels
- # announcements (1)
- # babashka (2)
- # beginners (17)
- # calva (11)
- # cider (4)
- # clara (3)
- # clj-kondo (19)
- # cljs-dev (60)
- # clojure (27)
- # clojure-europe (1)
- # clojure-nl (2)
- # clojure-spec (1)
- # clojure-uk (11)
- # clojurescript (128)
- # core-logic (7)
- # cursive (7)
- # data-science (3)
- # datomic (76)
- # defnpodcast (4)
- # fulcro (5)
- # malli (5)
- # off-topic (7)
- # re-frame (1)
- # reitit (3)
- # shadow-cljs (86)
- # spacemacs (5)
- # test-check (48)
- # tools-deps (9)
- # vim (12)
- # xtdb (6)
Can anyone recommend canonical examples of how common DOM types (eg NamedNodeMap
, HTMLCollection
, NodeList
, etc...) can/should implement CLJS protocols? I found pangloss/synergize
(https://github.com/pangloss/synergize/blob/master/src/synergize/browser.cljs#L69) and clojure.data.xml
(https://github.com/clojure/data.xml/blob/master/src/main/clojure/clojure/data/xml/js/dom.cljs#L172), but wanted to see if there's a set of impls commonly accepted by the community.
P.S. I'm aware of the discussions online regarding why these aren't part of CLJS core, and why one shouldn't extend native/platform types in a library. My use case is an application.
@robert.mather.rmm it isn't a great idea to make the DOM list types look like clojure datastructures (ie. protocols) since they are mutable underneath
one easy way of working with them is (array-seq html-coll-or-node-list)
(but they are still mutable underneath, so depending on what you are doing might be a good idea to (vec (array-seq ...))
When would you suggest using (vec (array-seq ...))
as opposed to just the first example?
(doseq [node (array-seq (js/document.querySelectorAll "div"))] (.remove node))
will end badly 😛
I spent a lot of time debugging the weirdest bugs only to later find out that things were mutable when I thought they weren't
Ahh. Is the idea that the vec
will realize the lazy seq thus making it more predictable to work with?
Awesome. Thanks!
@borkdude :import
exists primarily for the annoying case where a goog ctor is the same as the namespace itself
I was fixing a false positive in clj-kondo (a clojure linter) because people seem to be using it like this:
(ns foo (:import [goog.date UtcDateTime]))
(defn utc [x] (UtcDateTime.fromTimestamp x))
Maybe they shouldn't, but it has been seen in a couple of code basesis UtcDateTime
a class? I don't know if this is even a concept in JS (outside ES6, TS, etc.), hence my question
they seem to be calling it like that over here: https://google.github.io/closure-library/api/goog.date.UtcDateTime.html
(:import [foo.bar Baz])
lets you require a namespace called foo.bar.Baz
& use Baz
as if referred
according to the issuer you can also:
(:require [goog.date.UtcDateTime :as udt])
udt/fromTimestamp
IMHO it should probably be (defn utc [x] (UtcDateTime/fromTimestamp x))
. that is how clojure accesses static class methods
well that used to work years ago but we disallowed that to remove ambiguities about namespaces
yeah its a bit messy since closure "provides" don't actually always describe namespaces
dunno I would prefer allowing calling the actual :as
alias as a function. like we have for other JS
From a linter/tooling perspective it would be nice if UtcDateTime/...
could be restored
@thheller right, still kind of meh about doing that though - though to be fair we already have invokeable nses for JS modules
so this would only be supported for a limited set of classes baked into the compiler?
Rephrased: CLJS has to know if some import is a class. How can it know from arbitrary libraries.
like I said I'd like to see cases in Closure where you have static methods on a Foo
where you don't have constructor
that is foo.bar.Foo
if that's just a namespace and not a constructor seems to break the convention I've seen
(:require [foo.bar :refer (Foo)])
is problematic because the mapping isn't 1:1 and could be defined in foo/bar.js
or foo/bar/foo.js
So I followed the code splitting guide and have a clojurescript application built that properly code splits and I can load things dynamically using cljs-loader.
That all works great. Now I’d like to take those same code split modules (my home page, my about page, etc) and have node server where I require those modules and server side render them.
Sadly, that does not seem to work because when I try to require [mysite.about]
it tries to require cljs.loader
which does not exist in the node environment. Is there are way around this or a better way to accomplish the same goal? Does anyone have a setup like this working?
I think the issue w/ trying to use the loader in Node.js is that we're just using the Google Closure thing - so I doubt that would work under node - definitely meant for the browser
that said I don't really see why you need to bother w/ all this if you just want to server side render
just don't use the code split version of your code base - it does means you need to compile twice
I’m not actually trying to use the loader directly. The problem I’m running into is that, from my understanding, any modules I want to code split, I need to add the loader/set-loaded!
call to. So if I have a simple about page like this:
(ns my-site.about
(:require [cljs.loader :as loader]))
(defn main []
[:div [:h1 "About"]])
(loader/set-loaded! :about)
When I try to require my-site.about, it will try to require cljs-loader which will fail. I’m fine with compiling twice, but how would that get around this issue? Or am I doing something wrong with code splitting?(Just for context, I’m basically trying to make a nextjs like framework in clojurescript)
@dnolen Makes sense. Thanks!
I’m trying to interact with WASM from ClojureScript
On https://emscripten.org/docs/api_reference/module.html it’s explained to create a Module object that overrides print
and printerr
How do we do this in ClojureScript?
(defprotocol Module
(^:export print [this tex] ...)
(^:export printErr [this text] ...))
?One approach would be to create a JavaScript object from cljs named Module
, that has a method print
and printErr
The question is: how can I overwrite print
so I can access the stdout of the webassembly package in clojurescript and do something with it?
An approach I thought of is overwriting the module from javascript and then calling externed clojurescript methods
but I can’t overwrite module from js either 😕
@erwinrooijakkers you can just make an JS object just like the example shows
Thanks!!!
Oh that’s half of what I meant
I also want to assign the object to the js
namespace
js/Module
basically
Is that possible?
(set! js/Module # js {:print ...})
maybe
Oh that actually works 🙂
But the webassembly is not routed through it
Do you happen to have any experience overwriting js/Module? For WebAssembly? I think I am missing some key piece of insight. (set! js/Module #js {:print (fn [this text] (println "halllllo" text))})
is not doing anything
Also defining it in javascript does not do anything
While in the example of https://dev.zenroom.org/demo/ it does do something
In shell.js