@middy/core 3.0.0-alpha.1 → 3.0.0-alpha.5

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.
Files changed (3) hide show
  1. package/index.d.ts +3 -1
  2. package/index.js +103 -30
  3. package/package.json +4 -6
package/index.d.ts CHANGED
@@ -42,8 +42,10 @@ export interface MiddlewareObj<TEvent = any, TResult = any, TErr = Error, TConte
42
42
  // The AWS provided Handler type uses void | Promise<TResult> so we have no choice but to follow and suppress the linter warning
43
43
  // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
44
44
  type MiddyInputHandler<TEvent, TResult, TContext extends LambdaContext = LambdaContext> = (event: TEvent, context: TContext, callback: LambdaCallback<TResult>) => void | Promise<TResult>
45
+ type MiddyInputPromiseHandler<TEvent, TResult, TContext extends LambdaContext = LambdaContext> = (event: TEvent, context: TContext,) => Promise<TResult>
45
46
 
46
- export interface MiddyfiedHandler<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> extends MiddyInputHandler<TEvent, TResult, TContext> {
47
+ export interface MiddyfiedHandler<TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext> extends MiddyInputHandler<TEvent, TResult, TContext>,
48
+ MiddyInputPromiseHandler<TEvent, TResult, TContext> {
47
49
  use: UseFn<TEvent, TResult, TErr, TContext>
48
50
  before: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
49
51
  after: AttachMiddlewareFn<TEvent, TResult, TErr, TContext>
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { AbortController } from 'node-abort-controller';
1
+ import { EventEmitter } from 'events';
2
2
 
3
- const defaultBaseHandler = () => {};
3
+ const defaultLambdaHandler = () => {};
4
4
 
5
5
  const defaultPlugin = {
6
6
  timeoutEarlyInMillis: 5,
@@ -9,17 +9,18 @@ const defaultPlugin = {
9
9
  }
10
10
  };
11
11
 
12
- const middy = (baseHandler = defaultBaseHandler, plugin = {}) => {
12
+ const middy = (lambdaHandler = defaultLambdaHandler, plugin = {}) => {
13
13
  var _plugin$beforePrefetc, _plugin;
14
14
 
15
- if (typeof baseHandler !== 'function') {
16
- plugin = baseHandler;
17
- baseHandler = defaultBaseHandler;
15
+ if (typeof lambdaHandler !== 'function') {
16
+ plugin = lambdaHandler;
17
+ lambdaHandler = defaultLambdaHandler;
18
18
  }
19
19
 
20
20
  plugin = { ...defaultPlugin,
21
21
  ...plugin
22
22
  };
23
+ plugin.timeoutEarly = plugin.timeoutEarlyInMillis > 0;
23
24
  (_plugin$beforePrefetc = (_plugin = plugin).beforePrefetch) === null || _plugin$beforePrefetc === void 0 ? void 0 : _plugin$beforePrefetc.call(_plugin);
24
25
  const beforeMiddlewares = [];
25
26
  const afterMiddlewares = [];
@@ -36,7 +37,7 @@ const middy = (baseHandler = defaultBaseHandler, plugin = {}) => {
36
37
  error: undefined,
37
38
  internal: plugin.internal ?? {}
38
39
  };
39
- return runRequest(request, [...beforeMiddlewares], baseHandler, [...afterMiddlewares], [...onErrorMiddlewares], plugin);
40
+ return runRequest(request, [...beforeMiddlewares], lambdaHandler, [...afterMiddlewares], [...onErrorMiddlewares], plugin);
40
41
  };
41
42
 
42
43
  middy.use = middlewares => {
@@ -78,14 +79,18 @@ const middy = (baseHandler = defaultBaseHandler, plugin = {}) => {
78
79
  return middy;
79
80
  };
80
81
 
81
- middy.handler = replaceBaseHandler => {
82
- baseHandler = replaceBaseHandler;
82
+ middy.handler = replaceLambdaHandler => {
83
+ lambdaHandler = replaceLambdaHandler;
83
84
  };
84
85
 
85
86
  return middy;
86
87
  };
87
88
 
88
- const runRequest = async (request, beforeMiddlewares, baseHandler, afterMiddlewares, onErrorMiddlewares, plugin) => {
89
+ const runRequest = async (request, beforeMiddlewares, lambdaHandler, afterMiddlewares, onErrorMiddlewares, plugin) => {
90
+ const {
91
+ timeoutEarly
92
+ } = plugin;
93
+
89
94
  try {
90
95
  await runMiddlewares(request, beforeMiddlewares, plugin);
91
96
 
@@ -94,16 +99,17 @@ const runRequest = async (request, beforeMiddlewares, baseHandler, afterMiddlewa
94
99
 
95
100
  (_plugin$beforeHandler = plugin.beforeHandler) === null || _plugin$beforeHandler === void 0 ? void 0 : _plugin$beforeHandler.call(plugin);
96
101
  const handlerAbort = new AbortController();
97
- const timeoutAbort = new AbortController();
98
- request.response = await Promise.race([baseHandler(request.event, request.context, {
102
+ let timeoutAbort;
103
+ if (timeoutEarly) timeoutAbort = new AbortController();
104
+ request.response = await Promise.race([lambdaHandler(request.event, request.context, {
99
105
  signal: handlerAbort.signal
100
- }), plugin.timeoutEarlyInMillis > 0 ? setTimeoutPromise(request.context.getRemainingTimeInMillis() - plugin.timeoutEarlyInMillis, {
106
+ }), timeoutEarly ? setTimeoutPromise(request.context.getRemainingTimeInMillis() - plugin.timeoutEarlyInMillis, {
101
107
  signal: timeoutAbort.signal
102
108
  }).then(() => {
103
109
  handlerAbort.abort();
104
110
  return plugin.timeoutEarlyResponse();
105
111
  }) : Promise.race([])]);
106
- timeoutAbort.abort();
112
+ if (timeoutEarly) timeoutAbort.abort();
107
113
  (_plugin$afterHandler = plugin.afterHandler) === null || _plugin$afterHandler === void 0 ? void 0 : _plugin$afterHandler.call(plugin);
108
114
  await runMiddlewares(request, afterMiddlewares, plugin);
109
115
  }
@@ -144,25 +150,92 @@ const runMiddlewares = async (request, middlewares, plugin) => {
144
150
  }
145
151
  };
146
152
 
147
- const setTimeoutPromise = (ms, {
148
- signal
149
- }) => {
150
- if (signal.aborted) {
151
- return Promise.reject(new Error('Aborted', 'AbortError'));
152
- }
153
+ const polyfillAbortController = () => {
154
+ if (process.version < 'v15.0.0') {
155
+ class AbortSignal {
156
+ constructor() {
157
+ this.eventEmitter = new EventEmitter();
158
+ this.onabort = null;
159
+ this.aborted = false;
160
+ }
161
+
162
+ toString() {
163
+ return '[object AbortSignal]';
164
+ }
165
+
166
+ get [Symbol.toStringTag]() {
167
+ return 'AbortSignal';
168
+ }
169
+
170
+ removeEventListener(name, handler) {
171
+ this.eventEmitter.removeListener(name, handler);
172
+ }
173
+
174
+ addEventListener(name, handler) {
175
+ this.eventEmitter.on(name, handler);
176
+ }
177
+
178
+ dispatchEvent(type) {
179
+ const event = {
180
+ type,
181
+ target: this
182
+ };
183
+ const handlerName = `on${type}`;
184
+ if (typeof this[handlerName] === 'function') this[handlerName](event);
185
+ this.eventEmitter.emit(type, event);
186
+ }
187
+
188
+ }
189
+
190
+ return class AbortController {
191
+ constructor() {
192
+ this.signal = new AbortSignal();
193
+ }
194
+
195
+ abort() {
196
+ if (this.signal.aborted) return;
197
+ this.signal.aborted = true;
198
+ this.signal.dispatchEvent('abort');
199
+ }
200
+
201
+ toString() {
202
+ return '[object AbortController]';
203
+ }
204
+
205
+ get [Symbol.toStringTag]() {
206
+ return 'AbortController';
207
+ }
153
208
 
154
- return new Promise((resolve, reject) => {
155
- const abortHandler = () => {
156
- clearTimeout(timeout);
157
- reject(new Error('Aborted', 'AbortError'));
158
209
  };
210
+ } else {
211
+ return AbortController;
212
+ }
213
+ };
214
+
215
+ global.AbortController = polyfillAbortController();
159
216
 
160
- const timeout = setTimeout(() => {
161
- resolve();
162
- signal.removeEventListener('abort', abortHandler);
163
- }, ms);
164
- signal.addEventListener('abort', abortHandler);
165
- });
217
+ const polyfillSetTimeoutPromise = () => {
218
+ return (ms, {
219
+ signal
220
+ }) => {
221
+ if (signal.aborted) {
222
+ return Promise.reject(new Error('Aborted', 'AbortError'));
223
+ }
224
+
225
+ return new Promise((resolve, reject) => {
226
+ const abortHandler = () => {
227
+ clearTimeout(timeout);
228
+ reject(new Error('Aborted', 'AbortError'));
229
+ };
230
+
231
+ const timeout = setTimeout(() => {
232
+ resolve();
233
+ signal.removeEventListener('abort', abortHandler);
234
+ }, ms);
235
+ signal.addEventListener('abort', abortHandler);
236
+ });
237
+ };
166
238
  };
167
239
 
240
+ const setTimeoutPromise = polyfillSetTimeoutPromise();
168
241
  export default middy;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@middy/core",
3
- "version": "3.0.0-alpha.1",
3
+ "version": "3.0.0-alpha.5",
4
4
  "description": "🛵 The stylish Node.js middleware engine for AWS Lambda (core package)",
5
5
  "type": "module",
6
6
  "engines": {
@@ -18,7 +18,8 @@
18
18
  ],
19
19
  "scripts": {
20
20
  "test": "npm run test:unit",
21
- "test:unit": "ava"
21
+ "test:unit": "ava",
22
+ "test:benchmark": "node __benchmarks__/index.js"
22
23
  },
23
24
  "license": "MIT",
24
25
  "keywords": [
@@ -46,8 +47,5 @@
46
47
  "@types/aws-lambda": "^8.10.76",
47
48
  "@types/node": "^17.0.0"
48
49
  },
49
- "gitHead": "a14125c6b2e21b181824f9985a919a47f1e4711f",
50
- "dependencies": {
51
- "node-abort-controller": "3.0.1"
52
- }
50
+ "gitHead": "cf6a1b02a2e163bea353b10146d67e0d95ef8072"
53
51
  }