oox 0.1.0 → 0.3.0-beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/app.js +142 -0
- package/bin/argv.js +59 -84
- package/bin/cli.js +39 -54
- package/bin/configurer.js +37 -66
- package/bin/proxyer.js +54 -88
- package/bin/register.js +45 -95
- package/bin/starter.js +70 -129
- package/index.js +144 -6
- package/index.mjs +4 -0
- package/modules/http/index.js +180 -0
- package/modules/http/utils.js +73 -0
- package/modules/index.js +68 -0
- package/modules/module.js +16 -0
- package/package.json +34 -16
- package/types/app.d.ts +37 -0
- package/types/bin/argv.d.ts +8 -0
- package/types/bin/cli.d.ts +2 -0
- package/types/bin/configurer.d.ts +1 -0
- package/types/bin/proxyer.d.ts +1 -0
- package/types/bin/register.d.ts +1 -0
- package/types/bin/starter.d.ts +1 -0
- package/types/index.d.ts +70 -0
- package/types/modules/http/index.d.ts +47 -0
- package/types/modules/http/utils.d.ts +17 -0
- package/types/modules/index.d.ts +21 -0
- package/types/modules/module.d.ts +13 -0
- package/types/utils.d.ts +6 -0
- package/utils.js +63 -0
- package/.gitattributes +0 -2
- package/global.js +0 -143
- package/middleware.js +0 -167
- package/rpc/config.class.js +0 -48
- package/rpc/context.class.js +0 -15
- package/rpc/http.class.js +0 -327
- package/rpc/rpc.class.js +0 -128
- package/rpc/rpc.interface.class.js +0 -119
- package/rpc/socketio.class.js +0 -231
- package/service/service.class.js +0 -82
- package/service/socketio.class.js +0 -145
- package/setMap.class.js +0 -67
- package/socketio/client.class.js +0 -190
- package/socketio/server.class.js +0 -222
- package/socketio/socket.class.js +0 -23
- package/util.js +0 -373
package/rpc/http.class.js
DELETED
|
@@ -1,327 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const http = require ( 'http' )
|
|
3
|
-
|
|
4
|
-
const { parseHTTPBody, getTraceIdByStack, getIPAddress, httpRequest } = require ( '../util' )
|
|
5
|
-
|
|
6
|
-
const Context = require ( './context.class' )
|
|
7
|
-
|
|
8
|
-
const RPC = require ( './rpc.interface.class' )
|
|
9
|
-
|
|
10
|
-
const Global = require ( '../global' )
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
module.exports = class HTTPModule {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @type {RPC}
|
|
20
|
-
*/
|
|
21
|
-
rpc = null
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* listen port
|
|
27
|
-
*/
|
|
28
|
-
port = 0
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* socket.io service path
|
|
34
|
-
*/
|
|
35
|
-
path = '/'
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @param {{port:Number, path:String}} config
|
|
41
|
-
*/
|
|
42
|
-
set config ( config ) {
|
|
43
|
-
|
|
44
|
-
if ( !config ) return this.rpc.config.gateway.http = null
|
|
45
|
-
|
|
46
|
-
config = this.rpc.config.gateway.http = Object.assign ( this.config || { }, config )
|
|
47
|
-
|
|
48
|
-
this.port = config.port || 0
|
|
49
|
-
|
|
50
|
-
if ( config.path ) this.path = config.path
|
|
51
|
-
else config.path = this.path
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
get config ( ) {
|
|
57
|
-
|
|
58
|
-
return this.rpc.config.gateway.http
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @type {http.Server}
|
|
65
|
-
*/
|
|
66
|
-
server = null
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
*
|
|
72
|
-
* @param {RPC} rpc
|
|
73
|
-
*/
|
|
74
|
-
constructor ( rpc ) {
|
|
75
|
-
|
|
76
|
-
this.rpc = rpc
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* start http service
|
|
83
|
-
* @returns {http.Server}
|
|
84
|
-
*/
|
|
85
|
-
async serve ( ) {
|
|
86
|
-
|
|
87
|
-
await this.stop ( )
|
|
88
|
-
|
|
89
|
-
const config = this.config
|
|
90
|
-
|
|
91
|
-
if ( !config ) return
|
|
92
|
-
|
|
93
|
-
const { port } = config
|
|
94
|
-
|
|
95
|
-
const isRndPort = 'number' !== typeof port || port === 0
|
|
96
|
-
|
|
97
|
-
const server =
|
|
98
|
-
this.server = http.createServer ( this.call.bind ( this ) )
|
|
99
|
-
|
|
100
|
-
server.listen ( isRndPort ? 0 : port )
|
|
101
|
-
|
|
102
|
-
config.port = server.address ( ).port
|
|
103
|
-
config.path = this.path
|
|
104
|
-
|
|
105
|
-
return server
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* stop http service
|
|
112
|
-
*/
|
|
113
|
-
stop ( ) {
|
|
114
|
-
|
|
115
|
-
if ( this.server && this.server.listening )
|
|
116
|
-
return new Promise ( ( resolve, reject ) => {
|
|
117
|
-
|
|
118
|
-
this.server.close ( function ( error ) {
|
|
119
|
-
|
|
120
|
-
if ( error ) reject ( error )
|
|
121
|
-
else resolve ( )
|
|
122
|
-
} )
|
|
123
|
-
} )
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* CORS
|
|
130
|
-
* @param {http.IncomingMessage} request
|
|
131
|
-
* @param {http.ServerResponse} response
|
|
132
|
-
*/
|
|
133
|
-
cors ( request, response ) {
|
|
134
|
-
|
|
135
|
-
// origin checking
|
|
136
|
-
if ( this.rpc.config.origin ) {
|
|
137
|
-
|
|
138
|
-
const origin = this.rpc.config.origin
|
|
139
|
-
|
|
140
|
-
const requestOrigin = request.headers.origin
|
|
141
|
-
|
|
142
|
-
if ( origin === '*' ) {
|
|
143
|
-
|
|
144
|
-
response.setHeader ( 'Access-Control-Allow-Origin', '*' )
|
|
145
|
-
} else if ( origin === requestOrigin || Array.isArray ( origin ) && origin.includes ( requestOrigin ) ) {
|
|
146
|
-
|
|
147
|
-
response.setHeader ( 'Access-Control-Allow-Origin', requestOrigin )
|
|
148
|
-
|
|
149
|
-
response.setHeader ( 'Vary', 'Origin' )
|
|
150
|
-
} else {
|
|
151
|
-
|
|
152
|
-
response.statusCode = 403
|
|
153
|
-
|
|
154
|
-
response.end ( )
|
|
155
|
-
|
|
156
|
-
return false
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
response.setHeader ( 'Access-Control-Max-Age', 3600 )
|
|
160
|
-
response.setHeader ( 'Access-Control-Allow-Headers', 'x-caller,content-type' )
|
|
161
|
-
response.setHeader ( 'Access-Control-Allow-Methods', 'POST' )
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if ( request.method === 'OPTIONS' ) {
|
|
165
|
-
|
|
166
|
-
response.statusCode = 204
|
|
167
|
-
|
|
168
|
-
response.end ( )
|
|
169
|
-
|
|
170
|
-
return false
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return true
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* HTTP-RPC服务器请求监听方法
|
|
180
|
-
* @param {http.IncomingMessage} request
|
|
181
|
-
* @param {http.ServerResponse} response
|
|
182
|
-
*/
|
|
183
|
-
async call ( request, response ) {
|
|
184
|
-
|
|
185
|
-
if ( request.url !== this.path ) {
|
|
186
|
-
|
|
187
|
-
return this.respond ( request, response, new Error ( 'URL Incorrect' ) )
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if ( !this.cors ( request, response ) ) return
|
|
191
|
-
|
|
192
|
-
let body = Object.create ( null )
|
|
193
|
-
|
|
194
|
-
try {
|
|
195
|
-
|
|
196
|
-
body = await parseHTTPBody ( request )
|
|
197
|
-
|
|
198
|
-
if ( !body || 'object' !== typeof body ) throw new Error ( 'Content Invalid' )
|
|
199
|
-
|
|
200
|
-
} catch ( error ) {
|
|
201
|
-
|
|
202
|
-
return this.respond ( request, response, error )
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// global unique id
|
|
206
|
-
const traceId = request.headers [ 'x-trace-id' ]
|
|
207
|
-
|
|
208
|
-
// service name, required
|
|
209
|
-
const caller = request.headers [ 'x-caller' ] || 'anonymous'
|
|
210
|
-
|
|
211
|
-
// client ip or caller service ip
|
|
212
|
-
const ip = request.headers [ 'x-ip' ] || request.socket.remoteAddress
|
|
213
|
-
|
|
214
|
-
// startup client ip
|
|
215
|
-
const sourceIP = request.headers [ 'x-real-ip' ]
|
|
216
|
-
|
|
217
|
-
const { action, params = [ ] } = body
|
|
218
|
-
|
|
219
|
-
const context = Global.genContext ( { traceId, caller, sourceIP, ip } )
|
|
220
|
-
|
|
221
|
-
const format = await this.rpc.call ( action, params, context )
|
|
222
|
-
|
|
223
|
-
this.respond ( request, response, format )
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* HTTP Response Catch
|
|
230
|
-
* @param {http.IncomingMessage} request
|
|
231
|
-
* @param {http.ServerResponse} response
|
|
232
|
-
* @param {Object} format
|
|
233
|
-
* @param {Boolean} format.success
|
|
234
|
-
* @param {Error} format.error
|
|
235
|
-
* @param {any} format.body
|
|
236
|
-
*/
|
|
237
|
-
respond ( request, response, format ) {
|
|
238
|
-
|
|
239
|
-
let formatString = ''
|
|
240
|
-
|
|
241
|
-
if ( format instanceof Error ) {
|
|
242
|
-
|
|
243
|
-
format = {
|
|
244
|
-
success: false,
|
|
245
|
-
error: {
|
|
246
|
-
message: format.message,
|
|
247
|
-
stack: format.stack
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
try {
|
|
253
|
-
|
|
254
|
-
formatString = JSON.stringify ( format )
|
|
255
|
-
} catch ( { message, stack } ) {
|
|
256
|
-
|
|
257
|
-
delete format.body
|
|
258
|
-
|
|
259
|
-
format.success = false
|
|
260
|
-
|
|
261
|
-
format.error = {
|
|
262
|
-
message,
|
|
263
|
-
stack
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
formatString = JSON.stringify ( format )
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
response.setHeader ( 'Content-Type', 'application/json' )
|
|
270
|
-
|
|
271
|
-
response.setHeader ( 'Content-Length', Buffer.byteLength ( formatString ) )
|
|
272
|
-
|
|
273
|
-
response.end ( formatString )
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* HTTP RPC
|
|
280
|
-
* @param {String|URL|http.RequestOptions} url
|
|
281
|
-
* @param {String} action 函数名称
|
|
282
|
-
* @param {Array} params 参数列表
|
|
283
|
-
* @param {Context} context 上下文
|
|
284
|
-
*/
|
|
285
|
-
static async call ( url, action, params, context ) {
|
|
286
|
-
|
|
287
|
-
if ( !context || !context.traceId ) {
|
|
288
|
-
|
|
289
|
-
let trace = { }
|
|
290
|
-
|
|
291
|
-
Error.captureStackTrace ( trace )
|
|
292
|
-
|
|
293
|
-
context = Global.genContextByStack ( trace.stack )
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
const { traceId, caller, sourceIP } = context
|
|
297
|
-
|
|
298
|
-
const headers = {
|
|
299
|
-
'Content-Type': 'application/json',
|
|
300
|
-
'x-trace-id': String ( traceId ),
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if ( caller ) headers [ 'x-caller' ] = String ( caller )
|
|
304
|
-
|
|
305
|
-
if ( sourceIP ) headers [ 'x-real-ip' ] = sourceIP
|
|
306
|
-
|
|
307
|
-
headers [ 'x-ip' ] = getIPAddress ( 4 ) [ 0 ]
|
|
308
|
-
|
|
309
|
-
const format = await httpRequest ( url, {
|
|
310
|
-
headers
|
|
311
|
-
}, JSON.stringify ( { action, params } ) )
|
|
312
|
-
|
|
313
|
-
if ( 'string' === typeof format ) throw new Error ( format )
|
|
314
|
-
|
|
315
|
-
const { error, body } = format
|
|
316
|
-
|
|
317
|
-
if ( error ) {
|
|
318
|
-
|
|
319
|
-
const asyncError = new Error ( error.message )
|
|
320
|
-
|
|
321
|
-
throw asyncError
|
|
322
|
-
} else {
|
|
323
|
-
|
|
324
|
-
return body
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
package/rpc/rpc.class.js
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const { genOOXTrace } = require ( '../util' )
|
|
3
|
-
|
|
4
|
-
const Context = require ( './context.class' )
|
|
5
|
-
|
|
6
|
-
const HTTP = require ( './http.class' )
|
|
7
|
-
|
|
8
|
-
const SocketIO = require ( './socketio.class' )
|
|
9
|
-
|
|
10
|
-
const Global = require ( '../global' )
|
|
11
|
-
|
|
12
|
-
const RPCInterface = require ( './rpc.interface.class' )
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
module.exports = class RPC extends RPCInterface {
|
|
17
|
-
|
|
18
|
-
static Context = Context
|
|
19
|
-
|
|
20
|
-
static HTTP = HTTP
|
|
21
|
-
static SocketIO = SocketIO
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @type {HTTP}
|
|
27
|
-
*/
|
|
28
|
-
http = new this.constructor.HTTP ( this )
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @type {SocketIO}
|
|
34
|
-
*/
|
|
35
|
-
socketio = new this.constructor.SocketIO ( this )
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* new RPC service
|
|
41
|
-
* @param {*} methods
|
|
42
|
-
*/
|
|
43
|
-
constructor ( name, methods ) {
|
|
44
|
-
super ( name, methods )
|
|
45
|
-
|
|
46
|
-
Global.instances.push ( this )
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
async serve ( ) {
|
|
52
|
-
|
|
53
|
-
let isShareServer = false
|
|
54
|
-
|
|
55
|
-
if ( this.http.config && this.socketio.config ) {
|
|
56
|
-
|
|
57
|
-
isShareServer = !this.http.config.port && !this.socketio.config.port
|
|
58
|
-
|
|
59
|
-
isShareServer |= this.http.config.port === this.socketio.config.port
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
await this.http.serve ( )
|
|
63
|
-
|
|
64
|
-
if ( isShareServer ) this.socketio.server = this.http.server
|
|
65
|
-
|
|
66
|
-
await this.socketio.serve ( )
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
async stop ( ) {
|
|
72
|
-
|
|
73
|
-
await this.http.stop ( )
|
|
74
|
-
await this.socketio.stop ( )
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* 通用RPC调用方法
|
|
81
|
-
* @param {String} action
|
|
82
|
-
* @param {[]} params
|
|
83
|
-
* @param {Context} context
|
|
84
|
-
*/
|
|
85
|
-
async call ( action, params=[], context ) {
|
|
86
|
-
|
|
87
|
-
if ( !Array.isArray ( params ) ) params = [ params ]
|
|
88
|
-
|
|
89
|
-
const { traceId } = context
|
|
90
|
-
|
|
91
|
-
Global.contexts.set ( traceId, context )
|
|
92
|
-
|
|
93
|
-
this.emit ( 'request', action, params, context )
|
|
94
|
-
|
|
95
|
-
const format = {
|
|
96
|
-
traceId,
|
|
97
|
-
success: false
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const OOXTrace = genOOXTrace ( traceId, this.kvMethods )
|
|
101
|
-
|
|
102
|
-
try {
|
|
103
|
-
|
|
104
|
-
const result = await OOXTrace [ traceId ] ( action, [ ...params ], context )
|
|
105
|
-
|
|
106
|
-
format.body = result
|
|
107
|
-
|
|
108
|
-
format.success = true
|
|
109
|
-
|
|
110
|
-
this.emit ( 'success', action, params, context, result )
|
|
111
|
-
} catch ( error ) {
|
|
112
|
-
|
|
113
|
-
format.error = {
|
|
114
|
-
message: error.message,
|
|
115
|
-
stack: error.stack
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
this.emit ( 'fail', action, params, context, error )
|
|
119
|
-
} finally {
|
|
120
|
-
|
|
121
|
-
delete OOXTrace [ traceId ]
|
|
122
|
-
|
|
123
|
-
Global.contexts.delete ( traceId )
|
|
124
|
-
|
|
125
|
-
return format
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const { EventEmitter } = require ( 'events' )
|
|
3
|
-
|
|
4
|
-
const { genKVMethods, getIPAddress } = require ( '../util' )
|
|
5
|
-
|
|
6
|
-
const Context = require ( './context.class' )
|
|
7
|
-
|
|
8
|
-
const Config = require ( './config.class' )
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
module.exports = class RPC extends EventEmitter {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* refMethods => methods
|
|
18
|
-
*/
|
|
19
|
-
refMethods = { }
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* the kvMethods is all actions refs
|
|
25
|
-
* @type {Map<String,Function>}
|
|
26
|
-
*/
|
|
27
|
-
kvMethods = new Map ( )
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
set methods ( methods ) {
|
|
32
|
-
|
|
33
|
-
this.refMethods = methods
|
|
34
|
-
|
|
35
|
-
this.kvMethods.clear ( )
|
|
36
|
-
|
|
37
|
-
genKVMethods ( methods, this.kvMethods )
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
appendMethods ( methods ) {
|
|
43
|
-
|
|
44
|
-
genKVMethods ( methods, this.kvMethods )
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
get methods ( ) {
|
|
50
|
-
|
|
51
|
-
return this.refMethods
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* RPC Node Name
|
|
58
|
-
*/
|
|
59
|
-
name = ''
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
config = new Config
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* new RPC service
|
|
69
|
-
* @param {*} methods
|
|
70
|
-
*/
|
|
71
|
-
constructor ( name, methods ) {
|
|
72
|
-
super ( )
|
|
73
|
-
|
|
74
|
-
this.name = name
|
|
75
|
-
|
|
76
|
-
if ( methods )
|
|
77
|
-
this.methods = methods
|
|
78
|
-
|
|
79
|
-
const [ host ] = getIPAddress ( 4 )
|
|
80
|
-
|
|
81
|
-
this.config.host = host
|
|
82
|
-
|
|
83
|
-
this.config.name = name
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
async serve ( ) { }
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
async stop ( ) { }
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* RPC事件监听
|
|
98
|
-
* @param {'request'|'success'|'fail'} event
|
|
99
|
-
* @param {(action: String, params: [], context: Context, result: {
|
|
100
|
-
* traceId: String,
|
|
101
|
-
* success: Boolean,
|
|
102
|
-
* body: any,
|
|
103
|
-
* error: Error
|
|
104
|
-
* } | Error) => void} listener
|
|
105
|
-
*/
|
|
106
|
-
on ( event, listener ) {
|
|
107
|
-
return super.on ( event, listener )
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* 通用RPC调用方法
|
|
114
|
-
* @param {String} action
|
|
115
|
-
* @param {[]} params
|
|
116
|
-
* @param {Context} context
|
|
117
|
-
*/
|
|
118
|
-
async call ( action, params=[], context ) { }
|
|
119
|
-
}
|