dynamodb-reactive 0.1.11 → 0.1.12
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/infra.d.ts +1 -22
- package/dist/infra.js +9 -12
- package/dist/infra.js.map +1 -1
- package/dist/server.js +53 -20
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/dist/infra.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { A as AnyDynamoTable } from './types-2EfCnE0c.js';
|
|
2
|
-
import * as cdk from 'aws-cdk-lib';
|
|
3
2
|
import * as apigatewayv2 from 'aws-cdk-lib/aws-apigatewayv2';
|
|
4
3
|
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
|
|
5
4
|
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
6
|
-
import * as logs from 'aws-cdk-lib/aws-logs';
|
|
7
5
|
import { Construct } from 'constructs';
|
|
6
|
+
import * as cdk from 'aws-cdk-lib';
|
|
8
7
|
import 'zod';
|
|
9
8
|
|
|
10
9
|
/**
|
|
@@ -66,30 +65,10 @@ interface ReactiveEngineProps {
|
|
|
66
65
|
* System tables configuration
|
|
67
66
|
*/
|
|
68
67
|
systemTablesProps?: ReactiveSystemTablesProps;
|
|
69
|
-
/**
|
|
70
|
-
* Lambda function memory size in MB
|
|
71
|
-
* @default 256
|
|
72
|
-
*/
|
|
73
|
-
memorySize?: number;
|
|
74
|
-
/**
|
|
75
|
-
* Lambda function timeout
|
|
76
|
-
* @default Duration.seconds(30)
|
|
77
|
-
*/
|
|
78
|
-
timeout?: cdk.Duration;
|
|
79
|
-
/**
|
|
80
|
-
* Log retention period
|
|
81
|
-
* @default logs.RetentionDays.ONE_WEEK
|
|
82
|
-
*/
|
|
83
|
-
logRetention?: logs.RetentionDays;
|
|
84
68
|
/**
|
|
85
69
|
* Environment variables for Lambda functions
|
|
86
70
|
*/
|
|
87
71
|
environment?: Record<string, string>;
|
|
88
|
-
/**
|
|
89
|
-
* Enable tracing with X-Ray
|
|
90
|
-
* @default false
|
|
91
|
-
*/
|
|
92
|
-
tracing?: boolean;
|
|
93
72
|
}
|
|
94
73
|
/**
|
|
95
74
|
* ReactiveEngine - Main CDK construct for the reactive DynamoDB system
|
package/dist/infra.js
CHANGED
|
@@ -121,9 +121,9 @@ var ReactiveEngine = class extends Construct {
|
|
|
121
121
|
constructor(scope, id, props) {
|
|
122
122
|
super(scope, id);
|
|
123
123
|
const prefix = props.resourcePrefix ?? "";
|
|
124
|
-
const memorySize =
|
|
125
|
-
const timeout =
|
|
126
|
-
const logRetention =
|
|
124
|
+
const memorySize = 128;
|
|
125
|
+
const timeout = cdk2.Duration.seconds(30);
|
|
126
|
+
const logRetention = logs.RetentionDays.ONE_DAY;
|
|
127
127
|
this.systemTables = new ReactiveSystemTables(this, "SystemTables", {
|
|
128
128
|
tablePrefix: prefix,
|
|
129
129
|
...props.systemTablesProps
|
|
@@ -155,7 +155,8 @@ var ReactiveEngine = class extends Construct {
|
|
|
155
155
|
DEPENDENCIES_TABLE: this.systemTables.dependenciesTable.tableName,
|
|
156
156
|
QUERIES_TABLE: this.systemTables.queriesTable.tableName,
|
|
157
157
|
WEBSOCKET_ENDPOINT: this.callbackUrl,
|
|
158
|
-
...props.environment
|
|
158
|
+
...props.environment,
|
|
159
|
+
LOG_LEVEL: props.environment?.LOG_LEVEL ?? "INFO"
|
|
159
160
|
};
|
|
160
161
|
this.connectHandler = new nodejs.NodejsFunction(this, "ConnectHandler", {
|
|
161
162
|
functionName: `${prefix}ReactiveConnect`,
|
|
@@ -165,8 +166,7 @@ var ReactiveEngine = class extends Construct {
|
|
|
165
166
|
environment,
|
|
166
167
|
memorySize,
|
|
167
168
|
timeout,
|
|
168
|
-
logRetention
|
|
169
|
-
tracing: props.tracing ? lambda.Tracing.ACTIVE : lambda.Tracing.DISABLED
|
|
169
|
+
logRetention
|
|
170
170
|
});
|
|
171
171
|
this.disconnectHandler = new nodejs.NodejsFunction(
|
|
172
172
|
this,
|
|
@@ -179,8 +179,7 @@ var ReactiveEngine = class extends Construct {
|
|
|
179
179
|
environment,
|
|
180
180
|
memorySize,
|
|
181
181
|
timeout,
|
|
182
|
-
logRetention
|
|
183
|
-
tracing: props.tracing ? lambda.Tracing.ACTIVE : lambda.Tracing.DISABLED
|
|
182
|
+
logRetention
|
|
184
183
|
}
|
|
185
184
|
);
|
|
186
185
|
this.messageHandler = new nodejs.NodejsFunction(this, "MessageHandler", {
|
|
@@ -191,8 +190,7 @@ var ReactiveEngine = class extends Construct {
|
|
|
191
190
|
environment,
|
|
192
191
|
memorySize,
|
|
193
192
|
timeout,
|
|
194
|
-
logRetention
|
|
195
|
-
tracing: props.tracing ? lambda.Tracing.ACTIVE : lambda.Tracing.DISABLED
|
|
193
|
+
logRetention
|
|
196
194
|
});
|
|
197
195
|
this.streamHandler = new nodejs.NodejsFunction(this, "StreamHandler", {
|
|
198
196
|
functionName: `${prefix}ReactiveStream`,
|
|
@@ -205,8 +203,7 @@ var ReactiveEngine = class extends Construct {
|
|
|
205
203
|
},
|
|
206
204
|
memorySize,
|
|
207
205
|
timeout,
|
|
208
|
-
logRetention
|
|
209
|
-
tracing: props.tracing ? lambda.Tracing.ACTIVE : lambda.Tracing.DISABLED
|
|
206
|
+
logRetention
|
|
210
207
|
});
|
|
211
208
|
this.systemTables.connectionsTable.grantReadWriteData(this.connectHandler);
|
|
212
209
|
this.systemTables.connectionsTable.grantReadWriteData(
|
package/dist/infra.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../infra/src/handlers/lambda-handlers.ts","../../infra/src/tables.ts","../../infra/src/engine.ts","../../infra/src/stream-source.ts"],"names":["cdk","Construct","cdk3","lambda2"],"mappings":"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","file":"infra.js","sourcesContent":["/**\n * Entry point code generator for the reactive Lambda handlers.\n *\n * No user code is imported - the handlers use only environment variables\n * and stored query metadata for all operations.\n */\n\n/**\n * Generate the entry point code for Lambda functions.\n * This is called by the CDK construct to create the bundled entry file.\n */\nexport function generateEntryPointCode(): string {\n return `// Auto-generated entry point for reactive Lambda handlers\n// No user code required - all configuration comes from environment variables\nimport { createLambdaHandlers } from 'dynamodb-reactive/server';\n\nconst handlers = createLambdaHandlers();\n\nexport const connectHandler = handlers.connectHandler;\nexport const disconnectHandler = handlers.disconnectHandler;\nexport const messageHandler = handlers.messageHandler;\nexport const streamHandler = handlers.streamHandler;\n`;\n}\n","import { SystemTableNames } from '@dynamodb-reactive/core';\nimport * as cdk from 'aws-cdk-lib';\nimport * as dynamodb from 'aws-cdk-lib/aws-dynamodb';\nimport { Construct } from 'constructs';\n\n/**\n * Provisioning mode for DynamoDB tables\n * - \"ON_DEMAND\": Pay-per-request billing (default)\n * - { readWrite: number }: Provisioned capacity with specified RCU/WCU\n */\nexport type ProvisioningMode = 'ON_DEMAND' | { readWrite: number };\n\n/**\n * Props for ReactiveSystemTables\n */\nexport interface ReactiveSystemTablesProps {\n /**\n * Prefix for table names\n * @default - no prefix\n */\n tablePrefix?: string;\n\n /**\n * Provisioning mode for tables\n * @default \"ON_DEMAND\"\n */\n provisioningMode?: ProvisioningMode;\n}\n\n/**\n * Creates the three system tables for the reactive engine\n */\nexport class ReactiveSystemTables extends Construct {\n /**\n * ReactiveConnections table - tracks WebSocket connections\n */\n public readonly connectionsTable: dynamodb.Table;\n\n /**\n * ReactiveDependencies table - the inverted index\n */\n public readonly dependenciesTable: dynamodb.Table;\n\n /**\n * ReactiveConnectionQueries table - stores subscription state\n */\n public readonly queriesTable: dynamodb.Table;\n\n constructor(\n scope: Construct,\n id: string,\n props: ReactiveSystemTablesProps = {},\n ) {\n super(scope, id);\n\n const prefix = props.tablePrefix ? `${props.tablePrefix}-` : '';\n const provisioningMode = props.provisioningMode ?? 'ON_DEMAND';\n\n // Determine billing/capacity settings\n const isOnDemand = provisioningMode === 'ON_DEMAND';\n const capacityProps = isOnDemand\n ? { billingMode: dynamodb.BillingMode.PAY_PER_REQUEST }\n : {\n billingMode: dynamodb.BillingMode.PROVISIONED,\n readCapacity: provisioningMode.readWrite,\n writeCapacity: provisioningMode.readWrite,\n };\n\n // ReactiveConnections Table\n // Tracks active WebSocket connections and user context\n this.connectionsTable = new dynamodb.Table(this, 'ConnectionsTable', {\n tableName: `${prefix}${SystemTableNames.connections}`,\n partitionKey: {\n name: 'connectionId',\n type: dynamodb.AttributeType.STRING,\n },\n ...capacityProps,\n removalPolicy: cdk.RemovalPolicy.DESTROY,\n timeToLiveAttribute: 'ttl',\n });\n\n // ReactiveDependencies Table (The Inverted Index)\n // Maps Field#Value -> ConnectionID for O(1) lookups\n this.dependenciesTable = new dynamodb.Table(this, 'DependenciesTable', {\n tableName: `${prefix}${SystemTableNames.dependencies}`,\n partitionKey: {\n name: 'pk', // Format: \"TableName#FieldName#FieldValue\"\n type: dynamodb.AttributeType.STRING,\n },\n sortKey: {\n name: 'sk', // Format: \"ConnectionID#SubscriptionID\"\n type: dynamodb.AttributeType.STRING,\n },\n ...capacityProps,\n removalPolicy: cdk.RemovalPolicy.DESTROY,\n timeToLiveAttribute: 'ttl',\n });\n\n // Add GSI for querying by connectionId (for cleanup)\n // For provisioned mode, GSI needs its own capacity\n const gsiProps = isOnDemand\n ? {}\n : {\n readCapacity: provisioningMode.readWrite,\n writeCapacity: provisioningMode.readWrite,\n };\n\n this.dependenciesTable.addGlobalSecondaryIndex({\n indexName: 'byConnectionId',\n partitionKey: {\n name: 'connectionId',\n type: dynamodb.AttributeType.STRING,\n },\n projectionType: dynamodb.ProjectionType.KEYS_ONLY,\n ...gsiProps,\n });\n\n // ReactiveConnectionQueries Table\n // Stores subscription state for diffing\n this.queriesTable = new dynamodb.Table(this, 'QueriesTable', {\n tableName: `${prefix}${SystemTableNames.queries}`,\n partitionKey: {\n name: 'pk', // ConnectionID\n type: dynamodb.AttributeType.STRING,\n },\n sortKey: {\n name: 'sk', // SubscriptionID\n type: dynamodb.AttributeType.STRING,\n },\n ...capacityProps,\n removalPolicy: cdk.RemovalPolicy.DESTROY,\n timeToLiveAttribute: 'ttl',\n });\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { AnyDynamoTable } from '@dynamodb-reactive/core';\nimport * as cdk from 'aws-cdk-lib';\nimport * as apigatewayv2 from 'aws-cdk-lib/aws-apigatewayv2';\nimport * as apigatewayv2Integrations from 'aws-cdk-lib/aws-apigatewayv2-integrations';\nimport type * as dynamodb from 'aws-cdk-lib/aws-dynamodb';\nimport * as iam from 'aws-cdk-lib/aws-iam';\nimport * as lambda from 'aws-cdk-lib/aws-lambda';\nimport * as nodejs from 'aws-cdk-lib/aws-lambda-nodejs';\nimport * as logs from 'aws-cdk-lib/aws-logs';\nimport { Construct } from 'constructs';\n\nimport { generateEntryPointCode } from './handlers/lambda-handlers.js';\nimport {\n ReactiveSystemTables,\n type ReactiveSystemTablesProps,\n} from './tables.js';\n\n/**\n * Props for ReactiveEngine construct\n */\nexport interface ReactiveEngineProps {\n /**\n * User-defined DynamoDB tables to enable reactive updates on\n */\n tables: AnyDynamoTable[];\n\n /**\n * Prefix for all resource names\n * @default - no prefix\n */\n resourcePrefix?: string;\n\n /**\n * System tables configuration\n */\n systemTablesProps?: ReactiveSystemTablesProps;\n\n /**\n * Lambda function memory size in MB\n * @default 256\n */\n memorySize?: number;\n\n /**\n * Lambda function timeout\n * @default Duration.seconds(30)\n */\n timeout?: cdk.Duration;\n\n /**\n * Log retention period\n * @default logs.RetentionDays.ONE_WEEK\n */\n logRetention?: logs.RetentionDays;\n\n /**\n * Environment variables for Lambda functions\n */\n environment?: Record<string, string>;\n\n /**\n * Enable tracing with X-Ray\n * @default false\n */\n tracing?: boolean;\n}\n\n/**\n * ReactiveEngine - Main CDK construct for the reactive DynamoDB system\n */\nexport class ReactiveEngine extends Construct {\n public readonly systemTables: ReactiveSystemTables;\n public readonly webSocketApi: apigatewayv2.WebSocketApi;\n public readonly webSocketStage: apigatewayv2.WebSocketStage;\n public readonly connectHandler: lambda.Function;\n public readonly disconnectHandler: lambda.Function;\n public readonly messageHandler: lambda.Function;\n public readonly streamHandler: lambda.Function;\n public readonly webSocketUrl: string;\n public readonly callbackUrl: string;\n\n constructor(scope: Construct, id: string, props: ReactiveEngineProps) {\n super(scope, id);\n\n const prefix = props.resourcePrefix ?? '';\n const memorySize = props.memorySize ?? 256;\n const timeout = props.timeout ?? cdk.Duration.seconds(30);\n const logRetention = props.logRetention ?? logs.RetentionDays.ONE_WEEK;\n\n // Create system tables\n this.systemTables = new ReactiveSystemTables(this, 'SystemTables', {\n tablePrefix: prefix,\n ...props.systemTablesProps,\n });\n\n // Create WebSocket API\n this.webSocketApi = new apigatewayv2.WebSocketApi(this, 'WebSocketApi', {\n apiName: `${prefix}ReactiveWebSocket`,\n });\n\n this.webSocketStage = new apigatewayv2.WebSocketStage(\n this,\n 'WebSocketStage',\n {\n webSocketApi: this.webSocketApi,\n stageName: 'prod',\n autoDeploy: true,\n },\n );\n\n this.webSocketUrl = this.webSocketStage.url;\n this.callbackUrl = this.webSocketStage.callbackUrl;\n\n // Generate the entry point file (no user code required)\n // Write to cdk.out directory to avoid path resolution issues with temp directories\n const entryPointCode = generateEntryPointCode();\n const cdkOutDir = path.join(process.cwd(), 'cdk.out', '.generated');\n fs.mkdirSync(cdkOutDir, { recursive: true });\n const entryPointPath = path.join(\n cdkOutDir,\n `reactive-entry-${id}-${Date.now()}.ts`,\n );\n fs.writeFileSync(entryPointPath, entryPointCode);\n\n // Common environment variables\n const environment: Record<string, string> = {\n CONNECTIONS_TABLE: this.systemTables.connectionsTable.tableName,\n DEPENDENCIES_TABLE: this.systemTables.dependenciesTable.tableName,\n QUERIES_TABLE: this.systemTables.queriesTable.tableName,\n WEBSOCKET_ENDPOINT: this.callbackUrl,\n ...props.environment,\n };\n\n // Create handlers using NodejsFunction with the generated entry point\n this.connectHandler = new nodejs.NodejsFunction(this, 'ConnectHandler', {\n functionName: `${prefix}ReactiveConnect`,\n runtime: lambda.Runtime.NODEJS_LATEST,\n handler: 'connectHandler',\n entry: entryPointPath,\n environment,\n memorySize,\n timeout,\n logRetention,\n tracing: props.tracing ? lambda.Tracing.ACTIVE : lambda.Tracing.DISABLED,\n });\n\n this.disconnectHandler = new nodejs.NodejsFunction(\n this,\n 'DisconnectHandler',\n {\n functionName: `${prefix}ReactiveDisconnect`,\n runtime: lambda.Runtime.NODEJS_LATEST,\n handler: 'disconnectHandler',\n entry: entryPointPath,\n environment,\n memorySize,\n timeout,\n logRetention,\n tracing: props.tracing\n ? lambda.Tracing.ACTIVE\n : lambda.Tracing.DISABLED,\n },\n );\n\n this.messageHandler = new nodejs.NodejsFunction(this, 'MessageHandler', {\n functionName: `${prefix}ReactiveMessage`,\n runtime: lambda.Runtime.NODEJS_LATEST,\n handler: 'messageHandler',\n entry: entryPointPath,\n environment,\n memorySize,\n timeout,\n logRetention,\n tracing: props.tracing ? lambda.Tracing.ACTIVE : lambda.Tracing.DISABLED,\n });\n\n this.streamHandler = new nodejs.NodejsFunction(this, 'StreamHandler', {\n functionName: `${prefix}ReactiveStream`,\n runtime: lambda.Runtime.NODEJS_LATEST,\n handler: 'streamHandler',\n entry: entryPointPath,\n environment: {\n ...environment,\n USER_TABLES: props.tables.map((t) => t.tableName).join(','),\n },\n memorySize,\n timeout,\n logRetention,\n tracing: props.tracing ? lambda.Tracing.ACTIVE : lambda.Tracing.DISABLED,\n });\n\n // Grant permissions for system tables\n this.systemTables.connectionsTable.grantReadWriteData(this.connectHandler);\n this.systemTables.connectionsTable.grantReadWriteData(\n this.disconnectHandler,\n );\n this.systemTables.connectionsTable.grantReadWriteData(this.messageHandler);\n this.systemTables.connectionsTable.grantReadWriteData(this.streamHandler);\n\n this.systemTables.dependenciesTable.grantReadWriteData(this.messageHandler);\n this.systemTables.dependenciesTable.grantReadWriteData(this.streamHandler);\n\n this.systemTables.queriesTable.grantReadWriteData(this.messageHandler);\n this.systemTables.queriesTable.grantReadWriteData(this.streamHandler);\n\n // Grant WebSocket management permissions\n const managementPolicy = new iam.PolicyStatement({\n actions: ['execute-api:ManageConnections'],\n resources: [\n `arn:aws:execute-api:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:${this.webSocketApi.apiId}/${this.webSocketStage.stageName}/POST/@connections/*`,\n ],\n });\n\n this.messageHandler.addToRolePolicy(managementPolicy);\n this.streamHandler.addToRolePolicy(managementPolicy);\n\n // Set up WebSocket routes\n this.webSocketApi.addRoute('$connect', {\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'ConnectIntegration',\n this.connectHandler,\n ),\n });\n\n this.webSocketApi.addRoute('$disconnect', {\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'DisconnectIntegration',\n this.disconnectHandler,\n ),\n });\n\n this.webSocketApi.addRoute('$default', {\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'DefaultIntegration',\n this.messageHandler,\n ),\n });\n\n // Set up DynamoDB stream processing for user tables\n for (const table of props.tables) {\n this.setupStreamProcessing(table);\n }\n\n // Output the WebSocket URL\n new cdk.CfnOutput(this, 'WebSocketUrl', {\n value: this.webSocketUrl,\n description: 'WebSocket URL for reactive connections',\n });\n }\n\n private setupStreamProcessing(table: AnyDynamoTable): void {\n const tableArn = `arn:aws:dynamodb:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:table/${table.tableName}`;\n const streamArn = `${tableArn}/stream/*`;\n\n // Stream handler needs stream access\n this.streamHandler.addToRolePolicy(\n new iam.PolicyStatement({\n actions: [\n 'dynamodb:GetRecords',\n 'dynamodb:GetShardIterator',\n 'dynamodb:DescribeStream',\n 'dynamodb:ListStreams',\n ],\n resources: [streamArn],\n }),\n );\n\n // Both handlers need read access to user tables (including PartiQL for queries)\n const tableReadPolicy = new iam.PolicyStatement({\n actions: [\n 'dynamodb:Query',\n 'dynamodb:Scan',\n 'dynamodb:GetItem',\n 'dynamodb:BatchGetItem',\n 'dynamodb:PartiQLSelect',\n ],\n resources: [tableArn, `${tableArn}/index/*`],\n });\n\n this.streamHandler.addToRolePolicy(tableReadPolicy);\n this.messageHandler.addToRolePolicy(tableReadPolicy);\n\n // Message handler also needs write access for mutations\n this.messageHandler.addToRolePolicy(\n new iam.PolicyStatement({\n actions: [\n 'dynamodb:PutItem',\n 'dynamodb:UpdateItem',\n 'dynamodb:DeleteItem',\n 'dynamodb:BatchWriteItem',\n 'dynamodb:PartiQLInsert',\n 'dynamodb:PartiQLUpdate',\n 'dynamodb:PartiQLDelete',\n ],\n resources: [tableArn, `${tableArn}/index/*`],\n }),\n );\n }\n\n public addTable(table: dynamodb.ITable): void {\n if (!table.tableStreamArn) {\n throw new Error(`Table ${table.tableName} does not have streams enabled`);\n }\n\n table.grantStreamRead(this.streamHandler);\n table.grantReadData(this.streamHandler);\n\n new lambda.EventSourceMapping(this, `Stream-${table.tableName}`, {\n target: this.streamHandler,\n eventSourceArn: table.tableStreamArn,\n startingPosition: lambda.StartingPosition.TRIM_HORIZON,\n batchSize: 100,\n maxBatchingWindow: cdk.Duration.seconds(5),\n });\n }\n}\n","import * as cdk from 'aws-cdk-lib';\nimport type * as dynamodb from 'aws-cdk-lib/aws-dynamodb';\nimport * as lambda from 'aws-cdk-lib/aws-lambda';\nimport { Construct } from 'constructs';\n\n/**\n * Props for DynamoDBStreamSource\n */\nexport interface DynamoDBStreamSourceProps {\n /**\n * The DynamoDB table to create a stream source for\n */\n table: dynamodb.ITable;\n\n /**\n * The Lambda function to receive stream events\n */\n target: lambda.IFunction;\n\n /**\n * Batch size for stream processing\n * @default 100\n */\n batchSize?: number;\n\n /**\n * Maximum batching window\n * @default Duration.seconds(5)\n */\n maxBatchingWindow?: cdk.Duration;\n\n /**\n * Starting position for reading the stream\n * @default TRIM_HORIZON\n */\n startingPosition?: lambda.StartingPosition;\n\n /**\n * Enable parallel processing with multiple batches\n * @default 1\n */\n parallelizationFactor?: number;\n\n /**\n * Maximum record age to process\n * @default Duration.days(1)\n */\n maxRecordAge?: cdk.Duration;\n\n /**\n * Number of retries on failure\n * @default 3\n */\n retryAttempts?: number;\n\n /**\n * Filter patterns for the event source\n */\n filters?: lambda.FilterCriteria[];\n}\n\n/**\n * Helper construct for setting up DynamoDB stream event sources\n */\nexport class DynamoDBStreamSource extends Construct {\n public readonly eventSourceMapping: lambda.EventSourceMapping;\n\n constructor(scope: Construct, id: string, props: DynamoDBStreamSourceProps) {\n super(scope, id);\n\n const {\n table,\n target,\n batchSize = 100,\n maxBatchingWindow = cdk.Duration.seconds(5),\n startingPosition = lambda.StartingPosition.TRIM_HORIZON,\n parallelizationFactor = 1,\n maxRecordAge = cdk.Duration.days(1),\n retryAttempts = 3,\n filters,\n } = props;\n\n if (!table.tableStreamArn) {\n throw new Error(\n `Table ${table.tableName} does not have DynamoDB Streams enabled. ` +\n 'Enable streams with streamSpecification when creating the table.',\n );\n }\n\n // Grant stream read permissions\n table.grantStreamRead(target);\n\n // Create the event source mapping\n this.eventSourceMapping = new lambda.EventSourceMapping(\n this,\n 'EventSource',\n {\n target,\n eventSourceArn: table.tableStreamArn,\n startingPosition,\n batchSize,\n maxBatchingWindow,\n parallelizationFactor,\n maxRecordAge,\n retryAttempts,\n bisectBatchOnError: true,\n reportBatchItemFailures: true,\n filters,\n },\n );\n }\n}\n\n/**\n * Create a filter criteria for DynamoDB streams\n */\nexport function createStreamFilter(options: {\n /**\n * Filter by event name (INSERT, MODIFY, REMOVE)\n */\n eventName?: ('INSERT' | 'MODIFY' | 'REMOVE')[];\n\n /**\n * Custom filter patterns\n */\n patterns?: Record<string, unknown>[];\n}): lambda.FilterCriteria[] {\n const filters: Record<string, unknown>[] = [];\n\n if (options.eventName) {\n filters.push({\n eventName: options.eventName,\n });\n }\n\n if (options.patterns) {\n filters.push(...options.patterns);\n }\n\n if (filters.length === 0) {\n return [];\n }\n\n return [lambda.FilterCriteria.filter({ filters })];\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../infra/src/handlers/lambda-handlers.ts","../../infra/src/tables.ts","../../infra/src/engine.ts","../../infra/src/stream-source.ts"],"names":["cdk","Construct","cdk3","lambda2"],"mappings":";;;;;;;;;;;;;;;AAWO,SAAS,sBAAA,GAAiC;AAC/C,EAAA,OAAO,CAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAWT;ACSO,IAAM,oBAAA,GAAN,cAAmC,SAAA,CAAU;AAAA;AAAA;AAAA;AAAA,EAIlC,gBAAA;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAA;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA;AAAA,EAEhB,WAAA,CACE,KAAA,EACA,EAAA,EACA,KAAA,GAAmC,EAAC,EACpC;AACA,IAAA,KAAA,CAAM,OAAO,EAAE,CAAA;AAEf,IAAA,MAAM,SAAS,KAAA,CAAM,WAAA,GAAc,CAAA,EAAG,KAAA,CAAM,WAAW,CAAA,CAAA,CAAA,GAAM,EAAA;AAC7D,IAAA,MAAM,gBAAA,GAAmB,MAAM,gBAAA,IAAoB,WAAA;AAGnD,IAAA,MAAM,aAAa,gBAAA,KAAqB,WAAA;AACxC,IAAA,MAAM,gBAAgB,UAAA,GAClB,EAAE,WAAA,EAAsB,QAAA,CAAA,WAAA,CAAY,iBAAgB,GACpD;AAAA,MACE,aAAsB,QAAA,CAAA,WAAA,CAAY,WAAA;AAAA,MAClC,cAAc,gBAAA,CAAiB,SAAA;AAAA,MAC/B,eAAe,gBAAA,CAAiB;AAAA,KAClC;AAIJ,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAa,QAAA,CAAA,KAAA,CAAM,IAAA,EAAM,kBAAA,EAAoB;AAAA,MACnE,SAAA,EAAW,CAAA,EAAG,MAAM,CAAA,EAAG,iBAAiB,WAAW,CAAA,CAAA;AAAA,MACnD,YAAA,EAAc;AAAA,QACZ,IAAA,EAAM,cAAA;AAAA,QACN,MAAe,QAAA,CAAA,aAAA,CAAc;AAAA,OAC/B;AAAA,MACA,GAAG,aAAA;AAAA,MACH,eAAmBA,IAAA,CAAA,aAAA,CAAc,OAAA;AAAA,MACjC,mBAAA,EAAqB;AAAA,KACtB,CAAA;AAID,IAAA,IAAA,CAAK,iBAAA,GAAoB,IAAa,QAAA,CAAA,KAAA,CAAM,IAAA,EAAM,mBAAA,EAAqB;AAAA,MACrE,SAAA,EAAW,CAAA,EAAG,MAAM,CAAA,EAAG,iBAAiB,YAAY,CAAA,CAAA;AAAA,MACpD,YAAA,EAAc;AAAA,QACZ,IAAA,EAAM,IAAA;AAAA;AAAA,QACN,MAAe,QAAA,CAAA,aAAA,CAAc;AAAA,OAC/B;AAAA,MACA,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,IAAA;AAAA;AAAA,QACN,MAAe,QAAA,CAAA,aAAA,CAAc;AAAA,OAC/B;AAAA,MACA,GAAG,aAAA;AAAA,MACH,eAAmBA,IAAA,CAAA,aAAA,CAAc,OAAA;AAAA,MACjC,mBAAA,EAAqB;AAAA,KACtB,CAAA;AAID,IAAA,MAAM,QAAA,GAAW,UAAA,GACb,EAAC,GACD;AAAA,MACE,cAAc,gBAAA,CAAiB,SAAA;AAAA,MAC/B,eAAe,gBAAA,CAAiB;AAAA,KAClC;AAEJ,IAAA,IAAA,CAAK,kBAAkB,uBAAA,CAAwB;AAAA,MAC7C,SAAA,EAAW,gBAAA;AAAA,MACX,YAAA,EAAc;AAAA,QACZ,IAAA,EAAM,cAAA;AAAA,QACN,MAAe,QAAA,CAAA,aAAA,CAAc;AAAA,OAC/B;AAAA,MACA,gBAAyB,QAAA,CAAA,cAAA,CAAe,SAAA;AAAA,MACxC,GAAG;AAAA,KACJ,CAAA;AAID,IAAA,IAAA,CAAK,YAAA,GAAe,IAAa,QAAA,CAAA,KAAA,CAAM,IAAA,EAAM,cAAA,EAAgB;AAAA,MAC3D,SAAA,EAAW,CAAA,EAAG,MAAM,CAAA,EAAG,iBAAiB,OAAO,CAAA,CAAA;AAAA,MAC/C,YAAA,EAAc;AAAA,QACZ,IAAA,EAAM,IAAA;AAAA;AAAA,QACN,MAAe,QAAA,CAAA,aAAA,CAAc;AAAA,OAC/B;AAAA,MACA,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,IAAA;AAAA;AAAA,QACN,MAAe,QAAA,CAAA,aAAA,CAAc;AAAA,OAC/B;AAAA,MACA,GAAG,aAAA;AAAA,MACH,eAAmBA,IAAA,CAAA,aAAA,CAAc,OAAA;AAAA,MACjC,mBAAA,EAAqB;AAAA,KACtB,CAAA;AAAA,EACH;AACF;;;ACtFO,IAAM,cAAA,GAAN,cAA6BC,SAAAA,CAAU;AAAA,EAC5B,YAAA;AAAA,EACA,YAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EAEhB,WAAA,CAAY,KAAA,EAAkB,EAAA,EAAY,KAAA,EAA4B;AACpE,IAAA,KAAA,CAAM,OAAO,EAAE,CAAA;AAEf,IAAA,MAAM,MAAA,GAAS,MAAM,cAAA,IAAkB,EAAA;AACvC,IAAA,MAAM,UAAA,GAAa,GAAA;AACnB,IAAA,MAAM,OAAA,GAAc,IAAA,CAAA,QAAA,CAAS,OAAA,CAAQ,EAAE,CAAA;AACvC,IAAA,MAAM,eAAoB,IAAA,CAAA,aAAA,CAAc,OAAA;AAGxC,IAAA,IAAA,CAAK,YAAA,GAAe,IAAI,oBAAA,CAAqB,IAAA,EAAM,cAAA,EAAgB;AAAA,MACjE,WAAA,EAAa,MAAA;AAAA,MACb,GAAG,KAAA,CAAM;AAAA,KACV,CAAA;AAGD,IAAA,IAAA,CAAK,YAAA,GAAe,IAAiB,YAAA,CAAA,YAAA,CAAa,IAAA,EAAM,cAAA,EAAgB;AAAA,MACtE,OAAA,EAAS,GAAG,MAAM,CAAA,iBAAA;AAAA,KACnB,CAAA;AAED,IAAA,IAAA,CAAK,iBAAiB,IAAiB,YAAA,CAAA,cAAA;AAAA,MACrC,IAAA;AAAA,MACA,gBAAA;AAAA,MACA;AAAA,QACE,cAAc,IAAA,CAAK,YAAA;AAAA,QACnB,SAAA,EAAW,MAAA;AAAA,QACX,UAAA,EAAY;AAAA;AACd,KACF;AAEA,IAAA,IAAA,CAAK,YAAA,GAAe,KAAK,cAAA,CAAe,GAAA;AACxC,IAAA,IAAA,CAAK,WAAA,GAAc,KAAK,cAAA,CAAe,WAAA;AAIvC,IAAA,MAAM,iBAAiB,sBAAA,EAAuB;AAC9C,IAAA,MAAM,YAAiB,IAAA,CAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAI,EAAG,WAAW,YAAY,CAAA;AAClE,IAAG,EAAA,CAAA,SAAA,CAAU,SAAA,EAAW,EAAE,SAAA,EAAW,MAAM,CAAA;AAC3C,IAAA,MAAM,cAAA,GAAsB,IAAA,CAAA,IAAA;AAAA,MAC1B,SAAA;AAAA,MACA,CAAA,eAAA,EAAkB,EAAE,CAAA,CAAA,EAAI,IAAA,CAAK,KAAK,CAAA,GAAA;AAAA,KACpC;AACA,IAAG,EAAA,CAAA,aAAA,CAAc,gBAAgB,cAAc,CAAA;AAG/C,IAAA,MAAM,WAAA,GAAsC;AAAA,MAC1C,iBAAA,EAAmB,IAAA,CAAK,YAAA,CAAa,gBAAA,CAAiB,SAAA;AAAA,MACtD,kBAAA,EAAoB,IAAA,CAAK,YAAA,CAAa,iBAAA,CAAkB,SAAA;AAAA,MACxD,aAAA,EAAe,IAAA,CAAK,YAAA,CAAa,YAAA,CAAa,SAAA;AAAA,MAC9C,oBAAoB,IAAA,CAAK,WAAA;AAAA,MACzB,GAAG,KAAA,CAAM,WAAA;AAAA,MACT,SAAA,EAAW,KAAA,CAAM,WAAA,EAAa,SAAA,IAAa;AAAA,KAC7C;AAGA,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAW,MAAA,CAAA,cAAA,CAAe,IAAA,EAAM,gBAAA,EAAkB;AAAA,MACtE,YAAA,EAAc,GAAG,MAAM,CAAA,eAAA,CAAA;AAAA,MACvB,SAAgB,MAAA,CAAA,OAAA,CAAQ,aAAA;AAAA,MACxB,OAAA,EAAS,gBAAA;AAAA,MACT,KAAA,EAAO,cAAA;AAAA,MACP,WAAA;AAAA,MACA,UAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,IAAA,CAAK,oBAAoB,IAAW,MAAA,CAAA,cAAA;AAAA,MAClC,IAAA;AAAA,MACA,mBAAA;AAAA,MACA;AAAA,QACE,YAAA,EAAc,GAAG,MAAM,CAAA,kBAAA,CAAA;AAAA,QACvB,SAAgB,MAAA,CAAA,OAAA,CAAQ,aAAA;AAAA,QACxB,OAAA,EAAS,mBAAA;AAAA,QACT,KAAA,EAAO,cAAA;AAAA,QACP,WAAA;AAAA,QACA,UAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA;AACF,KACF;AAEA,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAW,MAAA,CAAA,cAAA,CAAe,IAAA,EAAM,gBAAA,EAAkB;AAAA,MACtE,YAAA,EAAc,GAAG,MAAM,CAAA,eAAA,CAAA;AAAA,MACvB,SAAgB,MAAA,CAAA,OAAA,CAAQ,aAAA;AAAA,MACxB,OAAA,EAAS,gBAAA;AAAA,MACT,KAAA,EAAO,cAAA;AAAA,MACP,WAAA;AAAA,MACA,UAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAW,MAAA,CAAA,cAAA,CAAe,IAAA,EAAM,eAAA,EAAiB;AAAA,MACpE,YAAA,EAAc,GAAG,MAAM,CAAA,cAAA,CAAA;AAAA,MACvB,SAAgB,MAAA,CAAA,OAAA,CAAQ,aAAA;AAAA,MACxB,OAAA,EAAS,eAAA;AAAA,MACT,KAAA,EAAO,cAAA;AAAA,MACP,WAAA,EAAa;AAAA,QACX,GAAG,WAAA;AAAA,QACH,WAAA,EAAa,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,SAAS,CAAA,CAAE,IAAA,CAAK,GAAG;AAAA,OAC5D;AAAA,MACA,UAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACD,CAAA;AAGD,IAAA,IAAA,CAAK,YAAA,CAAa,gBAAA,CAAiB,kBAAA,CAAmB,IAAA,CAAK,cAAc,CAAA;AACzE,IAAA,IAAA,CAAK,aAAa,gBAAA,CAAiB,kBAAA;AAAA,MACjC,IAAA,CAAK;AAAA,KACP;AACA,IAAA,IAAA,CAAK,YAAA,CAAa,gBAAA,CAAiB,kBAAA,CAAmB,IAAA,CAAK,cAAc,CAAA;AACzE,IAAA,IAAA,CAAK,YAAA,CAAa,gBAAA,CAAiB,kBAAA,CAAmB,IAAA,CAAK,aAAa,CAAA;AAExE,IAAA,IAAA,CAAK,YAAA,CAAa,iBAAA,CAAkB,kBAAA,CAAmB,IAAA,CAAK,cAAc,CAAA;AAC1E,IAAA,IAAA,CAAK,YAAA,CAAa,iBAAA,CAAkB,kBAAA,CAAmB,IAAA,CAAK,aAAa,CAAA;AAEzE,IAAA,IAAA,CAAK,YAAA,CAAa,YAAA,CAAa,kBAAA,CAAmB,IAAA,CAAK,cAAc,CAAA;AACrE,IAAA,IAAA,CAAK,YAAA,CAAa,YAAA,CAAa,kBAAA,CAAmB,IAAA,CAAK,aAAa,CAAA;AAGpE,IAAA,MAAM,gBAAA,GAAmB,IAAQ,GAAA,CAAA,eAAA,CAAgB;AAAA,MAC/C,OAAA,EAAS,CAAC,+BAA+B,CAAA;AAAA,MACzC,SAAA,EAAW;AAAA,QACT,uBAA2B,IAAA,CAAA,KAAA,CAAM,EAAA,CAAG,IAAI,CAAA,CAAE,MAAM,IAAQ,IAAA,CAAA,KAAA,CAAM,EAAA,CAAG,IAAI,CAAA,CAAE,OAAO,IAAI,IAAA,CAAK,YAAA,CAAa,KAAK,CAAA,CAAA,EAAI,IAAA,CAAK,eAAe,SAAS,CAAA,oBAAA;AAAA;AAC5I,KACD,CAAA;AAED,IAAA,IAAA,CAAK,cAAA,CAAe,gBAAgB,gBAAgB,CAAA;AACpD,IAAA,IAAA,CAAK,aAAA,CAAc,gBAAgB,gBAAgB,CAAA;AAGnD,IAAA,IAAA,CAAK,YAAA,CAAa,SAAS,UAAA,EAAY;AAAA,MACrC,aAAa,IAA6B,wBAAA,CAAA,0BAAA;AAAA,QACxC,oBAAA;AAAA,QACA,IAAA,CAAK;AAAA;AACP,KACD,CAAA;AAED,IAAA,IAAA,CAAK,YAAA,CAAa,SAAS,aAAA,EAAe;AAAA,MACxC,aAAa,IAA6B,wBAAA,CAAA,0BAAA;AAAA,QACxC,uBAAA;AAAA,QACA,IAAA,CAAK;AAAA;AACP,KACD,CAAA;AAED,IAAA,IAAA,CAAK,YAAA,CAAa,SAAS,UAAA,EAAY;AAAA,MACrC,aAAa,IAA6B,wBAAA,CAAA,0BAAA;AAAA,QACxC,oBAAA;AAAA,QACA,IAAA,CAAK;AAAA;AACP,KACD,CAAA;AAGD,IAAA,KAAA,MAAW,KAAA,IAAS,MAAM,MAAA,EAAQ;AAChC,MAAA,IAAA,CAAK,sBAAsB,KAAK,CAAA;AAAA,IAClC;AAGA,IAAA,IAAQ,IAAA,CAAA,SAAA,CAAU,MAAM,cAAA,EAAgB;AAAA,MACtC,OAAO,IAAA,CAAK,YAAA;AAAA,MACZ,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AAAA,EAEQ,sBAAsB,KAAA,EAA6B;AACzD,IAAA,MAAM,QAAA,GAAW,CAAA,iBAAA,EAAwB,IAAA,CAAA,KAAA,CAAM,EAAA,CAAG,IAAI,CAAA,CAAE,MAAM,CAAA,CAAA,EAAQ,IAAA,CAAA,KAAA,CAAM,GAAG,IAAI,CAAA,CAAE,OAAO,CAAA,OAAA,EAAU,MAAM,SAAS,CAAA,CAAA;AACrH,IAAA,MAAM,SAAA,GAAY,GAAG,QAAQ,CAAA,SAAA,CAAA;AAG7B,IAAA,IAAA,CAAK,aAAA,CAAc,eAAA;AAAA,MACjB,IAAQ,GAAA,CAAA,eAAA,CAAgB;AAAA,QACtB,OAAA,EAAS;AAAA,UACP,qBAAA;AAAA,UACA,2BAAA;AAAA,UACA,yBAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,SAAA,EAAW,CAAC,SAAS;AAAA,OACtB;AAAA,KACH;AAGA,IAAA,MAAM,eAAA,GAAkB,IAAQ,GAAA,CAAA,eAAA,CAAgB;AAAA,MAC9C,OAAA,EAAS;AAAA,QACP,gBAAA;AAAA,QACA,eAAA;AAAA,QACA,kBAAA;AAAA,QACA,uBAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,SAAA,EAAW,CAAC,QAAA,EAAU,CAAA,EAAG,QAAQ,CAAA,QAAA,CAAU;AAAA,KAC5C,CAAA;AAED,IAAA,IAAA,CAAK,aAAA,CAAc,gBAAgB,eAAe,CAAA;AAClD,IAAA,IAAA,CAAK,cAAA,CAAe,gBAAgB,eAAe,CAAA;AAGnD,IAAA,IAAA,CAAK,cAAA,CAAe,eAAA;AAAA,MAClB,IAAQ,GAAA,CAAA,eAAA,CAAgB;AAAA,QACtB,OAAA,EAAS;AAAA,UACP,kBAAA;AAAA,UACA,qBAAA;AAAA,UACA,qBAAA;AAAA,UACA,yBAAA;AAAA,UACA,wBAAA;AAAA,UACA,wBAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,SAAA,EAAW,CAAC,QAAA,EAAU,CAAA,EAAG,QAAQ,CAAA,QAAA,CAAU;AAAA,OAC5C;AAAA,KACH;AAAA,EACF;AAAA,EAEO,SAAS,KAAA,EAA8B;AAC5C,IAAA,IAAI,CAAC,MAAM,cAAA,EAAgB;AACzB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,MAAA,EAAS,KAAA,CAAM,SAAS,CAAA,8BAAA,CAAgC,CAAA;AAAA,IAC1E;AAEA,IAAA,KAAA,CAAM,eAAA,CAAgB,KAAK,aAAa,CAAA;AACxC,IAAA,KAAA,CAAM,aAAA,CAAc,KAAK,aAAa,CAAA;AAEtC,IAAA,IAAW,MAAA,CAAA,kBAAA,CAAmB,IAAA,EAAM,CAAA,OAAA,EAAU,KAAA,CAAM,SAAS,CAAA,CAAA,EAAI;AAAA,MAC/D,QAAQ,IAAA,CAAK,aAAA;AAAA,MACb,gBAAgB,KAAA,CAAM,cAAA;AAAA,MACtB,kBAAyB,MAAA,CAAA,gBAAA,CAAiB,YAAA;AAAA,MAC1C,SAAA,EAAW,GAAA;AAAA,MACX,iBAAA,EAAuB,IAAA,CAAA,QAAA,CAAS,OAAA,CAAQ,CAAC;AAAA,KAC1C,CAAA;AAAA,EACH;AACF;AChOO,IAAM,oBAAA,GAAN,cAAmCA,SAAAA,CAAU;AAAA,EAClC,kBAAA;AAAA,EAEhB,WAAA,CAAY,KAAA,EAAkB,EAAA,EAAY,KAAA,EAAkC;AAC1E,IAAA,KAAA,CAAM,OAAO,EAAE,CAAA;AAEf,IAAA,MAAM;AAAA,MACJ,KAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA,GAAY,GAAA;AAAA,MACZ,iBAAA,GAAwBC,IAAA,CAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA;AAAA,MAC1C,mBAA0BC,MAAA,CAAA,gBAAA,CAAiB,YAAA;AAAA,MAC3C,qBAAA,GAAwB,CAAA;AAAA,MACxB,YAAA,GAAmBD,IAAA,CAAA,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA;AAAA,MAClC,aAAA,GAAgB,CAAA;AAAA,MAChB;AAAA,KACF,GAAI,KAAA;AAEJ,IAAA,IAAI,CAAC,MAAM,cAAA,EAAgB;AACzB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,MAAA,EAAS,MAAM,SAAS,CAAA,yGAAA;AAAA,OAE1B;AAAA,IACF;AAGA,IAAA,KAAA,CAAM,gBAAgB,MAAM,CAAA;AAG5B,IAAA,IAAA,CAAK,qBAAqB,IAAWC,MAAA,CAAA,kBAAA;AAAA,MACnC,IAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA,QACE,MAAA;AAAA,QACA,gBAAgB,KAAA,CAAM,cAAA;AAAA,QACtB,gBAAA;AAAA,QACA,SAAA;AAAA,QACA,iBAAA;AAAA,QACA,qBAAA;AAAA,QACA,YAAA;AAAA,QACA,aAAA;AAAA,QACA,kBAAA,EAAoB,IAAA;AAAA,QACpB,uBAAA,EAAyB,IAAA;AAAA,QACzB;AAAA;AACF,KACF;AAAA,EACF;AACF;AAKO,SAAS,mBAAmB,OAAA,EAUP;AAC1B,EAAA,MAAM,UAAqC,EAAC;AAE5C,EAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,WAAW,OAAA,CAAQ;AAAA,KACpB,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,IAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,OAAA,CAAQ,QAAQ,CAAA;AAAA,EAClC;AAEA,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,OAAO,CAAQA,MAAA,CAAA,cAAA,CAAe,MAAA,CAAO,EAAE,OAAA,EAAS,CAAC,CAAA;AACnD","file":"infra.js","sourcesContent":["/**\n * Entry point code generator for the reactive Lambda handlers.\n *\n * No user code is imported - the handlers use only environment variables\n * and stored query metadata for all operations.\n */\n\n/**\n * Generate the entry point code for Lambda functions.\n * This is called by the CDK construct to create the bundled entry file.\n */\nexport function generateEntryPointCode(): string {\n return `// Auto-generated entry point for reactive Lambda handlers\n// No user code required - all configuration comes from environment variables\nimport { createLambdaHandlers } from 'dynamodb-reactive/server';\n\nconst handlers = createLambdaHandlers();\n\nexport const connectHandler = handlers.connectHandler;\nexport const disconnectHandler = handlers.disconnectHandler;\nexport const messageHandler = handlers.messageHandler;\nexport const streamHandler = handlers.streamHandler;\n`;\n}\n","import { SystemTableNames } from '@dynamodb-reactive/core';\nimport * as cdk from 'aws-cdk-lib';\nimport * as dynamodb from 'aws-cdk-lib/aws-dynamodb';\nimport { Construct } from 'constructs';\n\n/**\n * Provisioning mode for DynamoDB tables\n * - \"ON_DEMAND\": Pay-per-request billing (default)\n * - { readWrite: number }: Provisioned capacity with specified RCU/WCU\n */\nexport type ProvisioningMode = 'ON_DEMAND' | { readWrite: number };\n\n/**\n * Props for ReactiveSystemTables\n */\nexport interface ReactiveSystemTablesProps {\n /**\n * Prefix for table names\n * @default - no prefix\n */\n tablePrefix?: string;\n\n /**\n * Provisioning mode for tables\n * @default \"ON_DEMAND\"\n */\n provisioningMode?: ProvisioningMode;\n}\n\n/**\n * Creates the three system tables for the reactive engine\n */\nexport class ReactiveSystemTables extends Construct {\n /**\n * ReactiveConnections table - tracks WebSocket connections\n */\n public readonly connectionsTable: dynamodb.Table;\n\n /**\n * ReactiveDependencies table - the inverted index\n */\n public readonly dependenciesTable: dynamodb.Table;\n\n /**\n * ReactiveConnectionQueries table - stores subscription state\n */\n public readonly queriesTable: dynamodb.Table;\n\n constructor(\n scope: Construct,\n id: string,\n props: ReactiveSystemTablesProps = {},\n ) {\n super(scope, id);\n\n const prefix = props.tablePrefix ? `${props.tablePrefix}-` : '';\n const provisioningMode = props.provisioningMode ?? 'ON_DEMAND';\n\n // Determine billing/capacity settings\n const isOnDemand = provisioningMode === 'ON_DEMAND';\n const capacityProps = isOnDemand\n ? { billingMode: dynamodb.BillingMode.PAY_PER_REQUEST }\n : {\n billingMode: dynamodb.BillingMode.PROVISIONED,\n readCapacity: provisioningMode.readWrite,\n writeCapacity: provisioningMode.readWrite,\n };\n\n // ReactiveConnections Table\n // Tracks active WebSocket connections and user context\n this.connectionsTable = new dynamodb.Table(this, 'ConnectionsTable', {\n tableName: `${prefix}${SystemTableNames.connections}`,\n partitionKey: {\n name: 'connectionId',\n type: dynamodb.AttributeType.STRING,\n },\n ...capacityProps,\n removalPolicy: cdk.RemovalPolicy.DESTROY,\n timeToLiveAttribute: 'ttl',\n });\n\n // ReactiveDependencies Table (The Inverted Index)\n // Maps Field#Value -> ConnectionID for O(1) lookups\n this.dependenciesTable = new dynamodb.Table(this, 'DependenciesTable', {\n tableName: `${prefix}${SystemTableNames.dependencies}`,\n partitionKey: {\n name: 'pk', // Format: \"TableName#FieldName#FieldValue\"\n type: dynamodb.AttributeType.STRING,\n },\n sortKey: {\n name: 'sk', // Format: \"ConnectionID#SubscriptionID\"\n type: dynamodb.AttributeType.STRING,\n },\n ...capacityProps,\n removalPolicy: cdk.RemovalPolicy.DESTROY,\n timeToLiveAttribute: 'ttl',\n });\n\n // Add GSI for querying by connectionId (for cleanup)\n // For provisioned mode, GSI needs its own capacity\n const gsiProps = isOnDemand\n ? {}\n : {\n readCapacity: provisioningMode.readWrite,\n writeCapacity: provisioningMode.readWrite,\n };\n\n this.dependenciesTable.addGlobalSecondaryIndex({\n indexName: 'byConnectionId',\n partitionKey: {\n name: 'connectionId',\n type: dynamodb.AttributeType.STRING,\n },\n projectionType: dynamodb.ProjectionType.KEYS_ONLY,\n ...gsiProps,\n });\n\n // ReactiveConnectionQueries Table\n // Stores subscription state for diffing\n this.queriesTable = new dynamodb.Table(this, 'QueriesTable', {\n tableName: `${prefix}${SystemTableNames.queries}`,\n partitionKey: {\n name: 'pk', // ConnectionID\n type: dynamodb.AttributeType.STRING,\n },\n sortKey: {\n name: 'sk', // SubscriptionID\n type: dynamodb.AttributeType.STRING,\n },\n ...capacityProps,\n removalPolicy: cdk.RemovalPolicy.DESTROY,\n timeToLiveAttribute: 'ttl',\n });\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { AnyDynamoTable } from '@dynamodb-reactive/core';\nimport * as cdk from 'aws-cdk-lib';\nimport * as apigatewayv2 from 'aws-cdk-lib/aws-apigatewayv2';\nimport * as apigatewayv2Integrations from 'aws-cdk-lib/aws-apigatewayv2-integrations';\nimport type * as dynamodb from 'aws-cdk-lib/aws-dynamodb';\nimport * as iam from 'aws-cdk-lib/aws-iam';\nimport * as lambda from 'aws-cdk-lib/aws-lambda';\nimport * as nodejs from 'aws-cdk-lib/aws-lambda-nodejs';\nimport * as logs from 'aws-cdk-lib/aws-logs';\nimport { Construct } from 'constructs';\n\nimport { generateEntryPointCode } from './handlers/lambda-handlers.js';\nimport {\n ReactiveSystemTables,\n type ReactiveSystemTablesProps,\n} from './tables.js';\n\n/**\n * Props for ReactiveEngine construct\n */\nexport interface ReactiveEngineProps {\n /**\n * User-defined DynamoDB tables to enable reactive updates on\n */\n tables: AnyDynamoTable[];\n\n /**\n * Prefix for all resource names\n * @default - no prefix\n */\n resourcePrefix?: string;\n\n /**\n * System tables configuration\n */\n systemTablesProps?: ReactiveSystemTablesProps;\n /**\n * Environment variables for Lambda functions\n */\n environment?: Record<string, string>;\n}\n\n/**\n * ReactiveEngine - Main CDK construct for the reactive DynamoDB system\n */\nexport class ReactiveEngine extends Construct {\n public readonly systemTables: ReactiveSystemTables;\n public readonly webSocketApi: apigatewayv2.WebSocketApi;\n public readonly webSocketStage: apigatewayv2.WebSocketStage;\n public readonly connectHandler: lambda.Function;\n public readonly disconnectHandler: lambda.Function;\n public readonly messageHandler: lambda.Function;\n public readonly streamHandler: lambda.Function;\n public readonly webSocketUrl: string;\n public readonly callbackUrl: string;\n\n constructor(scope: Construct, id: string, props: ReactiveEngineProps) {\n super(scope, id);\n\n const prefix = props.resourcePrefix ?? '';\n const memorySize = 128;\n const timeout = cdk.Duration.seconds(30);\n const logRetention = logs.RetentionDays.ONE_DAY;\n\n // Create system tables\n this.systemTables = new ReactiveSystemTables(this, 'SystemTables', {\n tablePrefix: prefix,\n ...props.systemTablesProps,\n });\n\n // Create WebSocket API\n this.webSocketApi = new apigatewayv2.WebSocketApi(this, 'WebSocketApi', {\n apiName: `${prefix}ReactiveWebSocket`,\n });\n\n this.webSocketStage = new apigatewayv2.WebSocketStage(\n this,\n 'WebSocketStage',\n {\n webSocketApi: this.webSocketApi,\n stageName: 'prod',\n autoDeploy: true,\n },\n );\n\n this.webSocketUrl = this.webSocketStage.url;\n this.callbackUrl = this.webSocketStage.callbackUrl;\n\n // Generate the entry point file (no user code required)\n // Write to cdk.out directory to avoid path resolution issues with temp directories\n const entryPointCode = generateEntryPointCode();\n const cdkOutDir = path.join(process.cwd(), 'cdk.out', '.generated');\n fs.mkdirSync(cdkOutDir, { recursive: true });\n const entryPointPath = path.join(\n cdkOutDir,\n `reactive-entry-${id}-${Date.now()}.ts`,\n );\n fs.writeFileSync(entryPointPath, entryPointCode);\n\n // Common environment variables\n const environment: Record<string, string> = {\n CONNECTIONS_TABLE: this.systemTables.connectionsTable.tableName,\n DEPENDENCIES_TABLE: this.systemTables.dependenciesTable.tableName,\n QUERIES_TABLE: this.systemTables.queriesTable.tableName,\n WEBSOCKET_ENDPOINT: this.callbackUrl,\n ...props.environment,\n LOG_LEVEL: props.environment?.LOG_LEVEL ?? 'INFO',\n };\n\n // Create handlers using NodejsFunction with the generated entry point\n this.connectHandler = new nodejs.NodejsFunction(this, 'ConnectHandler', {\n functionName: `${prefix}ReactiveConnect`,\n runtime: lambda.Runtime.NODEJS_LATEST,\n handler: 'connectHandler',\n entry: entryPointPath,\n environment,\n memorySize,\n timeout,\n logRetention,\n });\n\n this.disconnectHandler = new nodejs.NodejsFunction(\n this,\n 'DisconnectHandler',\n {\n functionName: `${prefix}ReactiveDisconnect`,\n runtime: lambda.Runtime.NODEJS_LATEST,\n handler: 'disconnectHandler',\n entry: entryPointPath,\n environment,\n memorySize,\n timeout,\n logRetention,\n },\n );\n\n this.messageHandler = new nodejs.NodejsFunction(this, 'MessageHandler', {\n functionName: `${prefix}ReactiveMessage`,\n runtime: lambda.Runtime.NODEJS_LATEST,\n handler: 'messageHandler',\n entry: entryPointPath,\n environment,\n memorySize,\n timeout,\n logRetention,\n });\n\n this.streamHandler = new nodejs.NodejsFunction(this, 'StreamHandler', {\n functionName: `${prefix}ReactiveStream`,\n runtime: lambda.Runtime.NODEJS_LATEST,\n handler: 'streamHandler',\n entry: entryPointPath,\n environment: {\n ...environment,\n USER_TABLES: props.tables.map((t) => t.tableName).join(','),\n },\n memorySize,\n timeout,\n logRetention,\n });\n\n // Grant permissions for system tables\n this.systemTables.connectionsTable.grantReadWriteData(this.connectHandler);\n this.systemTables.connectionsTable.grantReadWriteData(\n this.disconnectHandler,\n );\n this.systemTables.connectionsTable.grantReadWriteData(this.messageHandler);\n this.systemTables.connectionsTable.grantReadWriteData(this.streamHandler);\n\n this.systemTables.dependenciesTable.grantReadWriteData(this.messageHandler);\n this.systemTables.dependenciesTable.grantReadWriteData(this.streamHandler);\n\n this.systemTables.queriesTable.grantReadWriteData(this.messageHandler);\n this.systemTables.queriesTable.grantReadWriteData(this.streamHandler);\n\n // Grant WebSocket management permissions\n const managementPolicy = new iam.PolicyStatement({\n actions: ['execute-api:ManageConnections'],\n resources: [\n `arn:aws:execute-api:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:${this.webSocketApi.apiId}/${this.webSocketStage.stageName}/POST/@connections/*`,\n ],\n });\n\n this.messageHandler.addToRolePolicy(managementPolicy);\n this.streamHandler.addToRolePolicy(managementPolicy);\n\n // Set up WebSocket routes\n this.webSocketApi.addRoute('$connect', {\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'ConnectIntegration',\n this.connectHandler,\n ),\n });\n\n this.webSocketApi.addRoute('$disconnect', {\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'DisconnectIntegration',\n this.disconnectHandler,\n ),\n });\n\n this.webSocketApi.addRoute('$default', {\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'DefaultIntegration',\n this.messageHandler,\n ),\n });\n\n // Set up DynamoDB stream processing for user tables\n for (const table of props.tables) {\n this.setupStreamProcessing(table);\n }\n\n // Output the WebSocket URL\n new cdk.CfnOutput(this, 'WebSocketUrl', {\n value: this.webSocketUrl,\n description: 'WebSocket URL for reactive connections',\n });\n }\n\n private setupStreamProcessing(table: AnyDynamoTable): void {\n const tableArn = `arn:aws:dynamodb:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:table/${table.tableName}`;\n const streamArn = `${tableArn}/stream/*`;\n\n // Stream handler needs stream access\n this.streamHandler.addToRolePolicy(\n new iam.PolicyStatement({\n actions: [\n 'dynamodb:GetRecords',\n 'dynamodb:GetShardIterator',\n 'dynamodb:DescribeStream',\n 'dynamodb:ListStreams',\n ],\n resources: [streamArn],\n }),\n );\n\n // Both handlers need read access to user tables (including PartiQL for queries)\n const tableReadPolicy = new iam.PolicyStatement({\n actions: [\n 'dynamodb:Query',\n 'dynamodb:Scan',\n 'dynamodb:GetItem',\n 'dynamodb:BatchGetItem',\n 'dynamodb:PartiQLSelect',\n ],\n resources: [tableArn, `${tableArn}/index/*`],\n });\n\n this.streamHandler.addToRolePolicy(tableReadPolicy);\n this.messageHandler.addToRolePolicy(tableReadPolicy);\n\n // Message handler also needs write access for mutations\n this.messageHandler.addToRolePolicy(\n new iam.PolicyStatement({\n actions: [\n 'dynamodb:PutItem',\n 'dynamodb:UpdateItem',\n 'dynamodb:DeleteItem',\n 'dynamodb:BatchWriteItem',\n 'dynamodb:PartiQLInsert',\n 'dynamodb:PartiQLUpdate',\n 'dynamodb:PartiQLDelete',\n ],\n resources: [tableArn, `${tableArn}/index/*`],\n }),\n );\n }\n\n public addTable(table: dynamodb.ITable): void {\n if (!table.tableStreamArn) {\n throw new Error(`Table ${table.tableName} does not have streams enabled`);\n }\n\n table.grantStreamRead(this.streamHandler);\n table.grantReadData(this.streamHandler);\n\n new lambda.EventSourceMapping(this, `Stream-${table.tableName}`, {\n target: this.streamHandler,\n eventSourceArn: table.tableStreamArn,\n startingPosition: lambda.StartingPosition.TRIM_HORIZON,\n batchSize: 100,\n maxBatchingWindow: cdk.Duration.seconds(5),\n });\n }\n}\n","import * as cdk from 'aws-cdk-lib';\nimport type * as dynamodb from 'aws-cdk-lib/aws-dynamodb';\nimport * as lambda from 'aws-cdk-lib/aws-lambda';\nimport { Construct } from 'constructs';\n\n/**\n * Props for DynamoDBStreamSource\n */\nexport interface DynamoDBStreamSourceProps {\n /**\n * The DynamoDB table to create a stream source for\n */\n table: dynamodb.ITable;\n\n /**\n * The Lambda function to receive stream events\n */\n target: lambda.IFunction;\n\n /**\n * Batch size for stream processing\n * @default 100\n */\n batchSize?: number;\n\n /**\n * Maximum batching window\n * @default Duration.seconds(5)\n */\n maxBatchingWindow?: cdk.Duration;\n\n /**\n * Starting position for reading the stream\n * @default TRIM_HORIZON\n */\n startingPosition?: lambda.StartingPosition;\n\n /**\n * Enable parallel processing with multiple batches\n * @default 1\n */\n parallelizationFactor?: number;\n\n /**\n * Maximum record age to process\n * @default Duration.days(1)\n */\n maxRecordAge?: cdk.Duration;\n\n /**\n * Number of retries on failure\n * @default 3\n */\n retryAttempts?: number;\n\n /**\n * Filter patterns for the event source\n */\n filters?: lambda.FilterCriteria[];\n}\n\n/**\n * Helper construct for setting up DynamoDB stream event sources\n */\nexport class DynamoDBStreamSource extends Construct {\n public readonly eventSourceMapping: lambda.EventSourceMapping;\n\n constructor(scope: Construct, id: string, props: DynamoDBStreamSourceProps) {\n super(scope, id);\n\n const {\n table,\n target,\n batchSize = 100,\n maxBatchingWindow = cdk.Duration.seconds(5),\n startingPosition = lambda.StartingPosition.TRIM_HORIZON,\n parallelizationFactor = 1,\n maxRecordAge = cdk.Duration.days(1),\n retryAttempts = 3,\n filters,\n } = props;\n\n if (!table.tableStreamArn) {\n throw new Error(\n `Table ${table.tableName} does not have DynamoDB Streams enabled. ` +\n 'Enable streams with streamSpecification when creating the table.',\n );\n }\n\n // Grant stream read permissions\n table.grantStreamRead(target);\n\n // Create the event source mapping\n this.eventSourceMapping = new lambda.EventSourceMapping(\n this,\n 'EventSource',\n {\n target,\n eventSourceArn: table.tableStreamArn,\n startingPosition,\n batchSize,\n maxBatchingWindow,\n parallelizationFactor,\n maxRecordAge,\n retryAttempts,\n bisectBatchOnError: true,\n reportBatchItemFailures: true,\n filters,\n },\n );\n }\n}\n\n/**\n * Create a filter criteria for DynamoDB streams\n */\nexport function createStreamFilter(options: {\n /**\n * Filter by event name (INSERT, MODIFY, REMOVE)\n */\n eventName?: ('INSERT' | 'MODIFY' | 'REMOVE')[];\n\n /**\n * Custom filter patterns\n */\n patterns?: Record<string, unknown>[];\n}): lambda.FilterCriteria[] {\n const filters: Record<string, unknown>[] = [];\n\n if (options.eventName) {\n filters.push({\n eventName: options.eventName,\n });\n }\n\n if (options.patterns) {\n filters.push(...options.patterns);\n }\n\n if (filters.length === 0) {\n return [];\n }\n\n return [lambda.FilterCriteria.filter({ filters })];\n}\n"]}
|
package/dist/server.js
CHANGED
|
@@ -304,10 +304,10 @@ var require_log = __commonJS({
|
|
|
304
304
|
}
|
|
305
305
|
var debug3 = (...args) => logprocess("DEBUG", args);
|
|
306
306
|
exports$1.debug = debug3;
|
|
307
|
-
var
|
|
308
|
-
exports$1.info =
|
|
309
|
-
var
|
|
310
|
-
exports$1.warn =
|
|
307
|
+
var info3 = (...args) => logprocess("INFO", args);
|
|
308
|
+
exports$1.info = info3;
|
|
309
|
+
var warn4 = (...args) => logprocess("WARN", args);
|
|
310
|
+
exports$1.warn = warn4;
|
|
311
311
|
var trace = (...args) => {
|
|
312
312
|
args.push(printStackTrace());
|
|
313
313
|
logprocess("TRACE", args);
|
|
@@ -883,7 +883,8 @@ function extractAffectedKeys(tableName, item) {
|
|
|
883
883
|
if (fieldValue !== null && fieldValue !== void 0) {
|
|
884
884
|
keys.push(`${tableName}#${fieldName}#${String(fieldValue)}`);
|
|
885
885
|
if (typeof fieldValue === "string") {
|
|
886
|
-
|
|
886
|
+
const maxPrefixLen = Math.min(fieldValue.length, 10);
|
|
887
|
+
for (let i = 1; i <= maxPrefixLen; i++) {
|
|
887
888
|
keys.push(
|
|
888
889
|
`${tableName}#${fieldName}#prefix:${fieldValue.substring(0, i)}`
|
|
889
890
|
);
|
|
@@ -1668,6 +1669,7 @@ function createDisconnectHandler(config) {
|
|
|
1668
1669
|
}
|
|
1669
1670
|
};
|
|
1670
1671
|
}
|
|
1672
|
+
var import_log3 = __toESM(require_log());
|
|
1671
1673
|
function createLambdaHandlers() {
|
|
1672
1674
|
const connectionsTable = process.env.CONNECTIONS_TABLE ?? SystemTableNames.connections;
|
|
1673
1675
|
const dependenciesTable = process.env.DEPENDENCIES_TABLE ?? SystemTableNames.dependencies;
|
|
@@ -1697,26 +1699,54 @@ function createLambdaHandlers() {
|
|
|
1697
1699
|
Item: connectionEntry
|
|
1698
1700
|
})
|
|
1699
1701
|
);
|
|
1700
|
-
|
|
1702
|
+
(0, import_log3.info)("Connection established:", connectionId);
|
|
1701
1703
|
return { statusCode: 200, body: "Connected" };
|
|
1702
1704
|
} catch (error) {
|
|
1703
|
-
|
|
1705
|
+
(0, import_log3.error)("Error creating connection:", error);
|
|
1704
1706
|
return { statusCode: 500, body: "Failed to connect" };
|
|
1705
1707
|
}
|
|
1706
1708
|
}
|
|
1707
1709
|
async function disconnectHandler(event) {
|
|
1708
1710
|
const connectionId = event.requestContext.connectionId;
|
|
1709
1711
|
try {
|
|
1712
|
+
const subsResponse = await docClient.send(
|
|
1713
|
+
new QueryCommand({
|
|
1714
|
+
TableName: queriesTable,
|
|
1715
|
+
KeyConditionExpression: "pk = :pk",
|
|
1716
|
+
ExpressionAttributeValues: { ":pk": connectionId }
|
|
1717
|
+
})
|
|
1718
|
+
);
|
|
1719
|
+
const subscriptions = subsResponse.Items ?? [];
|
|
1720
|
+
for (const sub of subscriptions) {
|
|
1721
|
+
for (const depKey of sub.dependencies ?? []) {
|
|
1722
|
+
await docClient.send(
|
|
1723
|
+
new DeleteCommand({
|
|
1724
|
+
TableName: dependenciesTable,
|
|
1725
|
+
Key: { pk: depKey, sk: `${connectionId}#${sub.sk}` }
|
|
1726
|
+
})
|
|
1727
|
+
);
|
|
1728
|
+
}
|
|
1729
|
+
await docClient.send(
|
|
1730
|
+
new DeleteCommand({
|
|
1731
|
+
TableName: queriesTable,
|
|
1732
|
+
Key: { pk: connectionId, sk: sub.sk }
|
|
1733
|
+
})
|
|
1734
|
+
);
|
|
1735
|
+
}
|
|
1710
1736
|
await docClient.send(
|
|
1711
1737
|
new DeleteCommand({
|
|
1712
1738
|
TableName: connectionsTable,
|
|
1713
1739
|
Key: { connectionId }
|
|
1714
1740
|
})
|
|
1715
1741
|
);
|
|
1716
|
-
|
|
1742
|
+
(0, import_log3.info)(
|
|
1743
|
+
"Connection removed:",
|
|
1744
|
+
connectionId,
|
|
1745
|
+
`(${subscriptions.length} subscriptions cleaned up)`
|
|
1746
|
+
);
|
|
1717
1747
|
return { statusCode: 200, body: "Disconnected" };
|
|
1718
1748
|
} catch (error) {
|
|
1719
|
-
|
|
1749
|
+
(0, import_log3.error)("Error removing connection:", error);
|
|
1720
1750
|
return { statusCode: 500, body: "Failed to disconnect" };
|
|
1721
1751
|
}
|
|
1722
1752
|
}
|
|
@@ -1782,11 +1812,14 @@ function createLambdaHandlers() {
|
|
|
1782
1812
|
);
|
|
1783
1813
|
return { statusCode: 200, body: "OK" };
|
|
1784
1814
|
} catch (error) {
|
|
1785
|
-
|
|
1815
|
+
(0, import_log3.error)("Error handling message:", error);
|
|
1786
1816
|
return { statusCode: 500, body: "Internal server error" };
|
|
1787
1817
|
}
|
|
1788
1818
|
}
|
|
1789
1819
|
async function streamHandler(event) {
|
|
1820
|
+
(0, import_log3.info)(
|
|
1821
|
+
`[stream] Processing ${event.Records.length} records from DynamoDB stream`
|
|
1822
|
+
);
|
|
1790
1823
|
const affectedSubscriptions = /* @__PURE__ */ new Map();
|
|
1791
1824
|
for (const record of event.Records) {
|
|
1792
1825
|
if (!record.dynamodb) continue;
|
|
@@ -1820,6 +1853,7 @@ function createLambdaHandlers() {
|
|
|
1820
1853
|
}
|
|
1821
1854
|
}
|
|
1822
1855
|
}
|
|
1856
|
+
(0, import_log3.info)(`[stream] Found ${affectedSubscriptions.size} affected connections`);
|
|
1823
1857
|
const sendPromises = [];
|
|
1824
1858
|
for (const [connectionId, subscriptions] of affectedSubscriptions) {
|
|
1825
1859
|
for (const [subscriptionId] of subscriptions) {
|
|
@@ -1827,6 +1861,7 @@ function createLambdaHandlers() {
|
|
|
1827
1861
|
}
|
|
1828
1862
|
}
|
|
1829
1863
|
await Promise.allSettled(sendPromises);
|
|
1864
|
+
(0, import_log3.info)("[stream] Processing complete");
|
|
1830
1865
|
}
|
|
1831
1866
|
function extractTableName(record) {
|
|
1832
1867
|
const arn = record.eventSourceARN;
|
|
@@ -1850,7 +1885,7 @@ function createLambdaHandlers() {
|
|
|
1850
1885
|
subscriptionId: item.subscriptionId
|
|
1851
1886
|
}));
|
|
1852
1887
|
} catch (error) {
|
|
1853
|
-
|
|
1888
|
+
(0, import_log3.error)("Error finding affected subscriptions:", error);
|
|
1854
1889
|
return [];
|
|
1855
1890
|
}
|
|
1856
1891
|
}
|
|
@@ -1864,9 +1899,7 @@ function createLambdaHandlers() {
|
|
|
1864
1899
|
);
|
|
1865
1900
|
const queryState = response.Item;
|
|
1866
1901
|
if (!queryState) {
|
|
1867
|
-
|
|
1868
|
-
`Subscription not found: ${connectionId}/${subscriptionId}`
|
|
1869
|
-
);
|
|
1902
|
+
(0, import_log3.warn)(`Subscription not found: ${connectionId}/${subscriptionId}`);
|
|
1870
1903
|
return;
|
|
1871
1904
|
}
|
|
1872
1905
|
const newResult = await executeQueryFromMetadata(
|
|
@@ -1891,7 +1924,7 @@ function createLambdaHandlers() {
|
|
|
1891
1924
|
if (error instanceof GoneException) {
|
|
1892
1925
|
await cleanupConnection(connectionId);
|
|
1893
1926
|
} else {
|
|
1894
|
-
|
|
1927
|
+
(0, import_log3.error)(
|
|
1895
1928
|
`Error processing subscription ${connectionId}/${subscriptionId}:`,
|
|
1896
1929
|
error
|
|
1897
1930
|
);
|
|
@@ -1915,8 +1948,8 @@ function createLambdaHandlers() {
|
|
|
1915
1948
|
(item) => unmarshall(item)
|
|
1916
1949
|
);
|
|
1917
1950
|
} catch (error) {
|
|
1918
|
-
|
|
1919
|
-
|
|
1951
|
+
(0, import_log3.error)("Error executing query from metadata:", error);
|
|
1952
|
+
(0, import_log3.error)("Statement:", statement);
|
|
1920
1953
|
return [];
|
|
1921
1954
|
}
|
|
1922
1955
|
}
|
|
@@ -2004,11 +2037,11 @@ function createLambdaHandlers() {
|
|
|
2004
2037
|
if (error instanceof GoneException) {
|
|
2005
2038
|
throw error;
|
|
2006
2039
|
}
|
|
2007
|
-
|
|
2040
|
+
(0, import_log3.error)(`Error sending patch to ${connectionId}:`, error);
|
|
2008
2041
|
}
|
|
2009
2042
|
}
|
|
2010
2043
|
async function cleanupConnection(connectionId) {
|
|
2011
|
-
|
|
2044
|
+
(0, import_log3.info)("Cleaning up disconnected connection:", connectionId);
|
|
2012
2045
|
try {
|
|
2013
2046
|
await docClient.send(
|
|
2014
2047
|
new DeleteCommand({
|
|
@@ -2017,7 +2050,7 @@ function createLambdaHandlers() {
|
|
|
2017
2050
|
})
|
|
2018
2051
|
);
|
|
2019
2052
|
} catch (error) {
|
|
2020
|
-
|
|
2053
|
+
(0, import_log3.error)("Error cleaning up connection:", error);
|
|
2021
2054
|
}
|
|
2022
2055
|
}
|
|
2023
2056
|
return {
|