@faasjs/func 0.0.2-beta.302 → 0.0.2-beta.320
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/{lib → dist}/index.d.ts +135 -132
- package/dist/index.js +233 -0
- package/dist/index.mjs +202 -0
- package/package.json +10 -15
- package/lib/index.es.js +0 -230
- package/lib/index.js +0 -236
- package/lib/plugins/run_handler/index.d.ts +0 -6
package/{lib → dist}/index.d.ts
RENAMED
|
@@ -1,132 +1,135 @@
|
|
|
1
|
-
import { Logger } from '@faasjs/logger';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
readonly
|
|
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
|
-
* @param config
|
|
94
|
-
* @param config.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
*
|
|
101
|
-
* @param data
|
|
102
|
-
* @param data.
|
|
103
|
-
* @param data.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
*
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
1
|
+
import { Logger } from '@faasjs/logger';
|
|
2
|
+
|
|
3
|
+
declare type Handler<TEvent = any, TContext = any, TResult = any> = (data: InvokeData<TEvent, TContext>) => Promise<TResult>;
|
|
4
|
+
declare type Next = () => Promise<void>;
|
|
5
|
+
declare type ExportedHandler<TEvent = any, TContext = any, TResult = any> = (event: TEvent, context?: TContext, callback?: (...args: any) => any) => Promise<TResult>;
|
|
6
|
+
declare type Plugin = {
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
readonly type: string;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
onDeploy?: (data: DeployData, next: Next) => void | Promise<void>;
|
|
11
|
+
onMount?: (data: MountData, next: Next) => void | Promise<void>;
|
|
12
|
+
onInvoke?: (data: InvokeData, next: Next) => void | Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
declare type ProviderConfig = {
|
|
15
|
+
type: string;
|
|
16
|
+
config: {
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
declare type Config = {
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
providers?: {
|
|
23
|
+
[key: string]: ProviderConfig;
|
|
24
|
+
};
|
|
25
|
+
plugins?: {
|
|
26
|
+
[key: string]: {
|
|
27
|
+
[key: string]: any;
|
|
28
|
+
provider?: string | ProviderConfig;
|
|
29
|
+
type: string;
|
|
30
|
+
config?: {
|
|
31
|
+
[key: string]: any;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
declare type DeployData = {
|
|
37
|
+
[key: string]: any;
|
|
38
|
+
root: string;
|
|
39
|
+
filename: string;
|
|
40
|
+
env?: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
config?: Config;
|
|
43
|
+
version?: string;
|
|
44
|
+
dependencies: {
|
|
45
|
+
[name: string]: string;
|
|
46
|
+
};
|
|
47
|
+
plugins?: {
|
|
48
|
+
[name: string]: {
|
|
49
|
+
[key: string]: any;
|
|
50
|
+
name?: string;
|
|
51
|
+
type: string;
|
|
52
|
+
provider?: string;
|
|
53
|
+
config: {
|
|
54
|
+
[key: string]: any;
|
|
55
|
+
};
|
|
56
|
+
plugin: Plugin;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
logger?: Logger;
|
|
60
|
+
};
|
|
61
|
+
declare type MountData = {
|
|
62
|
+
[key: string]: any;
|
|
63
|
+
config: Config;
|
|
64
|
+
event: any;
|
|
65
|
+
context: any;
|
|
66
|
+
};
|
|
67
|
+
declare type InvokeData<TEvent = any, TContext = any, TResult = any> = {
|
|
68
|
+
[key: string]: any;
|
|
69
|
+
event: TEvent;
|
|
70
|
+
context: TContext;
|
|
71
|
+
callback: any;
|
|
72
|
+
response: any;
|
|
73
|
+
logger: Logger;
|
|
74
|
+
handler?: Handler<TEvent, TContext, TResult>;
|
|
75
|
+
config: Config;
|
|
76
|
+
};
|
|
77
|
+
declare type LifeCycleKey = 'onDeploy' | 'onMount' | 'onInvoke';
|
|
78
|
+
declare type FuncConfig<TEvent = any, TContext = any, TResult = any> = {
|
|
79
|
+
plugins?: Plugin[];
|
|
80
|
+
handler?: Handler<TEvent, TContext, TResult>;
|
|
81
|
+
};
|
|
82
|
+
declare class Func<TEvent = any, TContext = any, TResult = any> {
|
|
83
|
+
[key: string]: any;
|
|
84
|
+
plugins: Plugin[];
|
|
85
|
+
handler?: Handler<TEvent, TContext, TResult>;
|
|
86
|
+
logger: Logger;
|
|
87
|
+
config: Config;
|
|
88
|
+
mounted: boolean;
|
|
89
|
+
filename?: string;
|
|
90
|
+
private cachedFunctions;
|
|
91
|
+
/**
|
|
92
|
+
* 新建流程
|
|
93
|
+
* @param config {object} 配置项
|
|
94
|
+
* @param config.plugins {Plugin[]} 插件
|
|
95
|
+
* @param config.handler {Handler} 业务函数
|
|
96
|
+
*/
|
|
97
|
+
constructor(config: FuncConfig<TEvent, TContext>);
|
|
98
|
+
compose(key: LifeCycleKey): (data: any, next?: () => void) => any;
|
|
99
|
+
/**
|
|
100
|
+
* 发布云资源
|
|
101
|
+
* @param data {object} 代码包信息
|
|
102
|
+
* @param data.root {string} 项目根目录
|
|
103
|
+
* @param data.filename {string} 包括完整路径的流程文件名
|
|
104
|
+
* @param data.env {string} 环境
|
|
105
|
+
*/
|
|
106
|
+
deploy(data: DeployData): any;
|
|
107
|
+
/**
|
|
108
|
+
* 启动云实例
|
|
109
|
+
*/
|
|
110
|
+
mount(data: {
|
|
111
|
+
event: TEvent;
|
|
112
|
+
context: TContext;
|
|
113
|
+
config?: Config;
|
|
114
|
+
}): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* 执行云函数
|
|
117
|
+
* @param data {object} 执行信息
|
|
118
|
+
*/
|
|
119
|
+
invoke(data: InvokeData<TEvent, TContext, TResult>): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* 创建触发函数
|
|
122
|
+
*/
|
|
123
|
+
export(config?: Config): {
|
|
124
|
+
handler: ExportedHandler<TEvent, TContext, TResult>;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
declare type UseifyPlugin = {
|
|
128
|
+
mount?: (data: {
|
|
129
|
+
config: Config;
|
|
130
|
+
}) => Promise<void>;
|
|
131
|
+
};
|
|
132
|
+
declare function usePlugin<T extends Plugin>(plugin: T & UseifyPlugin): T & UseifyPlugin;
|
|
133
|
+
declare function useFunc<TEvent = any, TContext = any, TResult = any>(handler: () => Handler<TEvent, TContext, TResult>): Func<TEvent, TContext, TResult>;
|
|
134
|
+
|
|
135
|
+
export { Config, DeployData, ExportedHandler, Func, FuncConfig, Handler, InvokeData, LifeCycleKey, MountData, Next, Plugin, ProviderConfig, UseifyPlugin, useFunc, usePlugin };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __reExport = (target, module2, copyDefault, desc) => {
|
|
11
|
+
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(module2))
|
|
13
|
+
if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default"))
|
|
14
|
+
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return target;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = /* @__PURE__ */ ((cache) => {
|
|
19
|
+
return (module2, temp) => {
|
|
20
|
+
return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp);
|
|
21
|
+
};
|
|
22
|
+
})(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0);
|
|
23
|
+
|
|
24
|
+
// src/index.ts
|
|
25
|
+
var src_exports = {};
|
|
26
|
+
__export(src_exports, {
|
|
27
|
+
Func: () => Func,
|
|
28
|
+
useFunc: () => useFunc,
|
|
29
|
+
usePlugin: () => usePlugin
|
|
30
|
+
});
|
|
31
|
+
var import_logger = require("@faasjs/logger");
|
|
32
|
+
|
|
33
|
+
// src/plugins/run_handler/index.ts
|
|
34
|
+
var RunHandler = class {
|
|
35
|
+
constructor() {
|
|
36
|
+
this.type = "handler";
|
|
37
|
+
this.name = "handler";
|
|
38
|
+
}
|
|
39
|
+
async onInvoke(data, next) {
|
|
40
|
+
if (data.handler)
|
|
41
|
+
if (!data.runHandler) {
|
|
42
|
+
try {
|
|
43
|
+
data.response = await new Promise(function(resolve, reject) {
|
|
44
|
+
data.callback = function(error, result) {
|
|
45
|
+
if (error)
|
|
46
|
+
reject(error);
|
|
47
|
+
else
|
|
48
|
+
resolve(result);
|
|
49
|
+
};
|
|
50
|
+
Promise.resolve(data.handler(data)).then(function(result) {
|
|
51
|
+
resolve(result);
|
|
52
|
+
}).catch(function(error) {
|
|
53
|
+
reject(error);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
} catch (error) {
|
|
57
|
+
data.logger.error(error);
|
|
58
|
+
data.response = error;
|
|
59
|
+
}
|
|
60
|
+
data.runHandler = true;
|
|
61
|
+
} else
|
|
62
|
+
data.logger.warn("[RunHandler] handler has been run");
|
|
63
|
+
await next();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// src/index.ts
|
|
68
|
+
var startedAt = Date.now();
|
|
69
|
+
var Func = class {
|
|
70
|
+
constructor(config) {
|
|
71
|
+
var _a;
|
|
72
|
+
this.logger = new import_logger.Logger("Func");
|
|
73
|
+
this.handler = config.handler;
|
|
74
|
+
this.plugins = (_a = config.plugins) != null ? _a : [];
|
|
75
|
+
this.plugins.push(new RunHandler());
|
|
76
|
+
this.config = {
|
|
77
|
+
providers: Object.create(null),
|
|
78
|
+
plugins: Object.create(null)
|
|
79
|
+
};
|
|
80
|
+
this.mounted = false;
|
|
81
|
+
this.cachedFunctions = Object.create(null);
|
|
82
|
+
try {
|
|
83
|
+
this.filename = new Error().stack.split("\n").find((s) => /[^/]\.func\.ts/.test(s)).match(/\((.*\.func\.ts).*\)/)[1];
|
|
84
|
+
} catch (error) {
|
|
85
|
+
this.logger.debug(error.message);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
compose(key) {
|
|
89
|
+
const logger = new import_logger.Logger(key);
|
|
90
|
+
let list = [];
|
|
91
|
+
if (this.cachedFunctions[key])
|
|
92
|
+
list = this.cachedFunctions[key];
|
|
93
|
+
else {
|
|
94
|
+
for (const plugin of this.plugins) {
|
|
95
|
+
const handler = plugin[key];
|
|
96
|
+
if (typeof handler === "function")
|
|
97
|
+
list.push({
|
|
98
|
+
key: plugin.name,
|
|
99
|
+
handler: handler.bind(plugin)
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
this.cachedFunctions[key] = list;
|
|
103
|
+
}
|
|
104
|
+
return async function(data, next) {
|
|
105
|
+
let index = -1;
|
|
106
|
+
const dispatch = async function(i) {
|
|
107
|
+
if (i <= index)
|
|
108
|
+
return Promise.reject(Error("next() called multiple times"));
|
|
109
|
+
index = i;
|
|
110
|
+
let fn = list[i];
|
|
111
|
+
if (i === list.length)
|
|
112
|
+
fn = next;
|
|
113
|
+
if (!fn)
|
|
114
|
+
return Promise.resolve();
|
|
115
|
+
if (typeof fn.key === "undefined")
|
|
116
|
+
fn.key = `UnNamedPlugin#${i}`;
|
|
117
|
+
logger.debug(`[${fn.key}] begin`);
|
|
118
|
+
logger.time(fn.key);
|
|
119
|
+
try {
|
|
120
|
+
const res = await Promise.resolve(fn.handler(data, dispatch.bind(null, i + 1)));
|
|
121
|
+
logger.timeEnd(fn.key, `[${fn.key}] end`);
|
|
122
|
+
return res;
|
|
123
|
+
} catch (err) {
|
|
124
|
+
logger.timeEnd(fn.key, `[${fn.key}] failed`);
|
|
125
|
+
console.error(err);
|
|
126
|
+
return Promise.reject(err);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
return await dispatch(0);
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
deploy(data) {
|
|
133
|
+
this.logger.debug("onDeploy");
|
|
134
|
+
return this.compose("onDeploy")(data);
|
|
135
|
+
}
|
|
136
|
+
async mount(data) {
|
|
137
|
+
this.logger.debug("onMount");
|
|
138
|
+
if (this.mounted) {
|
|
139
|
+
this.logger.warn("mount() has been called, skipped.");
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
data.config = this.config;
|
|
143
|
+
try {
|
|
144
|
+
this.logger.time("mount");
|
|
145
|
+
this.logger.debug("Plugins: " + this.plugins.map((p) => `${p.type}#${p.name}`).join(","));
|
|
146
|
+
await this.compose("onMount")(data);
|
|
147
|
+
this.mounted = true;
|
|
148
|
+
} finally {
|
|
149
|
+
this.logger.timeEnd("mount", "mounted");
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async invoke(data) {
|
|
153
|
+
if (!this.mounted)
|
|
154
|
+
await this.mount({
|
|
155
|
+
event: data.event,
|
|
156
|
+
context: data.context,
|
|
157
|
+
config: data.config
|
|
158
|
+
});
|
|
159
|
+
try {
|
|
160
|
+
await this.compose("onInvoke")(data);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
this.logger.error(error);
|
|
163
|
+
data.response = error;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
export(config) {
|
|
167
|
+
if (!this.config)
|
|
168
|
+
this.config = config || Object.create(null);
|
|
169
|
+
return {
|
|
170
|
+
handler: async (event, context, callback) => {
|
|
171
|
+
const logger = new import_logger.Logger();
|
|
172
|
+
if (startedAt) {
|
|
173
|
+
logger.debug(`Container started +${Date.now() - startedAt}ms`);
|
|
174
|
+
startedAt = 0;
|
|
175
|
+
}
|
|
176
|
+
logger.debug("event: %j", event);
|
|
177
|
+
logger.debug("context: %j", context);
|
|
178
|
+
if (typeof context === "undefined")
|
|
179
|
+
context = {};
|
|
180
|
+
if (!context.request_id)
|
|
181
|
+
context.request_id = new Date().getTime().toString();
|
|
182
|
+
if (!context.request_at)
|
|
183
|
+
context.request_at = Math.round(new Date().getTime() / 1e3);
|
|
184
|
+
context.callbackWaitsForEmptyEventLoop = false;
|
|
185
|
+
const data = {
|
|
186
|
+
event,
|
|
187
|
+
context,
|
|
188
|
+
callback,
|
|
189
|
+
response: void 0,
|
|
190
|
+
handler: this.handler,
|
|
191
|
+
logger,
|
|
192
|
+
config: this.config
|
|
193
|
+
};
|
|
194
|
+
await this.invoke(data);
|
|
195
|
+
if (Object.prototype.toString.call(data.response) === "[object Error]")
|
|
196
|
+
throw data.response;
|
|
197
|
+
return data.response;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
var plugins = [];
|
|
203
|
+
function usePlugin(plugin) {
|
|
204
|
+
if (!plugins.find((p) => p.name === plugin.name))
|
|
205
|
+
plugins.push(plugin);
|
|
206
|
+
if (plugin.mount == null)
|
|
207
|
+
plugin.mount = async function({ config }) {
|
|
208
|
+
if (plugin.onMount)
|
|
209
|
+
await plugin.onMount({
|
|
210
|
+
config,
|
|
211
|
+
event: {},
|
|
212
|
+
context: {}
|
|
213
|
+
}, async () => await Promise.resolve());
|
|
214
|
+
};
|
|
215
|
+
return plugin;
|
|
216
|
+
}
|
|
217
|
+
function useFunc(handler) {
|
|
218
|
+
plugins = [];
|
|
219
|
+
const invokeHandler = handler();
|
|
220
|
+
const func = new Func({
|
|
221
|
+
plugins,
|
|
222
|
+
handler: invokeHandler
|
|
223
|
+
});
|
|
224
|
+
plugins = [];
|
|
225
|
+
return func;
|
|
226
|
+
}
|
|
227
|
+
module.exports = __toCommonJS(src_exports);
|
|
228
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
229
|
+
0 && (module.exports = {
|
|
230
|
+
Func,
|
|
231
|
+
useFunc,
|
|
232
|
+
usePlugin
|
|
233
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { Logger } from "@faasjs/logger";
|
|
3
|
+
|
|
4
|
+
// src/plugins/run_handler/index.ts
|
|
5
|
+
var RunHandler = class {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.type = "handler";
|
|
8
|
+
this.name = "handler";
|
|
9
|
+
}
|
|
10
|
+
async onInvoke(data, next) {
|
|
11
|
+
if (data.handler)
|
|
12
|
+
if (!data.runHandler) {
|
|
13
|
+
try {
|
|
14
|
+
data.response = await new Promise(function(resolve, reject) {
|
|
15
|
+
data.callback = function(error, result) {
|
|
16
|
+
if (error)
|
|
17
|
+
reject(error);
|
|
18
|
+
else
|
|
19
|
+
resolve(result);
|
|
20
|
+
};
|
|
21
|
+
Promise.resolve(data.handler(data)).then(function(result) {
|
|
22
|
+
resolve(result);
|
|
23
|
+
}).catch(function(error) {
|
|
24
|
+
reject(error);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
} catch (error) {
|
|
28
|
+
data.logger.error(error);
|
|
29
|
+
data.response = error;
|
|
30
|
+
}
|
|
31
|
+
data.runHandler = true;
|
|
32
|
+
} else
|
|
33
|
+
data.logger.warn("[RunHandler] handler has been run");
|
|
34
|
+
await next();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/index.ts
|
|
39
|
+
var startedAt = Date.now();
|
|
40
|
+
var Func = class {
|
|
41
|
+
constructor(config) {
|
|
42
|
+
var _a;
|
|
43
|
+
this.logger = new Logger("Func");
|
|
44
|
+
this.handler = config.handler;
|
|
45
|
+
this.plugins = (_a = config.plugins) != null ? _a : [];
|
|
46
|
+
this.plugins.push(new RunHandler());
|
|
47
|
+
this.config = {
|
|
48
|
+
providers: Object.create(null),
|
|
49
|
+
plugins: Object.create(null)
|
|
50
|
+
};
|
|
51
|
+
this.mounted = false;
|
|
52
|
+
this.cachedFunctions = Object.create(null);
|
|
53
|
+
try {
|
|
54
|
+
this.filename = new Error().stack.split("\n").find((s) => /[^/]\.func\.ts/.test(s)).match(/\((.*\.func\.ts).*\)/)[1];
|
|
55
|
+
} catch (error) {
|
|
56
|
+
this.logger.debug(error.message);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
compose(key) {
|
|
60
|
+
const logger = new Logger(key);
|
|
61
|
+
let list = [];
|
|
62
|
+
if (this.cachedFunctions[key])
|
|
63
|
+
list = this.cachedFunctions[key];
|
|
64
|
+
else {
|
|
65
|
+
for (const plugin of this.plugins) {
|
|
66
|
+
const handler = plugin[key];
|
|
67
|
+
if (typeof handler === "function")
|
|
68
|
+
list.push({
|
|
69
|
+
key: plugin.name,
|
|
70
|
+
handler: handler.bind(plugin)
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
this.cachedFunctions[key] = list;
|
|
74
|
+
}
|
|
75
|
+
return async function(data, next) {
|
|
76
|
+
let index = -1;
|
|
77
|
+
const dispatch = async function(i) {
|
|
78
|
+
if (i <= index)
|
|
79
|
+
return Promise.reject(Error("next() called multiple times"));
|
|
80
|
+
index = i;
|
|
81
|
+
let fn = list[i];
|
|
82
|
+
if (i === list.length)
|
|
83
|
+
fn = next;
|
|
84
|
+
if (!fn)
|
|
85
|
+
return Promise.resolve();
|
|
86
|
+
if (typeof fn.key === "undefined")
|
|
87
|
+
fn.key = `UnNamedPlugin#${i}`;
|
|
88
|
+
logger.debug(`[${fn.key}] begin`);
|
|
89
|
+
logger.time(fn.key);
|
|
90
|
+
try {
|
|
91
|
+
const res = await Promise.resolve(fn.handler(data, dispatch.bind(null, i + 1)));
|
|
92
|
+
logger.timeEnd(fn.key, `[${fn.key}] end`);
|
|
93
|
+
return res;
|
|
94
|
+
} catch (err) {
|
|
95
|
+
logger.timeEnd(fn.key, `[${fn.key}] failed`);
|
|
96
|
+
console.error(err);
|
|
97
|
+
return Promise.reject(err);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
return await dispatch(0);
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
deploy(data) {
|
|
104
|
+
this.logger.debug("onDeploy");
|
|
105
|
+
return this.compose("onDeploy")(data);
|
|
106
|
+
}
|
|
107
|
+
async mount(data) {
|
|
108
|
+
this.logger.debug("onMount");
|
|
109
|
+
if (this.mounted) {
|
|
110
|
+
this.logger.warn("mount() has been called, skipped.");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
data.config = this.config;
|
|
114
|
+
try {
|
|
115
|
+
this.logger.time("mount");
|
|
116
|
+
this.logger.debug("Plugins: " + this.plugins.map((p) => `${p.type}#${p.name}`).join(","));
|
|
117
|
+
await this.compose("onMount")(data);
|
|
118
|
+
this.mounted = true;
|
|
119
|
+
} finally {
|
|
120
|
+
this.logger.timeEnd("mount", "mounted");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async invoke(data) {
|
|
124
|
+
if (!this.mounted)
|
|
125
|
+
await this.mount({
|
|
126
|
+
event: data.event,
|
|
127
|
+
context: data.context,
|
|
128
|
+
config: data.config
|
|
129
|
+
});
|
|
130
|
+
try {
|
|
131
|
+
await this.compose("onInvoke")(data);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
this.logger.error(error);
|
|
134
|
+
data.response = error;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export(config) {
|
|
138
|
+
if (!this.config)
|
|
139
|
+
this.config = config || Object.create(null);
|
|
140
|
+
return {
|
|
141
|
+
handler: async (event, context, callback) => {
|
|
142
|
+
const logger = new Logger();
|
|
143
|
+
if (startedAt) {
|
|
144
|
+
logger.debug(`Container started +${Date.now() - startedAt}ms`);
|
|
145
|
+
startedAt = 0;
|
|
146
|
+
}
|
|
147
|
+
logger.debug("event: %j", event);
|
|
148
|
+
logger.debug("context: %j", context);
|
|
149
|
+
if (typeof context === "undefined")
|
|
150
|
+
context = {};
|
|
151
|
+
if (!context.request_id)
|
|
152
|
+
context.request_id = new Date().getTime().toString();
|
|
153
|
+
if (!context.request_at)
|
|
154
|
+
context.request_at = Math.round(new Date().getTime() / 1e3);
|
|
155
|
+
context.callbackWaitsForEmptyEventLoop = false;
|
|
156
|
+
const data = {
|
|
157
|
+
event,
|
|
158
|
+
context,
|
|
159
|
+
callback,
|
|
160
|
+
response: void 0,
|
|
161
|
+
handler: this.handler,
|
|
162
|
+
logger,
|
|
163
|
+
config: this.config
|
|
164
|
+
};
|
|
165
|
+
await this.invoke(data);
|
|
166
|
+
if (Object.prototype.toString.call(data.response) === "[object Error]")
|
|
167
|
+
throw data.response;
|
|
168
|
+
return data.response;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
var plugins = [];
|
|
174
|
+
function usePlugin(plugin) {
|
|
175
|
+
if (!plugins.find((p) => p.name === plugin.name))
|
|
176
|
+
plugins.push(plugin);
|
|
177
|
+
if (plugin.mount == null)
|
|
178
|
+
plugin.mount = async function({ config }) {
|
|
179
|
+
if (plugin.onMount)
|
|
180
|
+
await plugin.onMount({
|
|
181
|
+
config,
|
|
182
|
+
event: {},
|
|
183
|
+
context: {}
|
|
184
|
+
}, async () => await Promise.resolve());
|
|
185
|
+
};
|
|
186
|
+
return plugin;
|
|
187
|
+
}
|
|
188
|
+
function useFunc(handler) {
|
|
189
|
+
plugins = [];
|
|
190
|
+
const invokeHandler = handler();
|
|
191
|
+
const func = new Func({
|
|
192
|
+
plugins,
|
|
193
|
+
handler: invokeHandler
|
|
194
|
+
});
|
|
195
|
+
plugins = [];
|
|
196
|
+
return func;
|
|
197
|
+
}
|
|
198
|
+
export {
|
|
199
|
+
Func,
|
|
200
|
+
useFunc,
|
|
201
|
+
usePlugin
|
|
202
|
+
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faasjs/func",
|
|
3
|
-
"version": "0.0.2-beta.
|
|
3
|
+
"version": "0.0.2-beta.320",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"main": "
|
|
6
|
-
"types": "
|
|
7
|
-
"module": "
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"module": "dist/index.mjs",
|
|
8
8
|
"homepage": "https://faasjs.com/docs/func",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -16,26 +16,21 @@
|
|
|
16
16
|
},
|
|
17
17
|
"funding": "https://github.com/sponsors/faasjs",
|
|
18
18
|
"scripts": {
|
|
19
|
-
"
|
|
20
|
-
"prepack": "rm -rf ./lib && rollup -c && mv lib/*/src/* lib/"
|
|
19
|
+
"build": "rm -rf ./dist && tsup-node src/index.ts --format esm,cjs --dts"
|
|
21
20
|
},
|
|
22
21
|
"files": [
|
|
23
|
-
"
|
|
22
|
+
"dist"
|
|
24
23
|
],
|
|
25
24
|
"peerDependencies": {
|
|
26
|
-
"@faasjs/deep_merge": "^0.0.2-beta.
|
|
27
|
-
"@faasjs/logger": "^0.0.2-beta.
|
|
25
|
+
"@faasjs/deep_merge": "^0.0.2-beta.320",
|
|
26
|
+
"@faasjs/logger": "^0.0.2-beta.320"
|
|
28
27
|
},
|
|
29
28
|
"devDependencies": {
|
|
30
|
-
"
|
|
31
|
-
"@types/jest": "*",
|
|
32
|
-
"@types/node": "*",
|
|
33
|
-
"rollup": "*",
|
|
34
|
-
"rollup-plugin-typescript2": "*",
|
|
29
|
+
"tsup": "*",
|
|
35
30
|
"typescript": "*"
|
|
36
31
|
},
|
|
37
32
|
"engines": {
|
|
38
33
|
"npm": ">=8.0.0"
|
|
39
34
|
},
|
|
40
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "4a9f699171ad7e20d922e68b74418d1ec5b7d016"
|
|
41
36
|
}
|
package/lib/index.es.js
DELETED
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import { Logger } from '@faasjs/logger';
|
|
2
|
-
|
|
3
|
-
class RunHandler {
|
|
4
|
-
constructor() {
|
|
5
|
-
this.type = 'handler';
|
|
6
|
-
this.name = 'handler';
|
|
7
|
-
}
|
|
8
|
-
async onInvoke(data, next) {
|
|
9
|
-
if (data.handler)
|
|
10
|
-
if (!data.runHandler) {
|
|
11
|
-
try {
|
|
12
|
-
data.response = await new Promise(function (resolve, reject) {
|
|
13
|
-
data.callback = function (error, result) {
|
|
14
|
-
if (error)
|
|
15
|
-
reject(error);
|
|
16
|
-
else
|
|
17
|
-
resolve(result);
|
|
18
|
-
};
|
|
19
|
-
Promise.resolve(data.handler(data)).then(function (result) {
|
|
20
|
-
resolve(result);
|
|
21
|
-
}).catch(function (error) {
|
|
22
|
-
reject(error);
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
27
|
-
data.logger.error(error);
|
|
28
|
-
data.response = error;
|
|
29
|
-
}
|
|
30
|
-
data.runHandler = true;
|
|
31
|
-
}
|
|
32
|
-
else
|
|
33
|
-
data.logger.warn('[RunHandler] handler has been run');
|
|
34
|
-
await next();
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
let startedAt = Date.now();
|
|
39
|
-
class Func {
|
|
40
|
-
/**
|
|
41
|
-
* 新建流程
|
|
42
|
-
* @param config {object} 配置项
|
|
43
|
-
* @param config.plugins {Plugin[]} 插件
|
|
44
|
-
* @param config.handler {Handler} 业务函数
|
|
45
|
-
*/
|
|
46
|
-
constructor(config) {
|
|
47
|
-
var _a;
|
|
48
|
-
this.logger = new Logger('Func');
|
|
49
|
-
this.handler = config.handler;
|
|
50
|
-
this.plugins = (_a = config.plugins) !== null && _a !== void 0 ? _a : [];
|
|
51
|
-
this.plugins.push(new RunHandler());
|
|
52
|
-
this.config = {
|
|
53
|
-
providers: Object.create(null),
|
|
54
|
-
plugins: Object.create(null)
|
|
55
|
-
};
|
|
56
|
-
this.mounted = false;
|
|
57
|
-
this.cachedFunctions = Object.create(null);
|
|
58
|
-
try {
|
|
59
|
-
this.filename = new Error().stack
|
|
60
|
-
.split('\n')
|
|
61
|
-
.find(s => /[^/]\.func\.ts/.test(s))
|
|
62
|
-
.match(/\((.*\.func\.ts).*\)/)[1];
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
this.logger.debug(error.message);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
compose(key) {
|
|
69
|
-
const logger = new Logger(key);
|
|
70
|
-
let list = [];
|
|
71
|
-
if (this.cachedFunctions[key])
|
|
72
|
-
list = this.cachedFunctions[key];
|
|
73
|
-
else {
|
|
74
|
-
for (const plugin of this.plugins) {
|
|
75
|
-
const handler = plugin[key];
|
|
76
|
-
if (typeof handler === 'function')
|
|
77
|
-
list.push({
|
|
78
|
-
key: plugin.name,
|
|
79
|
-
handler: handler.bind(plugin)
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
this.cachedFunctions[key] = list;
|
|
83
|
-
}
|
|
84
|
-
return async function (data, next) {
|
|
85
|
-
let index = -1;
|
|
86
|
-
const dispatch = async function (i) {
|
|
87
|
-
if (i <= index)
|
|
88
|
-
return Promise.reject(Error('next() called multiple times'));
|
|
89
|
-
index = i;
|
|
90
|
-
let fn = list[i];
|
|
91
|
-
if (i === list.length)
|
|
92
|
-
fn = next;
|
|
93
|
-
if (!fn)
|
|
94
|
-
return Promise.resolve();
|
|
95
|
-
if (typeof fn.key === 'undefined')
|
|
96
|
-
fn.key = `UnNamedPlugin#${i}`;
|
|
97
|
-
logger.debug(`[${fn.key}] begin`);
|
|
98
|
-
logger.time(fn.key);
|
|
99
|
-
try {
|
|
100
|
-
const res = await Promise.resolve(fn.handler(data, dispatch.bind(null, i + 1)));
|
|
101
|
-
logger.timeEnd(fn.key, `[${fn.key}] end`);
|
|
102
|
-
return res;
|
|
103
|
-
}
|
|
104
|
-
catch (err) {
|
|
105
|
-
logger.timeEnd(fn.key, `[${fn.key}] failed`);
|
|
106
|
-
console.error(err);
|
|
107
|
-
return Promise.reject(err);
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
return await dispatch(0);
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* 发布云资源
|
|
115
|
-
* @param data {object} 代码包信息
|
|
116
|
-
* @param data.root {string} 项目根目录
|
|
117
|
-
* @param data.filename {string} 包括完整路径的流程文件名
|
|
118
|
-
* @param data.env {string} 环境
|
|
119
|
-
*/
|
|
120
|
-
deploy(data) {
|
|
121
|
-
this.logger.debug('onDeploy');
|
|
122
|
-
return this.compose('onDeploy')(data);
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* 启动云实例
|
|
126
|
-
*/
|
|
127
|
-
async mount(data) {
|
|
128
|
-
this.logger.debug('onMount');
|
|
129
|
-
if (this.mounted) {
|
|
130
|
-
this.logger.warn('mount() has been called, skipped.');
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
data.config = this.config;
|
|
134
|
-
try {
|
|
135
|
-
this.logger.time('mount');
|
|
136
|
-
this.logger.debug('Plugins: ' + this.plugins.map(p => `${p.type}#${p.name}`).join(','));
|
|
137
|
-
await this.compose('onMount')(data);
|
|
138
|
-
this.mounted = true;
|
|
139
|
-
}
|
|
140
|
-
finally {
|
|
141
|
-
this.logger.timeEnd('mount', 'mounted');
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* 执行云函数
|
|
146
|
-
* @param data {object} 执行信息
|
|
147
|
-
*/
|
|
148
|
-
async invoke(data) {
|
|
149
|
-
// 实例未启动时执行启动函数
|
|
150
|
-
if (!this.mounted)
|
|
151
|
-
await this.mount({
|
|
152
|
-
event: data.event,
|
|
153
|
-
context: data.context,
|
|
154
|
-
config: data.config
|
|
155
|
-
});
|
|
156
|
-
try {
|
|
157
|
-
await this.compose('onInvoke')(data);
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
// 执行异常时回传异常
|
|
161
|
-
this.logger.error(error);
|
|
162
|
-
data.response = error;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* 创建触发函数
|
|
167
|
-
*/
|
|
168
|
-
export(config) {
|
|
169
|
-
if (!this.config)
|
|
170
|
-
this.config = config || Object.create(null);
|
|
171
|
-
return {
|
|
172
|
-
handler: async (event, context, callback) => {
|
|
173
|
-
const logger = new Logger();
|
|
174
|
-
if (startedAt) {
|
|
175
|
-
logger.debug(`Container started +${Date.now() - startedAt}ms`);
|
|
176
|
-
startedAt = 0;
|
|
177
|
-
}
|
|
178
|
-
logger.debug('event: %j', event);
|
|
179
|
-
logger.debug('context: %j', context);
|
|
180
|
-
if (typeof context === 'undefined')
|
|
181
|
-
context = {};
|
|
182
|
-
if (!context.request_id)
|
|
183
|
-
context.request_id = new Date().getTime().toString();
|
|
184
|
-
if (!context.request_at)
|
|
185
|
-
context.request_at = Math.round(new Date().getTime() / 1000);
|
|
186
|
-
context.callbackWaitsForEmptyEventLoop = false;
|
|
187
|
-
const data = {
|
|
188
|
-
event,
|
|
189
|
-
context,
|
|
190
|
-
callback,
|
|
191
|
-
response: undefined,
|
|
192
|
-
handler: this.handler,
|
|
193
|
-
logger,
|
|
194
|
-
config: this.config
|
|
195
|
-
};
|
|
196
|
-
await this.invoke(data);
|
|
197
|
-
if (Object.prototype.toString.call(data.response) === '[object Error]')
|
|
198
|
-
throw data.response;
|
|
199
|
-
return data.response;
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
let plugins = [];
|
|
205
|
-
function usePlugin(plugin) {
|
|
206
|
-
if (!plugins.find(p => p.name === plugin.name))
|
|
207
|
-
plugins.push(plugin);
|
|
208
|
-
if (plugin.mount == null)
|
|
209
|
-
plugin.mount = async function ({ config }) {
|
|
210
|
-
if (plugin.onMount)
|
|
211
|
-
await plugin.onMount({
|
|
212
|
-
config,
|
|
213
|
-
event: {},
|
|
214
|
-
context: {}
|
|
215
|
-
}, async () => await Promise.resolve());
|
|
216
|
-
};
|
|
217
|
-
return plugin;
|
|
218
|
-
}
|
|
219
|
-
function useFunc(handler) {
|
|
220
|
-
plugins = [];
|
|
221
|
-
const invokeHandler = handler();
|
|
222
|
-
const func = new Func({
|
|
223
|
-
plugins,
|
|
224
|
-
handler: invokeHandler
|
|
225
|
-
});
|
|
226
|
-
plugins = [];
|
|
227
|
-
return func;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export { Func, useFunc, usePlugin };
|
package/lib/index.js
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var logger = require('@faasjs/logger');
|
|
6
|
-
|
|
7
|
-
class RunHandler {
|
|
8
|
-
constructor() {
|
|
9
|
-
this.type = 'handler';
|
|
10
|
-
this.name = 'handler';
|
|
11
|
-
}
|
|
12
|
-
async onInvoke(data, next) {
|
|
13
|
-
if (data.handler)
|
|
14
|
-
if (!data.runHandler) {
|
|
15
|
-
try {
|
|
16
|
-
data.response = await new Promise(function (resolve, reject) {
|
|
17
|
-
data.callback = function (error, result) {
|
|
18
|
-
if (error)
|
|
19
|
-
reject(error);
|
|
20
|
-
else
|
|
21
|
-
resolve(result);
|
|
22
|
-
};
|
|
23
|
-
Promise.resolve(data.handler(data)).then(function (result) {
|
|
24
|
-
resolve(result);
|
|
25
|
-
}).catch(function (error) {
|
|
26
|
-
reject(error);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
catch (error) {
|
|
31
|
-
data.logger.error(error);
|
|
32
|
-
data.response = error;
|
|
33
|
-
}
|
|
34
|
-
data.runHandler = true;
|
|
35
|
-
}
|
|
36
|
-
else
|
|
37
|
-
data.logger.warn('[RunHandler] handler has been run');
|
|
38
|
-
await next();
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
let startedAt = Date.now();
|
|
43
|
-
class Func {
|
|
44
|
-
/**
|
|
45
|
-
* 新建流程
|
|
46
|
-
* @param config {object} 配置项
|
|
47
|
-
* @param config.plugins {Plugin[]} 插件
|
|
48
|
-
* @param config.handler {Handler} 业务函数
|
|
49
|
-
*/
|
|
50
|
-
constructor(config) {
|
|
51
|
-
var _a;
|
|
52
|
-
this.logger = new logger.Logger('Func');
|
|
53
|
-
this.handler = config.handler;
|
|
54
|
-
this.plugins = (_a = config.plugins) !== null && _a !== void 0 ? _a : [];
|
|
55
|
-
this.plugins.push(new RunHandler());
|
|
56
|
-
this.config = {
|
|
57
|
-
providers: Object.create(null),
|
|
58
|
-
plugins: Object.create(null)
|
|
59
|
-
};
|
|
60
|
-
this.mounted = false;
|
|
61
|
-
this.cachedFunctions = Object.create(null);
|
|
62
|
-
try {
|
|
63
|
-
this.filename = new Error().stack
|
|
64
|
-
.split('\n')
|
|
65
|
-
.find(s => /[^/]\.func\.ts/.test(s))
|
|
66
|
-
.match(/\((.*\.func\.ts).*\)/)[1];
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
this.logger.debug(error.message);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
compose(key) {
|
|
73
|
-
const logger$1 = new logger.Logger(key);
|
|
74
|
-
let list = [];
|
|
75
|
-
if (this.cachedFunctions[key])
|
|
76
|
-
list = this.cachedFunctions[key];
|
|
77
|
-
else {
|
|
78
|
-
for (const plugin of this.plugins) {
|
|
79
|
-
const handler = plugin[key];
|
|
80
|
-
if (typeof handler === 'function')
|
|
81
|
-
list.push({
|
|
82
|
-
key: plugin.name,
|
|
83
|
-
handler: handler.bind(plugin)
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
this.cachedFunctions[key] = list;
|
|
87
|
-
}
|
|
88
|
-
return async function (data, next) {
|
|
89
|
-
let index = -1;
|
|
90
|
-
const dispatch = async function (i) {
|
|
91
|
-
if (i <= index)
|
|
92
|
-
return Promise.reject(Error('next() called multiple times'));
|
|
93
|
-
index = i;
|
|
94
|
-
let fn = list[i];
|
|
95
|
-
if (i === list.length)
|
|
96
|
-
fn = next;
|
|
97
|
-
if (!fn)
|
|
98
|
-
return Promise.resolve();
|
|
99
|
-
if (typeof fn.key === 'undefined')
|
|
100
|
-
fn.key = `UnNamedPlugin#${i}`;
|
|
101
|
-
logger$1.debug(`[${fn.key}] begin`);
|
|
102
|
-
logger$1.time(fn.key);
|
|
103
|
-
try {
|
|
104
|
-
const res = await Promise.resolve(fn.handler(data, dispatch.bind(null, i + 1)));
|
|
105
|
-
logger$1.timeEnd(fn.key, `[${fn.key}] end`);
|
|
106
|
-
return res;
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
logger$1.timeEnd(fn.key, `[${fn.key}] failed`);
|
|
110
|
-
console.error(err);
|
|
111
|
-
return Promise.reject(err);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
return await dispatch(0);
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* 发布云资源
|
|
119
|
-
* @param data {object} 代码包信息
|
|
120
|
-
* @param data.root {string} 项目根目录
|
|
121
|
-
* @param data.filename {string} 包括完整路径的流程文件名
|
|
122
|
-
* @param data.env {string} 环境
|
|
123
|
-
*/
|
|
124
|
-
deploy(data) {
|
|
125
|
-
this.logger.debug('onDeploy');
|
|
126
|
-
return this.compose('onDeploy')(data);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* 启动云实例
|
|
130
|
-
*/
|
|
131
|
-
async mount(data) {
|
|
132
|
-
this.logger.debug('onMount');
|
|
133
|
-
if (this.mounted) {
|
|
134
|
-
this.logger.warn('mount() has been called, skipped.');
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
data.config = this.config;
|
|
138
|
-
try {
|
|
139
|
-
this.logger.time('mount');
|
|
140
|
-
this.logger.debug('Plugins: ' + this.plugins.map(p => `${p.type}#${p.name}`).join(','));
|
|
141
|
-
await this.compose('onMount')(data);
|
|
142
|
-
this.mounted = true;
|
|
143
|
-
}
|
|
144
|
-
finally {
|
|
145
|
-
this.logger.timeEnd('mount', 'mounted');
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* 执行云函数
|
|
150
|
-
* @param data {object} 执行信息
|
|
151
|
-
*/
|
|
152
|
-
async invoke(data) {
|
|
153
|
-
// 实例未启动时执行启动函数
|
|
154
|
-
if (!this.mounted)
|
|
155
|
-
await this.mount({
|
|
156
|
-
event: data.event,
|
|
157
|
-
context: data.context,
|
|
158
|
-
config: data.config
|
|
159
|
-
});
|
|
160
|
-
try {
|
|
161
|
-
await this.compose('onInvoke')(data);
|
|
162
|
-
}
|
|
163
|
-
catch (error) {
|
|
164
|
-
// 执行异常时回传异常
|
|
165
|
-
this.logger.error(error);
|
|
166
|
-
data.response = error;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* 创建触发函数
|
|
171
|
-
*/
|
|
172
|
-
export(config) {
|
|
173
|
-
if (!this.config)
|
|
174
|
-
this.config = config || Object.create(null);
|
|
175
|
-
return {
|
|
176
|
-
handler: async (event, context, callback) => {
|
|
177
|
-
const logger$1 = new logger.Logger();
|
|
178
|
-
if (startedAt) {
|
|
179
|
-
logger$1.debug(`Container started +${Date.now() - startedAt}ms`);
|
|
180
|
-
startedAt = 0;
|
|
181
|
-
}
|
|
182
|
-
logger$1.debug('event: %j', event);
|
|
183
|
-
logger$1.debug('context: %j', context);
|
|
184
|
-
if (typeof context === 'undefined')
|
|
185
|
-
context = {};
|
|
186
|
-
if (!context.request_id)
|
|
187
|
-
context.request_id = new Date().getTime().toString();
|
|
188
|
-
if (!context.request_at)
|
|
189
|
-
context.request_at = Math.round(new Date().getTime() / 1000);
|
|
190
|
-
context.callbackWaitsForEmptyEventLoop = false;
|
|
191
|
-
const data = {
|
|
192
|
-
event,
|
|
193
|
-
context,
|
|
194
|
-
callback,
|
|
195
|
-
response: undefined,
|
|
196
|
-
handler: this.handler,
|
|
197
|
-
logger: logger$1,
|
|
198
|
-
config: this.config
|
|
199
|
-
};
|
|
200
|
-
await this.invoke(data);
|
|
201
|
-
if (Object.prototype.toString.call(data.response) === '[object Error]')
|
|
202
|
-
throw data.response;
|
|
203
|
-
return data.response;
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
let plugins = [];
|
|
209
|
-
function usePlugin(plugin) {
|
|
210
|
-
if (!plugins.find(p => p.name === plugin.name))
|
|
211
|
-
plugins.push(plugin);
|
|
212
|
-
if (plugin.mount == null)
|
|
213
|
-
plugin.mount = async function ({ config }) {
|
|
214
|
-
if (plugin.onMount)
|
|
215
|
-
await plugin.onMount({
|
|
216
|
-
config,
|
|
217
|
-
event: {},
|
|
218
|
-
context: {}
|
|
219
|
-
}, async () => await Promise.resolve());
|
|
220
|
-
};
|
|
221
|
-
return plugin;
|
|
222
|
-
}
|
|
223
|
-
function useFunc(handler) {
|
|
224
|
-
plugins = [];
|
|
225
|
-
const invokeHandler = handler();
|
|
226
|
-
const func = new Func({
|
|
227
|
-
plugins,
|
|
228
|
-
handler: invokeHandler
|
|
229
|
-
});
|
|
230
|
-
plugins = [];
|
|
231
|
-
return func;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
exports.Func = Func;
|
|
235
|
-
exports.useFunc = useFunc;
|
|
236
|
-
exports.usePlugin = usePlugin;
|