Giter Club home page Giter Club logo

purescript-workers's People

Contributors

ktorz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

purescript-workers's Issues

Event APIs

Thanks for starting this project! I was attempting to implement this service worker example in PS and had to add some FFI for the event bits. I'm not too familiar with the whole Service Worker API yet, so I'm not sure where these things belong, but I don't mind PR'ing them in if they go here somewhere.

Here's my PS file:

module ServiceWorker where
  
import Prelude

import Cache (CACHE, Cache, addAll, match, openCache, put)
import Control.Monad.Aff (Aff)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Control.Monad.Eff.Exception (error)
import Control.Monad.Eff.Uncurried (EffFn2, runEffFn2)
import Control.Monad.Error.Class (throwError)
import Control.Promise (Promise, fromAff)
import Data.Foreign (isNull, toForeign, typeOf, unsafeFromForeign)
import Data.String (null)
import Fetch (FETCH, RequestInfo, Response, fetch)
import GlobalScope.Service (caches)
import Workers (WORKER)

type WorkerEffects e =
  ( worker :: WORKER
  | e )

type CacheEffects e = WorkerEffects
  ( cache :: CACHE
  | e )

type FetchEffects e =
  ( fetch :: FETCH
  | e )
  
appResources :: Array String
appResources =
  [ "./"
  , "./dist/app.js"
  ]

prepareServiceWorker :: forall e
   . Eff
      (WorkerEffects
        (CacheEffects
          (FetchEffects ( console :: CONSOLE | e ))))
      Unit
prepareServiceWorker = do
  addEventListener "install" \evt -> do
    log "The service worker is being installed."
    waitUntil evt =<< fromAff precache
  addEventListener "fetch" \evt -> do
    log "The service worker is serving the asset."
    respondWith evt =<< fromAff (fromCache (request evt))
    waitUntil evt =<< fromAff (update (request evt))

appCache :: forall e. Aff (CacheEffects e) Cache
appCache = do
  cacheStorage <- liftEff caches
  openCache cacheStorage "app"

precache :: forall e. Aff (CacheEffects e) Unit
precache = do
  cache <- appCache
  addAll cache appResources

fromCache :: forall e. RequestInfo -> Aff (CacheEffects e)
      Response
fromCache request = do
  cache <- appCache
  m <- match cache request
  if isEmpty m
    then throwError $ error "no-match"
    else pure m
  where
    isEmpty m =
      let
        mf = toForeign m
      in
        isNull mf ||
          (typeOf mf == "string" &&
            null (unsafeFromForeign mf :: String))

update :: forall e. RequestInfo -> Aff (CacheEffects (FetchEffects e)) Unit
update request = do
  response <- fetch request
  cache <- appCache
  put cache request response


-- | FFI Helpers

foreign import data Event :: Type

type EventHandler e = forall a. Event -> Eff e Unit

foreign import request :: Event -> RequestInfo

addEventListener :: forall e
   . String
  -> EventHandler e
  -> Eff (WorkerEffects e) Unit
addEventListener = runEffFn2 addEventListener_

foreign import addEventListener_ :: forall e
   . EffFn2 (WorkerEffects e) String (EventHandler e) Unit

waitUntil :: forall e a
   . Event
  -> (Promise a)
  -> Eff (WorkerEffects e) Unit
waitUntil = runEffFn2 waitUntil_

foreign import waitUntil_ :: forall e a
   . EffFn2 (WorkerEffects e) Event (Promise a) Unit

respondWith :: forall e a
   . Event
  -> (Promise a)
  -> Eff (WorkerEffects e) Unit
respondWith = runEffFn2 waitUntil_

foreign import respondWith_ :: forall e a
   . EffFn2 (WorkerEffects e) Event (Promise a) Unit

And my FFI file:

"use strict";

exports.addEventListener_ = function(event, handler) {
  self.addEventListener(event, handler);
}

exports.waitUntil_ = function(evt, promise) {
  evt.waitUntil(promise);
}

exports.respondWith_ = function(evt, promise) {
  evt.respondWith(promise);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.