Rerouted (retagged, needs approval). The tag now points at a different commit than when this version was published. The Lamdera package server serves a copy recovered from https://github.com/421anon/elm-flow.
What we checked: Tag 2.1.0 is still on github.com/421anon/elm-flow; its commit a0f12ea9a25f is from 2026-03-20 12:05 UTC, after the version was published (2026-03-20 11:50 UTC); elm.json is byte-identical to package.elm-lang.org's; the exposed modules match docs.json; the zip's SHA-1 is not the published one and nothing else confirms its contents.
We could not verify this copy against what was published, so the Lamdera compiler asks before using it (y/n). Without a terminal, as in CI, it stops with an error unless approved:
lamdera make --auto-approve-package-rerouting approves rerouted versions for that run,LAMDERA_AUTO_APPROVE_PACKAGE_REROUTING=1 does the same for every run in that environment,LAMDERA_CACHE=off skips the Lamdera package server altogether: packages come from package.elm-lang.org and GitHub only, as with elm, and a rerouted version then fails to download.Details · package.elm-lang.org's zip: https://github.com/421anon/elm-flow/zipball/2.1.0/
Channel primitives for connecting external event sources to Flow.
Use connect when you have both a subscription source and a command to
kick off the channel, or join when subscriptions alone are enough.
Then consume events with Flow.await (one event), Flow.Channel.acceptUntil
(events until a condition), or Flow.subscribe (all events indefinitely).
Build a channel from a subscription source and a command that opens or attaches it. The command is fired once when the channel is first awaited.
-- Port declarations:
-- port onMessage : (String -> msg) -> Sub msg
-- port subscribe : String -> Cmd msg
myChannel : Channel Model String
myChannel =
Flow.Channel.connect
(\callback -> Ports.onMessage callback)
(\_ -> Ports.subscribe "myTopic")Build a channel from a subscription source when no startup command is needed.
-- Port declaration:
-- port onKeyDown : (String -> msg) -> Sub msg
keyChannel : Channel Model String
keyChannel =
Flow.Channel.join (\callback -> Ports.onKeyDown callback)Filter events for a channel. Only events for which the predicate returns
True are forwarded; others are silently dropped.
The predicate receives the internal channel key and the event payload. In most cases you only need the payload:
Flow.Channel.filter (\_ msg -> msg /= "") myChannelSubscribe to a channel and run the handler for every incoming event, indefinitely. The subscription runs for the lifetime of the program with no built-in way to stop it.
listenForever : Flow Model ()
listenForever =
Flow.Channel.accept
(\msg -> Flow.modify (\m -> { m | lastMessage = msg }))
myChannelWait for the next single event from a channel and return it. The channel is closed after the first event arrives.
-- read one message then continue
Flow.Channel.acceptOne myChannel
|> Flow.andThen (\msg -> Flow.modify (\m -> { m | lastMessage = msg }))Wait for events from a channel, discarding each one until the predicate
returns True. Returns the first event that satisfies the predicate and
then closes the channel.
-- wait until the server sends "done"
Flow.Channel.acceptUntil (\msg -> msg == "done") myChannel
An opaque handle describing how to connect an external event source to a
Flowpipeline. Build one withconnectorjoin, then pass it toFlow.awaitorFlow.subscribe.