[{"name":"Flow","comment":" A monadic interface for _The Elm Architecture_, bridging synchronous state\nmodifications with asynchronous subscriptions via Channels.\n\n**Note:** This library merges concepts from two community packages:\n\n  - `chrilves/elm-io` (The free monad interface for TEA)\n  - `brian-watkins/elm-procedure` (Continuation-passing channels and subscriptions)\n\n\n## The Flow pattern\n\nIn a traditional TEA application you define a central `Msg` type and an\n`update : Msg -> Model -> (Model, Cmd Msg)` function that dispatches on it.\nWith `Flow` there is no separate `Msg` type and no central dispatch table.\n\nYour event handlers and subscriptions produce `Flow` values directly:\n\n    -- a button click\n    Html.button\n        [ Html.Events.onClick (Flow.modify (\\m -> { m | count = m.count + 1 })) ]\n        [ Html.text \"+\" ]\n\n    -- an HTTP response\n    Flow.lift (Http.get { url = \"/api/data\", expect = Http.expectJson handleResult decoder })\n\nThe runtime executes each `Flow` immediately as it arrives, keeping behaviour\nco-located with the event that triggers it.\n\n@docs Flow\n\n\n# Running a web application\n\n@docs Program, element, document, application\n\n\n# Subscriptions and channels\n\n@docs await, subscribe\n\n\n# Lifting values and commands into Flow\n\n@docs pure, lift, liftUpdate\n\n\n# Reading and writing the model\n\n@docs get, set, modify\n\n\n# Monadic operations\n\n@docs map, andThen, join, ap, flap, compose, seq, traverse, mapM\n\n\n# Zooming into sub-models via optics\n\n@docs replace\n\n\n# Terminating a computation\n\n@docs none\n\n\n# Forcing Elm to re-render\n\n@docs yield, forceRendering\n\n\n# Batching\n\n@docs batch, batchM\n\n\n# Assertions and guards\n\n@docs assertJust, assertOk, assertCondition, fromMaybe\n\n\n# Task helpers\n\n@docs attemptTask\n\n\n# Optics helpers\n\n@docs try, forAll, getAll, over, setAll, via\n\n\n# Control flow\n\n@docs when, return, async, bracket_, setting, locking\n\n","unions":[],"aliases":[{"name":"Flow","comment":" A description of a computation that can read and write state `s` and\neventually produces a value of type `a`.\n\n`Flow` is a free monad: values of this type are data structures that the\nruntime interprets, rather than functions that run immediately. This makes\nit possible to batch, sequence, and transform computations before any\nside-effects take place.\n\n","args":["s","a"],"type":"Flow.Internal.Flow s a"},{"name":"Program","comment":" The concrete Elm `Platform.Program` type produced by `Flow.element`,\n`Flow.document`, and `Flow.application`.\n","args":["flags","s","a"],"type":"Platform.Program flags ( s, Flow.Program.Model (Flow.Flow s a) ) (Flow.Program.RuntimeMsg (Flow.Flow s a))"}],"values":[{"name":"andThen","comment":" Chain two Flow computations. The second receives the value produced by the\nfirst.\n\n    Flow.get\n        |> Flow.andThen (\\m -> Flow.pure m.count)\n\n","type":"(a -> Flow.Flow s b) -> Flow.Flow s a -> Flow.Flow s b"},{"name":"ap","comment":" Apply a function wrapped in Flow to a value wrapped in Flow.\n\n    Flow.pure (\\n -> n + 1)\n        |> Flow.ap (Flow.pure 41)\n    -- produces 42\n\n","type":"Flow.Flow s (a -> b) -> Flow.Flow s a -> Flow.Flow s b"},{"name":"application","comment":" Like `document` but also handles URL changes, for single-page applications.\n\n    main =\n        Flow.application\n            { init = \\_ url key -> ( initialModel key, loadPage url )\n            , view = view\n            , subscriptions = \\_ -> Sub.none\n            , onUrlRequest = handleUrlRequest\n            , onUrlChange = handleUrlChange\n            }\n\n","type":"{ init : flags -> Url.Url -> Browser.Navigation.Key -> ( s, Flow.Flow s a ), view : s -> Browser.Document (Flow.Flow s a), subscriptions : s -> Platform.Sub.Sub (Flow.Flow s a), onUrlRequest : Browser.UrlRequest -> Flow.Flow s a, onUrlChange : Url.Url -> Flow.Flow s a } -> Flow.Program flags s a"},{"name":"assertCondition","comment":" Continue only if the predicate holds for the produced value, terminate\nwith `none` otherwise.\n\n    Flow.get\n        |> Flow.assertCondition (\\m -> m.count > 0)\n        |> Flow.andThen doSomethingWithPositiveCount\n\n","type":"(a -> Basics.Bool) -> Flow.Flow s a -> Flow.Flow s a"},{"name":"assertJust","comment":" Continue only if the value is `Just`, terminate with `none` otherwise.\n\n    fetchUser userId\n        |> Flow.assertJust\n        |> Flow.andThen renderUser\n\n","type":"Flow.Flow s (Maybe.Maybe a) -> Flow.Flow s a"},{"name":"assertOk","comment":" Continue only if the result is `Ok`, silently terminate on `Err`.\n\n    decodeResponse body\n        |> Flow.assertOk\n        |> Flow.andThen handleData\n\n","type":"Flow.Flow s (Result.Result e a) -> Flow.Flow s a"},{"name":"async","comment":" Fire a Flow as a background branch and immediately continue with `()`.\nThe background branch runs concurrently; its state writes are interleaved\nwith the rest of the batch.\n\n    Flow.async (longRunningSync model)\n        |> Flow.seq nextStep\n\n","type":"Flow.Flow s a -> Flow.Flow s ()"},{"name":"attemptTask","comment":" Fire a `Task` for its side-effects and ignore the result (both `Ok` and\n`Err` are discarded). Useful for fire-and-forget operations such as writing\nto `localStorage` via a port task.\n\n    Flow.attemptTask (Ports.saveToLocalStorage key value)\n\n","type":"Task.Task e a -> Flow.Flow s ()"},{"name":"await","comment":" Suspend this Flow pipeline, open a Channel, and resume when a value arrives.\n\n    type alias Model =\n        { latestMessage : String }\n\n    listenOnce : Flow Model ()\n    listenOnce =\n        Flow.await myChannel\n            |> Flow.andThen (\\msg -> Flow.modify (\\m -> { m | latestMessage = msg }))\n\n","type":"Flow.Channel.Channel s a -> Flow.Flow s a"},{"name":"batch","comment":" Run several independent Flow branches concurrently, one per list element.\nEach branch shares the same initial state snapshot; state writes from earlier\nbranches are visible to later ones (left-to-right evaluation order).\n\n    Flow.batch [ 1, 2, 3 ]\n        |> Flow.map (\\n -> n * 2)\n    -- forks into three branches producing 2, 4, 6\n\n","type":"List.List a -> Flow.Flow s a"},{"name":"batchM","comment":" Run a list of Flow computations as concurrent branches. Each branch runs\nindependently; the continuation (via `andThen`) is invoked once per branch\nwith that branch's individual result.\n\nUse `mapM` instead if you want the results collected into a `List`.\n\n    -- fire three notifications in parallel\n    Flow.batchM [ notifyAlice, notifyBob, notifyCarol ]\n\n    -- continuation runs once per branch, not once with a List\n    Flow.batchM [ fetchUserA, fetchUserB ]\n        |> Flow.andThen (\\user -> renderUser user)\n\n","type":"List.List (Flow.Flow s a) -> Flow.Flow s a"},{"name":"bracket_","comment":" Acquire a resource, run a computation, then release the resource —\neven if the computation terminates early with `none`.\n\n    Flow.bracket_\n        (Flow.modify (\\m -> { m | loading = True }))\n        (Flow.modify (\\m -> { m | loading = False }))\n        fetchData\n\n","type":"Flow.Flow s a -> Flow.Flow s b -> Flow.Flow s c -> Flow.Flow s c"},{"name":"compose","comment":" Compose two Kleisli arrows (functions returning Flow).\n\n    handleResponse : Response -> Flow Model ()\n    handleResponse =\n        Flow.compose persistToDisk fetchData\n\n","type":"(b -> Flow.Flow m c) -> (a -> Flow.Flow m b) -> a -> Flow.Flow m c"},{"name":"document","comment":" Like `element` but the view function returns a full `Document`, allowing\nyou to control the page `<title>`.\n\n    main =\n        Flow.document\n            { init = \\_ -> ( initialModel, loadData )\n            , view = view -- returns { title = \"…\", body = […] }\n            , subscriptions = \\_ -> Sub.none\n            }\n\n","type":"{ init : flags -> ( s, Flow.Flow s a ), view : s -> Browser.Document (Flow.Flow s a), subscriptions : s -> Platform.Sub.Sub (Flow.Flow s a) } -> Flow.Program flags s a"},{"name":"element","comment":" Build a standard `Browser.element` program whose messages are `Flow`\ncomputations.\n","type":"{ init : flags -> ( s, Flow.Flow s a ), view : s -> Html.Html (Flow.Flow s a), subscriptions : s -> Platform.Sub.Sub (Flow.Flow s a) } -> Flow.Program flags s a"},{"name":"flap","comment":" Flipped `ap` — apply a value to a function, both wrapped in Flow.\n\n    Flow.pure 41\n        |> Flow.flap (Flow.pure (\\n -> n + 1))\n    -- produces 42\n\n","type":"Flow.Flow s a -> Flow.Flow s (a -> b) -> Flow.Flow s b"},{"name":"forAll","comment":" Read a value through an optic, terminating with `none` if the optic does\nnot match.\n\n    Flow.forAll MyModel.selectedItem\n        (\\item -> renderItem item)\n\n","type":"Accessors.An_Optic pr ls s a -> (a -> Flow.Flow s b) -> Flow.Flow s b"},{"name":"forceRendering","comment":" Wrap a Flow so that every state write inside it is followed by a render\ncycle, giving the browser a chance to repaint between steps.\n\nUseful when you need the UI to visually reflect intermediate states during a\nmulti-step computation rather than only showing the final result.\n\n    -- the UI repaints after each step, not just at the end\n    Flow.forceRendering <|\n        Flow.mapM [ setStepOne, setStepTwo, setStepThree ]\n\n","type":"Flow.Flow a b -> Flow.Flow a b"},{"name":"fromMaybe","comment":" Unwrap a `Maybe` and feed the inner value into a continuation, or\nterminate with `none` if the `Maybe` is `Nothing`.\n\n    Flow.fromMaybe model.selectedId\n        (\\id -> fetchItem id |> Flow.andThen renderItem)\n\n","type":"Maybe.Maybe a -> (a -> Flow.Flow s b) -> Flow.Flow s b"},{"name":"get","comment":" Read the current model.\n\n    Flow.get\n        |> Flow.andThen (\\model -> Flow.pure model.count)\n\n","type":"Flow.Flow s s"},{"name":"getAll","comment":" Read all values targeted by an optic (useful for traversals).\n\n    Flow.getAll MyModel.allItems\n        (\\items -> Flow.pure (List.length items))\n\n","type":"Accessors.An_Optic pr ls s a -> (List.List a -> Flow.Flow s b) -> Flow.Flow s b"},{"name":"join","comment":" Flatten a nested `Flow s (Flow s a)` into `Flow s a`.\n\n    Flow.pure (Flow.pure 42)\n        |> Flow.join\n    -- same as Flow.pure 42\n\n","type":"Flow.Flow s (Flow.Flow s a) -> Flow.Flow s a"},{"name":"lift","comment":" Lift an Elm `Cmd` into Flow. The command is executed and its result\nbecomes the value produced by this Flow step.\n\n    Flow.lift (Http.get { url = \"/ping\", expect = Http.expectString identity })\n        |> Flow.andThen handleResponse\n\n","type":"Platform.Cmd.Cmd a -> Flow.Flow s a"},{"name":"liftUpdate","comment":" Lift a classic TEA `update`-style function into Flow. Reads the current\nmodel, applies the function, writes the new model, and emits any commands.\n\n    Flow.liftUpdate (MyOldModule.update msg)\n\n","type":"(s -> ( s, Platform.Cmd.Cmd a )) -> Flow.Flow s a"},{"name":"locking","comment":" Run a computation only if a `Bool` lens is currently `False`, and hold\nit at `True` for the duration. Subsequent calls while the lock is held are\nsilently dropped.\n\n    Flow.locking MyModel.isSaving saveRecord\n\n","type":"Accessors.A_Lens pr s Basics.Bool -> Flow.Flow s () -> Flow.Flow s ()"},{"name":"map","comment":" Transform the value produced by a Flow without changing state.\n\n    Flow.pure 3\n        |> Flow.map (\\n -> n * 2)\n    -- produces 6\n\n","type":"(a -> b) -> Flow.Flow s a -> Flow.Flow s b"},{"name":"mapM","comment":" Sequence a list of Flow computations, collecting all results.\n\nEquivalent to `traverse identity`.\n\n    Flow.mapM [ step1, step2, step3 ]\n        |> Flow.andThen finalize\n\n","type":"List.List (Flow.Flow s a) -> Flow.Flow s (List.List a)"},{"name":"modify","comment":" Apply a function to transform the model.\n\n    Flow.modify (\\m -> { m | count = m.count + 1 })\n\n","type":"(s -> s) -> Flow.Flow s ()"},{"name":"none","comment":" The empty computation — terminates the current branch without producing a\nvalue or changing state. Use this as the natural end-point of a pipeline.\n\n    Flow.get\n        |> Flow.andThen\n            (\\m ->\n                if m.ready then\n                    doWork\n\n                else\n                    Flow.none\n            )\n\n","type":"Flow.Flow s a"},{"name":"over","comment":" Modify the value(s) targeted by an optic.\n\n    Flow.over MyModel.count (\\n -> n + 1)\n\n","type":"Accessors.An_Optic pr ls s a -> (a -> a) -> Flow.Flow s ()"},{"name":"pure","comment":" Lift a plain value into Flow without performing any effects.\n\n    Flow.pure 42\n        |> Flow.map (\\n -> n + 1)\n    -- produces 43, state unchanged\n\n","type":"a -> Flow.Flow s a"},{"name":"replace","comment":" Re-interpret a `Flow a x` inside a larger context `Flow b x` by providing\na getter (`Flow b a`) and a setter (`a -> Flow b ()`).\n\nThis is the primitive that `via` and the other optics helpers are built on.\nUse `via` in normal code; reach for `replace` only when you need a custom\ntraversal that optics cannot express.\n\n","type":"Flow.Flow b a -> (a -> Flow.Flow b ()) -> Flow.Flow a x -> Flow.Flow b x"},{"name":"return","comment":" Run a Flow for its effects, then produce a fixed value `a` regardless of\nwhat the flow returned.\n\n    saveRecord\n        |> Flow.return \"saved\"\n\n","type":"a -> Flow.Flow s b -> Flow.Flow s a"},{"name":"seq","comment":" Run the piped Flow for its effects, discard its result, then run the\nargument Flow and return its result.\n\n    saveRecord\n        |> Flow.seq (Flow.pure \"saved!\")\n    -- runs saveRecord, then produces \"saved!\"\n\n","type":"Flow.Flow s b -> Flow.Flow s a -> Flow.Flow s b"},{"name":"set","comment":" Replace the model entirely.\n\n    Flow.set { count = 0 }\n\n","type":"s -> Flow.Flow s ()"},{"name":"setAll","comment":" Set the value(s) targeted by an optic.\n\n    Flow.setAll MyModel.status Loading\n\n","type":"Accessors.An_Optic pr ls s a -> a -> Flow.Flow s ()"},{"name":"setting","comment":" Set a `Bool` field to `True` for the duration of a computation, then\nrestore it to `False`. Useful for loading/busy flags.\n\n    Flow.setting MyModel.isLoading fetchData\n\n","type":"Accessors.An_Optic pr ls s Basics.Bool -> Flow.Flow s a -> Flow.Flow s a"},{"name":"subscribe","comment":" Open a channel and run the given handler for every value it produces,\nindefinitely.\n\n    listenForever : Flow Model ()\n    listenForever =\n        Flow.subscribe\n            (\\msg -> Flow.modify (\\m -> { m | latestMessage = msg }))\n            myChannel\n\n","type":"(a -> Flow.Flow s ()) -> Flow.Channel.Channel s a -> Flow.Flow s a"},{"name":"traverse","comment":" Map over a list with a function that returns Flow, collecting the results\nin order.\n\n    Flow.traverse fetchUser userIds\n        |> Flow.andThen renderAll\n\n","type":"(a -> Flow.Flow s b) -> List.List a -> Flow.Flow s (List.List b)"},{"name":"try","comment":" Read a value through an optic. Produces `Just a` if the optic matches,\n`Nothing` if it does not (e.g. a `Prism` pointing at the wrong variant).\n\n    Flow.try MyModel.selectedItem\n        (\\maybeItem ->\n            case maybeItem of\n                Just item ->\n                    renderItem item\n\n                Nothing ->\n                    showPlaceholder\n        )\n\n","type":"Accessors.An_Optic pr ls s a -> (Maybe.Maybe a -> Flow.Flow s b) -> Flow.Flow s b"},{"name":"via","comment":" Run a `Flow a x` in the context of a larger model `s`, using an optic to\nzoom in and out. State reads and writes inside the sub-flow are applied through\nthe optic.\n\n    Flow.via MyModel.editingRecord\n        (Flow.modify (\\r -> { r | name = newName }))\n\n","type":"Accessors.An_Optic pr ls s a -> Flow.Flow a x -> Flow.Flow s x"},{"name":"when","comment":" Run a Flow only when the condition is `True`, otherwise produce `()`.\n\n    Flow.when model.isLoggedIn savePreferences\n\n","type":"Basics.Bool -> Flow.Flow s () -> Flow.Flow s ()"},{"name":"yield","comment":" Yield a value back to the Elm runtime, allowing the browser to repaint,\nthen continue with the value. Equivalent to `Process.sleep 0`.\n\n    -- ensure the UI reflects intermediate state before a heavy computation\n    Flow.set loadingModel\n        |> Flow.seq (Flow.yield ())\n        |> Flow.seq heavyComputation\n\n","type":"a -> Flow.Flow s a"}],"binops":[]},{"name":"Flow.Channel","comment":" Channel primitives for connecting external event sources to `Flow`.\n\nUse `connect` when you have both a subscription source and a command to\nkick off the channel, or `join` when subscriptions alone are enough.\nThen consume events with `Flow.await` (one event), `Flow.Channel.acceptUntil`\n(events until a condition), or `Flow.subscribe` (all events indefinitely).\n\n@docs Channel\n@docs connect, join, filter\n@docs accept, acceptOne, acceptUntil\n\n","unions":[{"name":"Channel","comment":" An opaque handle describing how to connect an external event source to a\n`Flow` pipeline. Build one with `connect` or `join`, then pass it to\n`Flow.await` or `Flow.subscribe`.\n","args":["s","a"],"cases":[]}],"aliases":[],"values":[{"name":"accept","comment":" Subscribe to a channel and run the handler for every incoming event,\nindefinitely. The subscription runs for the lifetime of the program with\nno built-in way to stop it.\n\n    listenForever : Flow Model ()\n    listenForever =\n        Flow.Channel.accept\n            (\\msg -> Flow.modify (\\m -> { m | lastMessage = msg }))\n            myChannel\n\n","type":"(a -> Flow.Internal.Flow s ()) -> Flow.Channel.Channel s a -> Flow.Internal.Flow s a"},{"name":"acceptOne","comment":" Wait for the next single event from a channel and return it. The channel\nis closed after the first event arrives.\n\n    -- read one message then continue\n    Flow.Channel.acceptOne myChannel\n        |> Flow.andThen (\\msg -> Flow.modify (\\m -> { m | lastMessage = msg }))\n\n","type":"Flow.Channel.Channel s a -> Flow.Internal.Flow s a"},{"name":"acceptUntil","comment":" Wait for events from a channel, discarding each one until the predicate\nreturns `True`. Returns the first event that satisfies the predicate and\nthen closes the channel.\n\n    -- wait until the server sends \"done\"\n    Flow.Channel.acceptUntil (\\msg -> msg == \"done\") myChannel\n\n","type":"(a -> Basics.Bool) -> Flow.Channel.Channel s a -> Flow.Internal.Flow s a"},{"name":"connect","comment":" Build a channel from a subscription source and a command that opens or\nattaches it. The command is fired once when the channel is first awaited.\n\n    -- Port declarations:\n    --   port onMessage : (String -> msg) -> Sub msg\n    --   port subscribe : String -> Cmd msg\n\n    myChannel : Channel Model String\n    myChannel =\n        Flow.Channel.connect\n            (\\callback -> Ports.onMessage callback)\n            (\\_ -> Ports.subscribe \"myTopic\")\n\n","type":"((a -> Maybe.Maybe (Flow.Internal.Flow s a)) -> Platform.Sub.Sub (Maybe.Maybe (Flow.Internal.Flow s a))) -> (Flow.Channel.ChannelKey -> Platform.Cmd.Cmd (Flow.Internal.Flow s a)) -> Flow.Channel.Channel s a"},{"name":"filter","comment":" Filter events for a channel. Only events for which the predicate returns\n`True` are forwarded; others are silently dropped.\n\nThe predicate receives the internal channel key and the event payload.\nIn most cases you only need the payload:\n\n    Flow.Channel.filter (\\_ msg -> msg /= \"\") myChannel\n\n","type":"(Flow.Channel.ChannelKey -> a -> Basics.Bool) -> Flow.Channel.Channel s a -> Flow.Channel.Channel s a"},{"name":"join","comment":" Build a channel from a subscription source when no startup command is needed.\n\n    -- Port declaration:\n    --   port onKeyDown : (String -> msg) -> Sub msg\n\n    keyChannel : Channel Model String\n    keyChannel =\n        Flow.Channel.join (\\callback -> Ports.onKeyDown callback)\n\n","type":"((a -> Maybe.Maybe (Flow.Internal.Flow s a)) -> Platform.Sub.Sub (Maybe.Maybe (Flow.Internal.Flow s a))) -> Flow.Channel.Channel s a"}],"binops":[]}]