Lots of very breaking changes are likley to occur and im sure there's many bugs to be discovered!
Bring type-safety to the interface between js and elm! Automatically generate decoders/encoders and typescript definitions from your elm types.
Elm is great! But not everything can be done in pure elm. Sometimes we need to pass over into js-land and to do that we have ports. If our Elm app happens to be very port-heavy for whatever reason, we might find ourselved spending increasing amounts of time writing json decoders/encoders, syncing that with the js-side and debugging whenever a typo or something small like that slipps through. Elm and typescript helps us write code with fewer errors, lets bring them to the interface between Elm and js!
npm install --save-dev elm-port-schema
NOTE: We will use typescript instead of javascript. Typescript is essentially javascript with types, which is exacly what we need.
Everything revolves around a schema located at src/Schema.elm
and the two types that needs to be in it: FromElmMessage and ToElmMessage.
if your schema looks like this:
module Schema exposing (..)
type FromElmMessage = ...
type ToElmMessage = ...and you run elm-port-schema it will generate two files.
src/Port.elm. You can import this module from the rest of your Elm to send and recive messages. It looks a bit like this:
port module Port exposing (..)
type FromElmMessage = ...
type ToElmMessage = ...
send : FromElmMessage -> Cmd msg
send = ...
recive : (Result Json.Decode.Error ToElmMessage -> msg) -> Sub msg
recive = ...
...src/Main.d.ts. This file makes typescript aware of what data can be sent to and from Elm.
It look a little like this:
export let Elm: { Main: { init: (flags?: any) => ElmApp } }
export interface ElmApp {
ports: {
toElm: { send: (msg: ToElmMessage) => void },
fromElm: { subscribe: (f: (msg: FromElmMessage) => void) => void },
}
}
...Whenever you want to change how data is passed between elm and typescript,
just update Schema.elm, run elm-port-schema and fix all compiler errors
in your elm and typescript. Piece of cake!
Bool<=>boolInt,Float<=>numberChar,String<=>stringList<=>Array( Int, String )<=>[ number, string ]{ foo : Int, bar : String }<=>{ foo: number, bar: string }type Foo = Bar Int String<=>{ variant: "bar", _0: number, _1: string }
Maybe and Result values map to typescript just the same as any other
custom type would,
i.e Nothing maps to { variant: "Nothing" }, not null!
https://github.com/hugobastas/elm-port-schema-starter has the boilerplate needed
to get up and runing with elm-port-schema.
Before using this tool, know that it WILL add complexity to your project. compared to plain js and Elm you will need typescript, a bundler like webpack with a typescript and Elm loader. If you're only goin to spend a couple hours interfacing js and Elm this additional complexity might not be worth it. This comic commes to mind.
Also note that elm-port-schema is NOT intended for data interchange
between client and server. Thats a different problem and something like
elm-graphql would be more appropriate
to solve it.
Also read this vission for data interchange in elm. I found it to be very enlightening!
MIT