I'm not sure what I'm doing wrong. Can anyone spot the problem?
Declaration
proc newAudioWorkletNode*(ctx: AudioContext, name: cstring): AudioNode {.importjs: "new AudioWorkletNode(@,@)".}
Client code (compilation successful):
import dom
import webaudio
import std/asyncjs
proc init(c : AudioContext) : AudioNode {.async.} =
  discard await c.audioWorklet.addModule("worklets/random-noise.js")
  var n = newAudioWorkletNode(c, "random-noise")
  n.connect(c.destination)
window.addEventListener("click") do(e: Event) :
  var ctx : AudioContext = newAudioContext()
  discard init(ctx)
  ctx.resume()
Client code (compilation fails with message type mismatch: got 'Future[webaudio.AudioNode]' for 'jsResolve(n)' but expected 'AudioNode = ref AudioNodeObj')
import dom
import webaudio
import std/asyncjs
proc init(c : AudioContext) : AudioNode {.async.} =
  discard await c.audioWorklet.addModule("worklets/random-noise.js")
  var n = newAudioWorkletNode(c, "random-noise")
  result = n
window.addEventListener("click") do(e: Event) :
  var ctx : AudioContext = newAudioContext()
  var noise = init(ctx)
  noise.connect(ctx.destination)
  ctx.resume()
 Client code (compilation fails with message type mismatch: got 'Future[webaudio.AudioNode]' for 'jsResolve(n)' but expected 'AudioNode = ref AudioNodeObj')
But your code snippets never mention jsResolve, so it's hard to say.
<face palm> ... Thanks!
I was trying to port this code :
async function createNoiseProcessor(ctx) {
  await ctx.audioWorklet.addModule("worklets/random-noise.js");
  return new AudioWorkletNode(ctx, "random-noise");
}
window.addEventListener("click", () => {
  const ctx = new AudioContext();
  createNoiseProcessor(ctx).then((node) => {
    node.connect(ctx.destination);
  });
  ctx.resume();
});
to nim and forgot to resolve the promise.
What is the nim equivalent of this (JavaScript) expression?
  createNoiseProcessor(ctx).then((noise) => {
    noise.connect(ctx.destination)
  })
 I think all it should take is to replace the braces with parentheses and add a type to the parameter. Don't forget to import std/sugar.
createNoiseProcessor(ctx).then((noise: Noise) => (
  noise.connect(ctx.destination)
))
Thanks @xigoi . One compilation error remains: Error: attempting to call undeclared routine: 'then'.
Code here:
import dom
import webaudio
import std/asyncjs
import std/jsconsole
import std/sugar
proc createNoiseProcessor(c : AudioContext) : Future[AudioNode] {.async.} =
  discard await c.audioWorklet.addModule("worklets/random-noise.js")
  result = newAudioWorkletNode(c, "random-noise")
window.addEventListener("click") do(e: Event) :
  var ctx : AudioContext = newAudioContext()
  createNoiseProcessor(ctx).then((noise : AudioNode) => (
    noise.connect(ctx.destination)
  ))
  ctx.resume()
I feel I'm running in circle. Nope. then is just not recognized.
Another example:
import std/asyncjs
import std/jsconsole
import std/sugar
proc f() : Future[string] {.async.} =
  return "hello"
proc log(s : string) =
  console.log(s)
f().then(log)
then ...
$ nim js test.nim
Error: attempting to call undeclared routine: 'then'
 And simpler still ...
import std/asyncjs
import std/jsconsole
import std/sugar
proc f() : Future[string] {.async.} =
  return "hello"
f().then((s : string) => console.log(s))
$ nim js test.nim
Error: attempting to call undeclared routine: 'then'
 import std/asyncjs
import std/jsconsole
import std/sugar
proc f() : Future[string] {.async.} =
  return "hello"
discard f().then((s : string) => console.log(s))
nim js -d:nimExperimentalAsyncjsThen test.nim
... [successX]
It works! Thanks @DomoSkrat.