Skip to content

Commit

Permalink
barebones
Browse files Browse the repository at this point in the history
  • Loading branch information
machty committed May 5, 2017
1 parent db53ea3 commit f776f2c
Show file tree
Hide file tree
Showing 7 changed files with 5,695 additions and 3 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
root: true,
parser: "babel-eslint",
parserOptions: {
ecmaVersion: 2017,
sourceType: 'module'
Expand Down
77 changes: 76 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,84 @@
# ember-concurrency-decorators

This README outlines the details of collaborating on this Ember addon.
## EXPERIMENTAL

Babel support for decorator syntax has been fidgety, so expect a bit
of a bumpy ride. Also, the API of this addon is still pre-Alpha.
Probably don't use this in prod code.

## Overview

This Ember Addon let's you use the
[decorator syntax](https://github.com/tc39/proposal-decorators)
for declaring/configuring
[ember-concurrency](https://ember-concurrency.com) tasks.

Classic syntax (without decorators):

```js
import { task } from 'ember-concurrency';
export default Ember.Component.extend({
doStuff: task(function * () {
// ...
}).restartable()
});

// elsewhere:
this.get('doStuff').perform();
```

With decorator syntax

```js
import { restartableTask } from 'ember-concurrency-decorators';
export default Ember.Component.extend({
@restartableTask
doStuff: function * () {
// ...
}
});

// elsewhere:
this.get('doStuff').perform();
// `doStuff` is still a Task object that can be `.perform()`ed
```

There's actually an even nicer syntax that's on the horizon, but
is NOT YET SUPPORTED due to a [Babel bug](https://github.com/babel/babylon/issues/13).

```js
export default Ember.Component.extend({
// THIS SYNTAX IS NOT YET SUPPORTED, BUT SOON!
@restartableTask
*doStuff() {
// ...
}
});
```

When this Babel issue is addressed, this syntax should Just Work with
this addon.

## Installation

```
ember install ember-concurrency-decorators
npm install --save babel-plugin-transform-decorators-legacy
```

Then you'll need to enable the decorator transpilation plugin in your
`ember-cli-build.js` file:

```
var app = new EmberApp({
babel: {
plugins: ['transform-decorators-legacy']
}
});
```

## Working on this repo

* `git clone <repository-url>` this repository
* `cd ember-concurrency-decorators`
* `npm install`
Expand Down
54 changes: 54 additions & 0 deletions addon/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { task as ecTask } from 'ember-concurrency';

function extractValue(desc) {
return desc.value ||
(typeof desc.initializer === 'function' && desc.initializer());
}

function isDescriptor(item) {
return item &&
typeof item === 'object' &&
'writable' in item &&
'enumerable' in item &&
'configurable' in item;
}

function handleDescriptor(callback, target, key, desc, params = []) {
return {
enumerable: desc.enumerable,
configurable: desc.configurable,
writeable: desc.writeable,
initializer: function() {
if (!desc.writable) {
throw new Error('ember-concurrency-decorators does not support using getters and setters');
}

let value = extractValue(desc);
return callback(value, params);
}
};
}

function decorator(callback) {
return function(...params) {
// determine if user called as @task('blah', 'blah') or @task
if (isDescriptor(params[params.length - 1])) {
return handleDescriptor(callback, ...arguments);
} else {
return function(/* target, key, desc */) {
return handleDescriptor(callback, ...arguments, params);
};
}
};
}


function taskify(value) {
return (typeof value === 'function') ? ecTask(value) : value;
}

export const task = decorator(v => taskify(v));
export const restartableTask = decorator(v => taskify(v).restartable());
export const dropTask = decorator(v => taskify(v).drop());
export const keepLatestTask = decorator(v => taskify(v).keepLatest());
export const enqueueTask = decorator(v => taskify(v).enqueue());
4 changes: 3 additions & 1 deletion ember-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ const EmberAddon = require('ember-cli/lib/broccoli/ember-addon');

module.exports = function(defaults) {
var app = new EmberAddon(defaults, {
// Add options here
babel: {
plugins: ['transform-decorators-legacy']
}
});

/*
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ember-concurrency-decorators",
"version": "0.0.0",
"version": "0.0.1",
"description": "The default blueprint for ember-cli addons.",
"keywords": [
"ember-addon"
Expand All @@ -21,6 +21,8 @@
"ember-cli-babel": "^6.0.0"
},
"devDependencies": {
"babel-eslint": "^7.2.3",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"broccoli-asset-rev": "^2.4.5",
"ember-ajax": "^3.0.0",
"ember-cli": "2.13.1",
Expand All @@ -33,6 +35,7 @@
"ember-cli-shims": "^1.1.0",
"ember-cli-sri": "^2.1.0",
"ember-cli-uglify": "^1.2.0",
"ember-concurrency": "^0.8.2",
"ember-disable-prototype-extensions": "^1.1.0",
"ember-export-application-global": "^2.0.0",
"ember-load-initializers": "^1.0.0",
Expand Down
46 changes: 46 additions & 0 deletions tests/unit/decorators-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*eslint-disable*/

import Ember from 'ember';
import { timeout } from 'ember-concurrency';
import {
task,
restartableTask,
dropTask,
keepLatestTask,
enqueueTask,
maxConcurrency
} from 'ember-concurrency-decorators';
import { module, test } from 'qunit';

module('Unit: decorators');

test("a plethora of decorators", function(assert) {
assert.expect(1);

let Obj = Ember.Object.extend({
@task
doStuff: function * () {
return 123;
},

@restartableTask
a: function * () { },

@keepLatestTask
b: function * () { },

@dropTask
c: function * () { },

@enqueueTask
d: function * () { },
});

let obj;
Ember.run(() => {
obj = Obj.create();
obj.get('doStuff').perform();
});
assert.equal(obj.get('doStuff.last.value'), 123);
});

Loading

0 comments on commit f776f2c

Please sign in to comment.