421anon/elm-flow/4.0.0

NOTE: the latest version is 6.0.2

Flow.Channel

Channel primitives for connecting external event sources to Flow.

Describe an event source with a ChannelSpec: use connect when you have both a subscription source and a command to kick it off, or join when subscriptions alone are enough. Then consume events with Flow.await, Flow.subscribe, or Flow.subscribeWhile, each of which opens a live Channel from the spec.

type ChannelSpec s a

A description of how to connect an external event source to a Flow pipeline. A spec does nothing by itself and can be opened any number of times, including concurrently; each opening is a separate Channel.

type Channel s a

One live opening of a ChannelSpec. Receive further values from it with next.

type alias ChannelKey =
String

Key identifying a Channel.

Opening a spec creates a fresh key and passes it to the spec's command. The channel keeps that key for its whole lifetime, so the external source can tag its values with it and filter can match them.

((a -> Maybe (Flow s a)) -> Sub (Maybe (Flow s a)))
-> (ChannelKey -> Cmd Never)
-> ChannelSpec s a

Build a spec from a subscription source and a command that opens or attaches it. The command fires each time the spec is opened, receiving the key of the new channel; next does not fire it again.

-- Port declarations:
--   port onMessage : (String -> msg) -> Sub msg
--   port subscribe : String -> Cmd msg
myChannel : ChannelSpec Model String
myChannel =
    Flow.Channel.connect
        (\callback -> Ports.onMessage callback)
        (\_ -> Ports.subscribe "myTopic")
((a -> Maybe (Flow s a)) -> Sub (Maybe (Flow s a)))
-> ChannelSpec s a

Build a spec from a subscription source when no startup command is needed.

-- Port declaration:
--   port onKeyDown : (String -> msg) -> Sub msg
keyChannel : ChannelSpec Model String
keyChannel =
    Flow.Channel.join (\callback -> Ports.onKeyDown callback)
filter : (ChannelKey -> a -> Bool) -> ChannelSpec s a -> ChannelSpec s a

Filter events for a spec. Only events for which the predicate returns True are forwarded; others are silently dropped.

The predicate receives the ChannelKey of the channel and the event payload. Match on the key when the source tags values with it; otherwise you only need the payload:

Flow.Channel.filter (\_ msg -> msg /= "") myChannel
open : ChannelSpec s a -> (Channel s a -> a -> Maybe (Flow s a)) -> Flow s a

Open a channel from a spec, firing the spec's command, and suspend until the first value arrives. The callback receives the opened Channel and each value: Just flow resumes with flow, Nothing ignores the value and keeps waiting.

This is the low-level primitive that Flow.await and Flow.subscribe are built on. Prefer those unless you need custom continuation logic.