If i do something like the following to be able to use an npm library simple-git
(defonce git (node/require "simple-git"))
and I want to use the function tags
from that library, how do I do that?
(.tags git cb) gives me:
mygit.core.git.tags is not a function
I’m not quite getting how to use the npm libraries in lumo if they have multiple entry points like tags
Thanks!don't know if worth an issue but I have noticed a couple of warning during compilation of master
:
### Compiling Macro Namespaces
cljs.user=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=>
WARNING: Use of undeclared Var cljs.spec.test.alpha$macros/eval at line 112 cljs/spec/test/alpha.cljc
WARNING: Use of undeclared Var cljs.spec.test.alpha$macros/eval at line 135 cljs/spec/test/alpha.cljc
WARNING: Use of undeclared Var cljs.spec.test.alpha$macros/eval at line 245 cljs/spec/test/alpha.cljc
nil
@rberger according to docs, you need to pass a directory first: (defonce git ((node/require "simple-git") "my-dir"))
@richiardiandrea those are expected
We set!
eval later
ok thanks! it was then a good idea to write here first
I get a difference with requireing from node and lumo
(js/require "web-audio-api")
Octal literals are not allowed in strict mode.
....
> require('web-audio-api')
{ AudioContext: [Function: AudioContext],
AudioParam: [Function: AudioParam],
AudioNode: [Function: AudioNode],
AudioDestinationNode: [Function: AudioDestinationNode],
AudioBuffer: { [Function: AudioBuffer] filledWithVal: [Function], fromArray: [Function] },
AudioBufferSourceNode: [Function: AudioBufferSourceNode],
GainNode: [Function: GainNode],
constants: { BLOCK_SIZE: 128 } }
>
@hlolli (.setFlagsFromString (js/require "v8") "--no-use_strict")
Magic! wow thanks 🙂 @anmonteiro
@hlolli not magic. we set strict mode in lumo by default because it’s slightly faster
we’ve had a few people bumping into this, I don’t know if it’s a good default yet
if more people complain, maybe I can be convinced to change the default to be similar to Node’s
@anmonteiro crazy idea, can you override the message? If so, you can link to information
@dominicm open a ticket? 🙂
yes, or make an FAQ see if that helps.. yes bit old school to use Octal literals, read that its not recommended to be used.
I don’t know if it’s possible but can explore
On mobile right now, no github login. Will do if I can remember sometime tomorrow
I’ll open
thanks for the suggestion
Thanks
I guess I ask the web-audio-api people to clean the octal numbers, now non strict is seemingly conflicting with strict stuff
(new (.-AudioContext (js/require "web-audio-api")))
'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
(new)
chai.expect (/home/hlolli/csound/panaeolus/node_modules/chai/lib/chai/interface/expect.cljs:9:12)
to be fair, the blame is not web-audi-api but 'abc'
@hlolli it seems like you’re still in strict-mode
yes, you were right. Now it works. If I try requireing in strict, then turn if off, try again, then some dirt(state) is stored in the web-audio-api instance, so this works if it's done in right sequence!
@hlolli just set strict mode to false at the beginning of your script
you may run into issues if you enable it again
yup yup, I will try to do it conditionally, I'm attempting to use webassembly to run csound in my livecoding app, so if a user wants native installation, then I could see a potential efficiency boost from strict.
that means with electron, if I play the cards right, panaeolus the livecoding app Im making, could be 1 executeable file that could potentially run out of the box without deps.
if that succeeds, I'll do a release party in Berlin, free wine, all lumoers welcome 🙂
just built Lumo against Node 8.3.0-rc which has V8 6.0
should have a different perf profile now that TF + I are enabled by default
What are they?
TurboFan + Ignition
the new V8 execution pipeline
Sounds exciting
Let me restate my problem. Once I require a npm library (any npm library that has more than a single function) such as:
(defonce git (node/require "simple-git" "."))
How do I access the functions associated with the library?
For instance that library has a .tag
function. How would I execute that function in the library that would be represented by the object git
?
I’ve tried several ways and they don’t work, I’m sure I’m missing something easy, but I can’t figure it out.If I use the javascript accessor method
(.tags git (fn [err, tgs] (println "Yay; " tgs))))
I get :
mygit.core.git.tags is not a function
This is a general question on how to call functions from npm libraries
The function is .tag, you're calling tags
(.tag git (fn [err, tgs] (println "Yay; " tgs))))
...
mygit.core.git.tag is not a function
(It is .tags for that library)
Its failing the same way for both. I’m pretty sure there is something wrong with how I’m calling the library from clojurscript in lumo
I found that for a npm library that has a single entry I can do the following:
(defonce gitlatest (node/require "git-latest-semver-tag"))
(gitlatest (fn [err,tag] (println "err: " error " tags: " tag))))
And that worksI'm not familiar with how you're using require in the first example, what does the . Do?
That was in response to @metametadata statement that I needed to have a path passed as an argument to the library. But it doesn’t work with or without the "."
Yeah, you don't pass it there
Maybe I’m confusing things with this example using simple-git
My question is really how do I call a function from an npm library that has mulitple functions in clojurescript in lumo
require
takes 1 argument
It fails the same way with no argument
(def my-lib (js/require "my-lib"))
(.someFunction my-lib)
if the exports of my-lib
is an object
but the library can also export a single function
in which case you call (my-lib)
directly
Here’s my script:
(ns mygit.core
(:require [cljs.nodejs :as node]))
(node/enable-util-print!)
(def git (js/require "simple-git"))
(defn do-tags []
(.tags git (fn [err, tgs] (println "Yay; " tgs))))
(defn -main []
(do-tags))
And when I run it with: lumo -c src -m mygit.core
I get:
mygit.core.git.tags is not a function
mygit$core$do_tags (evalmachine.<anonymous>:5:23)
mygit$core$_main (evalmachine.<anonymous>:10:27)
cljs.core.Var.cljs$core$IFn$_invoke$arity$0 (NO_SOURCE_FILE <embedded>:389:475)
Function.cljs.core.apply_to_simple.cljs$core$IFn$_invoke$arity$2 (NO_SOURCE_FILE <embedded>:777:120)
Function.cljs.core.apply.cljs$core$IFn$_invoke$arity$2 (NO_SOURCE_FILE <embedded>:790:244)
(NO_SOURCE_FILE <embedded>:6352:455)
(NO_SOURCE_FILE <embedded>:5947:221)
z (NO_SOURCE_FILE <embedded>:5948:13)
Object.cljs.js.eval_str_STAR_ (NO_SOURCE_FILE <embedded>:5949:61)
Function.cljs.js.eval_str.cljs$core$IFn$_invoke$arity$5 (NO_SOURCE_FILE <embedded>:5952:508)
@rberger I’ll look into it in like 20 min and let you know
in a meeting right now
Really appreciate it!!! In the mean time I’ll try with another library
@rberger what happens if you do
(def git ((js/require "simple-git") "./"))
trying
Well that seemed to kind of work. The output is:
Yay; #object[TagList [object Object]]
So the issue was how I initialized even though the simple-git says the path is optional… Do I just do a js->clj on that object now?
You probably want to get properties of that object, with aget or .-property
Oh, Ok, Looks like you solved my problem… Thanks!!
@rberger you can do js/console.log
FWIW
I think it prints JS objects more nicely
glad your problem is solved. In your case, simple-git
is of type 2 in the examples I enumerated above
Ok, though the eventual thing will be to actually use the results. Is there any easy way to turn these async calls into sync calls? I’m pretty new to the JS interopt
the module exports a single function
turning async -> sync is not possible
Any pointers on good patterns of using such async calls in clojurescript scripting applications? My hope is to use Lumo in place of bash or other scripting for ops and for use with AWS Lambda. Having the vast npm libraries is the key right now, but this async style is non-intuitive for me. Thanks again for the help getting me past what turned out to be a simple error.
I was going to write something long, but in your case, you already have a callback on receive, so the difficult part is done for you there, just call a function, a callback within the callback, where you process the response.
So do I need to use something like core.async to mix the async stuff with my more linear flow of the script?
if you want the script to have some return value instead of just side effects, then maybe core.async could help you.
you will find it under the name Andare for lumo (patched for self-hostet cljs repls)
Will give it a try. Was hoping to avoid that, but looks unavoidable. There were some interesting attempts to hide this, but I couldn’t quite get it to work and its a bit old now: http://bryangilbert.com/post/code/clojure/escape-callback-hell-core-async/
in your case you could do something like
(def res-chan (chan 1))
(defn do-tags []
(.tags git (fn [err, tgs] (>! res-chan tgs))))
(defn -main []
(go
(do-tags)
(<! res-chan))
Thanks! That will give me something to go on. Appreciate the extra effort to help educate me!