Neck Protection Mandate

    elm-port-schema

    0.1.2 • Public • Published

    🚨 NOTE: This project is in early development 🚨

    Lots of very breaking changes are likley to occur and im sure there's many bugs to be discovered!

    elm-port-schema

    Bring type-safety to the interface between js and elm! Automatially generate decoders/encoders and typescript definitions from your elm types.

    Why i made this tool

    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 happends 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!

    Installation

    npm install --save-dev elm-port-schema

    How it works

    NOTE: We will use typescript instead of javascript. Typescript is essentially javascript with types, which is exacly what wen need.

    Everything revolves around a schema located at src/Schema.elm and the two types that need 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.

    1. 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 = ...
     
    ...

    1. 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!

    How elm and typescript maps to eachother

    • Bool <=> bool
    • Int, Float <=> number
    • Char, String <=> string
    • List <=> 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!

    Example

    https://github.com/hugobastas/elm-port-schema-starter has the boilerplate needed to get up and runing with elm-port-schema.

    Important notes / Words of caution

    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 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!

    License

    MIT

    Install

    npm i elm-port-schema

    DownloadsWeekly Downloads

    3

    Version

    0.1.2

    License

    MIT

    Unpacked Size

    436 kB

    Total Files

    5

    Last publish

    Collaborators

    • emmabastas