An elm-pkg-js
compliant package called author-name/my-package-name
must:
- Include its JS in a single, un-minified
src/my-package-name.js
source file - Export a synchronous
init
function, that takes an instantiated Elm application as argument - Provide type signatures for any
in
orout
ports it depends on, as well as any imports required for the port signatures.
The details are elaborated below.
TODO: Specify Browser Compatibility
export function init(app) {
// package javascript goes here
}
Any subscriptions need to be added synchronously otherwise there can be issues.
The following transformation from package name to port name happens:
MartinSStewart/elm-audio
: given a full Elm package nameMartinSStewart_elm_audio
: replace any non[a-zA-Z-]
with_
martinsstewart_elm_audio
: lowercase- add
to_js
andfrom_js
suffixes:martinsstewart_elm_audio_to_js
martinsstewart_elm_audio_from_js
Then the following ports file definition is set at the top of the src/my-package-name.js
file, including any required imports (which must always be qualified to prevent collisions).
/* elm-pkg-js
import Audio
import Json.Encode
port martinsstewart_elm_audio_to_js : Json.Encode.Value -> Cmd (Audio.Msg msg)
port martinsstewart_elm_audio_from_js : (Json.Encode.Value -> Audio.Msg msg) -> Sub (Audio.Msg msg)
*/
If the package uses no ports, then an empty annotation is required:
/* elm-pkg-js */
See the examples folder for Elm packages that include elm-pkg-js spec
compliant JS as per this proposal.
A tool for automating inclusion of elm-pkg-js
packages would:
- Create an
elm-pkg-js
folder - For each package's included JS, copy it to
elm-pkg-js/<package-name>-<version>.js
- Generate the
elm-pkg-js-includes.js
entrypoint file - Generate a
src/PkgPorts.elm
file with all the ports and signatures specified byelm-pkg-js
packages
The UI might look something like this:
elm-pkg-js install supermario/copy-to-clipboard
───> Validating...
───> Running `elm install supermario/copy-to-clipboard`
...
───> Adding package Javascript
-- UNTRUSTED JAVASCRIPT --------------------------------------------------------
This package includes 45 lines of Javascript, which you can review here:
<https://github.com/supermario/elm-pkg-js/blob/8ec1ef89d99249fc6ce180d052cad8e88af77e84/examples/copy-to-clipboard/src/copy-to-clipboard.js>
Are you sure you want to add this to elm-pkg-js-includes.js? [Y/N] y
───> Generating elm-pkg-js-includes.js (45 lines total)
───> Generating PkgPorts.elm
The package is now ready to use.
If this is your first `elm-pkg-js` addition, follow the setup steps:
https://github.com/supermario/elm-pkg-js/blob/master/setup.md
See setup.md for an overview of what user setup would look like.
These might not need to be part of the spec at all, but are interesting to note.
-
Export an async
upgrade
function, that takes an instantiated Elm application as argument. This can be used in environments where hot-reload is used with type-change awareness.exports.upgrade = async function upgrade(app) { // package javascript goes here, potentially re-using already initialised variables or context }
For example, Lamdera would use this on hot-reload deployments to keep
elm-audio
object refs live between app versions.