@celerity-sdk/serverless-aws 0.3.0 → 0.4.0

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/dist/entry.js CHANGED
@@ -2,12 +2,13 @@ var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
 
4
4
  // src/entry.ts
5
- import { dirname, resolve } from "path";
6
- import createDebug2 from "debug";
7
- import { discoverModule, bootstrap, executeHandlerPipeline, createDefaultSystemLayers, disposeLayers, resolveHandlerByModuleRef } from "@celerity-sdk/core";
5
+ import createDebug4 from "debug";
6
+ import { CelerityFactory, discoverModule } from "@celerity-sdk/core";
8
7
 
9
8
  // src/event-mapper.ts
10
9
  import createDebug from "debug";
10
+ import { unmarshall } from "@aws-sdk/util-dynamodb";
11
+ import { mapBucketEventType, mapDatastoreEventType } from "@celerity-sdk/common";
11
12
  var debug = createDebug("celerity:serverless-aws");
12
13
  function parseBody(event) {
13
14
  if (!event.body) return {
@@ -105,74 +106,497 @@ function mapHttpResponseToResult(response) {
105
106
  return result;
106
107
  }
107
108
  __name(mapHttpResponseToResult, "mapHttpResponseToResult");
109
+ var VALID_HANDLER_TYPES = /* @__PURE__ */ new Set([
110
+ "http",
111
+ "websocket",
112
+ "consumer",
113
+ "schedule",
114
+ "custom"
115
+ ]);
116
+ function hasNested(obj, key, nested) {
117
+ const child = obj[key];
118
+ return child !== null && typeof child === "object" && nested in child;
119
+ }
120
+ __name(hasNested, "hasNested");
121
+ function detectEventType(event) {
122
+ const envType = process.env.CELERITY_HANDLER_TYPE;
123
+ if (envType && VALID_HANDLER_TYPES.has(envType)) {
124
+ debug("detectEventType: using env var CELERITY_HANDLER_TYPE=%s", envType);
125
+ return envType;
126
+ }
127
+ if (!event || typeof event !== "object") return "custom";
128
+ const e = event;
129
+ if (hasNested(e, "requestContext", "http")) return "http";
130
+ if (hasNested(e, "requestContext", "connectionId") && hasNested(e, "requestContext", "eventType")) return "websocket";
131
+ if (Array.isArray(e.Records) && e.Records.length > 0 && e.Records[0]?.eventSource === "aws:sqs") return "consumer";
132
+ if ("source" in e && "detail-type" in e) return "schedule";
133
+ return "custom";
134
+ }
135
+ __name(detectEventType, "detectEventType");
136
+ var WS_EVENT_TYPE_MAP = {
137
+ CONNECT: "connect",
138
+ MESSAGE: "message",
139
+ DISCONNECT: "disconnect"
140
+ };
141
+ function mapApiGatewayWebSocketEvent(event) {
142
+ const rc = event.requestContext;
143
+ const eventType = WS_EVENT_TYPE_MAP[rc.eventType] ?? "message";
144
+ let jsonBody;
145
+ let binaryBody;
146
+ if (event.body) {
147
+ if (event.isBase64Encoded) {
148
+ binaryBody = Buffer.from(event.body, "base64");
149
+ } else {
150
+ try {
151
+ jsonBody = JSON.parse(event.body);
152
+ } catch {
153
+ jsonBody = event.body;
154
+ }
155
+ }
156
+ }
157
+ const message = {
158
+ messageType: binaryBody ? "binary" : "json",
159
+ eventType,
160
+ connectionId: rc.connectionId,
161
+ messageId: rc.requestId,
162
+ jsonBody,
163
+ binaryBody,
164
+ requestContext: {
165
+ requestId: rc.requestId,
166
+ requestTime: rc.requestTimeEpoch,
167
+ path: `/${rc.stage}`,
168
+ protocolVersion: "websocket",
169
+ headers: {},
170
+ clientIp: "",
171
+ query: {},
172
+ cookies: {}
173
+ },
174
+ traceContext: null
175
+ };
176
+ const routeKey = rc.routeKey;
177
+ const endpoint = `https://${rc.domainName}/${rc.stage}`;
178
+ debug("mapWebSocketEvent: %s connectionId=%s routeKey=%s", eventType, rc.connectionId, routeKey);
179
+ return {
180
+ message,
181
+ routeKey,
182
+ endpoint
183
+ };
184
+ }
185
+ __name(mapApiGatewayWebSocketEvent, "mapApiGatewayWebSocketEvent");
186
+ function tryParseJson(body) {
187
+ try {
188
+ return JSON.parse(body);
189
+ } catch {
190
+ return void 0;
191
+ }
192
+ }
193
+ __name(tryParseJson, "tryParseJson");
194
+ function isS3Notification(parsed) {
195
+ if (!parsed || typeof parsed !== "object") return false;
196
+ const obj = parsed;
197
+ if (!Array.isArray(obj.Records) || obj.Records.length === 0) return false;
198
+ const first = obj.Records[0];
199
+ return first.eventSource === "aws:s3";
200
+ }
201
+ __name(isS3Notification, "isS3Notification");
202
+ function isDynamoDBStreamRecord(parsed) {
203
+ if (!parsed || typeof parsed !== "object") return false;
204
+ return parsed.eventSource === "aws:dynamodb";
205
+ }
206
+ __name(isDynamoDBStreamRecord, "isDynamoDBStreamRecord");
207
+ function extractTableName(eventSourceARN) {
208
+ if (!eventSourceARN) return void 0;
209
+ const match = eventSourceARN.match(/table\/([^/]+)/);
210
+ return match?.[1];
211
+ }
212
+ __name(extractTableName, "extractTableName");
213
+ function transformS3Body(record) {
214
+ return JSON.stringify({
215
+ key: record.s3.object.key,
216
+ ...record.s3.object.size !== void 0 && {
217
+ size: record.s3.object.size
218
+ },
219
+ ...record.s3.object.eTag !== void 0 && {
220
+ eTag: record.s3.object.eTag
221
+ }
222
+ });
223
+ }
224
+ __name(transformS3Body, "transformS3Body");
225
+ function unmarshallRecord(attrs) {
226
+ if (!attrs) return void 0;
227
+ return unmarshall(attrs);
228
+ }
229
+ __name(unmarshallRecord, "unmarshallRecord");
230
+ function transformDynamoDBBody(record) {
231
+ const db = record.dynamodb;
232
+ return JSON.stringify({
233
+ keys: unmarshallRecord(db?.Keys) ?? {},
234
+ ...db?.NewImage !== void 0 && {
235
+ newItem: unmarshallRecord(db.NewImage)
236
+ },
237
+ ...db?.OldImage !== void 0 && {
238
+ oldItem: unmarshallRecord(db.OldImage)
239
+ }
240
+ });
241
+ }
242
+ __name(transformDynamoDBBody, "transformDynamoDBBody");
243
+ function mapSqsRecord(record) {
244
+ const sqsVendor = {
245
+ receiptHandle: record.receiptHandle,
246
+ attributes: record.attributes,
247
+ md5OfBody: record.md5OfBody,
248
+ eventSource: record.eventSource,
249
+ awsRegion: record.awsRegion
250
+ };
251
+ const parsed = tryParseJson(record.body);
252
+ if (isS3Notification(parsed)) {
253
+ const s3Record = parsed.Records[0];
254
+ return {
255
+ messageId: record.messageId,
256
+ body: transformS3Body(s3Record),
257
+ source: record.eventSourceARN,
258
+ sourceType: "bucket",
259
+ sourceName: s3Record.s3.bucket.name,
260
+ eventType: mapBucketEventType(s3Record.eventName),
261
+ messageAttributes: record.messageAttributes,
262
+ vendor: {
263
+ ...sqsVendor,
264
+ originalBody: parsed
265
+ }
266
+ };
267
+ }
268
+ if (isDynamoDBStreamRecord(parsed)) {
269
+ return {
270
+ messageId: record.messageId,
271
+ body: transformDynamoDBBody(parsed),
272
+ source: record.eventSourceARN,
273
+ sourceType: "datastore",
274
+ sourceName: extractTableName(parsed.eventSourceARN),
275
+ eventType: mapDatastoreEventType(parsed.eventName),
276
+ messageAttributes: record.messageAttributes,
277
+ vendor: {
278
+ ...sqsVendor,
279
+ originalBody: parsed
280
+ }
281
+ };
282
+ }
283
+ return {
284
+ messageId: record.messageId,
285
+ body: record.body,
286
+ source: record.eventSourceARN,
287
+ messageAttributes: record.messageAttributes,
288
+ vendor: sqsVendor
289
+ };
290
+ }
291
+ __name(mapSqsRecord, "mapSqsRecord");
292
+ function mapSqsEvent(event, handlerTag) {
293
+ const messages = event.Records.map(mapSqsRecord);
294
+ const firstTraceHeader = event.Records[0]?.attributes?.AWSTraceHeader;
295
+ const traceContext = firstTraceHeader ? {
296
+ "x-amzn-trace-id": firstTraceHeader
297
+ } : null;
298
+ debug("mapSqsEvent: %d records, handlerTag=%s", messages.length, handlerTag);
299
+ return {
300
+ handlerTag,
301
+ messages,
302
+ vendor: {
303
+ eventSource: "aws:sqs"
304
+ },
305
+ traceContext
306
+ };
307
+ }
308
+ __name(mapSqsEvent, "mapSqsEvent");
309
+ function mapConsumerResultToSqsBatchResponse(failures) {
310
+ const batchItemFailures = (failures ?? []).map((f) => ({
311
+ itemIdentifier: f.messageId
312
+ }));
313
+ return {
314
+ batchItemFailures
315
+ };
316
+ }
317
+ __name(mapConsumerResultToSqsBatchResponse, "mapConsumerResultToSqsBatchResponse");
318
+ function mapEventBridgeEvent(event, handlerTag) {
319
+ debug("mapEventBridgeEvent: id=%s handlerTag=%s", event.id, handlerTag);
320
+ return {
321
+ handlerTag,
322
+ scheduleId: event.id,
323
+ messageId: event.id,
324
+ schedule: "",
325
+ input: event.detail,
326
+ vendor: {
327
+ source: event.source,
328
+ detailType: event["detail-type"],
329
+ account: event.account,
330
+ region: event.region
331
+ },
332
+ traceContext: null
333
+ };
334
+ }
335
+ __name(mapEventBridgeEvent, "mapEventBridgeEvent");
108
336
 
109
- // src/entry.ts
337
+ // src/adapter.ts
338
+ import { dirname, resolve } from "path";
339
+ import createDebug3 from "debug";
340
+ import { executeHttpPipeline, executeWebSocketPipeline, executeConsumerPipeline, executeSchedulePipeline, executeCustomPipeline, resolveHandlerByModuleRef } from "@celerity-sdk/core";
341
+ import { WebSocketSender as WS_SENDER_TOKEN } from "@celerity-sdk/types";
342
+
343
+ // src/websocket-sender.ts
344
+ import createDebug2 from "debug";
110
345
  var debug2 = createDebug2("celerity:serverless-aws");
111
- var cached = null;
346
+ var API_GW_MGMT_PKG = "@aws-sdk/client-apigatewaymanagementapi";
347
+ var ApiGatewayWebSocketSender = class {
348
+ static {
349
+ __name(this, "ApiGatewayWebSocketSender");
350
+ }
351
+ endpoint;
352
+ client = null;
353
+ constructor(endpoint) {
354
+ this.endpoint = endpoint;
355
+ debug2("ApiGatewayWebSocketSender: created with endpoint=%s", endpoint);
356
+ }
357
+ async sendMessage(connectionId, data, _options) {
358
+ const client = await this.getClient();
359
+ const payload = typeof data === "string" ? data : JSON.stringify(data);
360
+ const { PostToConnectionCommand } = await import(API_GW_MGMT_PKG);
361
+ await client.send(new PostToConnectionCommand({
362
+ ConnectionId: connectionId,
363
+ Data: new TextEncoder().encode(payload)
364
+ }));
365
+ debug2("ApiGatewayWebSocketSender: sent message to connectionId=%s", connectionId);
366
+ }
367
+ async getClient() {
368
+ if (!this.client) {
369
+ const { ApiGatewayManagementApiClient } = await import(API_GW_MGMT_PKG);
370
+ this.client = new ApiGatewayManagementApiClient({
371
+ endpoint: this.endpoint
372
+ });
373
+ debug2("ApiGatewayWebSocketSender: client initialized for endpoint=%s", this.endpoint);
374
+ }
375
+ return this.client;
376
+ }
377
+ };
378
+
379
+ // src/adapter.ts
380
+ var debug3 = createDebug3("celerity:serverless-aws");
381
+ var AwsLambdaAdapter = class {
382
+ static {
383
+ __name(this, "AwsLambdaAdapter");
384
+ }
385
+ config;
386
+ wsSenderRegistered = false;
387
+ constructor() {
388
+ this.config = captureAwsLambdaConfig();
389
+ }
390
+ createHttpHandler(registry, options) {
391
+ let cachedHandler2 = null;
392
+ return async (event, _context) => {
393
+ const apiEvent = event;
394
+ const httpRequest = mapApiGatewayV2Event(apiEvent);
395
+ if (!cachedHandler2) {
396
+ debug3("adapter: cache miss, looking up handler for %s %s", httpRequest.method, httpRequest.path);
397
+ cachedHandler2 = (this.config.handlerId ? registry.getHandlerById("http", this.config.handlerId) : void 0) ?? null;
398
+ if (!cachedHandler2 && this.config.handlerId) {
399
+ cachedHandler2 = await resolveHandlerByModuleRef(this.config.handlerId, "http", registry, this.config.moduleDir);
400
+ }
401
+ if (!cachedHandler2) {
402
+ cachedHandler2 = registry.getHandler("http", `${httpRequest.method} ${httpRequest.path}`) ?? null;
403
+ }
404
+ } else {
405
+ debug3("adapter: using cached handler for %s %s", httpRequest.method, httpRequest.path);
406
+ }
407
+ if (!cachedHandler2) {
408
+ debug3("adapter: no handler found \u2192 404");
409
+ return {
410
+ statusCode: 404,
411
+ headers: {
412
+ "content-type": "application/json"
413
+ },
414
+ body: JSON.stringify({
415
+ message: `No handler for ${httpRequest.method} ${httpRequest.path}`
416
+ })
417
+ };
418
+ }
419
+ const httpResponse = await executeHttpPipeline(cachedHandler2, httpRequest, options);
420
+ return mapHttpResponseToResult(httpResponse);
421
+ };
422
+ }
423
+ createWebSocketHandler(registry, options) {
424
+ let cachedHandler2 = null;
425
+ return async (event, _context) => {
426
+ const wsEvent = event;
427
+ const { message, routeKey, endpoint } = mapApiGatewayWebSocketEvent(wsEvent);
428
+ if (!this.wsSenderRegistered) {
429
+ const sender = new ApiGatewayWebSocketSender(endpoint);
430
+ options.container.register(WS_SENDER_TOKEN, {
431
+ useValue: sender
432
+ });
433
+ this.wsSenderRegistered = true;
434
+ debug3("adapter: registered ApiGatewayWebSocketSender for endpoint=%s", endpoint);
435
+ }
436
+ if (!cachedHandler2) {
437
+ debug3("adapter: cache miss, looking up WebSocket handler for routeKey=%s", routeKey);
438
+ cachedHandler2 = (this.config.handlerId ? registry.getHandlerById("websocket", this.config.handlerId) : void 0) ?? null;
439
+ if (!cachedHandler2 && this.config.handlerId) {
440
+ cachedHandler2 = await resolveHandlerByModuleRef(this.config.handlerId, "websocket", registry, this.config.moduleDir);
441
+ }
442
+ if (!cachedHandler2) {
443
+ cachedHandler2 = registry.getHandler("websocket", routeKey) ?? null;
444
+ }
445
+ } else {
446
+ debug3("adapter: using cached WebSocket handler");
447
+ }
448
+ if (!cachedHandler2) {
449
+ debug3("adapter: no WebSocket handler found \u2192 404");
450
+ return {
451
+ statusCode: 404
452
+ };
453
+ }
454
+ await executeWebSocketPipeline(cachedHandler2, message, options);
455
+ return {
456
+ statusCode: 200
457
+ };
458
+ };
459
+ }
460
+ createConsumerHandler(registry, options) {
461
+ let cachedHandler2 = null;
462
+ return async (event, _context) => {
463
+ const sqsEvent = event;
464
+ const handlerTag = this.config.handlerTag ?? sqsEvent.Records[0]?.eventSourceARN ?? "unknown";
465
+ const consumerEvent = mapSqsEvent(sqsEvent, handlerTag);
466
+ if (!cachedHandler2) {
467
+ debug3("adapter: cache miss, looking up Consumer handler for tag=%s", handlerTag);
468
+ cachedHandler2 = (this.config.handlerId ? registry.getHandlerById("consumer", this.config.handlerId) : void 0) ?? null;
469
+ if (!cachedHandler2 && this.config.handlerId) {
470
+ cachedHandler2 = await resolveHandlerByModuleRef(this.config.handlerId, "consumer", registry, this.config.moduleDir);
471
+ }
472
+ if (!cachedHandler2) {
473
+ cachedHandler2 = registry.getHandler("consumer", handlerTag) ?? null;
474
+ }
475
+ } else {
476
+ debug3("adapter: using cached Consumer handler");
477
+ }
478
+ if (!cachedHandler2) {
479
+ debug3("adapter: no Consumer handler found \u2192 empty response");
480
+ return {
481
+ batchItemFailures: []
482
+ };
483
+ }
484
+ const result = await executeConsumerPipeline(cachedHandler2, consumerEvent, options);
485
+ return mapConsumerResultToSqsBatchResponse(result.failures);
486
+ };
487
+ }
488
+ createScheduleHandler(registry, options) {
489
+ let cachedHandler2 = null;
490
+ return async (event, _context) => {
491
+ const ebEvent = event;
492
+ const handlerTag = this.config.handlerTag ?? ebEvent.resources?.[0] ?? "unknown";
493
+ const scheduleEvent = mapEventBridgeEvent(ebEvent, handlerTag);
494
+ if (!cachedHandler2) {
495
+ debug3("adapter: cache miss, looking up Schedule handler for tag=%s", handlerTag);
496
+ cachedHandler2 = (this.config.handlerId ? registry.getHandlerById("schedule", this.config.handlerId) : void 0) ?? null;
497
+ if (!cachedHandler2 && this.config.handlerId) {
498
+ cachedHandler2 = await resolveHandlerByModuleRef(this.config.handlerId, "schedule", registry, this.config.moduleDir);
499
+ }
500
+ if (!cachedHandler2) {
501
+ cachedHandler2 = registry.getHandler("schedule", handlerTag) ?? null;
502
+ }
503
+ } else {
504
+ debug3("adapter: using cached Schedule handler");
505
+ }
506
+ if (!cachedHandler2) {
507
+ debug3("adapter: no Schedule handler found");
508
+ return {
509
+ success: false,
510
+ errorMessage: `No handler for schedule tag: ${handlerTag}`
511
+ };
512
+ }
513
+ return executeSchedulePipeline(cachedHandler2, scheduleEvent, options);
514
+ };
515
+ }
516
+ createCustomHandler(registry, options) {
517
+ let cachedHandler2 = null;
518
+ return async (event, _context) => {
519
+ let handlerName = this.config.handlerId;
520
+ let payload = event;
521
+ if (!handlerName && event && typeof event === "object") {
522
+ const e = event;
523
+ if (typeof e.handlerName === "string") {
524
+ handlerName = e.handlerName;
525
+ payload = e.payload ?? {};
526
+ }
527
+ }
528
+ if (!cachedHandler2) {
529
+ debug3("adapter: cache miss, looking up Custom handler for name=%s", handlerName);
530
+ cachedHandler2 = (handlerName ? registry.getHandlerById("custom", handlerName) : void 0) ?? null;
531
+ if (!cachedHandler2 && handlerName) {
532
+ cachedHandler2 = await resolveHandlerByModuleRef(handlerName, "custom", registry, this.config.moduleDir);
533
+ }
534
+ if (!cachedHandler2 && handlerName) {
535
+ cachedHandler2 = registry.getHandler("custom", handlerName) ?? null;
536
+ }
537
+ if (!cachedHandler2) {
538
+ const allCustom = registry.getHandlersByType("custom");
539
+ if (allCustom.length === 1) cachedHandler2 = allCustom[0];
540
+ }
541
+ } else {
542
+ debug3("adapter: using cached Custom handler");
543
+ }
544
+ if (!cachedHandler2) {
545
+ debug3("adapter: no Custom handler found");
546
+ return {
547
+ error: `No handler found for custom invoke: ${handlerName ?? "unknown"}`
548
+ };
549
+ }
550
+ return executeCustomPipeline(cachedHandler2, payload, options);
551
+ };
552
+ }
553
+ };
554
+ function captureAwsLambdaConfig() {
555
+ const modulePath = process.env.CELERITY_MODULE_PATH;
556
+ return {
557
+ handlerId: process.env.CELERITY_HANDLER_ID,
558
+ handlerTag: process.env.CELERITY_HANDLER_TAG,
559
+ moduleDir: modulePath ? dirname(resolve(modulePath)) : process.cwd()
560
+ };
561
+ }
562
+ __name(captureAwsLambdaConfig, "captureAwsLambdaConfig");
563
+
564
+ // src/entry.ts
565
+ var debug4 = createDebug4("celerity:serverless-aws");
566
+ var app = null;
567
+ var cachedHandler = null;
112
568
  var shutdownRegistered = false;
113
- function registerShutdownHandler(options) {
569
+ async function ensureBootstrapped() {
570
+ if (!app) {
571
+ debug4("entry: cold start, bootstrapping via CelerityFactory");
572
+ const rootModule = await discoverModule();
573
+ app = await CelerityFactory.create(rootModule, {
574
+ adapter: new AwsLambdaAdapter()
575
+ });
576
+ debug4("entry: bootstrap complete");
577
+ }
578
+ return app;
579
+ }
580
+ __name(ensureBootstrapped, "ensureBootstrapped");
581
+ function registerShutdownHandler(application) {
114
582
  if (shutdownRegistered) return;
115
583
  shutdownRegistered = true;
116
- debug2("entry: SIGTERM shutdown handler registered");
584
+ debug4("entry: SIGTERM shutdown handler registered");
117
585
  process.on("SIGTERM", async () => {
118
- await options.container.closeAll();
119
- await disposeLayers([
120
- ...options.systemLayers ?? [],
121
- ...options.appLayers ?? []
122
- ]);
586
+ await application.close();
123
587
  process.exit(0);
124
588
  });
125
589
  }
126
590
  __name(registerShutdownHandler, "registerShutdownHandler");
127
- async function ensureBootstrapped() {
128
- if (!cached) {
129
- debug2("entry: cold start, bootstrapping");
130
- const systemLayers = await createDefaultSystemLayers();
131
- debug2("entry: %d system layers created", systemLayers.length);
132
- const rootModule = await discoverModule();
133
- const result = await bootstrap(rootModule);
134
- const modulePath = process.env.CELERITY_MODULE_PATH;
135
- cached = {
136
- registry: result.registry,
137
- options: {
138
- container: result.container,
139
- systemLayers
140
- },
141
- moduleDir: modulePath ? dirname(resolve(modulePath)) : process.cwd()
142
- };
143
- debug2("entry: bootstrap complete");
144
- }
145
- return cached;
146
- }
147
- __name(ensureBootstrapped, "ensureBootstrapped");
148
- async function handler(event, _context) {
149
- const { registry, options, moduleDir } = await ensureBootstrapped();
150
- registerShutdownHandler(options);
151
- const apiEvent = event;
152
- const httpRequest = mapApiGatewayV2Event(apiEvent);
153
- debug2("entry: %s %s", httpRequest.method, httpRequest.path);
154
- const handlerId = process.env.CELERITY_HANDLER_ID;
155
- let resolved = handlerId ? registry.getHandlerById(handlerId) : void 0;
156
- if (!resolved && handlerId) {
157
- resolved = await resolveHandlerByModuleRef(handlerId, registry, moduleDir) ?? void 0;
158
- }
159
- if (!resolved) {
160
- resolved = registry.getHandler(httpRequest.path, httpRequest.method);
161
- }
162
- if (!resolved) {
163
- return {
164
- statusCode: 404,
165
- headers: {
166
- "content-type": "application/json"
167
- },
168
- body: JSON.stringify({
169
- statusCode: 404,
170
- message: `No handler for ${httpRequest.method} ${httpRequest.path}`
171
- })
172
- };
591
+ async function handler(event, context) {
592
+ const application = await ensureBootstrapped();
593
+ registerShutdownHandler(application);
594
+ if (!cachedHandler) {
595
+ const eventType = detectEventType(event);
596
+ debug4("entry: creating handler for type=%s", eventType);
597
+ cachedHandler = application.createHandler(eventType);
173
598
  }
174
- const httpResponse = await executeHandlerPipeline(resolved, httpRequest, options);
175
- return mapHttpResponseToResult(httpResponse);
599
+ return cachedHandler(event, context);
176
600
  }
177
601
  __name(handler, "handler");
178
602
  export {