This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-08-16
Channels
- # announcements (1)
- # beginners (83)
- # boot (10)
- # cider (23)
- # cljdoc (24)
- # cljs-dev (3)
- # clojure (138)
- # clojure-finland (1)
- # clojure-italy (12)
- # clojure-losangeles (2)
- # clojure-mexico (1)
- # clojure-nl (18)
- # clojure-russia (23)
- # clojure-sg (1)
- # clojure-spec (15)
- # clojure-uk (126)
- # clojurescript (94)
- # cloverage (2)
- # core-async (1)
- # cursive (98)
- # datomic (54)
- # figwheel-main (19)
- # hyperfiddle (21)
- # jobs (1)
- # jobs-rus (4)
- # leiningen (4)
- # liberator (4)
- # off-topic (15)
- # parinfer (9)
- # re-frame (23)
- # reagent (19)
- # reitit (2)
- # ring-swagger (3)
- # rum (3)
- # shadow-cljs (244)
- # sql (4)
Is it just me, or is there some issue with shadow
kicking me out of the REPL (`CompilerException java.lang.RuntimeException...`) when debugging core.async
code?
I'm getting an unusual number of these REPL terminations when working with core.async
. It looks as though, when something goes wrong within a chan
(e.g., an error like nil is not allowed in a channel
), stuff breaks
I'm sometimes receiving SyntaxErrors
when running karma tests. the message looks like this:
{
"message": "Uncaught SyntaxError: missing ) after argument list\nat ci.js:114889:322\n\nSyntaxError: missing ) after argument list",
"str": "Uncaught SyntaxError: missing ) after argument list\nat ci.js:114889:322\n\nSyntaxError: missing ) after argument list"
}
@loganpowell do you have an example of code that kicks you out? how are you debugging core.async code? async in general is pretty tough to debug given its async nature but I don't know what you mean by getting kicked out?
@arne-clojurians I believe there was an issue with karma running tests too early, meaning it started running tests while the file was still being written?
try setting a super high autoWatchBatchDelay
http://karma-runner.github.io/2.0/config/configuration-file.html (2000 or so should be good)
@thheller right now, it looks like anytime I get an error inside a chan
I'm getting kicked out.
I have to restart the Cursive REPL with (shadow.cljs.devtools.api/node-repl)
ah, ok
well, the shadow-cljs
node server keeps running, but Cursive breaks
maybe a Cursive issue
yessir
Ī» shadow-cljs clj-repl
shadow-cljs - config: C:\Users\Surface\Projects\clojure\cljs\census-geojson\shadow-cljs.edn cli version: 2.4.25 node: v8.11.3 shadow-cljs - starting ...
shadow-cljs - server version: 2.4.25
shadow-cljs - server running at
shadow-cljs - socket REPL running on port 50413
shadow-cljs - nREPL server started on port 3333
shadow-cljs - REPL - see (help)
To quit, type: :repl/quit
[1:0]~shadow.user=>
still running
ok, not a big deal, I can just keep restarting the node-repl
session in Cursive. This only seems to happen when working with core.async
so I hope to be done with that soon š
it is a big deal ... just need more info to piece together what exactly you are doing
so, anything that goes wrong inside a chan
seems to kick me out of the session. I'm trying to think of a better way to explain...
I get kicked out for putting nil
into a chan
, when a function that's being called in a go
block errors out, when I forget to eval a defn
before eval'ing a go
block that contains it... yes cursive gets disconnected
the nREPL session doesn't stop in the shadow-cljs clj-repl
session. I just have to re-eval (shadow.cljs.devtools.api/node-repl)
to start the Cursive REPL again and then re-eval the namespace, functions, etc.
I don't have to shadow-cljs clj-repl
again
sorry!
For example:
step 1) shadow-cljs clj-repl
=> REPL session starts
step 2) Error
put into a chan
=> Error thrown in Cursive REPL (`shadow-cljs` still running, doesn't break)
step 3) (shadow.cljs.devtools.api/node-repl)
=> restart node-repl
in Cursive
step 4) eval (ns...)
and functions to get me back to debugging the core.async
logic
step 5) bug in code = repeat from step 2)
It's remote
Separate terminal
Would it be better to use the terminal in IDEA?
Sweet! I will do that! Any particular command I should use in there, just the terminal included with Idea or something to do with Cursive?
any terminal is fine. point is that it doesn't use nrepl and I can see the full session
Gotcha. I'll do that and report on my findings. Thank you again Thomas!
I don't know how else to describe the behavior of having the shadow-cljs clj-repl
still running, but the Cursive REPL dies on me, requiring me to re-eval (shadow.cljs.devtools.api/node-repl)
in there to kick start Cursive REPL again. It feels like getting kicked out
Let me try the Idea REPL
I'll be back!
Yes, I'm using Node/NPM interop atm
I think that's what's happening, yes, I'm getting "kicked out" of the CLJS session and into CLJ
Sorry! š
Yes, it becomes a Java runtime
CompilerException java.lang.RuntimeException: Unable to resolve symbol: defn in this context, compiling:(null:1:1)
let me try
@thheller I can't find a link to a demo project you had that used shadow-cljs and was reading configs from the html file.
https://github.com/shadow-cljs/quickstart-browser/blob/master/public/index.html#L10 this one?
@loganpowell forget about it. I think I know whats happening.
maybe that is the issue but I don't see why because the fn gets called but the args don't
https://github.com/shadow-cljs/quickstart-browser/blob/master/src/starter/browser.cljs
ok. so you split the init
into 2 functions. one that can be called again (ie. doesn't use args) and one that puts the config somewhere safe
I don't know any to be honest. I have my own super basic one that I use for my work projects
[7:1]~cljs.user=> (require '[cljs.core.async :as a])
nil
[7:1]~cljs.user=> (a/go (throw (ex-info "foo" {})))
<eval>:1
(function (){var c__34073__auto__ = cljs.core.async.chan.call(null,(1));
^
TypeError: Cannot read property 'call' of undefined
at <eval>:1:58
at <eval>:89:3
at Script.runInThisContext (vm.js:65:33)
at runInThisContext (vm.js:199:38)
at global.SHADOW_NODE_EVAL ([stdin]:75:30)
at Object.shadow$cljs$devtools$client$node$node_eval [as node_eval] (C:\Users\thheller\code\shadow-cljs\.shadow-cljs\builds\node-repl\dev\out\cljs-runtime\shadow\cljs\devtools\client\node.cljs:25:16)
at shadow.cljs.devtools.client.node/node-eval (C:\Users\thheller\code\shadow-cljs\.shadow-cljs\builds\node-repl\dev\out\cljs-runtime\shadow\cljs\devtools\client\node.cljs:48:30)
at Object.repl-expr (C:\Users\thheller\code\shadow-cljs\.shadow-cljs\builds\node-repl\dev\out\cljs-runtime\shadow\cljs\devtools\client\env.cljs:91:16)
at Object.shadow$cljs$devtools$client$node$repl_invoke [as repl_invoke] (C:\Users\thheller\code\shadow-cljs\.shadow-cljs\builds\node-repl\dev\out\cljs-runtime\shadow\cljs\devtools\client\node.cljs:48:13)
at shadow.cljs.devtools.client.node/repl-invoke (C:\Users\thheller\code\shadow-cljs\.shadow-cljs\builds\node-repl\dev\out\cljs-runtime\shadow\cljs\devtools\client\node.cljs:116:6)
[7:1]~cljs.user=> (+ 1 2)
3
@loganpowell when I do the above in nrepl it breaks
I see, so nREPL
issue
I apologize
I was being lazy
forgive my laziness. You're being generous and I, greedy
I just don't know exactly what I'm doing wrong
yeah understandable. nrepl is a total mess and I don't understand whats going on half the time either
Your example helps me understand what you need for me to help you help me
ok, no worries! Without a hitch otherwise. The NPM interop is flawless
correct, shadow's repl keeps on humming
ok, onwards! Thank you again
always a model of patience
After some experimenting with wrapping AudioWorklet with clojurescript, I found goog.defineClass
, it works with "watch", but when I release, I encounter
Closure compilation failed with 1 errors
--- csound_wasm/browser.cljs:201
Unsupported class definition expression.
makes me wonder why it works with watch to begin with...maybe there's another way around this https://developers.google.com/web/updates/2017/12/audio-worklet somehow grabbing the prototypes and convert it to object...
yes, there's a lot of not supposed to, when it comes to mixing classes with clojurescript...
what I came up with was
(def CsoundWorkletNode
(goog.defineClass
js/AudioWorkletNode
#js {:constructor
(this-as that
(fn [ctx]
((.-superClass_ that) ctx "csound-processor")))}))
mocking this
class MyWorkletNode extends AudioWorkletNode {
constructor(context) {
super(context, 'my-worklet-processor');
}
}
and it worked surprisingly, luckily the superClass that's injected from closure library helped a lot.the error changed
Closure compilation failed with 1 errors
--- csound_wasm/browser.cljs:192
The class must be defined by an object literal
(def CsoundWorkletNode
(js/goog.defineClass
js/AudioWorkletNode
#js {:constructor
(fn [ctx]
(js/super ctx "csound-processor"))}))
your version
Closure compilation failed with 1 errors
--- externs.shadow.js:11
Parse error. 'identifier' expected
(def CsoundWorkletNode
(js/goog.defineClass
js/AudioWorkletNode
#js {:constructor
(fn [ctx]
(js* "super({}, {});" ctx "csound-processor"))}))
@thheller this is the error message from "who knows who"
Closure compilation failed with 1 errors
--- csound_wasm/browser.cljs:193
Parse error. Semi-colon expected
For anyone trying to get audioWorkletNode working in GClosure format, I found that the following worked... goog.provide('sounds');
sounds.mySoundProcessor = class extends AudioWorkletProcessor ({
constructor(){
super();
//example excitation
let excitationLength = 0.5*sampleRate; // 0.5 second excitation
this.excitation = new Array(excitationLength).fill(0);
}
// dirac impulse
this.excitation[0] = 1.0;
this.ptr = 0; // pointer to iterate through excitation or whatever sound is set up...
})
sounds.mySoundProcessor.prototype.process = function(inputs, outputs, parameters){
// etc
// this.excitation is available
// this.ptr is available
}
The "semi-colon" expected error goes away when writing sounds.mySoundProcessor = class extends AudioWorkletProcessor ...
instead of class sounds.mySoundProcessor extends AudioWorkletProcessor ....
Other than this one constructor function in the format of the webaudio API (), GClosure format seems OK for all other functions, as I try to show above with the sounds.mySoundProcessor.prototype.process = ...
expression. None of the above is in clojurescript of course, but it does compile in GClosure. I've not tried getting this to work in Clojurescript yet but perhaps it will work for anyone who is trying to get around this issue?
I don't get it. I guess the logic is, that only the newest browser support audioworklet, and old ecmascript can't compile classes anyway. Not sure what's the logic.
might be like web components where you MUST use class
with extends
or else it breaks
hmm yes... I need this shit twice, one for the global scope, another for script processor scope.
I could write some js and pass into it a js object from clojurescript, to run the code defined in cljs land
https://googlechromelabs.github.io/web-audio-samples/audio-worklet/basic/hello-audio-worklet.html
lol, it's even crackling a bit, which is the main point of preventing with audioworklet
I know absolutely nothing about audio processing so I have no idea what the point of any of this is š
previously there was audioProcessorNode, that would get latencies if you changed the dom or something.
https://gist.github.com/thheller/36332574918b974a3e4996efcb7457d2#file-web-component-v1-cljs-L2
the Reflect.construct
call might also work. it was necessary for web components a while back
ok nice, I saw similar thing here http://www.50ply.com/blog/2012/07/08/extending-closure-from-clojurescript/ surprised to see mutations on defn
:modules
{:shared {:entries [cljs.core] :depends-on #{}}
:main {:entries [demo.app] :depends-on #{:shared}}
:audio1 {:entries [demo.audio1] :depends-on #{:base} :web-worker true}}
the audio files will become huge otherwise since each will contain its own cljs.core version
the idea here
(set! (.. component-fn -prototype -constructor) my-component)
is that component-fn
is its own function and not my-component
?I think I have to sweat over this a bit, im getting
Uncaught TypeError: Illegal invocation
at Object.goog.object.extend (goog.object.object.js:610)
at browser.cljs:212
code
(goog.object/extend CsoundWorkletNode.prototype js/AudioWorkletNode.prototype)
yup, I still get the same error, changed it to see what would happen, the double dot macro I don't find to be so good looking, but will use it when/if needed š
I'm getting confused about that HTMLComponent parts, I assume I don't need them?
(defn component []
(js/AudioWorkletNode #js [] component))
(set! (.-prototype component)
(js/Object.create (.-prototype js/AudioWorkletNode)
#js {:constructor (fn [ctx])}))
@hlolli just a small tip, I suggest you try to using goog.object/set
instead of set!
, it's easier to read and is adv compilation proof
(defn component []
(js/Reflect.construct js/AudioWorkletNode #js [] component))
(set! (.-prototype component)
(js/Object.create (.-prototype js/AudioWorkletNode)
#js {:constructor (fn [ctx])}))
(def context (new js/AudioContext))
(-> (.addModule context.audioWorklet "./csound-wasm-worklet-processor.js")
(.then (fn [] (new component context))))
Uncaught (in promise) TypeError: Failed to construct 'AudioWorkletNode': 2 arguments required, but only 0 present.
at new csound_wasm$browser$component (browser.cljs:207)
I think it worked, just need to plugin the worker correctly now
(defn component [ ctx node-name ]
(js/Reflect.construct js/AudioWorkletNode #js [ ctx node-name ] component))
(set! (.-prototype component)
(js/Object.create (.-prototype js/AudioWorkletNode)
#js {:constructor (fn [ctx])}))
(def context (new js/AudioContext))
(-> (.addModule context.audioWorklet "./csound-wasm-worklet-processor.js")
(.then (fn [] (this-as that (new component context "csound-processor")))))
Uncaught (in promise) DOMException: Failed to construct 'AudioWorkletNode': AudioWorkletNode cannot be created: The node name 'csound-processor' is not defined in AudioWorkletGlobalScope.
I bet you've never seen this š
Uncaught TypeError: Cannot use 'in' operator to search for 'StopIteration' in undefined
at csound-wasm-worklet-processor.js:187
at csound-wasm-worklet-processor.js:2133