Fork me on GitHub
#clojurescript
<
2020-05-29
>
code star 803:05:20

Has anyone run into problems using node mjs files on Clojure Script?

code star 803:05:57

I keep hitting this ecma6 import vs require... And I feel like I keep crashing into a wall

hipster coder05:05:59

ok, heads up… there’s an issue with the latest node 14, typescript, not recognizing .ts files when you enable Ecma6 modules… I have the intuition this will affect clojurescript being able to load npm modules, until they fix it…

hipster coder05:05:33

so don’t get your hopes up about using the latest node version, ts, and ecma6 together

ingesol06:05:08

Quick tip for new users of the :target :bundle feature: Some JS libraries may require certain objects to be available in global scope. Some CLJSJS libs have done that for you. With bundle target, depending only on package.json you no longer get globals. You can solve that with the following webpack config, where reactstrap is a plain NPM module from your package.json . It makes the global GlobalReactstrap available to all other modules.

const webpack = require('webpack');

module.exports = {
   plugins: [
     new webpack.ProvidePlugin({      
       GlobalReactstrap: 'reactstrap'
     })
   ]   
}

👍 4
Karol Wójcik08:05:23

How define new var in library. In clojure I would do:

(in-ns 'some-library) 
(def new-symbol-in-library "X")
, but in clojurescript for obvious reasons is not possible

thheller08:05:42

you can't really do that

Karol Wójcik08:05:55

Ok good to know

Takis_12:05:12

Hello, mongodb can run javascript code for map reduce,or in filter using javascript using $where, is it possible to use Clojurescript instead? thank you

Eric Scott17:05:26

So I have a custom literal tag defined in a data_readers.cljc:

{
 lstr ont-app.vocabulary.lstr/read-LangStr
}
Said function works like this:
> (def x (read-LangStr "[email protected]"))
> x
#lstr "[email protected]"
> (type x)
ont-app.vocabulary.lstr/LangStr
The read-LangStr function itself works fine in both clj and cljs. The tag always works in clj. However, under certain circumstances the cljs reader will barf on #lstr with this message:
Attempting to call unbound fn: #'ont-app.vocabulary.lstr/read-LangStr
As I understand it, this means that the cljs.reader/tag-table somehow registers the association between the tag and the function, but at some critical point in the compilation process, that function is pointing at a bunch of nothing. This problem arises when I try to write a test function in the vocabulary library that uses the tag directly. I can fix it if I use cljs.reader/read-string on the string equivalent. It also goes away when I read the tag in a test within in a module that uses the vocabulary library as a dependency. It also arises when I use say rhino-repl. Can someone help me wrap my head around what's going on here? Thanks.

lilactown17:05:26

you need to ensure that the ont-app.vocabulary.lstr namespace is loaded before whatever namespace that uses the reader tag

lilactown17:05:41

the CLJS compiler does not guarantee this by default

Eric Scott17:05:32

I'm including this namespace in the require section of the testing module, and requiring it in the repls. Is that not enough?

noisesmith17:05:34

the requires are pulled in in order, so the one asking for the implementation of the tag must be before all the ones that use it

noisesmith17:05:10

alternatively, you could require the implementation ns for the reader function in every ns that uses that tag

Eric Scott17:05:33

I thought I was doing that. My require within my test module contains [ont-app.vocabulary.lstr].

Eric Scott17:05:54

Is there a way in lein/cljsbuild to specify that the lstr module is fully loaded before evaluating the data_readers.cljc file?

noisesmith17:05:49

clojure never does parallel loading

noisesmith17:05:10

well, I guess you could do something weird and force it to, but it won't do it via normal require forms

noisesmith17:05:34

the next require never happens until the previous succeeds

lilactown17:05:42

it’s hard for us to infer exactly what you mean by > my require within my test module the idea is that in your dependency graph, ont-app.vocabulary.lstr must be loaded before any code that uses it so if you do e.g.:

(ns module.a
  (:require [ont-app.vocabulary.lstr]
            [module.b]))
(ns module.b)

#lstr "foo"
you do not have a guarantee that module.b will be loaded after ont-app.vocabulary.lstr . your graph essentially looks like:
ont-app.vocabulary.lstr
         /
module.a
         \
           module.b

noisesmith17:05:21

this directly contradicts what I thought I knew about require

noisesmith17:05:44

do you have citation that there's some parallel path?

lilactown17:05:57

I didn’t mean to infer parallelization

lilactown17:05:21

it will be some order - but module.b will be loaded before module.a

noisesmith17:05:29

what I mean is that require processes args in order, and to completion, so the args do impose ordering

noisesmith17:05:49

yes, that's true... I must have misread

lilactown17:05:00

I was probably unclear

lilactown17:05:48

I didn’t know it was guaranteed to run in order

lilactown17:05:10

shadow-cljs does do parallel compilation IIRC

noisesmith17:05:51

oh, I find that surprising

noisesmith17:05:04

the clj version literally processes the clauses via doseq without any parallelization, and I am failing to find a precise source but I recall someone saying that parallel require was an unlikely feature

lilactown17:05:27

it’s different in CLJS because there’s two phases

noisesmith17:05:08

oh, right - I don't know as much about cljs, and I can see how the phases (and the model of compiling namespaces "in isolation") would break assumptions that work in clj

noisesmith17:05:07

because of course, if shadow-cljs supports hot-reloading, it will load an ns standalone and I can't make many assumptions about what other cljs code has been loaded in the context where that happens

Eric Scott17:05:10

No, the problem is happening here:

Eric Scott17:05:31

(ns ont-app.vocabulary.core-test
  (:require
   [ont-app.vocabulary.lstr :as lstr]
   ))

Eric Scott17:05:00

(test yadda yadda #lstr "[email protected]")

lilactown17:05:07

that’s surprising

Eric Scott17:05:40

(read-string "#lstr \"[email protected]\"")]

Eric Scott17:05:40

where read-string is cljs.reader/read-string

Eric Scott17:05:44

So it appears that the tag-table that informs the execution env uses a tag table with fully resolved function, but the compiler of the source only knows about the mapping, but not the definition of the function.

mfikes17:05:37

@eric.d.scott Not sure if this helps, but if I'm understanding you, I've solved that problem in this example by using -i to cause the definitions to be available to the ClojureScript compiler before the compiler runs: https://github.com/mfikes/precise (see the use of clj -i)

Eric Scott17:05:09

Am I correct in the impression that I'd need to switch from lein to deps to do this?

mfikes17:05:32

Perhaps there is a way to do the same with lein

Eric Scott17:05:54

Thanks @mfikes, I'll poke around a bit with this idea.

Spaceman21:05:03

What's the meaning of this error?:

router.cljc:204 Uncaught Error: [object Promise] is not ISeqable
    at Object.cljs$core$seq [as seq] (core.cljs:1226)
    at re_frame$fx$do_fx_after (fx.cljc:74)
    at Object.re_frame$interceptor$invoke_interceptor_fn [as invoke_interceptor_fn] (interceptor.cljc:71)
    at Object.re_frame$interceptor$invoke_interceptors [as invoke_interceptors] (interceptor.cljc:109)
    at Object.re_frame$interceptor$execute [as execute] (interceptor.cljc:204)
    at Object.re_frame$events$handle [as handle] (events.cljc:65)
    at Object.eval [as re_frame$router$IEventQueue$_process_1st_event_in_queue$arity$1] (router.cljc:179)
    at Object.eval [as re_frame$router$IEventQueue$_run_queue$arity$1] (router.cljc:198)
    at eval (router.cljc:146)
    at Object.eval [as re_frame$router$IEventQueue$_fsm_trigger$arity$3] (router.cljc:169)

Spaceman21:05:55

happening for these lines:

(let [create-token (.createToken stripe card-element)]
            (.then create-token
                   (fn [result]
                     (prn "result is" (.-token result)))))

eduardomrb21:05:55

I see you are using re-frame, if these lines are inside an event handler, for example, you are returning a Promise to re-frame

eduardomrb21:05:38

that could be the cause of the error

Spaceman21:05:19

"Promise to re-frame". I don't understand what that means. How to fix the error?

eduardomrb21:05:43

the code you posted, is it inside a re-frame event handler?

eduardomrb21:05:22

you could return a {} and the error will probably go away

(let [create-token (.createToken stripe card-element)]
            (.then create-token
                   (fn [result]
                     (prn "result is" (.-token result))))
  {} ;; <- here
)

Spaceman21:05:30

still giving me:

scheduler.development.js:108 Uncaught TypeError: lastCallbackNode is not a function
    at flushFirstCallback (scheduler.development.js:108)
    at flushWork (scheduler.development.js:220)
    at MessagePort.globalValue.port1.onmessage (scheduler.development.js:612)
flushFirstCallback @ scheduler.development.js:108
flushWork @ scheduler.development.js:220
globalValue.port1.onmessage @ scheduler.development.js:612

eduardomrb21:05:35

I think you put the {} as an argument to .then , didn’t you?

eduardomrb21:05:45

it should be the last expression of let

Spaceman21:05:30

( re-frame.core/reg-event-fx 
:set-stripe-token! 
( clojure.core/fn 
[ { :keys [ db ] } [ ___68384__auto__ stripe card-element ] ] ( prn "setting stripe token" ) ( let [ create-token ( .createToken stripe card-element ) ] ( prn "create token is " create-token ) ( .then create-token ( fn [ result ] ( prn "result is" ( .-token result ) ) ) ) {} ) ) )

eduardomrb21:05:41

alternatively you can return the same db or coeffects you received as parameters

Spaceman21:05:09

that's not good obviously

eduardomrb21:05:10

the code you posted last still doesn’t work?

thheller21:05:58

you are passing a Promise to something that expects a CLJS seq

Spaceman21:05:16

.then expects a cljs seq?

thheller21:05:14

any cljs collection. vector probably.

Spaceman22:05:00

what does this error mean:

react-dom.development.js:11366 Uncaught TypeError: lastCallbackNode is not a function
    at flushFirstCallback (scheduler.development.js:108)
    at flushImmediateWork (scheduler.development.js:170)
    at exports.unstable_runWithPriority (scheduler.development.js:262)
    at runWithPriority$2 (react-dom.development.js:11306)
    at flushSyncCallbackQueueImpl (react-dom.development.js:11350)
    at flushSyncCallbackQueue (react-dom.development.js:11339)
    at scheduleWork (react-dom.development.js:21432)
    at Object.enqueueForceUpdate (react-dom.development.js:13146)
    at cmp.Component.forceUpdate (react.development.js:354)
    at Object.reagent$impl$batching$run_queue [as run_queue] (batching.cljs:38)

thheller22:05:42

you are passing something that is not a function to something that expects a function

Spaceman22:05:53

how do I find which line this is happening?

thheller22:05:09

reagent$impl$batching$run_queue so something you passed to reagent at some point I guess. if you use chrome you can use "pause on uncaught exception" and look at the value in lastCallbackNode. maybe that has a clue for what you passed.

Spaceman22:05:26

@thheller that lands me to:

try {
    continuationCallback = callback();
  } finally {
    currentPriorityLevel = previousPriorityLevel;
    currentExpirationTime = previousExpirationTime;
  }
in scheduler.development.js

Spaceman22:05:03

I'm pretty sure the error is in my events.cljs, but not about which line

thheller22:05:05

don't look at the code, that doesn't matter.

thheller22:05:13

look at the variables on the side

Spaceman22:05:22

what are the variables supposed to tell me and which ones do I look at?

Shako Farhad00:05:55

Remember that on-click properties of reagent components want an anonymous function. To make an anonymous function you need to do like this: :on-click #(my-function) OR :on-click (fn [] my-function)

Spaceman00:05:02

yeah that's what I have in reality. Regular :div works but :>div needs re-focus or click in the browser

thheller22:05:23

I have no clue. lastCallbackNode is the name you are looking for. sorry I can't really explain how to use the debugger in more detail. bottom line is that you are probably passing an incorrect value into something somewhere

thheller22:05:49

can't help more than that, going to bed now. good luck 😛