-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
105 lines (78 loc) · 3.33 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
var each = require( 'lodash.foreach' );
module.exports = function create_instance(){
var map = {},
api = {},
running = [],
end = { run: false };
api.run = run_stack;
api.end = end_stack_run;
api.add = add_middleware;
api.del = api.delete = delete_middleware;
api.list = list_middlewares;
return api;
function run_stack( hook_name, main_input ){
if( ! hook_name || typeof hook_name !== 'string' ) throw new Error( 'name of hook is required and must be a string' );
if( ! map[ hook_name ] ) return main_input;
var hook_middlewares = map[ hook_name ],
supplementary_inputs = arguments.length > 2 ? Array.prototype.splice.call( arguments, 2, arguments.length - 1 ) : [],
middleware_args = [ main_input ].concat( supplementary_inputs ),
stack_output = main_input;
running.push( hook_name );
each( hook_middlewares, function( middleware ){
var result = middleware.apply( null, middleware_args );
if( end.run ) return false;
var has_result = Object.prototype.toString.call( result ) !== '[object Undefined]';
if( has_result ){
stack_output = result;
middleware_args = [ stack_output ].concat( supplementary_inputs );
}
});
if( end.run ){
if( Object.prototype.toString.call( end.val ) != '[object Undefined]' ) stack_output = end.val;
delete end.val;
end.run = false;
}
running.pop();
return stack_output;
}
function end_stack_run( final_value ){
if( running.length === 0 ) throw new Error( 'no hook is currently running' );
end.run = true;
if( Object.prototype.toString.call( final_value ) != '[object Undefined]' ) end.val = final_value;
}
function delete_middleware( hook, name ){
if( typeof hook !== 'string' || !hook ) throw new Error( 'hook name must be a string' );
if( typeof name !== 'string' || !name ) throw new Error( 'middleware name must be a string' );
if( map[ hook ] && map[ hook ][ name ] ) delete map[ hook ][ name ];
}
function add_middleware( hook, name, middleware ){
if( typeof hook !== 'string' || !hook ) throw new Error( 'hook name must be a string' );
if( typeof name !== 'string' || !name ) throw new Error( 'middleware name must be a string' );
if( typeof middleware !== 'function' ) throw new Error( 'middleware must be a function' );
if( !map.hasOwnProperty( hook ) ) map[ hook ] = {};
if( map[ hook ][ name ] ) throw new Error( 'hook "' + hook + '" already has middleware called "' + name + '"' );
map[ hook ][ name ] = middleware;
}
function list_middlewares( hook_name ){
var hook_name_type = Object.prototype.toString.call( hook_name ),
result;
switch( hook_name_type ){
case '[object String]':
if( ! map.hasOwnProperty( hook_name ) ) result = [];
else result = Object.keys( map[ hook_name ] );
break;
case '[object Undefined]':
result = {};
var all_hook_names = Object.keys( map );
all_hook_names.forEach( function( hook_name ){
var hook_middlewares = map[ hook_name ],
hook_middleware_names = Object.keys( hook_middlewares );
result[ hook_name ] = hook_middleware_names;
});
break;
default:
throw new Error( 'expected argument to be string, but it is not' );
}
return result;
}
}