@pikku/lambda 0.6.8 → 0.8.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/CHANGELOG.md CHANGED
@@ -1,4 +1,12 @@
1
- ## 0.6.1
1
+ ## 0.8.0
2
+
3
+ ### Major Features
4
+
5
+ - **SQS Queue Support**: Added SQS queue worker support
6
+
7
+ ## 0.7.0
8
+
9
+ - Updating to match remaining packages
2
10
 
3
11
  ## 0.6.8
4
12
 
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './http/index.js';
2
2
  export * from './websocket/index.js';
3
+ export * from './queue/index.js';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './http/index.js';
2
2
  export * from './websocket/index.js';
3
+ export * from './queue/index.js';
3
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1 @@
1
+ export { runSQSQueueWorker } from './sqs-worker.js';
@@ -0,0 +1,2 @@
1
+ export { runSQSQueueWorker } from './sqs-worker.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/queue/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { SQSBatchResponse, SQSEvent, SQSRecord } from 'aws-lambda';
2
+ import type { CoreSingletonServices, CreateSessionServices, QueueJob } from '@pikku/core';
3
+ export declare function mapSQSRecordToQueueJob(record: SQSRecord, maxAttempts?: number): QueueJob;
4
+ export declare const runSQSQueueWorker: (singletonServices: CoreSingletonServices, createSessionServices: CreateSessionServices<any, any, any> | undefined, event: SQSEvent) => Promise<SQSBatchResponse>;
@@ -0,0 +1,59 @@
1
+ import { runQueueJob } from '@pikku/core/queue';
2
+ export function mapSQSRecordToQueueJob(record, maxAttempts) {
3
+ let data;
4
+ try {
5
+ data = JSON.parse(record.body);
6
+ }
7
+ catch {
8
+ data = record.body;
9
+ }
10
+ if (!record.eventSourceARN) {
11
+ throw new Error('SQS record does not have eventSourceARN');
12
+ }
13
+ const queueName = record.eventSourceARN.split(':').pop();
14
+ const job = {
15
+ queueName,
16
+ data,
17
+ id: record.messageId,
18
+ status: async () => 'active',
19
+ metadata: () => ({
20
+ processedAt: new Date(),
21
+ attemptsMade: parseInt(record.attributes.ApproximateReceiveCount) - 1,
22
+ maxAttempts,
23
+ result: undefined,
24
+ progress: 0,
25
+ createdAt: new Date(parseInt(record.attributes.SentTimestamp)),
26
+ completedAt: undefined,
27
+ failedAt: undefined,
28
+ error: undefined,
29
+ }),
30
+ waitForCompletion: async () => {
31
+ throw new Error('SQS does not support waitForCompletion - jobs are fire-and-forget');
32
+ },
33
+ };
34
+ return job;
35
+ }
36
+ export const runSQSQueueWorker = async (singletonServices, createSessionServices, event) => {
37
+ console.log(JSON.stringify(event, null, 2));
38
+ const jobs = event.Records.map(mapSQSRecordToQueueJob);
39
+ const results = await Promise.allSettled(jobs.map((job) => runQueueJob({
40
+ singletonServices,
41
+ createSessionServices,
42
+ job,
43
+ })));
44
+ results.forEach((result, index) => {
45
+ if (result.status === 'rejected') {
46
+ singletonServices.logger.error(`Failed to process SQS message ${jobs[index].id}:`, result.reason);
47
+ }
48
+ });
49
+ return {
50
+ batchItemFailures: results
51
+ .map((result, index) => ({
52
+ result,
53
+ itemIdentifier: jobs[index].id || `message-${index}`,
54
+ }))
55
+ .filter(({ result }) => result.status === 'rejected')
56
+ .map(({ itemIdentifier }) => ({ itemIdentifier })),
57
+ };
58
+ };
59
+ //# sourceMappingURL=sqs-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqs-worker.js","sourceRoot":"","sources":["../../src/queue/sqs-worker.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/lambda",
3
- "version": "0.6.8",
3
+ "version": "0.8.0",
4
4
  "license": "MIT",
5
5
  "author": "yasser.fadl@gmail.com",
6
6
  "module": "dist/index.js",
@@ -19,11 +19,12 @@
19
19
  "exports": {
20
20
  ".": "./dist/index.js",
21
21
  "./http": "./dist/http/index.js",
22
- "./websocket": "./dist/websocket/index.js"
22
+ "./websocket": "./dist/websocket/index.js",
23
+ "./queue": "./dist/queue/index.js"
23
24
  },
24
25
  "peerDependencies": {
25
26
  "@aws-sdk/client-apigatewaymanagementapi": "^3.713.0",
26
- "@pikku/core": "^0.6.22",
27
+ "@pikku/core": "^0.8.0",
27
28
  "@types/aws-lambda": "^8.10.146"
28
29
  },
29
30
  "devDependencies": {
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './http/index.js'
2
2
  export * from './websocket/index.js'
3
+ export * from './queue/index.js'
@@ -0,0 +1 @@
1
+ export { runSQSQueueWorker } from './sqs-worker.js'
@@ -0,0 +1,97 @@
1
+ import { SQSBatchResponse, SQSEvent, SQSRecord } from 'aws-lambda'
2
+ import { runQueueJob } from '@pikku/core/queue'
3
+ import type {
4
+ CoreSingletonServices,
5
+ CreateSessionServices,
6
+ QueueJob,
7
+ QueueJobStatus,
8
+ } from '@pikku/core'
9
+
10
+ /**
11
+ * Enhanced version with additional SQS-specific features
12
+ */
13
+ export function mapSQSRecordToQueueJob(
14
+ record: SQSRecord,
15
+ maxAttempts?: number
16
+ ): QueueJob {
17
+ let data: any
18
+
19
+ try {
20
+ data = JSON.parse(record.body)
21
+ } catch {
22
+ data = record.body
23
+ }
24
+
25
+ if (!record.eventSourceARN) {
26
+ throw new Error('SQS record does not have eventSourceARN')
27
+ }
28
+
29
+ const queueName = record.eventSourceARN.split(':').pop()!
30
+
31
+ const job: QueueJob = {
32
+ queueName,
33
+ data,
34
+ id: record.messageId,
35
+ status: async () => 'active' as QueueJobStatus,
36
+ metadata: () => ({
37
+ processedAt: new Date(),
38
+ attemptsMade: parseInt(record.attributes.ApproximateReceiveCount) - 1,
39
+ maxAttempts,
40
+ result: undefined,
41
+ progress: 0,
42
+ createdAt: new Date(parseInt(record.attributes.SentTimestamp)),
43
+ completedAt: undefined,
44
+ failedAt: undefined,
45
+ error: undefined,
46
+ }),
47
+ waitForCompletion: async () => {
48
+ throw new Error(
49
+ 'SQS does not support waitForCompletion - jobs are fire-and-forget'
50
+ )
51
+ },
52
+ }
53
+ return job
54
+ }
55
+
56
+ /**
57
+ * Create an SQS handler that processes queue jobs using Pikku
58
+ */
59
+ export const runSQSQueueWorker = async (
60
+ singletonServices: CoreSingletonServices,
61
+ createSessionServices: CreateSessionServices<any, any, any> | undefined,
62
+ event: SQSEvent
63
+ ): Promise<SQSBatchResponse> => {
64
+ console.log(JSON.stringify(event, null, 2))
65
+ const jobs = event.Records.map(mapSQSRecordToQueueJob)
66
+
67
+ // Process all jobs in parallel
68
+ const results = await Promise.allSettled(
69
+ jobs.map((job) =>
70
+ runQueueJob({
71
+ singletonServices,
72
+ createSessionServices,
73
+ job,
74
+ })
75
+ )
76
+ )
77
+
78
+ // Log any failures but don't throw (SQS will handle retries)
79
+ results.forEach((result, index) => {
80
+ if (result.status === 'rejected') {
81
+ singletonServices.logger.error(
82
+ `Failed to process SQS message ${jobs[index]!.id}:`,
83
+ result.reason
84
+ )
85
+ }
86
+ })
87
+
88
+ return {
89
+ batchItemFailures: results
90
+ .map((result, index) => ({
91
+ result,
92
+ itemIdentifier: jobs[index]!.id || `message-${index}`,
93
+ }))
94
+ .filter(({ result }) => result.status === 'rejected')
95
+ .map(({ itemIdentifier }) => ({ itemIdentifier })),
96
+ }
97
+ }
package/tsconfig.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "extends": "../../../tsconfig.json",
3
3
  "compilerOptions": {
4
4
  "rootDir": "./src",
5
- "module": "Node16",
5
+ "module": "Node18",
6
6
  "outDir": "dist",
7
7
  "target": "esnext",
8
8
  "declaration": true
@@ -1 +1 @@
1
- {"root":["./src/index.ts","./src/request-converter.ts","./src/response-converter.ts","./src/http/index.ts","./src/http/run-fetch.ts","./src/websocket/index.ts","./src/websocket/lambda-channel-handler.ts","./src/websocket/lambda-eventhub-service.ts","./src/websocket/utils.ts","./src/websocket/websocket-connect.ts","./src/websocket/websocket-disconnect.ts","./src/websocket/websocket-message.ts","./src/websocket/websocket-types.ts"],"version":"5.7.3"}
1
+ {"root":["./src/index.ts","./src/request-converter.ts","./src/response-converter.ts","./src/http/index.ts","./src/http/run-fetch.ts","./src/queue/index.ts","./src/queue/sqs-worker.ts","./src/websocket/index.ts","./src/websocket/lambda-channel-handler.ts","./src/websocket/lambda-eventhub-service.ts","./src/websocket/utils.ts","./src/websocket/websocket-connect.ts","./src/websocket/websocket-disconnect.ts","./src/websocket/websocket-message.ts","./src/websocket/websocket-types.ts"],"version":"5.8.3"}