JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 15793
  • Score
    100M100P100Q153216F
  • License MIT

decorator syntax for declaring/configuring ember-concurrency tasks

Package Exports

  • ember-concurrency-decorators

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (ember-concurrency-decorators) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

ember-concurrency-decorators

Build Status npm version Download Total Ember Observer Score Ember Versions code style: prettier dependencies devDependencies

This Ember addon lets you use the decorator syntax for declaring/configuring ember-concurrency tasks.

Installation

You'll need at least ember-cli@2.13+ and ember-cli-babel@6+. Then install as any other addon:

ember install ember-concurrency-decorators

If you are not using TypeScript, in order for ember-cli-babel to understand the @decorator syntax, you at least also need to install @ember-decorators/babel-transforms. Instead of that you can also install the ember-decorators meta package:

ember install ember-decorators
# or
ember install @ember-decorators/babel-transforms

Usage

Available decorators

  • @task: turns a generator method into a task
    • @restartableTask
    • @dropTask
    • @keepLatestTask
    • @enqueueTask
  • @taskGroup: creates a task group from a property
    • @restartableTaskGroup
    • @dropTaskGroup
    • @keepLatestTaskGroup
    • @enqueueTaskGroup
  • @lastValue: alias a property to the result of a task with an optional default value

@task

import Component from '@ember/component';
import { task } from 'ember-concurrency-decorators';

export default class ExampleComponent extends Component {
  @task
  doStuff = function*() {
    // ...
  };

  // and then elsewhere
  executeTheTask() {
    // `doStuff` is still a `Task` object that can be `.perform()`ed
    this.doStuff.perform();
    console.log(this.doStuff.isRunning);
  }
}

You can also pass further options to the task decorator:

@task({
  maxConcurrency: 3,
  restartable: true
})
doStuff = function*() {
  // ...
}

For your convenience, there are extra decorators for all concurrency modifiers:

Shorthand Equivalent
@restartableTask @task({ restartable: true })
@dropTask @task({ drop: true })
@keepLatestTask @task({ keepLatest: true })
@enqueueTask @task({ enqueue: true })

You can still pass further options to these decorators, like:

@restartableTask({ maxConcurrency: 3 })
doStuff = function*() {
  // ...
}

@taskGroup

import Component from '@ember/component';
import { task, taskGroup } from 'ember-concurrency-decorators';

export default class ExampleComponent extends Component {
  @taskGroup
  someTaskGroup;

  @task({ group: 'someTaskGroup' })
  doStuff = function*() {
    // ...
  };

  @task({ group: 'someTaskGroup' })
  doOtherStuff = function*() {
    // ...
  };

  // and then elsewhere
  executeTheTask() {
    // `doStuff` is still a `Task `object that can be `.perform()`ed
    this.doStuff.perform();

    // `someTaskGroup` is still a `TaskGroup` object
    console.log(this.someTaskGroup.isRunning);
  }
}

You can also pass further options to the task group decorator:

@taskGroup({
  maxConcurrency: 3,
  drop: true
}) someTaskGroup;

As for @task, there are extra decorators for all concurrency modifiers:

Shorthand Equivalent
@restartableTaskGroup @taskGroup({ restartable: true })
@dropTaskGroup @taskGroup({ drop: true })
@keepLatestTaskGroup @taskGroup({ keepLatest: true })
@enqueueTaskGroup @taskGroup({ enqueue: true })

You can still pass further options to these decorators, like:

@dropTaskGroup({ maxConcurrency: 3 }) someTaskGroup;

@lastValue

This decorator allows you to alias a property to the result of a task. You can also provide a default value to use before the task has completed.

import Component from '@ember/component';
import { task } from 'ember-concurrency-decorators';
import { lastValue } from 'ember-concurrency-decorators';

export default class ExampleComponent extends Component {
  @task
  someTask = function*() {
    // ...
  };

  @lastValue('someTask')
  someTaskValue;

  @lastValue('someTask')
  someTaskValueWithDefault = 'A default value';
}

Syntax

TypeScript

Assuming you are using ember-cli-typescript, you can just use native ES6 class syntax with decorators on generator methods.

import Component from '@ember/component';
import { restartableTask } from 'ember-concurrency-decorators';

export default class ExampleComponent extends Component {
  @restartableTask
  *doStuff() {
    // ...
  }
});

// elsewhere:
this.doStuff.perform();

If you use @babel/plugin-transform-typescript with @babel/plugin-proposal-decorators in loose mode (as you currently must), you can't use the above syntax. Instead read on below:

JavaScript

If you are using plain old JavaScript, use the decorators like this:

import Component from '@ember/component';
import { restartableTask } from 'ember-concurrency-decorators';

export default class ExampleComponent extends Component {
  @restartableTask
  doStuff = function*() {
    // ...
  }
});

// elsewhere:
this.doStuff.perform();

You need to use this assignment / initializer syntax instead of "proper" generator methods, because of a bug in the loose mode of @babel/plugin-proposal-decorators, which ember-decorators depends on. When ember-decorators adds support for stage 2 decorators, you will be able to use the generator method syntax as well. 🎉

License

This project is licensed under the MIT License.