@auriclabs/events 0.4.0 → 0.4.1
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/.turbo/turbo-build.log +54 -32
- package/CHANGELOG.md +7 -0
- package/dist/index.cjs +85 -2
- package/dist/index.d.cts +145 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +145 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +84 -1
- package/dist/index.mjs.map +1 -1
- package/dist/stream-handler.entry.cjs +86 -1
- package/dist/stream-handler.entry.d.cts +185 -1
- package/dist/stream-handler.entry.d.cts.map +1 -1
- package/dist/stream-handler.entry.d.mts +185 -1
- package/dist/stream-handler.entry.d.mts.map +1 -1
- package/dist/stream-handler.entry.mjs +85 -1
- package/dist/stream-handler.entry.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/index2.d.cts +0 -148
- package/dist/index2.d.cts.map +0 -1
- package/dist/index2.d.mts +0 -148
- package/dist/index2.d.mts.map +0 -1
- package/dist/stream-handler.cjs +0 -91
- package/dist/stream-handler.mjs +0 -88
- package/dist/stream-handler.mjs.map +0 -1
package/dist/stream-handler.cjs
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
let _auriclabs_logger = require("@auriclabs/logger");
|
|
2
|
-
let _aws_sdk_client_eventbridge = require("@aws-sdk/client-eventbridge");
|
|
3
|
-
let _aws_sdk_client_sqs = require("@aws-sdk/client-sqs");
|
|
4
|
-
let _aws_sdk_util_dynamodb = require("@aws-sdk/util-dynamodb");
|
|
5
|
-
let lodash_es = require("lodash-es");
|
|
6
|
-
//#region src/stream-handler.ts
|
|
7
|
-
const BATCH_SIZE = 10;
|
|
8
|
-
/**
|
|
9
|
-
* Creates a Lambda handler for DynamoDB stream events.
|
|
10
|
-
* Processes INSERT events from the event store table and forwards them to SQS queues and EventBridge.
|
|
11
|
-
*/
|
|
12
|
-
function createStreamHandler(config) {
|
|
13
|
-
const sqsClient = new _aws_sdk_client_sqs.SQSClient();
|
|
14
|
-
const eventBridge = new _aws_sdk_client_eventbridge.EventBridgeClient({});
|
|
15
|
-
function chunkArray(array, chunkSize) {
|
|
16
|
-
const chunks = [];
|
|
17
|
-
for (let i = 0; i < array.length; i += chunkSize) chunks.push(array.slice(i, i + chunkSize));
|
|
18
|
-
return chunks;
|
|
19
|
-
}
|
|
20
|
-
async function sendToQueuesBatch(eventRecords) {
|
|
21
|
-
await Promise.all(config.queueUrls.map((queue) => sendToQueueBatch(eventRecords, queue)));
|
|
22
|
-
}
|
|
23
|
-
async function sendToQueueBatch(eventRecords, queue) {
|
|
24
|
-
const batches = chunkArray(eventRecords, BATCH_SIZE);
|
|
25
|
-
for (const batch of batches) try {
|
|
26
|
-
const entries = batch.map((eventRecord, index) => ({
|
|
27
|
-
Id: `${eventRecord.eventId}-${index}`,
|
|
28
|
-
MessageBody: JSON.stringify(eventRecord),
|
|
29
|
-
MessageGroupId: eventRecord.aggregateId,
|
|
30
|
-
MessageDeduplicationId: eventRecord.eventId
|
|
31
|
-
}));
|
|
32
|
-
await sqsClient.send(new _aws_sdk_client_sqs.SendMessageBatchCommand({
|
|
33
|
-
QueueUrl: queue,
|
|
34
|
-
Entries: entries
|
|
35
|
-
}));
|
|
36
|
-
} catch (error) {
|
|
37
|
-
_auriclabs_logger.logger.error({
|
|
38
|
-
error,
|
|
39
|
-
batch,
|
|
40
|
-
queue
|
|
41
|
-
}, "Error sending batch to queue");
|
|
42
|
-
throw error;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
async function sendToBusBatch(eventRecords) {
|
|
46
|
-
const batches = chunkArray(eventRecords, BATCH_SIZE);
|
|
47
|
-
for (const batch of batches) try {
|
|
48
|
-
const entries = batch.map((eventRecord) => {
|
|
49
|
-
return {
|
|
50
|
-
Source: eventRecord.source ?? (0, lodash_es.kebabCase)(eventRecord.aggregateType.split(".")[0]),
|
|
51
|
-
DetailType: eventRecord.eventType,
|
|
52
|
-
Detail: JSON.stringify(eventRecord),
|
|
53
|
-
EventBusName: config.busName
|
|
54
|
-
};
|
|
55
|
-
});
|
|
56
|
-
await eventBridge.send(new _aws_sdk_client_eventbridge.PutEventsCommand({ Entries: entries }));
|
|
57
|
-
} catch (error) {
|
|
58
|
-
_auriclabs_logger.logger.error({
|
|
59
|
-
error,
|
|
60
|
-
batch
|
|
61
|
-
}, "Error sending batch to bus");
|
|
62
|
-
throw error;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return async (event) => {
|
|
66
|
-
const eventRecords = event.Records.filter((record) => record.eventName === "INSERT").map((record) => {
|
|
67
|
-
try {
|
|
68
|
-
const data = record.dynamodb?.NewImage;
|
|
69
|
-
return (0, _aws_sdk_util_dynamodb.unmarshall)(data);
|
|
70
|
-
} catch (error) {
|
|
71
|
-
_auriclabs_logger.logger.error({
|
|
72
|
-
error,
|
|
73
|
-
record
|
|
74
|
-
}, "Error unmarshalling event record");
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
}).filter((eventRecord) => eventRecord?.itemType === "event");
|
|
78
|
-
if (eventRecords.length > 0) {
|
|
79
|
-
const tasks = [sendToQueuesBatch(eventRecords)];
|
|
80
|
-
if (config.busName) tasks.push(sendToBusBatch(eventRecords));
|
|
81
|
-
await Promise.all(tasks);
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
//#endregion
|
|
86
|
-
Object.defineProperty(exports, "createStreamHandler", {
|
|
87
|
-
enumerable: true,
|
|
88
|
-
get: function() {
|
|
89
|
-
return createStreamHandler;
|
|
90
|
-
}
|
|
91
|
-
});
|
package/dist/stream-handler.mjs
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { logger } from "@auriclabs/logger";
|
|
2
|
-
import { EventBridgeClient, PutEventsCommand } from "@aws-sdk/client-eventbridge";
|
|
3
|
-
import { SQSClient, SendMessageBatchCommand } from "@aws-sdk/client-sqs";
|
|
4
|
-
import { unmarshall } from "@aws-sdk/util-dynamodb";
|
|
5
|
-
import { kebabCase } from "lodash-es";
|
|
6
|
-
//#region src/stream-handler.ts
|
|
7
|
-
const BATCH_SIZE = 10;
|
|
8
|
-
/**
|
|
9
|
-
* Creates a Lambda handler for DynamoDB stream events.
|
|
10
|
-
* Processes INSERT events from the event store table and forwards them to SQS queues and EventBridge.
|
|
11
|
-
*/
|
|
12
|
-
function createStreamHandler(config) {
|
|
13
|
-
const sqsClient = new SQSClient();
|
|
14
|
-
const eventBridge = new EventBridgeClient({});
|
|
15
|
-
function chunkArray(array, chunkSize) {
|
|
16
|
-
const chunks = [];
|
|
17
|
-
for (let i = 0; i < array.length; i += chunkSize) chunks.push(array.slice(i, i + chunkSize));
|
|
18
|
-
return chunks;
|
|
19
|
-
}
|
|
20
|
-
async function sendToQueuesBatch(eventRecords) {
|
|
21
|
-
await Promise.all(config.queueUrls.map((queue) => sendToQueueBatch(eventRecords, queue)));
|
|
22
|
-
}
|
|
23
|
-
async function sendToQueueBatch(eventRecords, queue) {
|
|
24
|
-
const batches = chunkArray(eventRecords, BATCH_SIZE);
|
|
25
|
-
for (const batch of batches) try {
|
|
26
|
-
const entries = batch.map((eventRecord, index) => ({
|
|
27
|
-
Id: `${eventRecord.eventId}-${index}`,
|
|
28
|
-
MessageBody: JSON.stringify(eventRecord),
|
|
29
|
-
MessageGroupId: eventRecord.aggregateId,
|
|
30
|
-
MessageDeduplicationId: eventRecord.eventId
|
|
31
|
-
}));
|
|
32
|
-
await sqsClient.send(new SendMessageBatchCommand({
|
|
33
|
-
QueueUrl: queue,
|
|
34
|
-
Entries: entries
|
|
35
|
-
}));
|
|
36
|
-
} catch (error) {
|
|
37
|
-
logger.error({
|
|
38
|
-
error,
|
|
39
|
-
batch,
|
|
40
|
-
queue
|
|
41
|
-
}, "Error sending batch to queue");
|
|
42
|
-
throw error;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
async function sendToBusBatch(eventRecords) {
|
|
46
|
-
const batches = chunkArray(eventRecords, BATCH_SIZE);
|
|
47
|
-
for (const batch of batches) try {
|
|
48
|
-
const entries = batch.map((eventRecord) => {
|
|
49
|
-
return {
|
|
50
|
-
Source: eventRecord.source ?? kebabCase(eventRecord.aggregateType.split(".")[0]),
|
|
51
|
-
DetailType: eventRecord.eventType,
|
|
52
|
-
Detail: JSON.stringify(eventRecord),
|
|
53
|
-
EventBusName: config.busName
|
|
54
|
-
};
|
|
55
|
-
});
|
|
56
|
-
await eventBridge.send(new PutEventsCommand({ Entries: entries }));
|
|
57
|
-
} catch (error) {
|
|
58
|
-
logger.error({
|
|
59
|
-
error,
|
|
60
|
-
batch
|
|
61
|
-
}, "Error sending batch to bus");
|
|
62
|
-
throw error;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return async (event) => {
|
|
66
|
-
const eventRecords = event.Records.filter((record) => record.eventName === "INSERT").map((record) => {
|
|
67
|
-
try {
|
|
68
|
-
const data = record.dynamodb?.NewImage;
|
|
69
|
-
return unmarshall(data);
|
|
70
|
-
} catch (error) {
|
|
71
|
-
logger.error({
|
|
72
|
-
error,
|
|
73
|
-
record
|
|
74
|
-
}, "Error unmarshalling event record");
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
}).filter((eventRecord) => eventRecord?.itemType === "event");
|
|
78
|
-
if (eventRecords.length > 0) {
|
|
79
|
-
const tasks = [sendToQueuesBatch(eventRecords)];
|
|
80
|
-
if (config.busName) tasks.push(sendToBusBatch(eventRecords));
|
|
81
|
-
await Promise.all(tasks);
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
//#endregion
|
|
86
|
-
export { createStreamHandler as t };
|
|
87
|
-
|
|
88
|
-
//# sourceMappingURL=stream-handler.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stream-handler.mjs","names":[],"sources":["../src/stream-handler.ts"],"sourcesContent":["import { logger } from '@auriclabs/logger';\nimport { AttributeValue } from '@aws-sdk/client-dynamodb';\nimport { EventBridgeClient, PutEventsCommand } from '@aws-sdk/client-eventbridge';\nimport { SendMessageBatchCommand, SQSClient } from '@aws-sdk/client-sqs';\nimport { unmarshall } from '@aws-sdk/util-dynamodb';\nimport { DynamoDBStreamEvent } from 'aws-lambda';\nimport { kebabCase } from 'lodash-es';\n\nimport { AggregateHead, EventRecord } from './types';\n\nconst BATCH_SIZE = 10;\n\nexport interface CreateStreamHandlerConfig {\n busName?: string;\n queueUrls: string[];\n}\n\n/**\n * Creates a Lambda handler for DynamoDB stream events.\n * Processes INSERT events from the event store table and forwards them to SQS queues and EventBridge.\n */\nexport function createStreamHandler(config: CreateStreamHandlerConfig) {\n const sqsClient = new SQSClient();\n const eventBridge = new EventBridgeClient({});\n\n function chunkArray<T>(array: T[], chunkSize: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < array.length; i += chunkSize) {\n chunks.push(array.slice(i, i + chunkSize));\n }\n return chunks;\n }\n\n async function sendToQueuesBatch(eventRecords: EventRecord[]) {\n await Promise.all(config.queueUrls.map((queue) => sendToQueueBatch(eventRecords, queue)));\n }\n\n async function sendToQueueBatch(eventRecords: EventRecord[], queue: string) {\n const batches = chunkArray(eventRecords, BATCH_SIZE);\n\n for (const batch of batches) {\n try {\n const entries = batch.map((eventRecord, index) => ({\n Id: `${eventRecord.eventId}-${index}`,\n MessageBody: JSON.stringify(eventRecord),\n MessageGroupId: eventRecord.aggregateId,\n MessageDeduplicationId: eventRecord.eventId,\n }));\n\n await sqsClient.send(\n new SendMessageBatchCommand({\n QueueUrl: queue,\n Entries: entries,\n }),\n );\n } catch (error) {\n logger.error({ error, batch, queue }, 'Error sending batch to queue');\n throw error;\n }\n }\n }\n\n async function sendToBusBatch(eventRecords: EventRecord[]) {\n const batches = chunkArray(eventRecords, BATCH_SIZE);\n\n for (const batch of batches) {\n try {\n const entries = batch.map((eventRecord) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const source = eventRecord.source ?? kebabCase(eventRecord.aggregateType.split('.')[0]);\n return {\n Source: source,\n DetailType: eventRecord.eventType,\n Detail: JSON.stringify(eventRecord),\n EventBusName: config.busName,\n };\n });\n\n await eventBridge.send(\n new PutEventsCommand({\n Entries: entries,\n }),\n );\n } catch (error) {\n logger.error({ error, batch }, 'Error sending batch to bus');\n throw error;\n }\n }\n }\n\n return async (event: DynamoDBStreamEvent): Promise<void> => {\n const eventRecords = event.Records.filter((record) => record.eventName === 'INSERT')\n .map((record) => {\n try {\n const data = record.dynamodb?.NewImage;\n return unmarshall(data as Record<string, AttributeValue>) as EventRecord | AggregateHead;\n } catch (error) {\n logger.error({ error, record }, 'Error unmarshalling event record');\n return undefined;\n }\n })\n .filter((eventRecord): eventRecord is EventRecord => eventRecord?.itemType === 'event');\n\n if (eventRecords.length > 0) {\n const tasks: Promise<void>[] = [sendToQueuesBatch(eventRecords)];\n if (config.busName) {\n tasks.push(sendToBusBatch(eventRecords));\n }\n await Promise.all(tasks);\n }\n };\n}\n"],"mappings":";;;;;;AAUA,MAAM,aAAa;;;;;AAWnB,SAAgB,oBAAoB,QAAmC;CACrE,MAAM,YAAY,IAAI,WAAW;CACjC,MAAM,cAAc,IAAI,kBAAkB,EAAE,CAAC;CAE7C,SAAS,WAAc,OAAY,WAA0B;EAC3D,MAAM,SAAgB,EAAE;AACxB,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,UACrC,QAAO,KAAK,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC;AAE5C,SAAO;;CAGT,eAAe,kBAAkB,cAA6B;AAC5D,QAAM,QAAQ,IAAI,OAAO,UAAU,KAAK,UAAU,iBAAiB,cAAc,MAAM,CAAC,CAAC;;CAG3F,eAAe,iBAAiB,cAA6B,OAAe;EAC1E,MAAM,UAAU,WAAW,cAAc,WAAW;AAEpD,OAAK,MAAM,SAAS,QAClB,KAAI;GACF,MAAM,UAAU,MAAM,KAAK,aAAa,WAAW;IACjD,IAAI,GAAG,YAAY,QAAQ,GAAG;IAC9B,aAAa,KAAK,UAAU,YAAY;IACxC,gBAAgB,YAAY;IAC5B,wBAAwB,YAAY;IACrC,EAAE;AAEH,SAAM,UAAU,KACd,IAAI,wBAAwB;IAC1B,UAAU;IACV,SAAS;IACV,CAAC,CACH;WACM,OAAO;AACd,UAAO,MAAM;IAAE;IAAO;IAAO;IAAO,EAAE,+BAA+B;AACrE,SAAM;;;CAKZ,eAAe,eAAe,cAA6B;EACzD,MAAM,UAAU,WAAW,cAAc,WAAW;AAEpD,OAAK,MAAM,SAAS,QAClB,KAAI;GACF,MAAM,UAAU,MAAM,KAAK,gBAAgB;AAGzC,WAAO;KACL,QAFa,YAAY,UAAU,UAAU,YAAY,cAAc,MAAM,IAAI,CAAC,GAAG;KAGrF,YAAY,YAAY;KACxB,QAAQ,KAAK,UAAU,YAAY;KACnC,cAAc,OAAO;KACtB;KACD;AAEF,SAAM,YAAY,KAChB,IAAI,iBAAiB,EACnB,SAAS,SACV,CAAC,CACH;WACM,OAAO;AACd,UAAO,MAAM;IAAE;IAAO;IAAO,EAAE,6BAA6B;AAC5D,SAAM;;;AAKZ,QAAO,OAAO,UAA8C;EAC1D,MAAM,eAAe,MAAM,QAAQ,QAAQ,WAAW,OAAO,cAAc,SAAS,CACjF,KAAK,WAAW;AACf,OAAI;IACF,MAAM,OAAO,OAAO,UAAU;AAC9B,WAAO,WAAW,KAAuC;YAClD,OAAO;AACd,WAAO,MAAM;KAAE;KAAO;KAAQ,EAAE,mCAAmC;AACnE;;IAEF,CACD,QAAQ,gBAA4C,aAAa,aAAa,QAAQ;AAEzF,MAAI,aAAa,SAAS,GAAG;GAC3B,MAAM,QAAyB,CAAC,kBAAkB,aAAa,CAAC;AAChE,OAAI,OAAO,QACT,OAAM,KAAK,eAAe,aAAa,CAAC;AAE1C,SAAM,QAAQ,IAAI,MAAM"}
|