dynamodb-reactive 0.4.0 → 0.6.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/README.md +93 -51
- package/dist/{client-Zb67giI5.d.ts → client-BPAct-Dz.d.ts} +19 -0
- package/dist/client.cjs +68 -55
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +68 -55
- package/dist/client.js.map +1 -1
- package/dist/cloudflare.cjs +223 -36
- package/dist/cloudflare.cjs.map +1 -1
- package/dist/cloudflare.d.cts +78 -6
- package/dist/cloudflare.d.ts +78 -6
- package/dist/cloudflare.js +223 -36
- package/dist/cloudflare.js.map +1 -1
- package/dist/cluster.cjs +81 -66
- package/dist/cluster.cjs.map +1 -1
- package/dist/cluster.js +81 -66
- package/dist/cluster.js.map +1 -1
- package/dist/core.cjs +1 -3
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +1 -3
- package/dist/core.js.map +1 -1
- package/dist/hub.cjs +35 -10
- package/dist/hub.cjs.map +1 -1
- package/dist/hub.d.cts +18 -3
- package/dist/hub.d.ts +18 -3
- package/dist/hub.js +35 -10
- package/dist/hub.js.map +1 -1
- package/dist/index.cjs +1 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/infra.cjs +19 -33
- package/dist/infra.cjs.map +1 -1
- package/dist/infra.js +19 -33
- package/dist/infra.js.map +1 -1
- package/dist/react.cjs +71 -65
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +71 -65
- package/dist/react.js.map +1 -1
- package/dist/server.cjs +46 -139
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +46 -139
- package/dist/server.js.map +1 -1
- package/package.json +22 -24
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../core/src/schema.ts","../../core/src/table.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\nimport type { FilterCondition } from './types.js';\n\nexport const FilterConditionSchema: z.ZodType<FilterCondition> = z.lazy(() => {\n const comparison = z\n .object({\n type: z.literal('comparison'),\n operator: z.enum(['eq', 'ne', 'gt', 'gte', 'lt', 'lte']),\n field: z.string().min(1),\n value: z.unknown(),\n })\n .strict();\n const queryFunction = z.union([\n z\n .object({\n type: z.literal('function'),\n operator: z.literal('between'),\n field: z.string().min(1),\n value: z.unknown(),\n value2: z.unknown(),\n })\n .strict(),\n z\n .object({\n type: z.literal('function'),\n operator: z.enum(['beginsWith', 'contains']),\n field: z.string().min(1),\n value: z.unknown(),\n })\n .strict(),\n ]);\n const logical = z\n .object({\n type: z.literal('logical'),\n operator: z.enum(['and', 'or', 'not']),\n conditions: z.array(FilterConditionSchema).min(1),\n })\n .strict()\n .superRefine((condition, context) => {\n if (condition.operator === 'not' && condition.conditions.length !== 1) {\n context.addIssue({\n code: 'custom',\n path: ['conditions'],\n message: 'not requires exactly one condition',\n });\n }\n });\n return z.union([comparison, queryFunction, logical]);\n});\n\nexport const QueryMetadataSchema = z\n .object({\n planVersion: z.literal(1),\n tableName: z.string().min(1),\n indexName: z.string().min(1).optional(),\n indexPkField: z.string().min(1).optional(),\n indexSkField: z.string().min(1).optional(),\n filterConditions: z.array(FilterConditionSchema),\n sortField: z.string().min(1).optional(),\n sortOrder: z.enum(['asc', 'desc']).optional(),\n limit: z.number().int().positive().optional(),\n })\n .strict()\n .superRefine((metadata, context) => {\n if (metadata.indexName && !metadata.indexPkField) {\n context.addIssue({\n code: 'custom',\n path: ['indexPkField'],\n message: 'Index metadata requires its partition key field',\n });\n }\n if (!metadata.indexName && (metadata.indexPkField || metadata.indexSkField)) {\n context.addIssue({\n code: 'custom',\n path: ['indexName'],\n message: 'Index key fields require an index name',\n });\n }\n if (Boolean(metadata.sortField) !== Boolean(metadata.sortOrder)) {\n context.addIssue({\n code: 'custom',\n path: ['sortOrder'],\n message: 'Sort field and order must be specified together',\n });\n }\n });\n\nconst DeliveryVersionSchema = z.object({\n generation: z.number().int().nonnegative(),\n fromVersion: z.number().int().nonnegative(),\n toVersion: z.number().int().positive(),\n messageId: z.string().min(1),\n});\n\nexport const PendingDeliverySchema = z.discriminatedUnion('type', [\n DeliveryVersionSchema.extend({\n type: z.literal('patch'),\n patches: z.array(\n z.object({\n op: z.enum(['add', 'remove', 'replace', 'move', 'copy', 'test']),\n path: z.string(),\n value: z.unknown().optional(),\n from: z.string().optional(),\n }),\n ),\n }),\n DeliveryVersionSchema.extend({\n type: z.literal('resync'),\n }).strict(),\n]);\n\n/**\n * System table schemas for the reactive engine\n */\nexport const SystemSchemas = {\n /**\n * ReactiveConnectionsV2 - Tracks active WebSocket connections\n */\n connections: z.object({\n connectionId: z.string(),\n status: z.enum(['open', 'closed']),\n context: z.record(z.string(), z.unknown()).optional(),\n authorizerContext: z.record(z.string(), z.unknown()).optional(),\n requestIdentity: z.record(z.string(), z.unknown()).optional(),\n connectedAt: z.number(),\n ttl: z.number(),\n }),\n\n /**\n * ReactiveDependenciesV2 - The inverted index for O(1) lookups\n */\n dependencies: z.object({\n pk: z.string(), // Versioned encoded dependency key\n sk: z.string(), // ConnectionID#SubscriptionID\n connectionId: z.string(),\n subscriptionId: z.string(),\n tableName: z.string(),\n fieldName: z.string(),\n fieldValue: z.string(),\n generation: z.number().int().nonnegative(),\n registrationId: z.string().min(1),\n ttl: z.number(),\n }),\n\n /**\n * ReactiveConnectionQueriesV2 - Stores subscription state for diffing\n */\n queries: z.object({\n pk: z.string(), // ConnectionID\n sk: z.string(), // SubscriptionID\n connectionId: z.string(),\n subscriptionId: z.string(),\n status: z.enum(['registering', 'active', 'cancelled', 'faulted']),\n generation: z.number().int().nonnegative(),\n registrationId: z.string().min(1),\n queryMetadata: QueryMetadataSchema,\n lastResult: z.array(z.unknown()),\n dependencies: z.array(z.string()),\n version: z.number().int().nonnegative(),\n pendingDelivery: PendingDeliverySchema.optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n ttl: z.number(),\n }),\n};\n\n/** Storage/protocol generation used by all reactive system tables. */\nexport const SYSTEM_TABLE_PROTOCOL_VERSION = 2 as const;\n\n/**\n * Versioned system table names. The V2 suffix intentionally prevents state\n * written by the incompatible 0.1.x dependency protocol from being reused.\n */\nexport const SystemTableNames = {\n connections: 'ReactiveConnectionsV2',\n dependencies: 'ReactiveDependenciesV2',\n queries: 'ReactiveConnectionQueriesV2',\n} as const;\n","import type { z } from 'zod';\n\nimport type {\n DynamoTableConfig,\n FieldRef,\n IndexDefinition,\n SupportedSchema,\n} from './types.js';\n\n/**\n * Extract all field names from a schema (handles both ZodObject and ZodDiscriminatedUnion)\n */\nfunction getSchemaFields(schema: SupportedSchema): Set<string> {\n const fields = new Set<string>();\n\n // Check if it's a discriminated union by looking for 'options' property\n if ('options' in schema && Array.isArray(schema.options)) {\n // It's a discriminated union - collect fields from all options\n for (const option of schema.options) {\n if ('shape' in option && typeof option.shape === 'object') {\n for (const key of Object.keys(option.shape)) {\n fields.add(key);\n }\n }\n }\n } else if ('shape' in schema && typeof schema.shape === 'object') {\n // It's a regular ZodObject\n for (const key of Object.keys(schema.shape)) {\n fields.add(key);\n }\n }\n\n return fields;\n}\n\n/**\n * Creates field references for type-safe query building\n */\ntype FieldRefs<TSchema extends SupportedSchema> = {\n [K in keyof z.infer<TSchema>]: FieldRef<K & string, z.infer<TSchema>[K]>;\n};\n\n/**\n * DynamoTable - Defines a DynamoDB table with type-safe schema\n *\n * Supports both ZodObject and ZodDiscriminatedUnion schemas for single-table design patterns.\n *\n * @example\n * ```ts\n * // Simple schema\n * const TodoTable = new DynamoTable({\n * tableName: 'prod-todo-table',\n * schema: z.object({\n * PK: z.string(),\n * SK: z.string(),\n * text: z.string(),\n * isDone: z.boolean(),\n * }),\n * pk: 'PK',\n * sk: 'SK',\n * });\n *\n * // Discriminated union for single-table design\n * const MultiEntityTable = new DynamoTable({\n * tableName: 'prod-entities',\n * schema: z.discriminatedUnion('entityType', [\n * z.object({ PK: z.string(), SK: z.string(), entityType: z.literal('USER'), name: z.string() }),\n * z.object({ PK: z.string(), SK: z.string(), entityType: z.literal('ITEM'), title: z.string() }),\n * ]),\n * pk: 'PK',\n * sk: 'SK',\n * });\n * ```\n */\nexport class DynamoTable<\n TSchema extends SupportedSchema,\n TPk extends keyof z.infer<TSchema>,\n TSk extends keyof z.infer<TSchema> | undefined = undefined,\n TIndexes extends Record<string, IndexDefinition> = Record<\n string,\n IndexDefinition\n >,\n> {\n public readonly tableName: string;\n public readonly schema: TSchema;\n public readonly pk: TPk;\n public readonly sk: TSk;\n public readonly indexes: TIndexes;\n public readonly field: FieldRefs<TSchema>;\n\n constructor(config: DynamoTableConfig<TSchema, TPk, TSk, TIndexes>) {\n this.tableName = config.tableName;\n this.schema = config.schema;\n this.pk = config.pk;\n this.sk = config.sk as TSk;\n this.indexes = (config.indexes ?? {}) as TIndexes;\n\n // Create field references for query building\n this.field = this.createFieldRefs();\n }\n\n private createFieldRefs(): FieldRefs<TSchema> {\n const fields = getSchemaFields(this.schema);\n const refs: Record<string, FieldRef<string, unknown>> = {};\n\n for (const key of fields) {\n refs[key] = {\n fieldName: key,\n _type: undefined as unknown,\n };\n }\n\n return refs as FieldRefs<TSchema>;\n }\n\n /**\n * Validate an item against the schema\n */\n validate(item: unknown): z.infer<TSchema> {\n return this.schema.parse(item) as z.infer<TSchema>;\n }\n\n /**\n * Safely validate an item, returning a result object\n */\n safeParse(item: unknown): z.ZodSafeParseResult<z.infer<TSchema>> {\n return this.schema.safeParse(item) as z.ZodSafeParseResult<\n z.infer<TSchema>\n >;\n }\n\n /**\n * Get the list of field names in the schema\n */\n getFieldNames(): (keyof z.infer<TSchema>)[] {\n return Array.from(\n getSchemaFields(this.schema),\n ) as (keyof z.infer<TSchema>)[];\n }\n\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../core/src/schema.ts","../../core/src/table.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\nimport type { FilterCondition } from './types.js';\n\nexport const FilterConditionSchema: z.ZodType<FilterCondition> = z.lazy(() => {\n const comparison = z\n .object({\n type: z.literal('comparison'),\n operator: z.enum(['eq', 'ne', 'gt', 'gte', 'lt', 'lte']),\n field: z.string().min(1),\n value: z.unknown(),\n })\n .strict();\n const queryFunction = z.union([\n z\n .object({\n type: z.literal('function'),\n operator: z.literal('between'),\n field: z.string().min(1),\n value: z.unknown(),\n value2: z.unknown(),\n })\n .strict(),\n z\n .object({\n type: z.literal('function'),\n operator: z.enum(['beginsWith', 'contains']),\n field: z.string().min(1),\n value: z.unknown(),\n })\n .strict(),\n ]);\n const logical = z\n .object({\n type: z.literal('logical'),\n operator: z.enum(['and', 'or', 'not']),\n conditions: z.array(FilterConditionSchema).min(1),\n })\n .strict()\n .superRefine((condition, context) => {\n if (condition.operator === 'not' && condition.conditions.length !== 1) {\n context.addIssue({\n code: 'custom',\n path: ['conditions'],\n message: 'not requires exactly one condition',\n });\n }\n });\n return z.union([comparison, queryFunction, logical]);\n});\n\nexport const QueryMetadataSchema = z\n .object({\n planVersion: z.literal(1),\n tableName: z.string().min(1),\n indexName: z.string().min(1).optional(),\n indexPkField: z.string().min(1).optional(),\n indexSkField: z.string().min(1).optional(),\n filterConditions: z.array(FilterConditionSchema),\n sortField: z.string().min(1).optional(),\n sortOrder: z.enum(['asc', 'desc']).optional(),\n limit: z.number().int().positive().optional(),\n })\n .strict()\n .superRefine((metadata, context) => {\n if (metadata.indexName && !metadata.indexPkField) {\n context.addIssue({\n code: 'custom',\n path: ['indexPkField'],\n message: 'Index metadata requires its partition key field',\n });\n }\n if (!metadata.indexName && (metadata.indexPkField || metadata.indexSkField)) {\n context.addIssue({\n code: 'custom',\n path: ['indexName'],\n message: 'Index key fields require an index name',\n });\n }\n if (Boolean(metadata.sortField) !== Boolean(metadata.sortOrder)) {\n context.addIssue({\n code: 'custom',\n path: ['sortOrder'],\n message: 'Sort field and order must be specified together',\n });\n }\n });\n\nconst DeliveryVersionSchema = z.object({\n generation: z.number().int().nonnegative(),\n fromVersion: z.number().int().nonnegative(),\n toVersion: z.number().int().positive(),\n messageId: z.string().min(1),\n});\n\nexport const PendingDeliverySchema = z.discriminatedUnion('type', [\n DeliveryVersionSchema.extend({\n type: z.literal('patch'),\n patches: z.array(\n z.object({\n op: z.enum(['add', 'remove', 'replace', 'move', 'copy', 'test']),\n path: z.string(),\n value: z.unknown().optional(),\n from: z.string().optional(),\n }),\n ),\n }),\n DeliveryVersionSchema.extend({\n type: z.literal('resync'),\n }).strict(),\n]);\n\n/**\n * System table schemas for the reactive engine\n */\nexport const SystemSchemas = {\n /**\n * ReactiveConnectionsV2 - Tracks active WebSocket connections\n */\n connections: z.object({\n connectionId: z.string(),\n status: z.enum(['open', 'closed']),\n context: z.record(z.string(), z.unknown()).optional(),\n authorizerContext: z.record(z.string(), z.unknown()).optional(),\n requestIdentity: z.record(z.string(), z.unknown()).optional(),\n connectedAt: z.number(),\n ttl: z.number(),\n }),\n\n /**\n * ReactiveDependenciesV2 - The inverted index for O(1) lookups\n */\n dependencies: z.object({\n pk: z.string(), // Versioned encoded dependency key\n sk: z.string(), // ConnectionID#SubscriptionID\n connectionId: z.string(),\n subscriptionId: z.string(),\n tableName: z.string(),\n fieldName: z.string(),\n fieldValue: z.string(),\n generation: z.number().int().nonnegative(),\n registrationId: z.string().min(1),\n ttl: z.number(),\n }),\n\n /**\n * ReactiveConnectionQueriesV2 - Stores subscription state for diffing\n */\n queries: z.object({\n pk: z.string(), // ConnectionID\n sk: z.string(), // SubscriptionID\n connectionId: z.string(),\n subscriptionId: z.string(),\n status: z.enum(['registering', 'active', 'cancelled', 'faulted']),\n generation: z.number().int().nonnegative(),\n registrationId: z.string().min(1),\n queryMetadata: QueryMetadataSchema,\n lastResult: z.array(z.unknown()),\n dependencies: z.array(z.string()),\n version: z.number().int().nonnegative(),\n pendingDelivery: PendingDeliverySchema.optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n ttl: z.number(),\n }),\n};\n\n/** Storage/protocol generation used by all reactive system tables. */\nexport const SYSTEM_TABLE_PROTOCOL_VERSION = 2 as const;\n\n/**\n * Versioned system table names. The V2 suffix intentionally prevents state\n * written by the incompatible 0.1.x dependency protocol from being reused.\n */\nexport const SystemTableNames = {\n connections: 'ReactiveConnectionsV2',\n dependencies: 'ReactiveDependenciesV2',\n queries: 'ReactiveConnectionQueriesV2',\n} as const;\n","import type { z } from 'zod';\n\nimport type { DynamoTableConfig, FieldRef, IndexDefinition, SupportedSchema } from './types.js';\n\n/**\n * Extract all field names from a schema (handles both ZodObject and ZodDiscriminatedUnion)\n */\nfunction getSchemaFields(schema: SupportedSchema): Set<string> {\n const fields = new Set<string>();\n\n // Check if it's a discriminated union by looking for 'options' property\n if ('options' in schema && Array.isArray(schema.options)) {\n // It's a discriminated union - collect fields from all options\n for (const option of schema.options) {\n if ('shape' in option && typeof option.shape === 'object') {\n for (const key of Object.keys(option.shape)) {\n fields.add(key);\n }\n }\n }\n } else if ('shape' in schema && typeof schema.shape === 'object') {\n // It's a regular ZodObject\n for (const key of Object.keys(schema.shape)) {\n fields.add(key);\n }\n }\n\n return fields;\n}\n\n/**\n * Creates field references for type-safe query building\n */\ntype FieldRefs<TSchema extends SupportedSchema> = {\n [K in keyof z.infer<TSchema>]: FieldRef<K & string, z.infer<TSchema>[K]>;\n};\n\n/**\n * DynamoTable - Defines a DynamoDB table with type-safe schema\n *\n * Supports both ZodObject and ZodDiscriminatedUnion schemas for single-table design patterns.\n *\n * @example\n * ```ts\n * // Simple schema\n * const TodoTable = new DynamoTable({\n * tableName: 'prod-todo-table',\n * schema: z.object({\n * PK: z.string(),\n * SK: z.string(),\n * text: z.string(),\n * isDone: z.boolean(),\n * }),\n * pk: 'PK',\n * sk: 'SK',\n * });\n *\n * // Discriminated union for single-table design\n * const MultiEntityTable = new DynamoTable({\n * tableName: 'prod-entities',\n * schema: z.discriminatedUnion('entityType', [\n * z.object({ PK: z.string(), SK: z.string(), entityType: z.literal('USER'), name: z.string() }),\n * z.object({ PK: z.string(), SK: z.string(), entityType: z.literal('ITEM'), title: z.string() }),\n * ]),\n * pk: 'PK',\n * sk: 'SK',\n * });\n * ```\n */\nexport class DynamoTable<\n TSchema extends SupportedSchema,\n TPk extends keyof z.infer<TSchema>,\n TSk extends keyof z.infer<TSchema> | undefined = undefined,\n TIndexes extends Record<string, IndexDefinition> = Record<string, IndexDefinition>,\n> {\n public readonly tableName: string;\n public readonly schema: TSchema;\n public readonly pk: TPk;\n public readonly sk: TSk;\n public readonly indexes: TIndexes;\n public readonly field: FieldRefs<TSchema>;\n\n constructor(config: DynamoTableConfig<TSchema, TPk, TSk, TIndexes>) {\n this.tableName = config.tableName;\n this.schema = config.schema;\n this.pk = config.pk;\n this.sk = config.sk as TSk;\n this.indexes = (config.indexes ?? {}) as TIndexes;\n\n // Create field references for query building\n this.field = this.createFieldRefs();\n }\n\n private createFieldRefs(): FieldRefs<TSchema> {\n const fields = getSchemaFields(this.schema);\n const refs: Record<string, FieldRef<string, unknown>> = {};\n\n for (const key of fields) {\n refs[key] = {\n fieldName: key,\n _type: undefined as unknown,\n };\n }\n\n return refs as FieldRefs<TSchema>;\n }\n\n /**\n * Validate an item against the schema\n */\n validate(item: unknown): z.infer<TSchema> {\n return this.schema.parse(item) as z.infer<TSchema>;\n }\n\n /**\n * Safely validate an item, returning a result object\n */\n safeParse(item: unknown): z.ZodSafeParseResult<z.infer<TSchema>> {\n return this.schema.safeParse(item) as z.ZodSafeParseResult<z.infer<TSchema>>;\n }\n\n /**\n * Get the list of field names in the schema\n */\n getFieldNames(): (keyof z.infer<TSchema>)[] {\n return Array.from(getSchemaFields(this.schema)) as (keyof z.infer<TSchema>)[];\n }\n}\n"]}
|
package/dist/infra.cjs
CHANGED
|
@@ -356,15 +356,11 @@ var ReactiveEngine = class extends constructs.Construct {
|
|
|
356
356
|
this.webSocketApi = new apigatewayv2__namespace.WebSocketApi(this, "WebSocketApi", {
|
|
357
357
|
apiName: resourceName("ReactiveWebSocket")
|
|
358
358
|
});
|
|
359
|
-
this.webSocketStage = new apigatewayv2__namespace.WebSocketStage(
|
|
360
|
-
this,
|
|
361
|
-
"
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
stageName: "prod",
|
|
365
|
-
autoDeploy: true
|
|
366
|
-
}
|
|
367
|
-
);
|
|
359
|
+
this.webSocketStage = new apigatewayv2__namespace.WebSocketStage(this, "WebSocketStage", {
|
|
360
|
+
webSocketApi: this.webSocketApi,
|
|
361
|
+
stageName: "prod",
|
|
362
|
+
autoDeploy: true
|
|
363
|
+
});
|
|
368
364
|
this.webSocketUrl = this.webSocketStage.url;
|
|
369
365
|
this.callbackUrl = this.webSocketStage.callbackUrl;
|
|
370
366
|
const cdkOutDir = path__namespace.join(process.cwd(), "cdk.out", ".generated");
|
|
@@ -396,21 +392,17 @@ var ReactiveEngine = class extends constructs.Construct {
|
|
|
396
392
|
timeout,
|
|
397
393
|
logGroup: this.createLogGroup("ConnectLogGroup")
|
|
398
394
|
});
|
|
399
|
-
this.disconnectHandler = new nodejs__namespace.NodejsFunction(
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
timeout,
|
|
411
|
-
logGroup: this.createLogGroup("DisconnectLogGroup")
|
|
412
|
-
}
|
|
413
|
-
);
|
|
395
|
+
this.disconnectHandler = new nodejs__namespace.NodejsFunction(this, "DisconnectHandler", {
|
|
396
|
+
functionName: resourceName("ReactiveDisconnect"),
|
|
397
|
+
runtime: lambda__namespace.Runtime.NODEJS_24_X,
|
|
398
|
+
handler: "disconnectHandler",
|
|
399
|
+
entry: entryPointPath,
|
|
400
|
+
bundling,
|
|
401
|
+
environment,
|
|
402
|
+
memorySize,
|
|
403
|
+
timeout,
|
|
404
|
+
logGroup: this.createLogGroup("DisconnectLogGroup")
|
|
405
|
+
});
|
|
414
406
|
this.messageHandler = new nodejs__namespace.NodejsFunction(this, "MessageHandler", {
|
|
415
407
|
functionName: resourceName("ReactiveMessage"),
|
|
416
408
|
runtime: lambda__namespace.Runtime.NODEJS_24_X,
|
|
@@ -473,11 +465,7 @@ var ReactiveEngine = class extends constructs.Construct {
|
|
|
473
465
|
});
|
|
474
466
|
iam__namespace.Grant.addToPrincipal({
|
|
475
467
|
grantee: this.streamHandler,
|
|
476
|
-
actions: [
|
|
477
|
-
"dynamodb:GetItem",
|
|
478
|
-
"dynamodb:Query",
|
|
479
|
-
"dynamodb:UpdateItem"
|
|
480
|
-
],
|
|
468
|
+
actions: ["dynamodb:GetItem", "dynamodb:Query", "dynamodb:UpdateItem"],
|
|
481
469
|
resourceArns: [this.systemTables.queriesTable.tableArn]
|
|
482
470
|
});
|
|
483
471
|
const managementPolicy = new iam__namespace.PolicyStatement({
|
|
@@ -598,16 +586,14 @@ var ReactiveEngine = class extends constructs.Construct {
|
|
|
598
586
|
if (!(child instanceof dynamodb__namespace.CfnTable) && !(child instanceof dynamodb__namespace.CfnGlobalTable)) {
|
|
599
587
|
return;
|
|
600
588
|
}
|
|
601
|
-
const specification = cdk2__namespace.Stack.of(this).resolve(
|
|
602
|
-
child.streamSpecification
|
|
603
|
-
);
|
|
589
|
+
const specification = cdk2__namespace.Stack.of(this).resolve(child.streamSpecification);
|
|
604
590
|
if (!specification || cdk2__namespace.Token.isUnresolved(specification) || typeof specification !== "object" || !("streamViewType" in specification)) {
|
|
605
591
|
return;
|
|
606
592
|
}
|
|
607
593
|
const streamViewType = specification.streamViewType;
|
|
608
594
|
if (!cdk2__namespace.Token.isUnresolved(streamViewType) && streamViewType !== dynamodb__namespace.StreamViewType.NEW_AND_OLD_IMAGES) {
|
|
609
595
|
throw new Error(
|
|
610
|
-
`Table ${definition.tableName} uses stream view ${streamViewType}; NEW_AND_OLD_IMAGES is required.`
|
|
596
|
+
`Table ${definition.tableName} uses stream view ${String(streamViewType)}; NEW_AND_OLD_IMAGES is required.`
|
|
611
597
|
);
|
|
612
598
|
}
|
|
613
599
|
}
|
package/dist/infra.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../infra/src/handlers/lambda-handlers.ts","../../core/src/schema.ts","../../infra/src/tables.ts","../../infra/src/engine.ts"],"names":["z","Construct","cdk","dynamodb","cdk2","apigatewayv2","path","fs","nodejs","lambda","iam","apigatewayv2Integrations","logs","dynamodb2"],"mappings":"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","file":"infra.cjs","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 { z } from 'zod';\n\nimport type { FilterCondition } from './types.js';\n\nexport const FilterConditionSchema: z.ZodType<FilterCondition> = z.lazy(() => {\n const comparison = z\n .object({\n type: z.literal('comparison'),\n operator: z.enum(['eq', 'ne', 'gt', 'gte', 'lt', 'lte']),\n field: z.string().min(1),\n value: z.unknown(),\n })\n .strict();\n const queryFunction = z.union([\n z\n .object({\n type: z.literal('function'),\n operator: z.literal('between'),\n field: z.string().min(1),\n value: z.unknown(),\n value2: z.unknown(),\n })\n .strict(),\n z\n .object({\n type: z.literal('function'),\n operator: z.enum(['beginsWith', 'contains']),\n field: z.string().min(1),\n value: z.unknown(),\n })\n .strict(),\n ]);\n const logical = z\n .object({\n type: z.literal('logical'),\n operator: z.enum(['and', 'or', 'not']),\n conditions: z.array(FilterConditionSchema).min(1),\n })\n .strict()\n .superRefine((condition, context) => {\n if (condition.operator === 'not' && condition.conditions.length !== 1) {\n context.addIssue({\n code: 'custom',\n path: ['conditions'],\n message: 'not requires exactly one condition',\n });\n }\n });\n return z.union([comparison, queryFunction, logical]);\n});\n\nexport const QueryMetadataSchema = z\n .object({\n planVersion: z.literal(1),\n tableName: z.string().min(1),\n indexName: z.string().min(1).optional(),\n indexPkField: z.string().min(1).optional(),\n indexSkField: z.string().min(1).optional(),\n filterConditions: z.array(FilterConditionSchema),\n sortField: z.string().min(1).optional(),\n sortOrder: z.enum(['asc', 'desc']).optional(),\n limit: z.number().int().positive().optional(),\n })\n .strict()\n .superRefine((metadata, context) => {\n if (metadata.indexName && !metadata.indexPkField) {\n context.addIssue({\n code: 'custom',\n path: ['indexPkField'],\n message: 'Index metadata requires its partition key field',\n });\n }\n if (!metadata.indexName && (metadata.indexPkField || metadata.indexSkField)) {\n context.addIssue({\n code: 'custom',\n path: ['indexName'],\n message: 'Index key fields require an index name',\n });\n }\n if (Boolean(metadata.sortField) !== Boolean(metadata.sortOrder)) {\n context.addIssue({\n code: 'custom',\n path: ['sortOrder'],\n message: 'Sort field and order must be specified together',\n });\n }\n });\n\nconst DeliveryVersionSchema = z.object({\n generation: z.number().int().nonnegative(),\n fromVersion: z.number().int().nonnegative(),\n toVersion: z.number().int().positive(),\n messageId: z.string().min(1),\n});\n\nexport const PendingDeliverySchema = z.discriminatedUnion('type', [\n DeliveryVersionSchema.extend({\n type: z.literal('patch'),\n patches: z.array(\n z.object({\n op: z.enum(['add', 'remove', 'replace', 'move', 'copy', 'test']),\n path: z.string(),\n value: z.unknown().optional(),\n from: z.string().optional(),\n }),\n ),\n }),\n DeliveryVersionSchema.extend({\n type: z.literal('resync'),\n }).strict(),\n]);\n\n/**\n * System table schemas for the reactive engine\n */\nexport const SystemSchemas = {\n /**\n * ReactiveConnectionsV2 - Tracks active WebSocket connections\n */\n connections: z.object({\n connectionId: z.string(),\n status: z.enum(['open', 'closed']),\n context: z.record(z.string(), z.unknown()).optional(),\n authorizerContext: z.record(z.string(), z.unknown()).optional(),\n requestIdentity: z.record(z.string(), z.unknown()).optional(),\n connectedAt: z.number(),\n ttl: z.number(),\n }),\n\n /**\n * ReactiveDependenciesV2 - The inverted index for O(1) lookups\n */\n dependencies: z.object({\n pk: z.string(), // Versioned encoded dependency key\n sk: z.string(), // ConnectionID#SubscriptionID\n connectionId: z.string(),\n subscriptionId: z.string(),\n tableName: z.string(),\n fieldName: z.string(),\n fieldValue: z.string(),\n generation: z.number().int().nonnegative(),\n registrationId: z.string().min(1),\n ttl: z.number(),\n }),\n\n /**\n * ReactiveConnectionQueriesV2 - Stores subscription state for diffing\n */\n queries: z.object({\n pk: z.string(), // ConnectionID\n sk: z.string(), // SubscriptionID\n connectionId: z.string(),\n subscriptionId: z.string(),\n status: z.enum(['registering', 'active', 'cancelled', 'faulted']),\n generation: z.number().int().nonnegative(),\n registrationId: z.string().min(1),\n queryMetadata: QueryMetadataSchema,\n lastResult: z.array(z.unknown()),\n dependencies: z.array(z.string()),\n version: z.number().int().nonnegative(),\n pendingDelivery: PendingDeliverySchema.optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n ttl: z.number(),\n }),\n};\n\n/** Storage/protocol generation used by all reactive system tables. */\nexport const SYSTEM_TABLE_PROTOCOL_VERSION = 2 as const;\n\n/**\n * Versioned system table names. The V2 suffix intentionally prevents state\n * written by the incompatible 0.1.x dependency protocol from being reused.\n */\nexport const SystemTableNames = {\n connections: 'ReactiveConnectionsV2',\n dependencies: 'ReactiveDependenciesV2',\n queries: 'ReactiveConnectionQueriesV2',\n} as const;\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 * Nonempty, concrete prefix for the fixed physical table names.\n * Use the same value as the application's `tablePrefix`.\n */\n tablePrefix: string;\n\n /**\n * Provisioning mode for tables\n * @default \"ON_DEMAND\"\n */\n provisioningMode?: ProvisioningMode;\n\n /**\n * Policy applied when a system table is removed or replaced.\n * Set to RemovalPolicy.DESTROY only for disposable environments.\n * Retained tables have fixed names, so recreating a stack with the same\n * prefix requires importing or manually removing any retained tables first.\n * @default RemovalPolicy.RETAIN\n */\n removalPolicy?: cdk.RemovalPolicy;\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 if (\n cdk.Token.isUnresolved(props.tablePrefix) ||\n !/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(props.tablePrefix) ||\n props.tablePrefix.length > 229\n ) {\n throw new Error(\n 'ReactiveSystemTables tablePrefix must be a nonempty concrete value of at most 229 letters, numbers, hyphens, or underscores, starting with a letter or number.',\n );\n }\n\n const tableName = (name: string): string =>\n `${props.tablePrefix}-${name}`;\n const provisioningMode = props.provisioningMode ?? 'ON_DEMAND';\n const removalPolicy = props.removalPolicy ?? cdk.RemovalPolicy.RETAIN;\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: tableName(SystemTableNames.connections),\n partitionKey: {\n name: 'connectionId',\n type: dynamodb.AttributeType.STRING,\n },\n ...capacityProps,\n removalPolicy,\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: tableName(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,\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: tableName(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,\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 * 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\nconst PARTIQL_ACTIONS = [\n 'dynamodb:PartiQLInsert',\n 'dynamodb:PartiQLUpdate',\n 'dynamodb:PartiQLDelete',\n];\nconst DEFAULT_STREAM_BATCH_SIZE = 100;\nconst MAX_STREAM_BATCH_SIZE = 1_000;\n\n/** Resource limits that can be tuned for the DynamoDB stream processor. */\nexport type ReactiveStreamHandlerProps = Pick<\n nodejs.NodejsFunctionProps,\n 'memorySize' | 'timeout'\n>;\n\n/** Associates an application table definition with its deployed CDK table. */\nexport interface ReactiveTableBinding {\n readonly definition: AnyDynamoTable;\n\n /**\n * Deployed table with DynamoDB Streams configured for NEW_AND_OLD_IMAGES.\n * Imported ITable resources must supply tableStreamArn; CDK cannot expose\n * their stream view type, so callers remain responsible for that setting.\n */\n readonly table: dynamodb.ITable;\n}\n\n/** Props for ReactiveEngine construct. */\nexport interface ReactiveEngineProps {\n /** User-defined tables and their deployed CDK resources. */\n tables: readonly ReactiveTableBinding[];\n\n /**\n * Authorizer applied to the WebSocket $connect route.\n * WebSocketIamAuthorizer is supported; its requestContext.identity is\n * persisted with the connection. Lambda authorizer context is also persisted.\n * Authorizers whose bind result uses NONE authorization are rejected.\n */\n connectAuthorizer?: apigatewayv2.IWebSocketRouteAuthorizer;\n\n /**\n * Explicitly permit unauthenticated WebSocket connections.\n * Cannot be combined with connectAuthorizer.\n * @default false\n */\n allowUnauthenticatedConnections?: boolean;\n\n /**\n * Nonempty, concrete prefix for physical resource names. Pass this same value\n * as the server application's `tablePrefix`.\n */\n resourcePrefix: string;\n\n /** System tables configuration. */\n systemTablesProps?: Omit<ReactiveSystemTablesProps, 'tablePrefix'>;\n\n /** Environment variables for Lambda functions. */\n environment?: Record<string, string>;\n\n /** Memory and timeout overrides for the DynamoDB stream processor. */\n streamHandlerProps?: ReactiveStreamHandlerProps;\n\n /** Number of DynamoDB stream records delivered in one invocation. @default 100 */\n streamBatchSize?: number;\n}\n\n/** Main CDK construct for the reactive DynamoDB system. */\nexport class ReactiveEngine extends Construct {\n public readonly tables: readonly ReactiveTableBinding[];\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 if (\n cdk.Token.isUnresolved(props.resourcePrefix) ||\n !/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(props.resourcePrefix) ||\n props.resourcePrefix.length > 45\n ) {\n throw new Error(\n 'ReactiveEngine resourcePrefix must be a nonempty concrete value of at most 45 letters, numbers, hyphens, or underscores, starting with a letter or number.',\n );\n }\n\n if (props.connectAuthorizer && props.allowUnauthenticatedConnections) {\n throw new Error(\n 'Specify either connectAuthorizer or allowUnauthenticatedConnections, not both.',\n );\n }\n if (\n props.connectAuthorizer instanceof apigatewayv2.WebSocketNoneAuthorizer\n ) {\n throw new Error(\n 'WebSocketNoneAuthorizer does not authenticate connections. Set allowUnauthenticatedConnections to true instead.',\n );\n }\n if (!props.connectAuthorizer && !props.allowUnauthenticatedConnections) {\n throw new Error(\n 'WebSocket authentication is required. Provide connectAuthorizer or explicitly set allowUnauthenticatedConnections to true.',\n );\n }\n if (\n props.streamBatchSize !== undefined &&\n (!Number.isInteger(props.streamBatchSize) ||\n props.streamBatchSize < 1 ||\n props.streamBatchSize > MAX_STREAM_BATCH_SIZE)\n ) {\n throw new Error(\n `ReactiveEngine streamBatchSize must be an integer from 1 to ${MAX_STREAM_BATCH_SIZE}.`,\n );\n }\n\n for (const binding of props.tables) {\n this.validateTableName(binding);\n this.validateStream(binding);\n }\n this.tables = [...props.tables];\n\n const resourceName = (name: string): string =>\n `${props.resourcePrefix}-${name}`;\n const memorySize = 128;\n const timeout = cdk.Duration.seconds(30);\n\n this.systemTables = new ReactiveSystemTables(this, 'SystemTables', {\n ...props.systemTablesProps,\n tablePrefix: props.resourcePrefix,\n });\n\n this.webSocketApi = new apigatewayv2.WebSocketApi(this, 'WebSocketApi', {\n apiName: resourceName('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 // Every engine uses the same generated source, so its path and asset are stable.\n const cdkOutDir = path.join(process.cwd(), 'cdk.out', '.generated');\n fs.mkdirSync(cdkOutDir, { recursive: true });\n const entryPointPath = path.join(cdkOutDir, 'reactive-entry.ts');\n fs.writeFileSync(entryPointPath, generateEntryPointCode());\n\n const environment: Record<string, string> = {\n ...props.environment,\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 LOG_LEVEL: props.environment?.LOG_LEVEL ?? 'INFO',\n };\n const bundling: nodejs.BundlingOptions = {\n format: nodejs.OutputFormat.CJS,\n minify: true,\n sourceMap: false,\n target: 'node24',\n };\n\n this.connectHandler = new nodejs.NodejsFunction(this, 'ConnectHandler', {\n functionName: resourceName('ReactiveConnect'),\n runtime: lambda.Runtime.NODEJS_24_X,\n handler: 'connectHandler',\n entry: entryPointPath,\n bundling,\n environment,\n memorySize,\n timeout,\n logGroup: this.createLogGroup('ConnectLogGroup'),\n });\n\n this.disconnectHandler = new nodejs.NodejsFunction(\n this,\n 'DisconnectHandler',\n {\n functionName: resourceName('ReactiveDisconnect'),\n runtime: lambda.Runtime.NODEJS_24_X,\n handler: 'disconnectHandler',\n entry: entryPointPath,\n bundling,\n environment,\n memorySize,\n timeout,\n logGroup: this.createLogGroup('DisconnectLogGroup'),\n },\n );\n\n this.messageHandler = new nodejs.NodejsFunction(this, 'MessageHandler', {\n functionName: resourceName('ReactiveMessage'),\n runtime: lambda.Runtime.NODEJS_24_X,\n handler: 'messageHandler',\n entry: entryPointPath,\n bundling,\n environment,\n memorySize,\n timeout,\n logGroup: this.createLogGroup('MessageLogGroup'),\n });\n\n this.streamHandler = new nodejs.NodejsFunction(this, 'StreamHandler', {\n functionName: resourceName('ReactiveStream'),\n runtime: lambda.Runtime.NODEJS_24_X,\n handler: 'streamHandler',\n entry: entryPointPath,\n bundling,\n environment: {\n ...environment,\n USER_TABLES: props.tables\n .map(({ definition }) => definition.tableName)\n .join(','),\n },\n memorySize: props.streamHandlerProps?.memorySize ?? memorySize,\n timeout: props.streamHandlerProps?.timeout ?? timeout,\n logGroup: this.createLogGroup('StreamLogGroup'),\n });\n\n iam.Grant.addToPrincipal({\n grantee: this.connectHandler,\n actions: ['dynamodb:PutItem'],\n resourceArns: [this.systemTables.connectionsTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.disconnectHandler,\n actions: ['dynamodb:UpdateItem'],\n resourceArns: [this.systemTables.connectionsTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.disconnectHandler,\n actions: ['dynamodb:Query', 'dynamodb:UpdateItem'],\n resourceArns: [this.systemTables.queriesTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.disconnectHandler,\n actions: ['dynamodb:DeleteItem'],\n resourceArns: [this.systemTables.dependenciesTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.messageHandler,\n actions: ['dynamodb:UpdateItem'],\n resourceArns: [this.systemTables.connectionsTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.streamHandler,\n actions: ['dynamodb:UpdateItem'],\n resourceArns: [this.systemTables.connectionsTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.streamHandler,\n actions: ['dynamodb:Query', 'dynamodb:DeleteItem'],\n resourceArns: [this.systemTables.dependenciesTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.streamHandler,\n actions: [\n 'dynamodb:GetItem',\n 'dynamodb:Query',\n 'dynamodb:UpdateItem',\n ],\n resourceArns: [this.systemTables.queriesTable.tableArn],\n });\n\n const managementPolicy = new iam.PolicyStatement({\n actions: ['execute-api:ManageConnections'],\n resources: [\n cdk.Stack.of(this).formatArn({\n service: 'execute-api',\n resource: this.webSocketApi.apiId,\n resourceName: `${this.webSocketStage.stageName}/POST/@connections/*`,\n arnFormat: cdk.ArnFormat.SLASH_RESOURCE_NAME,\n }),\n ],\n });\n this.messageHandler.addToRolePolicy(managementPolicy);\n this.streamHandler.addToRolePolicy(managementPolicy);\n\n const connectAuthorizer = props.connectAuthorizer\n ? {\n bind: (\n options: apigatewayv2.WebSocketRouteAuthorizerBindOptions,\n ): apigatewayv2.WebSocketRouteAuthorizerConfig => {\n const config = props.connectAuthorizer!.bind(options);\n if (config.authorizationType === 'NONE') {\n throw new Error(\n 'The connectAuthorizer bind result uses NONE authorization. Set allowUnauthenticatedConnections to true instead.',\n );\n }\n return config;\n },\n }\n : undefined;\n\n this.webSocketApi.addRoute('$connect', {\n authorizer: connectAuthorizer,\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'ConnectIntegration',\n this.connectHandler,\n ),\n });\n this.webSocketApi.addRoute('$disconnect', {\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'DisconnectIntegration',\n this.disconnectHandler,\n ),\n });\n this.webSocketApi.addRoute('$default', {\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'DefaultIntegration',\n this.messageHandler,\n ),\n });\n\n for (const [index, binding] of props.tables.entries()) {\n this.setupStreamProcessing(\n binding,\n index,\n props.streamBatchSize ?? DEFAULT_STREAM_BATCH_SIZE,\n );\n }\n\n new cdk.CfnOutput(this, 'WebSocketUrl', {\n value: this.webSocketUrl,\n description: 'WebSocket URL for reactive connections',\n });\n }\n\n /** Grant an external application handler access to reactive and user data. */\n public grantApplicationAccess(grantee: iam.IGrantable): void {\n this.systemTables.connectionsTable.grantReadWriteData(grantee);\n this.systemTables.dependenciesTable.grantReadWriteData(grantee);\n this.systemTables.queriesTable.grantReadWriteData(grantee);\n iam.Grant.addToPrincipal({\n grantee,\n actions: ['dynamodb:TransactWriteItems'],\n resourceArns: [\n this.systemTables.connectionsTable.tableArn,\n this.systemTables.dependenciesTable.tableArn,\n this.systemTables.queriesTable.tableArn,\n ],\n });\n\n for (const { table } of this.tables) {\n table.grantReadWriteData(grantee);\n iam.Grant.addToPrincipal({\n grantee,\n actions: ['dynamodb:PartiQLSelect'],\n resourceArns: [table.tableArn, `${table.tableArn}/index/*`],\n });\n iam.Grant.addToPrincipal({\n grantee,\n actions: PARTIQL_ACTIONS,\n resourceArns: [table.tableArn],\n });\n }\n }\n\n private setupStreamProcessing(\n binding: ReactiveTableBinding,\n index: number,\n batchSize: number,\n ): void {\n const { table } = binding;\n table.grantStreamRead(this.streamHandler);\n iam.Grant.addToPrincipal({\n grantee: this.streamHandler,\n actions: ['dynamodb:PartiQLSelect'],\n resourceArns: [table.tableArn, `${table.tableArn}/index/*`],\n });\n\n new lambda.EventSourceMapping(this, `UserTableStream${index}`, {\n target: this.streamHandler,\n eventSourceArn: table.tableStreamArn!,\n startingPosition: lambda.StartingPosition.TRIM_HORIZON,\n batchSize,\n maxBatchingWindow: cdk.Duration.seconds(5),\n bisectBatchOnError: true,\n reportBatchItemFailures: true,\n });\n }\n\n private createLogGroup(id: string): logs.LogGroup {\n return new logs.LogGroup(this, id, {\n retention: logs.RetentionDays.ONE_DAY,\n removalPolicy: cdk.RemovalPolicy.DESTROY,\n });\n }\n\n private validateStream(binding: ReactiveTableBinding): void {\n const { definition, table } = binding;\n if (!table.tableStreamArn) {\n throw new Error(\n `Table ${definition.tableName} does not have DynamoDB Streams enabled. NEW_AND_OLD_IMAGES is required.`,\n );\n }\n\n const child = table.node.defaultChild;\n if (\n !(child instanceof dynamodb.CfnTable) &&\n !(child instanceof dynamodb.CfnGlobalTable)\n ) {\n return;\n }\n\n const specification = cdk.Stack.of(this).resolve(\n child.streamSpecification,\n ) as unknown;\n if (\n !specification ||\n cdk.Token.isUnresolved(specification) ||\n typeof specification !== 'object' ||\n !('streamViewType' in specification)\n ) {\n return;\n }\n\n const streamViewType = specification.streamViewType;\n if (\n !cdk.Token.isUnresolved(streamViewType) &&\n streamViewType !== dynamodb.StreamViewType.NEW_AND_OLD_IMAGES\n ) {\n throw new Error(\n `Table ${definition.tableName} uses stream view ${streamViewType}; NEW_AND_OLD_IMAGES is required.`,\n );\n }\n }\n\n private validateTableName(binding: ReactiveTableBinding): void {\n const { definition, table } = binding;\n const child = table.node.defaultChild;\n const childTableName =\n child && typeof child === 'object' && 'tableName' in child\n ? (child as { tableName?: string }).tableName\n : undefined;\n const physicalTableName = !cdk.Token.isUnresolved(table.tableName)\n ? table.tableName\n : childTableName && !cdk.Token.isUnresolved(childTableName)\n ? childTableName\n : table.tableName;\n\n if (!physicalTableName || cdk.Token.isUnresolved(physicalTableName)) {\n throw new Error(\n `Table ${definition.tableName} has an unresolved physical table name. Set an explicit tableName equal to definition.tableName; separately bundled application code cannot coordinate CloudFormation-generated names.`,\n );\n }\n if (physicalTableName !== definition.tableName) {\n throw new Error(\n `Table binding name mismatch: definition.tableName is \"${definition.tableName}\" but the physical table name is \"${physicalTableName}\". Set an explicit matching tableName.`,\n );\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../infra/src/handlers/lambda-handlers.ts","../../core/src/schema.ts","../../infra/src/tables.ts","../../infra/src/engine.ts"],"names":["z","Construct","cdk","dynamodb","cdk2","apigatewayv2","path","fs","nodejs","lambda","iam","apigatewayv2Integrations","logs","dynamodb2"],"mappings":"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","file":"infra.cjs","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 { z } from 'zod';\n\nimport type { FilterCondition } from './types.js';\n\nexport const FilterConditionSchema: z.ZodType<FilterCondition> = z.lazy(() => {\n const comparison = z\n .object({\n type: z.literal('comparison'),\n operator: z.enum(['eq', 'ne', 'gt', 'gte', 'lt', 'lte']),\n field: z.string().min(1),\n value: z.unknown(),\n })\n .strict();\n const queryFunction = z.union([\n z\n .object({\n type: z.literal('function'),\n operator: z.literal('between'),\n field: z.string().min(1),\n value: z.unknown(),\n value2: z.unknown(),\n })\n .strict(),\n z\n .object({\n type: z.literal('function'),\n operator: z.enum(['beginsWith', 'contains']),\n field: z.string().min(1),\n value: z.unknown(),\n })\n .strict(),\n ]);\n const logical = z\n .object({\n type: z.literal('logical'),\n operator: z.enum(['and', 'or', 'not']),\n conditions: z.array(FilterConditionSchema).min(1),\n })\n .strict()\n .superRefine((condition, context) => {\n if (condition.operator === 'not' && condition.conditions.length !== 1) {\n context.addIssue({\n code: 'custom',\n path: ['conditions'],\n message: 'not requires exactly one condition',\n });\n }\n });\n return z.union([comparison, queryFunction, logical]);\n});\n\nexport const QueryMetadataSchema = z\n .object({\n planVersion: z.literal(1),\n tableName: z.string().min(1),\n indexName: z.string().min(1).optional(),\n indexPkField: z.string().min(1).optional(),\n indexSkField: z.string().min(1).optional(),\n filterConditions: z.array(FilterConditionSchema),\n sortField: z.string().min(1).optional(),\n sortOrder: z.enum(['asc', 'desc']).optional(),\n limit: z.number().int().positive().optional(),\n })\n .strict()\n .superRefine((metadata, context) => {\n if (metadata.indexName && !metadata.indexPkField) {\n context.addIssue({\n code: 'custom',\n path: ['indexPkField'],\n message: 'Index metadata requires its partition key field',\n });\n }\n if (!metadata.indexName && (metadata.indexPkField || metadata.indexSkField)) {\n context.addIssue({\n code: 'custom',\n path: ['indexName'],\n message: 'Index key fields require an index name',\n });\n }\n if (Boolean(metadata.sortField) !== Boolean(metadata.sortOrder)) {\n context.addIssue({\n code: 'custom',\n path: ['sortOrder'],\n message: 'Sort field and order must be specified together',\n });\n }\n });\n\nconst DeliveryVersionSchema = z.object({\n generation: z.number().int().nonnegative(),\n fromVersion: z.number().int().nonnegative(),\n toVersion: z.number().int().positive(),\n messageId: z.string().min(1),\n});\n\nexport const PendingDeliverySchema = z.discriminatedUnion('type', [\n DeliveryVersionSchema.extend({\n type: z.literal('patch'),\n patches: z.array(\n z.object({\n op: z.enum(['add', 'remove', 'replace', 'move', 'copy', 'test']),\n path: z.string(),\n value: z.unknown().optional(),\n from: z.string().optional(),\n }),\n ),\n }),\n DeliveryVersionSchema.extend({\n type: z.literal('resync'),\n }).strict(),\n]);\n\n/**\n * System table schemas for the reactive engine\n */\nexport const SystemSchemas = {\n /**\n * ReactiveConnectionsV2 - Tracks active WebSocket connections\n */\n connections: z.object({\n connectionId: z.string(),\n status: z.enum(['open', 'closed']),\n context: z.record(z.string(), z.unknown()).optional(),\n authorizerContext: z.record(z.string(), z.unknown()).optional(),\n requestIdentity: z.record(z.string(), z.unknown()).optional(),\n connectedAt: z.number(),\n ttl: z.number(),\n }),\n\n /**\n * ReactiveDependenciesV2 - The inverted index for O(1) lookups\n */\n dependencies: z.object({\n pk: z.string(), // Versioned encoded dependency key\n sk: z.string(), // ConnectionID#SubscriptionID\n connectionId: z.string(),\n subscriptionId: z.string(),\n tableName: z.string(),\n fieldName: z.string(),\n fieldValue: z.string(),\n generation: z.number().int().nonnegative(),\n registrationId: z.string().min(1),\n ttl: z.number(),\n }),\n\n /**\n * ReactiveConnectionQueriesV2 - Stores subscription state for diffing\n */\n queries: z.object({\n pk: z.string(), // ConnectionID\n sk: z.string(), // SubscriptionID\n connectionId: z.string(),\n subscriptionId: z.string(),\n status: z.enum(['registering', 'active', 'cancelled', 'faulted']),\n generation: z.number().int().nonnegative(),\n registrationId: z.string().min(1),\n queryMetadata: QueryMetadataSchema,\n lastResult: z.array(z.unknown()),\n dependencies: z.array(z.string()),\n version: z.number().int().nonnegative(),\n pendingDelivery: PendingDeliverySchema.optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n ttl: z.number(),\n }),\n};\n\n/** Storage/protocol generation used by all reactive system tables. */\nexport const SYSTEM_TABLE_PROTOCOL_VERSION = 2 as const;\n\n/**\n * Versioned system table names. The V2 suffix intentionally prevents state\n * written by the incompatible 0.1.x dependency protocol from being reused.\n */\nexport const SystemTableNames = {\n connections: 'ReactiveConnectionsV2',\n dependencies: 'ReactiveDependenciesV2',\n queries: 'ReactiveConnectionQueriesV2',\n} as const;\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 * Nonempty, concrete prefix for the fixed physical table names.\n * Use the same value as the application's `tablePrefix`.\n */\n tablePrefix: string;\n\n /**\n * Provisioning mode for tables\n * @default \"ON_DEMAND\"\n */\n provisioningMode?: ProvisioningMode;\n\n /**\n * Policy applied when a system table is removed or replaced.\n * Set to RemovalPolicy.DESTROY only for disposable environments.\n * Retained tables have fixed names, so recreating a stack with the same\n * prefix requires importing or manually removing any retained tables first.\n * @default RemovalPolicy.RETAIN\n */\n removalPolicy?: cdk.RemovalPolicy;\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(scope: Construct, id: string, props: ReactiveSystemTablesProps) {\n super(scope, id);\n\n if (\n cdk.Token.isUnresolved(props.tablePrefix) ||\n !/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(props.tablePrefix) ||\n props.tablePrefix.length > 229\n ) {\n throw new Error(\n 'ReactiveSystemTables tablePrefix must be a nonempty concrete value of at most 229 letters, numbers, hyphens, or underscores, starting with a letter or number.',\n );\n }\n\n const tableName = (name: string): string => `${props.tablePrefix}-${name}`;\n const provisioningMode = props.provisioningMode ?? 'ON_DEMAND';\n const removalPolicy = props.removalPolicy ?? cdk.RemovalPolicy.RETAIN;\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: tableName(SystemTableNames.connections),\n partitionKey: {\n name: 'connectionId',\n type: dynamodb.AttributeType.STRING,\n },\n ...capacityProps,\n removalPolicy,\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: tableName(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,\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: tableName(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,\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 * 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 { ReactiveSystemTables, type ReactiveSystemTablesProps } from './tables.js';\n\nconst PARTIQL_ACTIONS = [\n 'dynamodb:PartiQLInsert',\n 'dynamodb:PartiQLUpdate',\n 'dynamodb:PartiQLDelete',\n];\nconst DEFAULT_STREAM_BATCH_SIZE = 100;\nconst MAX_STREAM_BATCH_SIZE = 1_000;\n\n/** Resource limits that can be tuned for the DynamoDB stream processor. */\nexport type ReactiveStreamHandlerProps = Pick<nodejs.NodejsFunctionProps, 'memorySize' | 'timeout'>;\n\n/** Associates an application table definition with its deployed CDK table. */\nexport interface ReactiveTableBinding {\n readonly definition: AnyDynamoTable;\n\n /**\n * Deployed table with DynamoDB Streams configured for NEW_AND_OLD_IMAGES.\n * Imported ITable resources must supply tableStreamArn; CDK cannot expose\n * their stream view type, so callers remain responsible for that setting.\n */\n readonly table: dynamodb.ITable;\n}\n\n/** Props for ReactiveEngine construct. */\nexport interface ReactiveEngineProps {\n /** User-defined tables and their deployed CDK resources. */\n tables: readonly ReactiveTableBinding[];\n\n /**\n * Authorizer applied to the WebSocket $connect route.\n * WebSocketIamAuthorizer is supported; its requestContext.identity is\n * persisted with the connection. Lambda authorizer context is also persisted.\n * Authorizers whose bind result uses NONE authorization are rejected.\n */\n connectAuthorizer?: apigatewayv2.IWebSocketRouteAuthorizer;\n\n /**\n * Explicitly permit unauthenticated WebSocket connections.\n * Cannot be combined with connectAuthorizer.\n * @default false\n */\n allowUnauthenticatedConnections?: boolean;\n\n /**\n * Nonempty, concrete prefix for physical resource names. Pass this same value\n * as the server application's `tablePrefix`.\n */\n resourcePrefix: string;\n\n /** System tables configuration. */\n systemTablesProps?: Omit<ReactiveSystemTablesProps, 'tablePrefix'>;\n\n /** Environment variables for Lambda functions. */\n environment?: Record<string, string>;\n\n /** Memory and timeout overrides for the DynamoDB stream processor. */\n streamHandlerProps?: ReactiveStreamHandlerProps;\n\n /** Number of DynamoDB stream records delivered in one invocation. @default 100 */\n streamBatchSize?: number;\n}\n\n/** Main CDK construct for the reactive DynamoDB system. */\nexport class ReactiveEngine extends Construct {\n public readonly tables: readonly ReactiveTableBinding[];\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 if (\n cdk.Token.isUnresolved(props.resourcePrefix) ||\n !/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(props.resourcePrefix) ||\n props.resourcePrefix.length > 45\n ) {\n throw new Error(\n 'ReactiveEngine resourcePrefix must be a nonempty concrete value of at most 45 letters, numbers, hyphens, or underscores, starting with a letter or number.',\n );\n }\n\n if (props.connectAuthorizer && props.allowUnauthenticatedConnections) {\n throw new Error(\n 'Specify either connectAuthorizer or allowUnauthenticatedConnections, not both.',\n );\n }\n if (props.connectAuthorizer instanceof apigatewayv2.WebSocketNoneAuthorizer) {\n throw new Error(\n 'WebSocketNoneAuthorizer does not authenticate connections. Set allowUnauthenticatedConnections to true instead.',\n );\n }\n if (!props.connectAuthorizer && !props.allowUnauthenticatedConnections) {\n throw new Error(\n 'WebSocket authentication is required. Provide connectAuthorizer or explicitly set allowUnauthenticatedConnections to true.',\n );\n }\n if (\n props.streamBatchSize !== undefined &&\n (!Number.isInteger(props.streamBatchSize) ||\n props.streamBatchSize < 1 ||\n props.streamBatchSize > MAX_STREAM_BATCH_SIZE)\n ) {\n throw new Error(\n `ReactiveEngine streamBatchSize must be an integer from 1 to ${MAX_STREAM_BATCH_SIZE}.`,\n );\n }\n\n for (const binding of props.tables) {\n this.validateTableName(binding);\n this.validateStream(binding);\n }\n this.tables = [...props.tables];\n\n const resourceName = (name: string): string => `${props.resourcePrefix}-${name}`;\n const memorySize = 128;\n const timeout = cdk.Duration.seconds(30);\n\n this.systemTables = new ReactiveSystemTables(this, 'SystemTables', {\n ...props.systemTablesProps,\n tablePrefix: props.resourcePrefix,\n });\n\n this.webSocketApi = new apigatewayv2.WebSocketApi(this, 'WebSocketApi', {\n apiName: resourceName('ReactiveWebSocket'),\n });\n\n this.webSocketStage = new apigatewayv2.WebSocketStage(this, 'WebSocketStage', {\n webSocketApi: this.webSocketApi,\n stageName: 'prod',\n autoDeploy: true,\n });\n\n this.webSocketUrl = this.webSocketStage.url;\n this.callbackUrl = this.webSocketStage.callbackUrl;\n\n // Every engine uses the same generated source, so its path and asset are stable.\n const cdkOutDir = path.join(process.cwd(), 'cdk.out', '.generated');\n fs.mkdirSync(cdkOutDir, { recursive: true });\n const entryPointPath = path.join(cdkOutDir, 'reactive-entry.ts');\n fs.writeFileSync(entryPointPath, generateEntryPointCode());\n\n const environment: Record<string, string> = {\n ...props.environment,\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 LOG_LEVEL: props.environment?.LOG_LEVEL ?? 'INFO',\n };\n const bundling: nodejs.BundlingOptions = {\n format: nodejs.OutputFormat.CJS,\n minify: true,\n sourceMap: false,\n target: 'node24',\n };\n\n this.connectHandler = new nodejs.NodejsFunction(this, 'ConnectHandler', {\n functionName: resourceName('ReactiveConnect'),\n runtime: lambda.Runtime.NODEJS_24_X,\n handler: 'connectHandler',\n entry: entryPointPath,\n bundling,\n environment,\n memorySize,\n timeout,\n logGroup: this.createLogGroup('ConnectLogGroup'),\n });\n\n this.disconnectHandler = new nodejs.NodejsFunction(this, 'DisconnectHandler', {\n functionName: resourceName('ReactiveDisconnect'),\n runtime: lambda.Runtime.NODEJS_24_X,\n handler: 'disconnectHandler',\n entry: entryPointPath,\n bundling,\n environment,\n memorySize,\n timeout,\n logGroup: this.createLogGroup('DisconnectLogGroup'),\n });\n\n this.messageHandler = new nodejs.NodejsFunction(this, 'MessageHandler', {\n functionName: resourceName('ReactiveMessage'),\n runtime: lambda.Runtime.NODEJS_24_X,\n handler: 'messageHandler',\n entry: entryPointPath,\n bundling,\n environment,\n memorySize,\n timeout,\n logGroup: this.createLogGroup('MessageLogGroup'),\n });\n\n this.streamHandler = new nodejs.NodejsFunction(this, 'StreamHandler', {\n functionName: resourceName('ReactiveStream'),\n runtime: lambda.Runtime.NODEJS_24_X,\n handler: 'streamHandler',\n entry: entryPointPath,\n bundling,\n environment: {\n ...environment,\n USER_TABLES: props.tables.map(({ definition }) => definition.tableName).join(','),\n },\n memorySize: props.streamHandlerProps?.memorySize ?? memorySize,\n timeout: props.streamHandlerProps?.timeout ?? timeout,\n logGroup: this.createLogGroup('StreamLogGroup'),\n });\n\n iam.Grant.addToPrincipal({\n grantee: this.connectHandler,\n actions: ['dynamodb:PutItem'],\n resourceArns: [this.systemTables.connectionsTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.disconnectHandler,\n actions: ['dynamodb:UpdateItem'],\n resourceArns: [this.systemTables.connectionsTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.disconnectHandler,\n actions: ['dynamodb:Query', 'dynamodb:UpdateItem'],\n resourceArns: [this.systemTables.queriesTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.disconnectHandler,\n actions: ['dynamodb:DeleteItem'],\n resourceArns: [this.systemTables.dependenciesTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.messageHandler,\n actions: ['dynamodb:UpdateItem'],\n resourceArns: [this.systemTables.connectionsTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.streamHandler,\n actions: ['dynamodb:UpdateItem'],\n resourceArns: [this.systemTables.connectionsTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.streamHandler,\n actions: ['dynamodb:Query', 'dynamodb:DeleteItem'],\n resourceArns: [this.systemTables.dependenciesTable.tableArn],\n });\n iam.Grant.addToPrincipal({\n grantee: this.streamHandler,\n actions: ['dynamodb:GetItem', 'dynamodb:Query', 'dynamodb:UpdateItem'],\n resourceArns: [this.systemTables.queriesTable.tableArn],\n });\n\n const managementPolicy = new iam.PolicyStatement({\n actions: ['execute-api:ManageConnections'],\n resources: [\n cdk.Stack.of(this).formatArn({\n service: 'execute-api',\n resource: this.webSocketApi.apiId,\n resourceName: `${this.webSocketStage.stageName}/POST/@connections/*`,\n arnFormat: cdk.ArnFormat.SLASH_RESOURCE_NAME,\n }),\n ],\n });\n this.messageHandler.addToRolePolicy(managementPolicy);\n this.streamHandler.addToRolePolicy(managementPolicy);\n\n const connectAuthorizer = props.connectAuthorizer\n ? {\n bind: (\n options: apigatewayv2.WebSocketRouteAuthorizerBindOptions,\n ): apigatewayv2.WebSocketRouteAuthorizerConfig => {\n const config = props.connectAuthorizer!.bind(options);\n if (config.authorizationType === 'NONE') {\n throw new Error(\n 'The connectAuthorizer bind result uses NONE authorization. Set allowUnauthenticatedConnections to true instead.',\n );\n }\n return config;\n },\n }\n : undefined;\n\n this.webSocketApi.addRoute('$connect', {\n authorizer: connectAuthorizer,\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'ConnectIntegration',\n this.connectHandler,\n ),\n });\n this.webSocketApi.addRoute('$disconnect', {\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'DisconnectIntegration',\n this.disconnectHandler,\n ),\n });\n this.webSocketApi.addRoute('$default', {\n integration: new apigatewayv2Integrations.WebSocketLambdaIntegration(\n 'DefaultIntegration',\n this.messageHandler,\n ),\n });\n\n for (const [index, binding] of props.tables.entries()) {\n this.setupStreamProcessing(\n binding,\n index,\n props.streamBatchSize ?? DEFAULT_STREAM_BATCH_SIZE,\n );\n }\n\n new cdk.CfnOutput(this, 'WebSocketUrl', {\n value: this.webSocketUrl,\n description: 'WebSocket URL for reactive connections',\n });\n }\n\n /** Grant an external application handler access to reactive and user data. */\n public grantApplicationAccess(grantee: iam.IGrantable): void {\n this.systemTables.connectionsTable.grantReadWriteData(grantee);\n this.systemTables.dependenciesTable.grantReadWriteData(grantee);\n this.systemTables.queriesTable.grantReadWriteData(grantee);\n iam.Grant.addToPrincipal({\n grantee,\n actions: ['dynamodb:TransactWriteItems'],\n resourceArns: [\n this.systemTables.connectionsTable.tableArn,\n this.systemTables.dependenciesTable.tableArn,\n this.systemTables.queriesTable.tableArn,\n ],\n });\n\n for (const { table } of this.tables) {\n table.grantReadWriteData(grantee);\n iam.Grant.addToPrincipal({\n grantee,\n actions: ['dynamodb:PartiQLSelect'],\n resourceArns: [table.tableArn, `${table.tableArn}/index/*`],\n });\n iam.Grant.addToPrincipal({\n grantee,\n actions: PARTIQL_ACTIONS,\n resourceArns: [table.tableArn],\n });\n }\n }\n\n private setupStreamProcessing(\n binding: ReactiveTableBinding,\n index: number,\n batchSize: number,\n ): void {\n const { table } = binding;\n table.grantStreamRead(this.streamHandler);\n iam.Grant.addToPrincipal({\n grantee: this.streamHandler,\n actions: ['dynamodb:PartiQLSelect'],\n resourceArns: [table.tableArn, `${table.tableArn}/index/*`],\n });\n\n new lambda.EventSourceMapping(this, `UserTableStream${index}`, {\n target: this.streamHandler,\n eventSourceArn: table.tableStreamArn!,\n startingPosition: lambda.StartingPosition.TRIM_HORIZON,\n batchSize,\n maxBatchingWindow: cdk.Duration.seconds(5),\n bisectBatchOnError: true,\n reportBatchItemFailures: true,\n });\n }\n\n private createLogGroup(id: string): logs.LogGroup {\n return new logs.LogGroup(this, id, {\n retention: logs.RetentionDays.ONE_DAY,\n removalPolicy: cdk.RemovalPolicy.DESTROY,\n });\n }\n\n private validateStream(binding: ReactiveTableBinding): void {\n const { definition, table } = binding;\n if (!table.tableStreamArn) {\n throw new Error(\n `Table ${definition.tableName} does not have DynamoDB Streams enabled. NEW_AND_OLD_IMAGES is required.`,\n );\n }\n\n const child = table.node.defaultChild;\n if (!(child instanceof dynamodb.CfnTable) && !(child instanceof dynamodb.CfnGlobalTable)) {\n return;\n }\n\n const specification = cdk.Stack.of(this).resolve(child.streamSpecification) as unknown;\n if (\n !specification ||\n cdk.Token.isUnresolved(specification) ||\n typeof specification !== 'object' ||\n !('streamViewType' in specification)\n ) {\n return;\n }\n\n const streamViewType = specification.streamViewType;\n if (\n !cdk.Token.isUnresolved(streamViewType) &&\n streamViewType !== dynamodb.StreamViewType.NEW_AND_OLD_IMAGES\n ) {\n throw new Error(\n `Table ${definition.tableName} uses stream view ${String(streamViewType)}; NEW_AND_OLD_IMAGES is required.`,\n );\n }\n }\n\n private validateTableName(binding: ReactiveTableBinding): void {\n const { definition, table } = binding;\n const child = table.node.defaultChild;\n const childTableName =\n child && typeof child === 'object' && 'tableName' in child\n ? (child as { tableName?: string }).tableName\n : undefined;\n const physicalTableName = !cdk.Token.isUnresolved(table.tableName)\n ? table.tableName\n : childTableName && !cdk.Token.isUnresolved(childTableName)\n ? childTableName\n : table.tableName;\n\n if (!physicalTableName || cdk.Token.isUnresolved(physicalTableName)) {\n throw new Error(\n `Table ${definition.tableName} has an unresolved physical table name. Set an explicit tableName equal to definition.tableName; separately bundled application code cannot coordinate CloudFormation-generated names.`,\n );\n }\n if (physicalTableName !== definition.tableName) {\n throw new Error(\n `Table binding name mismatch: definition.tableName is \"${definition.tableName}\" but the physical table name is \"${physicalTableName}\". Set an explicit matching tableName.`,\n );\n }\n }\n}\n"]}
|
package/dist/infra.js
CHANGED
|
@@ -325,15 +325,11 @@ var ReactiveEngine = class extends Construct {
|
|
|
325
325
|
this.webSocketApi = new apigatewayv2.WebSocketApi(this, "WebSocketApi", {
|
|
326
326
|
apiName: resourceName("ReactiveWebSocket")
|
|
327
327
|
});
|
|
328
|
-
this.webSocketStage = new apigatewayv2.WebSocketStage(
|
|
329
|
-
this,
|
|
330
|
-
"
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
stageName: "prod",
|
|
334
|
-
autoDeploy: true
|
|
335
|
-
}
|
|
336
|
-
);
|
|
328
|
+
this.webSocketStage = new apigatewayv2.WebSocketStage(this, "WebSocketStage", {
|
|
329
|
+
webSocketApi: this.webSocketApi,
|
|
330
|
+
stageName: "prod",
|
|
331
|
+
autoDeploy: true
|
|
332
|
+
});
|
|
337
333
|
this.webSocketUrl = this.webSocketStage.url;
|
|
338
334
|
this.callbackUrl = this.webSocketStage.callbackUrl;
|
|
339
335
|
const cdkOutDir = path.join(process.cwd(), "cdk.out", ".generated");
|
|
@@ -365,21 +361,17 @@ var ReactiveEngine = class extends Construct {
|
|
|
365
361
|
timeout,
|
|
366
362
|
logGroup: this.createLogGroup("ConnectLogGroup")
|
|
367
363
|
});
|
|
368
|
-
this.disconnectHandler = new nodejs.NodejsFunction(
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
timeout,
|
|
380
|
-
logGroup: this.createLogGroup("DisconnectLogGroup")
|
|
381
|
-
}
|
|
382
|
-
);
|
|
364
|
+
this.disconnectHandler = new nodejs.NodejsFunction(this, "DisconnectHandler", {
|
|
365
|
+
functionName: resourceName("ReactiveDisconnect"),
|
|
366
|
+
runtime: lambda.Runtime.NODEJS_24_X,
|
|
367
|
+
handler: "disconnectHandler",
|
|
368
|
+
entry: entryPointPath,
|
|
369
|
+
bundling,
|
|
370
|
+
environment,
|
|
371
|
+
memorySize,
|
|
372
|
+
timeout,
|
|
373
|
+
logGroup: this.createLogGroup("DisconnectLogGroup")
|
|
374
|
+
});
|
|
383
375
|
this.messageHandler = new nodejs.NodejsFunction(this, "MessageHandler", {
|
|
384
376
|
functionName: resourceName("ReactiveMessage"),
|
|
385
377
|
runtime: lambda.Runtime.NODEJS_24_X,
|
|
@@ -442,11 +434,7 @@ var ReactiveEngine = class extends Construct {
|
|
|
442
434
|
});
|
|
443
435
|
iam.Grant.addToPrincipal({
|
|
444
436
|
grantee: this.streamHandler,
|
|
445
|
-
actions: [
|
|
446
|
-
"dynamodb:GetItem",
|
|
447
|
-
"dynamodb:Query",
|
|
448
|
-
"dynamodb:UpdateItem"
|
|
449
|
-
],
|
|
437
|
+
actions: ["dynamodb:GetItem", "dynamodb:Query", "dynamodb:UpdateItem"],
|
|
450
438
|
resourceArns: [this.systemTables.queriesTable.tableArn]
|
|
451
439
|
});
|
|
452
440
|
const managementPolicy = new iam.PolicyStatement({
|
|
@@ -567,16 +555,14 @@ var ReactiveEngine = class extends Construct {
|
|
|
567
555
|
if (!(child instanceof dynamodb.CfnTable) && !(child instanceof dynamodb.CfnGlobalTable)) {
|
|
568
556
|
return;
|
|
569
557
|
}
|
|
570
|
-
const specification = cdk2.Stack.of(this).resolve(
|
|
571
|
-
child.streamSpecification
|
|
572
|
-
);
|
|
558
|
+
const specification = cdk2.Stack.of(this).resolve(child.streamSpecification);
|
|
573
559
|
if (!specification || cdk2.Token.isUnresolved(specification) || typeof specification !== "object" || !("streamViewType" in specification)) {
|
|
574
560
|
return;
|
|
575
561
|
}
|
|
576
562
|
const streamViewType = specification.streamViewType;
|
|
577
563
|
if (!cdk2.Token.isUnresolved(streamViewType) && streamViewType !== dynamodb.StreamViewType.NEW_AND_OLD_IMAGES) {
|
|
578
564
|
throw new Error(
|
|
579
|
-
`Table ${definition.tableName} uses stream view ${streamViewType}; NEW_AND_OLD_IMAGES is required.`
|
|
565
|
+
`Table ${definition.tableName} uses stream view ${String(streamViewType)}; NEW_AND_OLD_IMAGES is required.`
|
|
580
566
|
);
|
|
581
567
|
}
|
|
582
568
|
}
|