fission-suite/webnative-elm/2.1.0

NOTE: the latest version is 7.0.0

Renamed to fission-codes/webnative-elm. It is published under that name, and new versions come out there.

Versions published as fission-suite/webnative-elm still install under that name. 9 versions of 9 come from the new location (see their notes).

Rerouted (renamed, verified). The GitHub user or repository was renamed. The tag is still there, at the new name. The Lamdera package server serves a copy recovered from https://github.com/fission-codes/webnative-elm.

What we checked: The repo moved to github.com/fission-codes/webnative-elm. Rebuilt with git archive from commit 226279036a9a of https://github.com/fission-codes/webnative-elm (zip prefix fission-suite-webnative-elm-2262790/, America/Los_Angeles times): the zip is byte-identical to the one package.elm-lang.org recorded, SHA-1 09e51ed1ff6c2819d3b374aba9b39a057c432a01.

The Lamdera compiler uses this copy and prints a one-line notice saying so. elm itself fails to download this version.

Details Ā· package.elm-lang.org's zip: https://github.com/fission-suite/webnative-elm/zipball/2.1.0/

Webnative Elm

Built by FISSION Discord Discourse

A thin wrapper around webnative for Elm.

Fission helps developers build and scale their apps. We’re building a web native file system that combines files, encryption, and identity, like an open source iCloud.

QuickStart

elm install fission-suite/webnative-elm
npm install webnative-elm webnative

Setup the necessary ports on your Elm app.

port module Ports exposing (..)

import Webnative

port webnativeRequest : Webnative.Request -> Cmd msg
port webnativeResponse : (Webnative.Response -> msg) -> Sub msg

Then import the javascript portion of this library to connect up the ports.

import * as webnative from "webnative"
import * as webnativeElm from "webnative-elm"

// elmApp = Elm.Main.init()

webnativeElm.setup(elmApp)

Once we have that setup, we need can write our webnative Elm code.

import Webnative exposing (Context(..))
import Wnfs


-- INIT


permissions : Webnative.Permissions
permissions =
  { app = Just { creator = "Fission", name = "Example" }
  , fs = Nothing
  }


init : (Model, Cmd Msg)
init =
  ( {}
  , permissions
      |> Webnative.init
      |> Ports.webnativeRequest
      -- šŸš€ We'll get a response in the `GotWebnativeResponse` msg
  )



-- FILESYSTEM PREP


type Tag
  = ReadHelloTxt
  | Mutation


base : Wnfs.Base
base =
  Wnfs.AppData permissions.app



-- UPDATE


type Msg
  = GotWebnativeResponse Webnative.Response
  --
  | ReadWnfsFile
  | WriteToWnfsFile


update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    GotWebnativeResponse response ->
      case Webnative.decodeResponse tagFromString response of
        -----------------------------------------
        -- šŸš€
        -----------------------------------------
        Ok ( _, _, Initialisation state ) ->
          if Webnative.isAuthenticated state then
            loadUserData
          else
            welcome

        -----------------------------------------
        -- šŸ’¾
        -----------------------------------------
        Ok ( Wnfs, Just ReadHelloTxt, Wnfs.Utf8Content helloContents ) ->
          -- Do something with content from hello.txt

        Ok ( Wnfs, Just Mutation, _ ) ->
          ( model
          , Ports.webnativeRequest Wnfs.publish
          )

        -----------------------------------------
        -- 🄵
        -----------------------------------------
        Err ( maybeContext, errString ) ->
          -- Initialisation error, tag parse error, etc.

    --

    ReadWnfsFile ->
      { path = [ "hello.txt" ]
      , tag = tagToString ReadHelloTxt
      }
        |> Wnfs.readUtf8 base
        |> Ports.webnativeRequest
        |> Tuple.pair model

    WriteToWnfsFile ->
      "šŸ‘‹"
        |> Wnfs.writeUtf8 base
          { path = [ "hello.txt" ]
          , tag = tagToString Mutation
          }
        |> Ports.webnativeRequest
        |> Tuple.pair model


subscriptions : Sub Msg
subscriptions =
  Ports.webnativeResponse GotWebnativeResponse



-- TAG ENCODING/DECODING


tagToString : Tag -> String
tagToString tag =
  case tag of
    ReadHelloTxt -> "ReadHelloTxt"
    Mutation -> "Mutation"


tagFromString : String -> Result String Tag
tagFromString string =
  case string of
    "ReadHelloTxt" -> Ok ReadHelloTxt
    "Mutation" -> Ok Mutation
    _ -> Err "Invalid tag"

What's this tag thing?

You can chain webnative commands in Elm by providing a tag, which is then attached to the response. In the following example I have a custom type for my tags, which I then encode/decode to/from a string.

import Webnative exposing (Context(..))
import Wnfs

type Tag = Mutation

-- Request
Wnfs.writeUtf8 base
  { path = [ "hello.txt" ]
  , tag = tagToString Mutation
  }

-- Response
case Webnative.decodeResponse tagFromString response of
  Ok ( Wnfs, Just Mutation, _ ) ->
    ( model
    , Ports.webnativeRequest Wnfs.publish
    )

Request from the Webnative module don't have tags, that's why we're using a Maybe.

API

We don't support all the functions from webnative yet.
For now you can do the following from Elm:

  • All WNFS interactions
  • Redirect to lobby

More coming later.
Let us know if you have any requests.

Filesystem

Alternatively you can load the filesystem separately.
You may want to do this when working with a web worker.

import Webnative exposing (defaultInitOptions)

Webnative.initWithOptions
  { defaultInitOptions | loadFilesystem = False }

And then load it either in Elm or in javascript.

Webnative.loadFilesystem permissions
const fs = await webnative.loadFilesystem(permissions)
webnativeElm.setup(elmApp, () => fs)

Customisation

You can customise the port names by passing in a third parameter.

webnativeElm.setup(elmApp, undefined, {
  incoming: "webnativeRequest",
  outgoing: "webnativeResponse"
})