[{"name":"Flow","comment":" Write effectful Elm logic as composable steps - no `Msg` type, no `update` function.\n\nEvent 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\n@docs Flow\n\n\n# Composing flows\n\n@docs pure, map, andThen, join, ap, flap, compose, seq, return, traverse, mapM\n\n\n# Control flow\n\n@docs if_, when, unless, bracket_\n\n\n# Terminating a fiber\n\n@docs none, assertJust, assertOk, assertCondition, fromMaybe\n\n\n# Reading and writing the model\n\n@docs get, set, modify\n\n\n# Optics\n\n@docs try, forAll, getAll, over, setAll, ifHas, whenHas, unlessHas, setting, locking\n\n\n# Zooming into sub-models\n\n@docs viaLens, viaPrism, replace\n\n\n# Commands and tasks\n\n@docs lift, liftUpdate, performTask, attemptTask, attemptTaskWith\n\n\n# Concurrency\n\n@docs batch, batchM, async, gather, gather_, Codec\n\n\n# Rendering\n\n@docs yield, forceRendering\n\n\n# Channels\n\nDescribe an event source with a `ChannelSpec`: use `connect` when you have both\na subscription source and a command to kick it off, or `listen` when\nsubscriptions alone are enough. Then consume events with `await`, `subscribe`,\nor `subscribeWhile`, each of which opens a live `Channel` from the spec.\n\n@docs ChannelSpec, Channel, ChannelKey\n@docs connect, listen, filterChannel\n@docs await, subscribe, subscribeWhile\n@docs openChannel, nextOnChannel\n@docs ffi\n\n\n# Running a program\n\n@docs Program, element, document, application\n\n","unions":[{"name":"Channel","comment":" One live opening of a `ChannelSpec`. Receive further values from it with\n`nextOnChannel`.\n","args":["a"],"cases":[]},{"name":"ChannelSpec","comment":" A description of how to connect an external event source to a `Flow`\npipeline. A spec does nothing by itself and can be opened any number of times,\nincluding concurrently; each opening is a separate `Channel`.\n","args":["a"],"cases":[]},{"name":"Codec","comment":" How to turn a value into JSON and back: an encoder and a decoder that\naccepts whatever the encoder produces.\n\n    userCodec : Flow.Codec User\n    userCodec =\n        Flow.Codec encodeUser userDecoder\n\n","args":["a"],"cases":[["Codec",["a -> Json.Encode.Value","Json.Decode.Decoder a"]]]},{"name":"Flow","comment":" A description of a computation that can read and write state `s` and\neventually produces a value of type `a`.\n","args":["s","a"],"cases":[]}],"aliases":[{"name":"ChannelKey","comment":" Key identifying a `Channel`.\n\nOpening a spec creates a fresh key and passes it to the spec's command. The\nchannel keeps that key for its whole lifetime, so the external source can tag\nits values with it and `filterChannel` can match them.\n\n","args":[],"type":"String.String"},{"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.Runtime s a ) (Flow.RuntimeMsg 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":"attemptTaskWith","comment":" Run a `Task` and feed its `Result` into a continuation.\n\n    Flow.attemptTaskWith\n        (\\result ->\n            case result of\n                Ok data ->\n                    Flow.modify (\\m -> { m | data = data })\n\n                Err err ->\n                    Flow.modify (\\m -> { m | error = Just err })\n        )\n        (Http.task { ... })\n\n","type":"(Result.Result e a -> Flow.Flow s b) -> Task.Task e a -> Flow.Flow s b"},{"name":"await","comment":" Suspend this Flow pipeline, open a channel from the spec, 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.ChannelSpec 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\n**WARNING:** `batchM` multiplies the number of fibers by the number of continuations.\nIf you wish to extend a multi-fiber Flow on a single branch, consider [`async`](#async).\n\nUse [`mapM`](#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.\n\n**WARNING:** If the computation forks into multiple fibers, the\nrelease step will run once per fiber. This also means that if the\ncomputation is terminating (which is equivalent to forking into 0 fibers),\nthen the release step will NOT run.\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":"connect","comment":" Build a spec from a subscription port and a command that opens or\nattaches it. The command fires each time the spec is opened, receiving the key\nof the new channel; `nextOnChannel` does not fire it again.\n\n    -- Port declarations:\n    --   port onMessage : (String -> msg) -> Sub msg\n    --   port subscribe : String -> Cmd msg\n    myChannel : ChannelSpec String\n    myChannel =\n        Flow.connect Ports.onMessage (\\_ -> Ports.subscribe \"myTopic\")\n\nTo drop or transform values before they reach the channel, wrap the port:\n\n    -- port onJson : (Json.Decode.Value -> msg) -> Sub msg\n    userChannel : ChannelSpec User\n    userChannel =\n        Flow.listen\n            (\\toMsg -> Ports.onJson (Json.Decode.decodeValue userDecoder >> Result.toMaybe >> Maybe.andThen toMsg))\n\n","type":"((a -> Maybe.Maybe a) -> Platform.Sub.Sub (Maybe.Maybe a)) -> (Flow.ChannelKey -> Platform.Cmd.Cmd Basics.Never) -> Flow.ChannelSpec a"},{"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":"ffi","comment":" Instead of creating a new port for every JavaScript interaction, you can use `Flow.ffi`\nto call many JS functions by name using a single pair of ports.\n\nYou provide the JS function name, an encoder for the outgoing data, and a decoder for\nthe return value. Under the hood, this helper uses a unique string key to automatically\nmatch JavaScript responses back to the correct `Flow` request.\n\n    -- 1. Define one pair of ports\n\n\n\n    port ffiOut : { key : String, fn : String, value : Json.Encode.Value } -> Cmd msg\n\n    port ffiIn : ({ key : String, value : Json.Decode.Value } -> msg) -> Sub msg\n\n    -- 2. Wire them into a helper\n    callJs : String -> (a -> Json.Encode.Value) -> Json.Decode.Decoder b -> a -> Flow s b\n    callJs =\n        Flow.ffi Ports.ffiOut Ports.ffiIn\n\n    -- 3. Call any JS function by name\n    fetchData : String -> Flow Model ()\n    fetchData id =\n        callJs \"fetchData\" Json.Encode.string decodeData id\n            |> Flow.andThen handleData\n\n    -- On the JavaScript side:\n    -- app.ports.ffiOut.subscribe(async (req) => {\n    --     if (req.fn === \"fetchData\") {\n    --         const data = await fetch(\"/api/data/\" + req.value).then(r => r.json());\n    --         app.ports.ffiIn.send({ key: req.key, value: data });\n    --     }\n    -- });\n\n","type":"({ key : String.String, fn : String.String, value : Json.Encode.Value } -> Platform.Cmd.Cmd Basics.Never) -> (({ key : String.String, value : Json.Decode.Value } -> Maybe.Maybe { key : String.String, value : Json.Decode.Value }) -> Platform.Sub.Sub (Maybe.Maybe { key : String.String, value : Json.Decode.Value })) -> String.String -> (a -> Json.Encode.Value) -> Json.Decode.Decoder b -> a -> Flow.Flow s b"},{"name":"filterChannel","comment":" Filter events for a spec. Only events for which the predicate returns\n`True` are forwarded; others are silently dropped.\n\nThe predicate receives the `ChannelKey` of the channel and the event payload.\nMatch on the key when the source tags values with it; otherwise you only need\nthe payload:\n\n    Flow.filterChannel (\\_ msg -> msg /= \"\") myChannel\n\n","type":"(Flow.ChannelKey -> a -> Basics.Bool) -> Flow.ChannelSpec a -> Flow.ChannelSpec 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":" Fork into n concurrent fibers for each matching value through an optic.\n\n    -- Only runs if a user is logged in\n    Flow.forAll MyLenses.currentUser\n        (\\user -> showWelcomeBanner user.name)\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":"gather","comment":" Join the branches of a batched Flow: wait until every branch has finished,\nthen continue once with all of their results.\n\nResults come in branch order (the order of the `batch` / `batchM` lists),\nnot in completion order. Branches that terminate with `none` contribute\nnothing.\n\nResults are stored outside the Flow while the other branches are still\nrunning, so they travel as JSON: provide a [`Codec`](#Codec) for the result\ntype. If its decoder rejects an encoded result, the joined Flow terminates.\n\n**WARNING:** the join waits for every branch forked inside it, including\nbackground branches started with [`async`](#async) or [`subscribe`](#subscribe).\nA branch that never finishes keeps the join waiting forever.\n\n    -- fetch all users concurrently, then store them in input order\n    Flow.batch userIds\n        |> Flow.andThen fetchUser\n        |> Flow.gather (Flow.Codec encodeUser userDecoder)\n        |> Flow.andThen (\\users -> Flow.modify (\\m -> { m | users = users }))\n\n","type":"Flow.Codec a -> Flow.Flow s a -> Flow.Flow s (List.List a)"},{"name":"gather_","comment":" Like [`gather`](#gather), but discards the results: wait until every\nbranch has finished, then continue once with `()`. Needs no `Codec`.\n\n**WARNING:** like `gather`, it waits for every branch forked inside it,\nincluding background branches.\n\n    -- save every draft concurrently, then report once\n    Flow.batch drafts\n        |> Flow.andThen saveDraft\n        |> Flow.gather_\n        |> Flow.seq (Flow.modify (\\m -> { m | status = AllSaved }))\n\n","type":"Flow.Flow s a -> Flow.Flow s ()"},{"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 MyLenses.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":"ifHas","comment":" Branch on whether an optic matches: run `onPresent` with the matched value\nwhen the optic succeeds, `onAbsent` otherwise. Exactly one branch runs.\n\n    Flow.ifHas\n        (currentProject << success)\n        openStream\n        closeStream\n\n","type":"Accessors.An_Optic pr ls s a -> (a -> Flow.Flow s b) -> Flow.Flow s b -> Flow.Flow s b"},{"name":"if_","comment":" Branch on a `Bool`: run `onTrue` when the condition holds, `onFalse` otherwise.\n\nExactly one branch runs.\n\n    Flow.if_ model.isLoggedIn\n        loadDashboard\n        redirectToLogin\n\n","type":"Basics.Bool -> Flow.Flow s a -> Flow.Flow s a -> Flow.Flow s a"},{"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":"listen","comment":" Build a spec from a subscription port when no startup command is needed.\n\n    -- Port declaration:\n    --   port onKeyDown : (String -> msg) -> Sub msg\n    keyChannel : ChannelSpec String\n    keyChannel =\n        Flow.listen Ports.onKeyDown\n\n","type":"((a -> Maybe.Maybe a) -> Platform.Sub.Sub (Maybe.Maybe a)) -> Flow.ChannelSpec 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 MyLenses.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":"nextOnChannel","comment":" Wait for the next value on an already opened channel, without firing the\nspec's command again.\n","type":"Flow.Channel a -> (a -> Maybe.Maybe (Flow.Flow s b)) -> Flow.Flow s b"},{"name":"none","comment":" The empty computation. Terminates the current branch without producing a\nvalue or changing state.\n\n**WARNING:** `none` is a 0-fiber program - it has no active fiber to carry\na continuation forward. Chaining it with `andThen`, `seq`, etc. produces\nanother 0-fiber program, so those continuations will never run.\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":"openChannel","comment":" Open a channel from a spec, firing the spec's command, and suspend until the\nfirst value arrives. The callback receives the opened `Channel` and each value:\n`Just flow` resumes with `flow`, `Nothing` ignores the value and keeps waiting.\n\nThis is the low-level primitive that `await` and `subscribe` are built on.\nPrefer those unless you need custom continuation logic.\n\n","type":"Flow.ChannelSpec a -> (Flow.Channel a -> a -> Maybe.Maybe (Flow.Flow s b)) -> Flow.Flow s b"},{"name":"over","comment":" Modify the value(s) targeted by an optic.\n\n    Flow.over MyLenses.count (\\n -> n + 1)\n\n","type":"Accessors.An_Optic pr ls s a -> (a -> a) -> Flow.Flow s ()"},{"name":"performTask","comment":" Run an infallible `Task` and produce its result.\n\n    Flow.performTask (Task.succeed 42)\n        |> Flow.andThen (\\n -> Flow.modify (\\m -> { m | count = n }))\n\n","type":"Task.Task Basics.Never a -> Flow.Flow s a"},{"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 `viaLens` is built on. Use `viaLens` in normal code;\nreach for `replace` only when you need a custom traversal that optics cannot\nexpress.\n\n","type":"Flow.Flow b a -> (a -> Flow.Flow b ()) -> Flow.Flow a x -> Flow.Flow b x"},{"name":"return","comment":" Shorthand for \\`Flow.seq (Flow.pure a).\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 MyLenses.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 MyLenses.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. It never produces a value of its own; use `Flow.map never` to\nfit it where another result type is expected.\n\n    listenForever : Flow Model ()\n    listenForever =\n        Flow.subscribe\n            (\\msg -> Flow.modify (\\m -> { m | latestMessage = msg }))\n            myChannel\n            |> Flow.map never\n\n","type":"(a -> Flow.Flow s ()) -> Flow.ChannelSpec a -> Flow.Flow s Basics.Never"},{"name":"subscribeWhile","comment":" Like `subscribe`, but stops when the predicate returns `False`.\nThe predicate receives both the current model and the incoming value, so\ncancellation can be based on model state, the value itself, or both.\nCancellation is lazy: the check runs on each incoming message, not\nimmediately when the model changes.\n\n    -- stop based on model state alone\n    Flow.subscribeWhile (\\model _ -> model.listening) handleMessage myChannel\n\n    -- stop on a specific sentinel value\n    Flow.subscribeWhile (\\_ msg -> msg /= \"disconnect\") handleMessage myChannel\n\n","type":"(s -> a -> Basics.Bool) -> (a -> Flow.Flow s ()) -> Flow.ChannelSpec a -> Flow.Flow s Basics.Never"},{"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 MyLenses.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":"unless","comment":" Run a Flow only when the condition is `False`, otherwise produce `()`.\n\n    Flow.unless model.isCached fetchFromServer\n\n","type":"Basics.Bool -> Flow.Flow s () -> Flow.Flow s ()"},{"name":"unlessHas","comment":" Run a Flow only when an optic does NOT match. A match produces `Flow.pure ()`.\n\n    Flow.unlessHas (currentProject << success) handleMissingProject\n\n","type":"Accessors.An_Optic pr ls s a -> Flow.Flow s () -> Flow.Flow s ()"},{"name":"viaLens","comment":" Embed a `Flow inner a` into a larger model `outer` through a lens. All state\nreads and writes inside the sub-flow are transparently routed through the lens.\n\nThis is the primary tool for reusable components: write a self-contained `Flow`\nagainst a sub-model type, then embed it anywhere that sub-model appears by\npassing in the appropriate lens.\n\n    -- SelectState is a reusable component with its own Flow logic\n    handleArrowDown : Flow SelectState ()\n    handleArrowDown =\n        Flow.get\n            |> Flow.map (get activeIndex)\n            |> Flow.andThen (\\i -> Flow.modify (set activeIndex (i + 1)))\n\n    -- Embed it into the parent model through a lens\n    Flow.viaLens MyLenses.selectState handleArrowDown\n\n","type":"Accessors.A_Lens pr outer inner -> Flow.Flow inner a -> Flow.Flow outer a"},{"name":"viaPrism","comment":" Embed a `Flow inner a` into a larger model `outer` through a prism.\n\nWhen the prism matches, the sub-flow runs with its state routed through the\nprism and its result is returned as `Just`. When the prism does not match, the\nsub-flow is skipped and the result is `Nothing`. If the prism stops matching\nwhile the sub-flow is suspended (for example across `await`), the sub-flow\nstops there and produces `Nothing`.\n\n    -- Run a component only while the model holds its active variant\n    Flow.viaPrism MyLenses.activePage handlePageEvent\n\n","type":"Accessors.A_Prism ls outer inner -> Flow.Flow inner a -> Flow.Flow outer (Maybe.Maybe a)"},{"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":"whenHas","comment":" Run a Flow only when an optic matches. No match produces `Flow.pure ()`.\n\n    Flow.whenHas (currentProject << success) openStream\n\n","type":"Accessors.An_Optic pr ls s a -> (a -> 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":[]}]