Repository: vigetlabs/microcosm
Pull request #289 (2017-04-06 17:38:31)

Rework generator sequence
cc @efatsi 

It doesn't make sense to obscure the repo during an action generator sequence. Let's just pass it straight in:

```javascript
    function sleep (time) {
      return action => {
        setTimeout(() => action.resolve(true), time)
      }
    }

    function dream (time) {
      return function * (repo) {
        yield repo.push(sleep, time)
        yield repo.push(sleep, time)
        yield repo.push(sleep, time)
      }
    }

    repo.push(dream, 100)
```


Patch:
diff --git a/docs/api/actions.md b/docs/api/actions.md
index b1a2910b..1edaa729 100644
--- a/docs/api/actions.md
+++ b/docs/api/actions.md
@@ -135,9 +135,9 @@ function deleteUser (id) {
 }
 
 function confirmAndDelete (user) {
-  return function * (send) {
-    yield send(ask, `Are you sure you want to delete ${user.name}?`)
-    yield send(deleteUser, user.id)
+  return function * (repo) {
+    yield repo.push(ask, `Are you sure you want to delete ${user.name}?`)
+    yield repo.push(deleteUser, user.id)
   }
 }
 ```
diff --git a/src/coroutine.js b/src/coroutine.js
index 3d6b68ad..bedbd44b 100644
--- a/src/coroutine.js
+++ b/src/coroutine.js
@@ -33,7 +33,7 @@ export default function coroutine (action, body, repo) {
   if (isGeneratorFn(body)) {
     action.open()
 
-    let iterator = body(repo.push.bind(repo), repo)
+    let iterator = body(repo)
 
     function step (payload) {
       let next = iterator.next(payload)
@@ -45,14 +45,13 @@ export default function coroutine (action, body, repo) {
       }
     }
 
-    function progress (value) {
-      if (value instanceof Action) {
-        value.onDone(step)
-        value.onCancel(action.cancel, action)
-        value.onError(action.reject, action)
-      } else {
-        step(value)
-      }
+    function progress (subAction) {
+      console.assert(subAction instanceof Action,
+                     `Iteration of generator expected an Action. Instead got ${subAction}`)
+
+      subAction.onDone(step)
+      subAction.onCancel(action.cancel, action)
+      subAction.onError(action.reject, action)
     }
 
     step()


Test patch:
diff --git a/test/unit/middleware/generator-middleware.test.js b/test/unit/middleware/generator-middleware.test.js
index f408b2a0..7d0479f1 100644
--- a/test/unit/middleware/generator-middleware.test.js
+++ b/test/unit/middleware/generator-middleware.test.js
@@ -9,11 +9,11 @@ describe('Generator Middleware', function () {
     let repo = new Microcosm()
 
     function range (start, end) {
-      return function * (send) {
+      return function * (repo) {
         let value = start
 
         while (value < end) {
-          value = yield send(stepper, value)
+          value = yield repo.push(stepper, value)
         }
       }
     }
@@ -23,22 +23,20 @@ describe('Generator Middleware', function () {
     })
   })
 
-  it('continues if yielding a non-action value', function () {
+  it('throws if yielding a non-action value', function () {
     expect.assertions(1)
 
     let repo = new Microcosm()
     let step = n => n
 
     function test () {
-      return function * (send) {
-        yield send(step, 1)
+      return function * (repo) {
+        yield repo.push(step, 1)
         yield true
       }
     }
 
-    repo.push(test).onDone(result => {
-      expect(result).toEqual(true)
-    })
+    expect(() => repo.push(test)).toThrow("Iteration of generator expected an Action")
   })
 
   it('a rejected step halts the chain', function () {
@@ -48,10 +46,10 @@ describe('Generator Middleware', function () {
     let repo = new Microcosm()
 
     let sequence = repo.push(function () {
-      return function * (send, repo) {
-        yield send(stepper, 0)
+      return function * (repo) {
+        yield repo.push(stepper, 0)
         yield repo.append(stepper).reject('Failure')
-        yield send(stepper)
+        yield repo.push(stepper)
       }
     })
 
@@ -71,10 +69,10 @@ describe('Generator Middleware', function () {
     let repo = new Microcosm()
 
     let sequence = repo.push(function () {
-      return function * (send, repo) {
-        yield send(stepper, 0)
+      return function * (repo) {
+        yield repo.push(stepper, 0)
         yield repo.append(stepper).cancel('Cancelled')
-        yield send(stepper)
+        yield repo.push(stepper)
       }
     })
 
@@ -102,9 +100,9 @@ describe('Generator Middleware', function () {
     }
 
     return repo.push(function () {
-      return function * (send, repo) {
-        yield send(sleep, 100)
-        yield send(sleep, 100)
+      return function * (repo) {
+        yield repo.push(sleep, 100)
+        yield repo.push(sleep, 100)
       }
     }).onDone(function (payload) {
       expect(payload).toEqual(true)
@@ -122,16 +120,16 @@ describe('Generator Middleware', function () {
     }
 
     function dream (time) {
-      return function * (send, repo) {
-        yield send(sleep, time)
-        yield send(sleep, time)
+      return function * (repo) {
+        yield repo.push(sleep, time)
+        yield repo.push(sleep, time)
       }
     }
 
     return repo.push(function () {
-      return function * (send, repo) {
-        yield send(dream, 100)
-        yield send(dream, 100)
+      return function * (repo) {
+        yield repo.push(dream, 100)
+        yield repo.push(dream, 100)
       }
     }).onDone(function (payload) {
       expect(payload).toEqual(true)
@@ -149,16 +147,16 @@ describe('Generator Middleware', function () {
     }
 
     function dream (time) {
-      return function * (send, repo) {
-        yield send(sleep, time)
-        yield send(sleep, time)
+      return function * (repo) {
+        yield repo.push(sleep, time)
+        yield repo.push(sleep, time)
       }
     }
 
     function dream100 () {
-      return function * (send, repo) {
-        yield send(dream, 100)
-        yield send(dream, 100)
+      return function * (repo) {
+        yield repo.push(dream, 100)
+        yield repo.push(dream, 100)
       }
     }
 
@@ -175,10 +173,10 @@ describe('Generator Middleware', function () {
     }
 
     function dream (time) {
-      return function * (send, repo) {
-        yield send(sleep, time)
-        yield send(sleep, time)
-        yield send(sleep, time)
+      return function * (repo) {
+        yield repo.push(sleep, time)
+        yield repo.push(sleep, time)
+        yield repo.push(sleep, time)
       }
     }