A Quick Example
In the next section you'll learn about the Flow architecture and how update,
audio, view, and listen come together to form a complete application, but for
now here is a typical counter app with an audio twist.
import { Program, Effect, Action, Audio, DOM } from "@flow/framework"
const { Element, Attribute, Event } = DOM
const { Node, Property } = Audio
const App = Program.instrument(init, update, audio, view, listen)
function init () {
return 1
}
function update ({ action }, model) {
switch (action) {
case "Increment":
return [model + 1, Effect.none()]
case "Decrement":
return [model - 1, Effect.none()]
}
}
function audio (model) {
return Node.oscillator([ Property.frequency(440) ], [
Node.gain([ Property.gain(model / 10) ], [
Node.dac()
])
])
}
function view (model) {
return Element.div([], [
Element.button([ Attribute.className(".inc") ], [ "+" ]),
Element.div([], [ model.toString() ]),
Element.button([ Attribute.className(".dec") ], [ "-" ])
])
}
function listen (model) {
return [
Event.click(".inc", _ => Action("Increment")),
Event.click(".dec", _ => Action("Decrement"))
]
}
App.use(Event)
App.start({
content: new AudioContext(),
root: document.querySelector("#app")
})
Notice how each element is entirely decoupled. The runtime is in charge of
slotting all these pieces together, so your application becomes a highly modular.
It's now trivial to try different views or different audio graphs without
wasting time hooking everything up.