From c4239e249e4c252762d1efc1cd8226f8ee068bc0 Mon Sep 17 00:00:00 2001 From: Nathan Hunzaker Date: Mon, 19 Jun 2017 09:10:05 -0400 Subject: [PATCH] Allow top level generator types for actions 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 ``` --- examples/react-router/app/actions/lists.js | 14 +++---- src/coroutine.js | 12 ++++-- .../middleware/generator-middleware.test.js | 40 +++++++++++++++++++ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/examples/react-router/app/actions/lists.js b/examples/react-router/app/actions/lists.js index 7a8cf271..0b389f06 100644 --- a/examples/react-router/app/actions/lists.js +++ b/examples/react-router/app/actions/lists.js @@ -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) } diff --git a/src/coroutine.js b/src/coroutine.js index 16363fe5..239996f3 100644 --- a/src/coroutine.js +++ b/src/coroutine.js @@ -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) @@ -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) /** @@ -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) } /** diff --git a/test/unit/middleware/generator-middleware.test.js b/test/unit/middleware/generator-middleware.test.js index f456be5b..d8268084 100644 --- a/test/unit/middleware/generator-middleware.test.js +++ b/test/unit/middleware/generator-middleware.test.js @@ -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) @@ -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) + }) })