@faasjs/func 0.0.2-beta.269 → 0.0.2-beta.318

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  云函数模块。
4
4
 
5
- [![License: MIT](https://img.shields.io/npm/l/@faasjs/func.svg)](https://github.com/faasjs/faasjs/blob/master/packages/faasjs/func/LICENSE)
5
+ [![License: MIT](https://img.shields.io/npm/l/@faasjs/func.svg)](https://github.com/faasjs/faasjs/blob/main/packages/faasjs/func/LICENSE)
6
6
  [![NPM Stable Version](https://img.shields.io/npm/v/@faasjs/func/stable.svg)](https://www.npmjs.com/package/@faasjs/func)
7
7
  [![NPM Beta Version](https://img.shields.io/npm/v/@faasjs/func/beta.svg)](https://www.npmjs.com/package/@faasjs/func)
8
8
 
@@ -1,132 +1,135 @@
1
- import { Logger } from '@faasjs/logger';
2
- export declare type Handler<TEvent = any, TContext = any, TResult = any> = (data: InvokeData<TEvent, TContext>) => Promise<TResult>;
3
- export declare type Next = () => Promise<void>;
4
- export declare type ExportedHandler<TEvent = any, TContext = any, TResult = any> = (event: TEvent, context?: TContext, callback?: (...args: any) => any) => Promise<TResult>;
5
- export declare type Plugin = {
6
- [key: string]: any;
7
- readonly type: string;
8
- readonly name: string;
9
- onDeploy?: (data: DeployData, next: Next) => void | Promise<void>;
10
- onMount?: (data: MountData, next: Next) => void | Promise<void>;
11
- onInvoke?: (data: InvokeData, next: Next) => void | Promise<void>;
12
- };
13
- export declare type ProviderConfig = {
14
- type: string;
15
- config: {
16
- [key: string]: any;
17
- };
18
- };
19
- export declare type Config = {
20
- [key: string]: any;
21
- providers?: {
22
- [key: string]: ProviderConfig;
23
- };
24
- plugins?: {
25
- [key: string]: {
26
- [key: string]: any;
27
- provider?: string | ProviderConfig;
28
- type: string;
29
- config?: {
30
- [key: string]: any;
31
- };
32
- };
33
- };
34
- };
35
- export declare type DeployData = {
36
- [key: string]: any;
37
- root: string;
38
- filename: string;
39
- env?: string;
40
- name?: string;
41
- config?: Config;
42
- version?: string;
43
- dependencies: {
44
- [name: string]: string;
45
- };
46
- plugins?: {
47
- [name: string]: {
48
- [key: string]: any;
49
- name?: string;
50
- type: string;
51
- provider?: string;
52
- config: {
53
- [key: string]: any;
54
- };
55
- plugin: Plugin;
56
- };
57
- };
58
- logger?: Logger;
59
- };
60
- export declare type MountData = {
61
- [key: string]: any;
62
- config: Config;
63
- event: any;
64
- context: any;
65
- };
66
- export declare type InvokeData<TEvent = any, TContext = any, TResult = any> = {
67
- [key: string]: any;
68
- event: TEvent;
69
- context: TContext;
70
- callback: any;
71
- response: any;
72
- logger: Logger;
73
- handler?: Handler<TEvent, TContext, TResult>;
74
- config: Config;
75
- };
76
- export declare type LifeCycleKey = 'onDeploy' | 'onMount' | 'onInvoke';
77
- export declare type FuncConfig<TEvent = any, TContext = any, TResult = any> = {
78
- plugins?: Plugin[];
79
- handler?: Handler<TEvent, TContext, TResult>;
80
- };
81
- export declare class Func<TEvent = any, TContext = any, TResult = any> {
82
- [key: string]: any;
83
- plugins: Plugin[];
84
- handler?: Handler<TEvent, TContext, TResult>;
85
- logger: Logger;
86
- config: Config;
87
- mounted: boolean;
88
- filename?: string;
89
- private cachedFunctions;
90
- /**
91
- * 新建流程
92
- * @param config {object} 配置项
93
- * @param config.plugins {Plugin[]} 插件
94
- * @param config.handler {Handler} 业务函数
95
- */
96
- constructor(config: FuncConfig<TEvent, TContext>);
97
- compose(key: LifeCycleKey): (data: any, next?: () => void) => any;
98
- /**
99
- * 发布云资源
100
- * @param data {object} 代码包信息
101
- * @param data.root {string} 项目根目录
102
- * @param data.filename {string} 包括完整路径的流程文件名
103
- * @param data.env {string} 环境
104
- */
105
- deploy(data: DeployData): any;
106
- /**
107
- * 启动云实例
108
- */
109
- mount(data: {
110
- event: TEvent;
111
- context: TContext;
112
- config?: Config;
113
- }): Promise<void>;
114
- /**
115
- * 执行云函数
116
- * @param data {object} 执行信息
117
- */
118
- invoke(data: InvokeData<TEvent, TContext, TResult>): Promise<void>;
119
- /**
120
- * 创建触发函数
121
- */
122
- export(config?: Config): {
123
- handler: ExportedHandler<TEvent, TContext, TResult>;
124
- };
125
- }
126
- export declare type UseifyPlugin = {
127
- mount?: (data: {
128
- config: Config;
129
- }) => Promise<void>;
130
- };
131
- export declare function usePlugin<T extends Plugin>(plugin: T & UseifyPlugin): T & UseifyPlugin;
132
- export declare function useFunc<TEvent = any, TContext = any, TResult = any>(handler: () => Handler<TEvent, TContext, TResult>): Func<TEvent, TContext, TResult>;
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,34 +1,36 @@
1
1
  {
2
2
  "name": "@faasjs/func",
3
- "version": "0.0.2-beta.269",
3
+ "version": "0.0.2-beta.318",
4
4
  "license": "MIT",
5
- "main": "lib/index.js",
6
- "types": "lib/index.d.ts",
7
- "module": "lib/index.es.js",
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",
11
11
  "url": "git+https://github.com/faasjs/faasjs.git",
12
12
  "directory": "packages/func"
13
13
  },
14
+ "bugs": {
15
+ "url": "https://github.com/faasjs/faasjs/issues"
16
+ },
17
+ "funding": "https://github.com/sponsors/faasjs",
14
18
  "scripts": {
15
- "lint": "eslint --ext .ts src",
16
- "prepack": "rm -rf ./lib && rollup -c && mv lib/*/src/* lib/"
19
+ "build": "rm -rf ./dist && tsup-node src/index.ts --format esm,cjs --dts"
17
20
  },
18
21
  "files": [
19
- "lib"
22
+ "dist"
20
23
  ],
21
24
  "peerDependencies": {
22
25
  "@faasjs/deep_merge": "^0.0.2-beta.244",
23
26
  "@faasjs/logger": "^0.0.2-beta.243"
24
27
  },
25
28
  "devDependencies": {
26
- "@types/debug": "*",
27
- "@types/jest": "*",
28
- "@types/node": "*",
29
- "rollup": "*",
30
- "rollup-plugin-typescript2": "*",
29
+ "tsup": "*",
31
30
  "typescript": "*"
32
31
  },
33
- "gitHead": "4654b7c74cfc41e2b85c10a0545ac999e241cf52"
32
+ "engines": {
33
+ "npm": ">=8.0.0"
34
+ },
35
+ "gitHead": "4a9f699171ad7e20d922e68b74418d1ec5b7d016"
34
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;
@@ -1,6 +0,0 @@
1
- import { InvokeData, Plugin } from '../../index';
2
- export default class RunHandler implements Plugin {
3
- readonly type: string;
4
- readonly name: string;
5
- onInvoke(data: InvokeData, next: () => Promise<void>): Promise<void>;
6
- }