GithubHelp home page GithubHelp logo

scandinavianairlines / remix-workers-poc Goto Github PK

View Code? Open in Web Editor NEW
12.0 6.0 1.0 1.93 MB

A proof of concept for adding Remix loaders and actions in a service-worker

License: MIT License

JavaScript 100.00%

remix-workers-poc's Introduction

Remix worker actions and loaders

The main purpose of this repository is to show how to use Remix's actions and loaders in a service worker. The idea comes from finding a way to use all the Remix features and capabilities totally offline.

How does it work?

Following the same principles as the Remix actions and loaders, where the loaders and actions functions are exported from a route file and then a compiler process them to include them only in the server bundle and register the routes automatically.

Compiler

We created a compiler that mimics the remix compiler, but for a service worker. The compiler is a esbuild node script that uses the remix config manifest to know all the routes files and compile only the exported workerActions and workerLoader function from each route file. In that way, the compiler creates a routes list with all information needed to "register a route" and inject it in the service worker. We held an interal scripts/service-worker.js file that is the compiler entry point and have the logic to listen to a fetch event and match the request with the right route workerAction or workerLoader function. Finally, the compiler bundles everything needed for the service worker in a single file and writes it to the condigure workerBuildDirectory in the remix.config.js file.

Worker actions and loaders

The worker actions and worker loaders are the same as the Remix actions and Remix loaders, but with a different name to easily identify the context where they are running. Both follows the same principles as in a normal action or loader, recives the request object and returns a response object. The only difference is that the worker actions and worker loaders are executed in the service worker thread and not in a Node.js server.

workerAction

export function workerAction({ request, params, context }: ActionArgs): Promise<Response> | Response | Promise<AppData> | AppData

workerLoader

export function workerLoader({ request, params, context }: LoaderArgs): Promise<Response> | Response | Promise<AppData> | AppData

Context

The context object is the same as in a normal Remix app, but with some extra properties:

  • context.event: The fetch event that was triggered.
  • context.fetchFromServer: A function that can be used to perform the original request.

The compiler also supports a way to create your own context that will be pass to all worker actions and worker loaders. A getLoadContext function should be exported from the application service worker file and will be called in each fetch event.

getLoadContext

export function getLoadContext(event: FetchEvent): AppLoadContext

Default event handler

The compiler also supports a way to create a default event handler that will be called if no worker action or worker loader matches the request. A defaultEventHandler function should be exported from the application service worker file.

defaultFetchHandler

export function defaultFetchHandler({ request, params, context }: LoaderArgs): Promise<Response> | Response

If no defaultFetchHandler is exported, the compiler will use a default one that will try to fetch the request from the server.

Error handler

The compiler also supports a way to create a error handler that will be called if an error is thrown in a worker action or worker loader. A errorHandler function should be exported from the application service worker file.

handleError

export function handleError(error: Error, { request, params, context }: LoaderArgs | ActionArgs)): void

If no errorHandler is exported, the compiler will use a default one that will log the error to the console.

Configuration

The service worker can be configured in the remix.config.js file. The following options are available:

  • worker: The path to the service worker file. Defaults to app/entry.worker.js.
  • workerName: The name of the service worker output file without the extension. Defaults to service-worker.
  • workerMinify: Whether to minify the service worker file. Defaults to false.
  • workerBuildDirectory: The directory to build the service worker file in. Defaults to public/.

Considerations

  • The compiler removes all dependencies related to react, react-dom and any @remix-run/* packages intended to be used in an specific environment like cloudflare, node, deno, etc
  • Remix methods like json, defer and redirect needs to be imported from @remix-run/router otherwise it won't work.
  • ⚠️ The first render (if you are online and don't have any cache around), will always go to the server. There is no way to intercept this request as the service worker is not activated yet.
  • ⚠️ The service worker runs on a background thread and can only access Server Worker API's.

Project setup

This project was bootstrapped with Remix, uses Yarn as its package manager and Node.js as its runtime.

Install dependencies

From your terminal:

yarn install

Start development mode

From your terminal:

yarn dev

This starts your app in development mode with a built-in service worker, rebuilding assets on file changes. It uses two node scripts: dev:remix and dev:worker.

  • dev:remix starts the Remix development server, which serves your app at localhost:3000.
  • dev:worker builds your service worker and watches for changes to your app's assets.

Build for production

From your terminal:

yarn build

This builds your app for production, including your service worker.


Created by the Airline Digitalization Team.

SAS

remix-workers-poc's People

Contributors

lfantone avatar

Stargazers

Rafael Contreras avatar Eddy Recio avatar Ian Callaghan avatar  avatar Clifford Fajardo  avatar Michael Carter avatar Achmad Mahardi avatar Sébastien Lorber avatar Dustin Mihalik avatar  avatar Matthew Fainman avatar Abdur-Rahman avatar

Watchers

Juan Pablo Garcia Ripa avatar Fede Ratier avatar Kellen Busby avatar Viktor Ceder avatar Matthew Fainman avatar Abdur-Rahman avatar

Forkers

flysas-test

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.