{"id":31103828,"url":"https://github.com/peterszerzo/elm-porter","last_synced_at":"2025-09-17T02:58:52.087Z","repository":{"id":52696834,"uuid":"106931912","full_name":"peterszerzo/elm-porter","owner":"peterszerzo","description":"Elm ports' wrapper for uncomplicated request-response-style communication","archived":false,"fork":false,"pushed_at":"2021-04-20T19:40:04.000Z","size":44,"stargazers_count":29,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-14T23:57:17.802Z","etag":null,"topics":["elm","ports","request-response"],"latest_commit_sha":null,"homepage":null,"language":"Elm","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peterszerzo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-14T13:54:06.000Z","updated_at":"2021-11-24T10:31:16.000Z","dependencies_parsed_at":"2022-08-22T07:40:29.477Z","dependency_job_id":null,"html_url":"https://github.com/peterszerzo/elm-porter","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/peterszerzo/elm-porter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterszerzo%2Felm-porter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterszerzo%2Felm-porter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterszerzo%2Felm-porter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterszerzo%2Felm-porter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peterszerzo","download_url":"https://codeload.github.com/peterszerzo/elm-porter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterszerzo%2Felm-porter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275526439,"owners_count":25480460,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elm","ports","request-response"],"created_at":"2025-09-17T02:58:49.143Z","updated_at":"2025-09-17T02:58:52.068Z","avatar_url":"https://github.com/peterszerzo.png","language":"Elm","funding_links":[],"categories":[],"sub_categories":[],"readme":"# elm-porter\n\nPort message manager that emulate a request-response style communication, a'la `Http.send Response request`.\n\n## Example\n\nRun the example like so:\n\n`cd ./example`\n\n`elm-reactor`\n\nNavigate to: `http://localhost:8000/index.html`\n\n## How it works\n\n```elm\nport module Example exposing (..)\n\nimport Porter\nimport Html exposing (Html, text)\nimport Json.Encode as Encode\nimport Json.Decode as Decode\n\n\n-- Configure Porter\n\n\nport outgoing : Encode.Value -\u003e Cmd msg\n\n\nport incoming : (Decode.Value -\u003e msg) -\u003e Sub msg\n\n\nporterConfig : Porter.Config String String Msg\nporterConfig =\n    { outgoingPort = outgoing\n    , incomingPort = incoming\n\n    -- Porter works with a single Request and Response data types. They can both be anything, as long as you supply decoders :)\n    , encodeRequest = Encode.string\n    , decodeResponse = Decode.string\n    -- Porter uses a message added to your Msg type for its internal communications (See `type Msg` below)\n    , porterMsg = PorterMsg\n    }\n\n\n\n-- Application model\n\n\ntype alias Model =\n    { porter : Porter.Model String String Msg\n    , response : String\n    }\n\n\ninit : ( Model, Cmd Msg )\ninit =\n    ( { porter = Porter.init\n      , response = \"\"\n      }\n      -- Send a request through porter, specifying the response handler directly\n      , Porter.send porterConfig Receive (Porter.simpleRequest \"Reverse me!\")\n    )\n\n\n\n-- Message includes Porter's message\n\n\ntype Msg\n    = PorterMsg (Porter.Msg String String Msg)\n    | Receive String\n\n\n\n-- Update porter accordingly\n\n\nupdate : Msg -\u003e Model -\u003e ( Model, Cmd Msg )\nupdate msg model =\n    case msg of\n        PorterMsg porterMsg -\u003e\n            let\n                ( porterModel, porterCmd ) =\n                    Porter.update porterConfig porterMsg model.porter\n            in\n                ( { model | porter = porterModel }, porterCmd )\n\n        Receive response -\u003e\n            ( { model | response = response }, Cmd.none )\n\n\n\n-- Set up porter's subscriptions\n\n\nsubscriptions : Model -\u003e Sub Msg\nsubscriptions model =\n    Porter.subscriptions porterConfig\n\n\n\n-- Any view you like\n\n\nview : Model -\u003e Html Msg\nview model =\n    text (toString model)\n\n\n\n--\n\n\nmain : Program Never Model Msg\nmain =\n    Html.program\n        { init = init\n        , update = update\n        , subscriptions = subscriptions\n        , view = view\n        }\n```\n\n## Handling messages in JS\n\nOutgoing messages into JavaScript as JSON, with an id that Porter generates and uses to match up with response handlers.\n\n```js\nconst app = Elm.Example.fullscreen()\napp.ports.outgoing.subscribe(msgWithId =\u003e {\n  const id = msgWithId.id\n  const request = msgWithId.msg\n  // Reverse response\n  const response = request.split(\"\").reverse().join(\"\")\n  // Simply include the same `id` and the response under the `msg` key.\n  app.ports.incoming.send({\n    id: id,\n    msg: response\n  })\n})\n```\n\n## Chaining Requests\n\nIf you want to perform multiple requests where some of these request depend on responses from other requests, you can use `Porter.request` in combination with `Porter.andThen` and `Porter.sendRequest`.\n\n```elm\nPorter.simpleRequest (\"Reverse me too!\")\n  |\u003e Porter.andThen (\\reversedStr -\u003e Porter.simpleRequest (reversedStr ++ \" The Quick Brown Fox!\"))\n  |\u003e Porter.andThen (\\reversedStr -\u003e Porter.simpleRequest (reversedStr ++ \" A man a plan a canal: panama\"))\n  |\u003e Porter.sendRequest porterConfig Receive\n```\n\n\n## Changelog\n\n### 3.0\n\n- Merge `Porter.Multi` into `Porter` so now there is a single way to send requests.\n- Introduce `simpleRequest` in addition to `request` to cover the simple use-case when the response is not converted.\n- Introduce `succeed` to expose short-circuit functionality.\n- Remove `andThenResult` - use `succeed` and work with `Result` values directly instead.\n\n###  2.0\n\n- The `Porter.Config` type now has a `porterMsg`-field.\n- Signature of `Porter.send` was changed: \n  - It now takes the `porterConfig` as argument, meaning (in combination with the previous change) that `Cmd.map`ping the result to your Msg type is no longer necessary because this is handled for you.\n  - Requests are now constructed using `Porter.request` and can be chained using `Porter.andThen` before passing them off to `Porter.send`. \n\nSo: Where in Version 1 you'd use `Porter.send responseHandler request`, you'd now use `Porter.send porterConfig responseHandler (Porter.request request)`.\n\n\n### 1.0\n\nFirst stable release\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeterszerzo%2Felm-porter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeterszerzo%2Felm-porter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeterszerzo%2Felm-porter/lists"}