{"id":16710771,"url":"https://github.com/overminddl1/elm-jsphoenix","last_synced_at":"2025-09-07T07:37:19.480Z","repository":{"id":149888382,"uuid":"64237978","full_name":"OvermindDL1/elm-jsphoenix","owner":"OvermindDL1","description":"Elm Port wrapper around Phoenix Socket/Presence javascript library to allow compatibility with existing javascript websocket usage","archived":false,"fork":false,"pushed_at":"2016-08-08T14:51:10.000Z","size":6,"stargazers_count":14,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T05:41:55.505Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/OvermindDL1.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-26T16:42:27.000Z","updated_at":"2017-02-06T15:55:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"ddcc2d3c-3660-46c2-a713-ff7836e990ed","html_url":"https://github.com/OvermindDL1/elm-jsphoenix","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/OvermindDL1/elm-jsphoenix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OvermindDL1%2Felm-jsphoenix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OvermindDL1%2Felm-jsphoenix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OvermindDL1%2Felm-jsphoenix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OvermindDL1%2Felm-jsphoenix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OvermindDL1","download_url":"https://codeload.github.com/OvermindDL1/elm-jsphoenix/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OvermindDL1%2Felm-jsphoenix/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274010098,"owners_count":25206763,"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-07T02:00:09.463Z","response_time":67,"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":[],"created_at":"2024-10-12T20:09:30.325Z","updated_at":"2025-09-07T07:37:19.438Z","avatar_url":"https://github.com/OvermindDL1.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# elm-jsphoenix\nElm Port wrapper around Phoenix Socket/Presence javascript library to allow compatibility with existing javascript websocket usage\n\n## Installation\nInclude the JSPhoenix.elm module however you wish.\n\nAdd the javascript file to your Phoenix brunch (or whatever you've replaced it with) build system to include in your Phoenix project (generally it should go in `web/static/js` or some subdirectory there-of, adjust the include below for where it is put, but it needs to be babel-transpiled).\n\nIn the javascript for your Phoenix project any Elm app that you instance just call the `setup_phoenix_socket_ports` from the setup_phoenix_socket_ports javascript module, such as by:\n```javascript\nimport socket from './socket'\nimport Elm from './elm' // Assuming your Elm mains compile to a ./elm.js in the same directory as your app.js\nimport setup_phoenix_socket_ports from 'setup_phoenix_socket_ports' // Or from where-ever\n\n\nlet socket_setup_once = false\nsocket.onOpen(() =\u003e {\n  $(document).ready(function(){\n    if(socket_setup_once) return\n    socket_setup_once = true\n\n    // Here setup all your usual javascript that also needs to use the websocket\n\n    let app = Elm.Main.embed(document.querySelector('#my-elm-container'))\n    setup_phoenix_socket_ports(app, socket)\n  }\n}\n```\n\nEven if you do not have any other javascript code using the socket this still ensures full compatibility of your Elm app with the Phoenix socket interface, heartbeats, recovery, and all.\n\n\n## Usage\nThe bindings are not absolutely complete to the javascript code, but rather a useful interface is exposed to Elm within its type system.\n\nThis is a brand new project and the documentation is not entirely complete, however the code is short and should be readable.\n\n### General usage is as follows\n\nConnect to a channel, specify presence sync ports and some message ports and how to use:\n```elm\nimport JSPhoenix exposing (ChannelEventMsg, ChanExitCB)\n\n-- Currently this next line does not work due to Elm bugs...\n--type alias RoomSyncState = List (JSPhoenix.PresenceObject {} {online_at : JSPhoenix.TimexDateTime, nick : String})\n-- So instead you have to do this mess for each of your presence sync object types because of Elm port bugs:\ntype alias RoomSyncMeta =\n  { phx_ref : String -- Until Elm bug is fixed, phx_ref should 'generally' always be here\n  , loc : String\n  , online_at : JSPhoenix.TimexDateTime\n  , nick : String\n  }\n\ntype alias RoomSyncState =\n  List ( String, { metas : List RoomSyncMeta } ) -- Until Elm bug is fixed 'metas' must *always* be here with a List of records\n\n\n-- Same bug issue as above, you should be able to do:\n--type alias RoomSyncEvent = JSPhoenix.PresenceObject {} {online_at : JSPhoenix.TimexDateTime, nick : String}\n-- Instead you have to do this mess for each presence sync event type\ntype alias RoomSyncEvent =\n  { id : String\n  , old : Maybe { String, List RoomSyncMeta }\n  , new : List ( String, List RoomSyncMeta )\n  }\n\n-- Custom messages, whatever fits your Phoenix app:\ntype alias RoomMessage =\n  { room_id : Int\n  , uid : Int\n  , inserted_at : JSPhoenix.TimexDateTime\n  , updated_at : JSPhoenix.TimexDateTime\n  , nick : String\n  , msg : String\n  }\n\ntype alias RoomMessages =\n  { msgs : List RoomMessage }\n\nport onRoomConnect : (ChannelEventMsg {} Int -\u003e msg) -\u003e Sub msg\nport onRoomInfo : (ChannelEventMsg {} Int -\u003e msg) -\u003e Sub msg\nport onRoomMsgsInit : (ChannelEventMsg RoomMessages Int -\u003e msg) -\u003e Sub msg\nport onRoomMsgsAdd : (ChannelEventMsg RoomMessages Int -\u003e msg) -\u003e Sub msg\nport onRoomSyncState : (ChannelEventMsg RoomSyncState Int -\u003e msg) -\u003e Sub msg\nport onRoomSyncJoin : (ChannelEventMsg RoomSyncEvent Int -\u003e msg) -\u003e Sub msg\nport onRoomSyncLeave : (ChannelEventMsg RoomSyncEvent Int -\u003e msg) -\u003e Sub msg\n\nconnect_room rid =\n  JSPhoenix.connect\n      { topic = room_id_to_topic rid\n      , timeout_ms = Nothing -- Just 10000 -- Default value is 10000 if Nothing is used\n      , chanCloseCB = Nothing\n      , chanErrorCB = Nothing\n      , syncState = Just { portName = \"onRoomSyncState\", cb_data = (int rid) }\n      , syncJoin = Just { portName = \"onRoomSyncJoin\", cb_data = (int rid) }\n      , syncLeave = Just { portName = \"onRoomSyncLeave\", cb_data = (int rid) }\n      , joinData = null\n      , joinEvents =\n          [ { portName = \"onRoomConnect\", msgID = \"ok\", cb_data = (int rid) }\n          ]\n      , onPorts =\n          [ { portName = \"onRoomInfo\", msgID = \"room:info\", cb_data = (int rid) }\n          , { portName = \"onRoomMsgsInit\", msgID = \"msgs:init\", cb_data = (int rid) }\n          , { portName = \"onRoomMsgsAdd\", msgID = \"msgs:add\", cb_data = (int rid) }\n          ]\n      }\n\nupdate : Msg -\u003e Model -\u003e ( Model, Cmd Msg )\nupdate msg model =\n  case msg of\n    -- ... other messages\n\n    MyConnectMessage rid -\u003e\n      ( model\n      , connect_room rid -- You can use the JSPhoenix.connect like any normal command\n      )\n\nsubscriptions : Model -\u003e Sub Msg\nsubscriptions model =\n  Sub.batch -- Subscribe to your port events to get their messages\n    [ onRoomConnect (\\{ msg, cb_data } -\u003e MyRoomConnectMsg msg cb_data) -- Example to show you the structure of the data\n    , onRoomInfo MyRoomInfoMsg\n    , onRoomMsgsInit MyRoomMsgsInitMsg\n    , onRoomMsgsAdd MyRoomMsgsAddMsg\n    , onRoomSyncState MyRoomSyncStateMsg\n    , onRoomSyncJoin MyRoomSyncJoinMsg\n    , onRoomSyncLeave MyRoomSyncLeaveMsg\n    ]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foverminddl1%2Felm-jsphoenix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foverminddl1%2Felm-jsphoenix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foverminddl1%2Felm-jsphoenix/lists"}