webnative-elm
TypeScript icon, indicating that this package has built-in type declarations

8.1.0 • Public • Published

Built by FISSION Discord Discourse

A thin wrapper around Webnative for Elm.

The Webnative SDK empowers developers to build fully distributed web applications without needing a complex back-end. The SDK provides:

Webnative applications work offline and store data encrypted for the user by leveraging the power of the web platform. You can read more about Webnative in Fission's Webnative Guide. There's also an API reference which can be found at webnative.fission.app

QuickStart

elm install fission-codes/webnative-elm

# requires webnative version 0.35 or later
npm install webnative
npm install webnative-elm

Then import the javascript portion of this library and elm-taskport. We'll need to initialise both of these.

import * as TaskPort from "elm-taskport"
import * as WebnativeElm from "webnative-elm"

TaskPort.install()
WebnativeElm.init({ TaskPort })

// elmApp = Elm.Main.init()

Once we have that setup, we can write our Webnative Elm code. The following is an entire Webnative app which creates or links a user account, manages user sessions and their file system, and writes to and reads from that file system.

import Task
import Webnative
import Webnative.Auth
import Webnative.Configuration
import Webnative.Error exposing (Error)
import Webnative.FileSystem exposing (Base(..), FileSystem)
import Webnative.Namespace
import Webnative.Path as Path
import Webnative.Program exposing (Program)
import Webnative.Session exposing (Session)


-- INIT


appInfo : Webnative.AppInfo
appInfo =
  { creator = "Webnative", name = "Example" }


config : Webnative.Configuration
config =
  appInfo
    |> Webnative.Namespace.fromAppInfo
    |> Webnative.Configuration.fromNamespace


type Model
  = Unprepared
  | NotAuthenticated Program
  | Authenticated Program Session FileSystem


init : (Model, Cmd Msg)
init =
  ( Unprepared
  , -- 🚀
    config
      |> Webnative.program
      |> Webnative.attemptTask
          { ok = Liftoff
          , err = HandleWebnativeError
          }
  )



-- UPDATE


type Msg
  = HandleWebnativeError Error
  | GotFileContents String
  | GotSession Session
  | Liftoff Foundation
  | RegisterUser { success : Bool }


update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    -----------------------------------------
    -- 🚀
    -----------------------------------------
    Liftoff foundation ->
      let
        newModel =
          -- Previous authenticated session?
          -- Presence of a FileSystem depends on your configuration.
          case (foundation.fileSystem, foundation.session) of
            (Just fs, Just session) -> Authenticated program session fs
            _                       -> NotAuthenticated program
      in
      ( newModel

      -- Next action
      --------------
      , case newModel of
          NotAuthenticated program ->
            -- Option (A), register a new account.
            -- We're skipping the username validation and
            -- username availability checking here to keep it short.
            { email = Nothing
            , username = Just "user"
            }
            |> Webnative.Auth.register program
            |> Webnative.attemptTask
                { ok = RegisterUser
                , error = HandleWebnativeError
                }

            -- Option (B), link an existing account.
            -- See 'Linking' section below.
          
          _ ->
            Cmd.none
      )

    -----------------------------------------
    -- 🙋
    -----------------------------------------
    RegisterUser { success } ->
      if success then
        ( model
        , program
            |> Webnative.Auth.sessionWithFileSystem
            |> Webnative.attemptTask
                { ok = RegisterUser
                , error = HandleWebnativeError
                }
        )
      else
        -- Could show message in create-account form.
        (model, Cmd.none)

    GotSessionAndFileSystem (Just { fileSystem, session }) ->
      ( -- Authenticated
        case model of
          NotAuthenticated program  -> Authenticated program session fileSystem
          _                         -> model

      -- Next action
      --------------
      , let
          path =
            Path.file [ "Sub Directory", "hello.txt" ]
        in
        "👋"
            |> Webnative.FileSystem.writeUtf8 fileSystem Private path
            |> Task.andThen (\_ -> Webnative.FileSystem.publish fileSystem)
            |> Task.andThen (\_ -> Webnative.FileSystem.readUtf8 fileSystem Private path)
            |> Webnative.attemptTask
                { ok = GotFileContents
                , error = HandleWebnativeError
                }
      )

    -----------------------------------------
    -- 💾
    -----------------------------------------
    GotFileContents string -> ...

    -----------------------------------------
    -- 🥵
    -----------------------------------------
    HandleWebnativeError UnsupportedBrowser ->        -- No indexedDB? Depends on how Webnative is configured.
    HandleWebnativeError InsecureContext ->           -- Webnative requires a secure context
    HandleWebnativeError (JavascriptError string) ->  -- Notification.push ("Got JS error: " ++ string)

Linking

When a user has already registered an account, they can link a device instead.

-- TODO: Yet to be implemented

Filesystem

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

import Webnative

config =
  { namespace = ...
  
  --
  , debug = Nothing
  , fileSystem = Just { loadImmediately = Just True, version = Nothing }
  , permissions = Nothing
  }

Webnative.program config

And then load it either in Elm or in javascript.

Webnative.FileSystem.load program { username = "username" }
const fs = await program.loadFileSystem("username")
webnativeElm.init({ fileSystems: [ fs ] })

Readme

Keywords

none

Package Sidebar

Install

npm i webnative-elm

Weekly Downloads

15

Version

8.1.0

License

none

Unpacked Size

9.1 MB

Total Files

11

Last publish

Collaborators

  • icidasset