@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.
@@ -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
- });
@@ -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"}