You can’t mix @module with new@send. First you need to factor out the new binding into your own external, which is then used together with your @send bindings.
Here is a full port of the midi-writer-js README example:
// MidiWriter.res
module Event = {
type t
@new @module("midi-writer-js")
external programChangeEvent: {"instrument": int} => t = "ProgramChangeEvent"
@new @module("midi-writer-js")
external noteEvent: ({"pitch": array<string>, "duration": string}) => t = "NoteEvent"
}
module Track = {
type t
@module("midi-writer-js") @new external make: unit => t = "Track"
@send external addEvent: (t, Event.t) => unit = "addEvent"
}
module Writer = {
type t
@module("midi-writer-js") @new external make: (Track.t) => t = "default"
@send external dataUri: t => string = "dataUri"
}
let _ = {
let track = Track.make()
let change = Event.programChangeEvent({"instrument": 1})
track->Track.addEvent(change)
let note = Event.noteEvent({"pitch": ["C4", "D4", "E4"], "duration": "4"})
track->Track.addEvent(note)
let write = Writer.make(track)
write->Writer.dataUri->Js.log
}
Amazing, thank you.
It’s a conceptual challenge to master this.
I only had to change the line @module("midi-writer-js") @new external make: (Track.t) => t = "default"
to @module("midi-writer-js") @new external make: (Track.t) => t = "Writer"
What’s most amazing is that the generated javascript looks exactly as the original from the README example, except for the added exports and indentation.