Skip to content

Commit 8256b1b

Browse files
committed
[ Add ] Nested OnionStack support
[ Add ] Example code
1 parent 765cdfd commit 8256b1b

File tree

5 files changed

+101
-56
lines changed

5 files changed

+101
-56
lines changed

ReadMe.md

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,51 @@
1-
# MiddleStack
1+
# OnionStack
22

33
**Middleware** framework based on [Async Generator][1] of ECMAScript 2018, inspired by [Koa 2][2].
44

5-
[![NPM Dependency](https://david-dm.org/TechQuery/middle-stack.svg)](https://david-dm.org/TechQuery/middle-stack)
6-
[![Build Status](https://travis-ci.com/TechQuery/middle-stack.svg?branch=master)](https://travis-ci.com/TechQuery/middle-stack)
7-
[![](https://data.jsdelivr.com/v1/package/npm/middle-stack/badge?style=rounded)](https://www.jsdelivr.com/package/npm/middle-stack)
5+
[![NPM Dependency](https://david-dm.org/TechQuery/onion-stack.svg)](https://david-dm.org/TechQuery/onion-stack)
6+
[![Build Status](https://travis-ci.com/TechQuery/onion-stack.svg?branch=master)](https://travis-ci.com/TechQuery/onion-stack)
7+
[![](https://data.jsdelivr.com/v1/package/npm/onion-stack/badge?style=rounded)](https://www.jsdelivr.com/package/npm/onion-stack)
88

9-
[![NPM](https://nodei.co/npm/middle-stack.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/middle-stack/)
9+
[![NPM](https://nodei.co/npm/onion-stack.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/onion-stack/)
1010

11-
## Usage
11+
## Example
1212

13-
[**Typical cases**](https://tech-query.me/test-file/test/index.js.html)
13+
```JavaScript
14+
import OnionStack from 'onion-stack';
1415

15-
`.babelrc`
1616

17-
```JSON
18-
{
19-
"presets": [
20-
"@babel/preset-env"
21-
],
22-
"plugins": [
23-
"@babel/plugin-proposal-async-generator-functions"
24-
]
25-
}
17+
const list = [ ];
18+
19+
const stack = new OnionStack(
20+
function*() {
21+
list.push(1);
22+
23+
yield;
24+
25+
list.push(2);
26+
27+
yield;
28+
29+
list.push(3);
30+
},
31+
async function*() {
32+
await delay(0.1);
33+
34+
list.push(4);
35+
36+
yield;
37+
38+
list.push(5);
39+
},
40+
function() {
41+
list.push(6);
42+
}
43+
);
44+
45+
stack.execute().then(() => console.log( list )); // [1, 4, 6, 5, 2]
2646
```
2747

48+
[More cases](https://tech-query.me/onion-stack/test.html)
49+
2850
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of#Iterating_over_async_generators
2951
[2]: https://koajs.com

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "middle-stack",
3-
"version": "0.1.0",
2+
"name": "onion-stack",
3+
"version": "0.2.0",
44
"description": "Middleware framework based on Async Generator of ECMAScript 2018, inspired by Koa 2",
55
"keywords": [
66
"middleware",
@@ -9,18 +9,18 @@
99
"ecmascript",
1010
"koa"
1111
],
12-
"license": "ISC",
12+
"license": "LGPL-3.0",
1313
"author": "[email protected]",
14-
"homepage": "https://tech-query.me/middle-stack/",
14+
"homepage": "https://tech-query.me/onion-stack/",
1515
"repository": {
1616
"type": "git",
17-
"url": "git+https://github.com/TechQuery/middle-stack.git"
17+
"url": "git+https://github.com/TechQuery/onion-stack.git"
1818
},
1919
"bugs": {
20-
"url": "https://github.com/TechQuery/middle-stack/issues"
20+
"url": "https://github.com/TechQuery/onion-stack/issues"
2121
},
2222
"module": "source/index.js",
23-
"main": "dist/index.js",
23+
"main": "dist/index.min.js",
2424
"directories": {
2525
"test": "test"
2626
},
@@ -43,7 +43,6 @@
4343
"@babel/polyfill": "^7.2.5"
4444
},
4545
"devDependencies": {
46-
"@babel/plugin-proposal-async-generator-functions": "^7.2.0",
4746
"@babel/polyfill": "^7.2.5",
4847
"@babel/preset-env": "^7.3.4",
4948
"@babel/register": "^7.0.0",
@@ -61,9 +60,6 @@
6160
"babel": {
6261
"presets": [
6362
"@babel/preset-env"
64-
],
65-
"plugins": [
66-
"@babel/plugin-proposal-async-generator-functions"
6763
]
6864
},
6965
"prettier": {

source/index.js

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export default class MiddleStack extends Array {
1+
export default class OnionStack extends Array {
22
/**
33
* @param {...Function} middleware
44
*/
@@ -7,32 +7,42 @@ export default class MiddleStack extends Array {
77
}
88

99
/**
10-
* @param {...*} parameter
10+
* @protected
11+
*
12+
* @param {Function} func
13+
* @param {?Array} parameter
1114
*/
12-
async execute(...parameter) {
13-
const func = this[++this.last];
15+
async exec(func, parameter) {
16+
const iterator = func.apply(null, parameter);
1417

15-
if (func)
16-
try {
17-
const iterator = func.apply(null, parameter);
18+
if (!((iterator || '').next instanceof Function)) return;
1819

19-
if ((iterator || '').next instanceof Function) {
20-
await iterator.next();
20+
await iterator.next();
2121

22-
await this.execute.apply(this, parameter);
22+
await this.execute.apply(this, parameter);
2323

24-
const { done } = await iterator.next();
24+
const { done } = await iterator.next();
2525

26-
if (!done)
27-
console.warn(
28-
'Only one `yield` is made sense in a Middleware'
29-
);
30-
}
31-
} catch (error) {
32-
this.last--;
26+
if (!done)
27+
console.warn('Only one `yield` is made sense in a Middleware');
28+
}
3329

34-
throw error;
35-
}
30+
/**
31+
* @param {...*} parameter
32+
*/
33+
async execute(...parameter) {
34+
const middleware = this[++this.last];
35+
36+
try {
37+
if (middleware instanceof OnionStack)
38+
await middleware.execute.apply(middleware, parameter);
39+
else if (middleware instanceof Function)
40+
await this.exec(middleware, parameter);
41+
} catch (error) {
42+
this.last--;
43+
44+
throw error;
45+
}
3646

3747
this.last--;
3848
}

test/index.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import MiddleStack from '../source';
1+
import OnionStack from '../source';
22

33
function delay(seconds) {
44
return new Promise(resolve => setTimeout(resolve, seconds * 1000));
@@ -32,14 +32,14 @@ var list = [],
3232
];
3333

3434
/**
35-
* @test {MiddleStack}
35+
* @test {OnionStack}
3636
*/
37-
describe('Call stack', () => {
37+
describe('Middleware callstack', () => {
3838
/**
39-
* @test {MiddleStack#execute}
39+
* @test {OnionStack#execute}
4040
*/
4141
it('Execute normally', async () => {
42-
stack = MiddleStack.from(stack);
42+
stack = OnionStack.from(stack);
4343

4444
await stack.execute();
4545

@@ -49,11 +49,13 @@ describe('Call stack', () => {
4949
});
5050

5151
/**
52-
* @test {MiddleStack#execute}
52+
* @test {OnionStack#exec}
5353
*/
5454
it('Execute abnormally', async () => {
5555
list.length = 0;
5656

57+
const right = stack[1];
58+
5759
stack[1] = async function*() {
5860
await delay(0.1);
5961

@@ -69,5 +71,20 @@ describe('Call stack', () => {
6971
list.should.be.eql([1, 4, 6]);
7072

7173
stack.last.should.be.equal(-1);
74+
75+
stack[1] = right;
76+
});
77+
78+
/**
79+
* @test {OnionStack#execute}
80+
*/
81+
it('Nested stack', async () => {
82+
list.length = 0;
83+
84+
stack.splice(2, 0, OnionStack.from(stack));
85+
86+
await stack.execute();
87+
88+
list.should.be.eql([1, 4, 1, 4, 6, 5, 2, 5, 2]);
7289
});
7390
});

0 commit comments

Comments
 (0)