All Projects → srowhani → ember-artisans

srowhani / ember-artisans

Licence: other
An abstraction layer around using web-workers in Ember.js

Programming Languages

javascript
184084 projects - #8 most used programming language
Handlebars
879 projects
HTML
75241 projects
CSS
56736 projects

Projects that are alternatives of or similar to ember-artisans

ember-simple-auth-token
Ember Simple Auth extension that is compatible with token-based authentication like JWT.
Stars: ✭ 356 (+1595.24%)
Mutual labels:  ember
ember-credit-card
"make your credit card form dreamy in one line of code"
Stars: ✭ 89 (+323.81%)
Mutual labels:  ember
ember-deep-tracked
Deep auto-tracking for when you just don't care, and want things to work (at the cost of performance in some situtations)
Stars: ✭ 20 (-4.76%)
Mutual labels:  ember
ember-typings
Typescript type definitions for ember.js
Stars: ✭ 13 (-38.1%)
Mutual labels:  ember
els-component-extraction-addon
Component extraction addon
Stars: ✭ 11 (-47.62%)
Mutual labels:  ember
ember-stripe-elements
A simple Ember wrapper for Stripe Elements.
Stars: ✭ 64 (+204.76%)
Mutual labels:  ember
ember-luxon
🕐 🌐 [deprecated] Addon thats brings Luxon to Ember applications.
Stars: ✭ 20 (-4.76%)
Mutual labels:  ember
ember-website
The emberjs.com website.
Stars: ✭ 61 (+190.48%)
Mutual labels:  ember
ember-links-with-follower
Render a set of links with a "follower" line underneath. The follower moves to the active link, matching size and position on the page.
Stars: ✭ 43 (+104.76%)
Mutual labels:  ember
ember-sort-filter-table
A sortable/searchable table addon for ember cli
Stars: ✭ 13 (-38.1%)
Mutual labels:  ember
glimmer-apollo
Ember and Glimmer integration for Apollo Client.
Stars: ✭ 32 (+52.38%)
Mutual labels:  ember
create-react-app-typescript-web-worker-setup
Using Web Workers in a TypeScript React project based on create-react-app.
Stars: ✭ 21 (+0%)
Mutual labels:  web-worker
ember-new-relic
Adds New Relic to your Ember CLI app based on the app's environment
Stars: ✭ 29 (+38.1%)
Mutual labels:  ember
ember-polaris
An Ember addon for Shopify's Polaris design system
Stars: ✭ 59 (+180.95%)
Mutual labels:  ember
Stage.js
Stage.js - Single-Page Web Application front-end framework
Stars: ✭ 13 (-38.1%)
Mutual labels:  web-worker
ember-changeset-conditional-validations
Conditional validations for ember-changeset-validations
Stars: ✭ 26 (+23.81%)
Mutual labels:  ember
ember-rapid-forms
Smart, Intuitive forms for Ember.js styled with Bootstrap, Multi layouts and Validation support.
Stars: ✭ 58 (+176.19%)
Mutual labels:  ember
november-cli
❄️ Generate a Node.js API for your Ember.js app
Stars: ✭ 51 (+142.86%)
Mutual labels:  ember
chat-app-v2
Shorter Chat App Demo
Stars: ✭ 14 (-33.33%)
Mutual labels:  ember
ember-meta
Setup meta for your Prember/Ember blog to support opengraph, microdata, Facebook, Twitter, Slack etc.
Stars: ✭ 15 (-28.57%)
Mutual labels:  ember

ember-artisans

NPM Version Build Status semantic-release

Artisans is a tool that makes using web workers in your application a lot more accessible. It offers an easy to use, Promise based API, that lets you break up your business logic to run on other threads, so that client side logic doesn't bog down your application's user experience.

Here's an example of how it might look in your application!

// app/controllers/application.js
import Controller from '@ember/controller'
import { action } from '@ember/object';
import { createWorker } from 'ember-artisans';

export default class ApplicationController extends Controller {
  worker = createWorker('/assets/workers/foo.js');

  @action
  async onFooBar() {
    const result = await this.worker.foo('bar');
    // ...
  }
}
// workers/foo.js
export default class FooBarWorker {
  foo (bar) {
    return `foo${bar}`;
  }
}

That's it! In the above example we're instantiating a worker using the createWorker utility. This returns a proxied Web Worker, that allows for any method you invoke will be delegated to it's corresponding worker.

Migration Guide (1.x -> 2.x)

Starting from version 2, the interface has changed so that the result will no longer have to be unwrapped from the worker response.

Before 🕸

export default class ApplicationController extends Controller {
  worker = createWorker('/assets/workers/foo.js');

  @action
  async onFooBar() {
    const { result }  = await this.worker.foo('bar');
    // ...
  }
}

After

export default class ApplicationController extends Controller {
  worker = createWorker('/assets/workers/foo.js');

  @action
  async onFooBar() {
    const result = await this.worker.foo('bar');
  }
}

This also means if that the worker will no longer silently fail if an exception is thrown. Be sure to properly handle errors if they are present!

Getting Started

Installation 🎉

The first step is installing ember-artisans. This will provide you with the templates for generating your workers, as well as the necessary build steps along the way.

yarn add -D ember-artisans

Creating workers 🛠

Once this has completed, you'll be able to start writing your workers! Running ember g artisan <name> will create your web worker for you in the root of your project inside <root>/workers All changes made to the files in this directory will be automatically picked up by the live reload server, and updated inside your app!

Here's some example input, and the corresponding output:

ember g artisan foo-bar

/**
 * Add your worker description here.
 */
export default class FooBarWorker {
  // Add your worker methods here.

  /**
   * @returns Promise<void>
   */
  async fooBar() {
    
  }
}

API 👩‍💻

There are a couple ways to pull the worker in, and make use of them. I'll walk over each of the available methods of interacting with your workers.

createWorker

import { createWorker } from 'ember-artisans';

createWorker(
  workerPath: string,
  options = {
    timeout: 5000,
  },
) => Proxy<Worker>

Specifying a worker path is done by providing the url that the workers are built at. By default - workers are place inside of dist/assets/workers/<name>.js This means that you would consume them by referencing their public location.

const 🐹 = createWorker('/assets/workers/tomster.js')

createWorkerPool

import { createWorkerPool } from 'ember-artisans';

export function createWorkerPool(
  workerPath: string,
  poolSize: number,
)

createWorkerPool will work the same as createWorker, except that when a method is invoked on a worker pool, it will instead look for the first non-busy worker to delegate your task to.

Using it would look something like this:

// app/controllers/foo.js
import { createWorkerPool } from 'ember-artisans';

const taskPool = createWorkerPool('/assets/workers/task-pool.js', 5);
await taskPool.doSomething();
...
// workers/worker-pool.js
export default class TaskPoolWorker {
  async doSomething () {
    return await something();
  }
}

service('artisans')

This addon also provides a service that lets you instantiate a worker pool to be shared across different parts of your application.

// app/controllers/foo.js
import Controller from '@ember/controller';

import { inject as service } from '@ember/service';
import { task } from 'ember-concurrency';

export default class FooController extends Controller {
  @service('artisans')
  artisanService;

  @(task(function* () {
    const workerPool = this.artisanService.poolFor('/assets/workers/pool.js', 2);
    return workerPool.doSomething();
  }))
  poolTask;
}

Handling Responses

Methods on your Worker will return as such, on successful completion.

import { createWorker } from 'ember-artisans';

const tomsterWorker = createWorker('/assets/workers/tomster.js');

const {
  result, // optional, present if the worker ran successfully!
  error, // optional, present if there was an error encountered by the worker, or in the event of a timeout
  id,   // identifier corresponding to the request instance, used internally to map postMessage to responses
} = await tomsterWorker.runOnWheel();

Notes 📓

Worker Syntax

Currently worker's can be specified as the default export (ESM), or as the module.export (CJS). That means that each of the following is an acceptable way of declaring your workers.

// esm
export default class FoobarWorker {
  async foo() {
    const response = await bar();
    return baz(response);
  }
  ...
}
// cjs
module.exports = {
  async foo() {
    const response = await bar();
    return baz(response);
  }
}

ESM Imports in Workers

You're able to import any of your node_modules/ into your worker, as long as they're able to run in browser context!

Here's a sample worker using the uuid package on npm.

import { v4 as uuidV4 } from 'uuid';

export default class UUIDWorker {
  generateUuid() {
    return uuidV4();
  }
}

Naming Worker Methods

To preserve the native methods present on a worker, avoid naming your Artisan worker methods the same as the native Worker methods.

My Worker Isn't Being Detected 🕵️‍♂️

If you create a new worker after the development server is already running, you might need to restart it for the worker to be properly be built into the public assets directory.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].