Skip to content

Commit

Permalink
Allow top level generator types for actions
Browse files Browse the repository at this point in the history
This commit adds a short-hand for generator actions. For example:

```javascript
let count = n => n

function * range (repo, start, end) {
  while (start <= end)
    yield repo.push(count, start++)
  }
}

repo.push(range, 1, 10) // 1,2,3,4,5,6,7,8,9,10
```
  • Loading branch information
nhunzaker committed Jun 19, 2017
1 parent d7c73b6 commit 00bf4e8
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 13 deletions.
14 changes: 5 additions & 9 deletions examples/react-router/app/actions/lists.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import Lists from '../domains/lists'
import { visit } from './routing'

export function addList(params) {
return function*(repo) {
let list = yield repo.push(Lists.create, params)
export function* addList(repo, params) {
let list = yield repo.push(Lists.create, params)

yield repo.push(visit, `/lists/${list.id}`)
}
yield repo.push(visit, `/lists/${list.id}`)
}

export function removeList(id) {
return function*(repo) {
yield repo.push(Lists.destroy, id)
}
export function* removeList(repo, id) {
yield repo.push(Lists.destroy, id)
}
12 changes: 8 additions & 4 deletions src/coroutine.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { isFunction, isPromise, isGeneratorFn } from './utils'
* order.
* @private
*/
function processGenerator(action, body, repo) {
action.open()
function processGenerator(action, body, repo, params) {
action.open(...params)

let iterator = body(repo)
let iterator = body(repo, ...params)

function step(payload) {
let next = iterator.next(payload)
Expand Down Expand Up @@ -46,6 +46,10 @@ function processGenerator(action, body, repo) {
* the body of their associated command.
*/
export default function coroutine(action, command, params, repo) {
if (isGeneratorFn(command)) {
return processGenerator(action, command, repo, params)
}

let body = command.apply(null, params)

/**
Expand Down Expand Up @@ -73,7 +77,7 @@ export default function coroutine(action, command, params, repo) {
* in order
*/
if (isGeneratorFn(body)) {
return processGenerator(action, body, repo)
return processGenerator(action, body, repo, params)
}

/**
Expand Down
40 changes: 40 additions & 0 deletions test/unit/middleware/generator-middleware.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
import Microcosm from '../../../src/microcosm'

describe('Generator Middleware', function() {
it('opens with the parameters', function() {
let stepper = n => n + 1
let repo = new Microcosm()

function stall(n) {
return function*(repo) {
yield repo.push(() => new Promise(() => {}))
}
}

let action = repo.push(stall, 2)

expect(action).toHaveStatus('open')
expect(action.payload).toEqual(2)
})

it('processes actions sequentially', function() {
expect.assertions(1)

Expand Down Expand Up @@ -235,4 +251,28 @@ describe('Generator Middleware', function() {
})
})
})

it('allows the top level action description to be a generator', function() {
let count = n => n

function* sequence(repo, start) {
yield repo.push(count, 1)
yield repo.push(count, 2)
yield repo.push(count, 3)
}

class Repo extends Microcosm {
register() {
return {
[count]: (_last, next) => next
}
}
}

let repo = new Repo()

repo.push(sequence, 1)

expect(repo.state).toEqual(3)
})
})

0 comments on commit 00bf4e8

Please sign in to comment.