dynamodb-reactive 0.1.22 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +378 -153
  2. package/dist/client-r_tnzwqi.d.ts +224 -0
  3. package/dist/client.cjs +1023 -0
  4. package/dist/client.cjs.map +1 -0
  5. package/dist/client.d.cts +6 -0
  6. package/dist/client.d.ts +4 -70
  7. package/dist/client.js +1013 -1
  8. package/dist/client.js.map +1 -1
  9. package/dist/core.cjs +232 -0
  10. package/dist/core.cjs.map +1 -0
  11. package/dist/core.d.cts +4 -0
  12. package/dist/core.d.ts +3 -3
  13. package/dist/core.js +222 -1
  14. package/dist/core.js.map +1 -1
  15. package/dist/index.cjs +232 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.cts +157 -0
  18. package/dist/index.d.ts +103 -56
  19. package/dist/index.js +222 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/infra.cjs +623 -0
  22. package/dist/infra.cjs.map +1 -0
  23. package/dist/infra.d.cts +119 -0
  24. package/dist/infra.d.ts +50 -102
  25. package/dist/infra.js +371 -144
  26. package/dist/infra.js.map +1 -1
  27. package/dist/react.cjs +1250 -0
  28. package/dist/react.cjs.map +1 -0
  29. package/dist/react.d.cts +68 -0
  30. package/dist/react.d.ts +68 -3
  31. package/dist/react.js +1237 -1
  32. package/dist/react.js.map +1 -1
  33. package/dist/server.cjs +2351 -0
  34. package/dist/server.cjs.map +1 -0
  35. package/dist/server.d.cts +364 -0
  36. package/dist/server.d.ts +58 -313
  37. package/dist/server.js +1855 -1208
  38. package/dist/server.js.map +1 -1
  39. package/dist/{table-tN3D4Tm-.d.ts → table-BijJ73pX.d.ts} +2 -34
  40. package/dist/{types-ISMJfyIv.d.ts → types-LMLk8JVC.d.ts} +56 -30
  41. package/package.json +79 -41
  42. package/dist/chunk-2KC44Q5I.js +0 -1103
  43. package/dist/chunk-2KC44Q5I.js.map +0 -1
  44. package/dist/chunk-ZAJA4KBE.js +0 -150
  45. package/dist/chunk-ZAJA4KBE.js.map +0 -1
  46. package/dist/react-D_NLHuuO.d.ts +0 -556
package/dist/server.d.ts CHANGED
@@ -1,35 +1,22 @@
1
1
  import { z } from 'zod';
2
- import { D as DynamoTable } from './table-tN3D4Tm-.js';
3
- import { A as AnyDynamoTable, F as FieldRef, a as FilterCondition, Q as QueryMetadata, J as JsonPatch } from './types-ISMJfyIv.js';
2
+ import { A as AnyDynamoTable, a as FilterCondition } from './types-LMLk8JVC.js';
3
+ import { FieldRef, QueryMetadata, ConnectionEntry } from './core.js';
4
+ import { DynamoTable } from './core.js';
4
5
  import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
5
- import { DynamoDBStreamEvent, APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
6
+ import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
7
+ import * as aws_lambda from 'aws-lambda';
8
+ import { APIGatewayProxyEvent, APIGatewayProxyResult, DynamoDBStreamEvent } from 'aws-lambda';
9
+ import { ApiGatewayManagementApiClient } from '@aws-sdk/client-apigatewaymanagementapi';
6
10
 
7
- /**
8
- * Context type for procedures
9
- */
10
- interface ProcedureContext<TContext = unknown> {
11
- ctx: TContext & {
12
- db: DatabaseContext;
13
- };
14
- input: unknown;
15
- }
16
11
  /**
17
12
  * Database context provided to procedures
18
13
  */
19
14
  interface DatabaseContext {
20
15
  query<TTable extends AnyDynamoTable>(table: TTable): QueryBuilder<TTable>;
21
- /**
22
- * Get a single item by key
23
- * @template TItem - Optional explicit item type (defaults to TableItem<TTable>)
24
- */
25
- get<TItem = never, TTable extends AnyDynamoTable = AnyDynamoTable>(table: TTable, key: TableKeyInput<TTable>): Promise<([TItem] extends [never] ? TableItem<TTable> : TItem) | null>;
16
+ get<TTable extends AnyDynamoTable>(table: TTable, key: TableKeyInput<TTable>): Promise<TableItem<TTable> | null>;
26
17
  put<TTable extends AnyDynamoTable>(table: TTable, item: TableItem<TTable>): Promise<void>;
27
18
  delete<TTable extends AnyDynamoTable>(table: TTable, key: TableKeyInput<TTable>): Promise<void>;
28
- /**
29
- * Update an item and return the updated item
30
- * @template TItem - Optional explicit item type (defaults to TableItem<TTable>)
31
- */
32
- update<TItem = never, TTable extends AnyDynamoTable = AnyDynamoTable>(table: TTable, key: TableKeyInput<TTable>, updates: Partial<[TItem] extends [never] ? TableItem<TTable> : TItem>): Promise<[TItem] extends [never] ? TableItem<TTable> : TItem>;
19
+ update<TTable extends AnyDynamoTable>(table: TTable, key: TableKeyInput<TTable>, updates: Partial<TableItem<TTable>>): Promise<TableItem<TTable>>;
33
20
  }
34
21
  /**
35
22
  * Extract the item type from a DynamoTable
@@ -52,9 +39,8 @@ type TableKeyInput<T extends AnyDynamoTable> = T extends DynamoTable<infer TSche
52
39
  */
53
40
  interface QueryBuilder<TTable extends AnyDynamoTable> {
54
41
  filter(fn: (q: FilterBuilder<TTable>) => FilterCondition): QueryBuilder<TTable>;
55
- useIndex(indexName: keyof TableIndexes<TTable>): QueryBuilder<TTable>;
42
+ useIndex(indexName: keyof TTable['indexes'] & string): QueryBuilder<TTable>;
56
43
  take(limit: number): QueryBuilder<TTable>;
57
- startFrom(key: TableKeyInput<TTable>): QueryBuilder<TTable>;
58
44
  sortAscending(): QueryBuilder<TTable>;
59
45
  sortDescending(): QueryBuilder<TTable>;
60
46
  execute(): Promise<TableItem<TTable>[]>;
@@ -76,12 +62,6 @@ interface FilterBuilder<TTable extends AnyDynamoTable> {
76
62
  or(...conditions: FilterCondition[]): FilterCondition;
77
63
  not(condition: FilterCondition): FilterCondition;
78
64
  }
79
- /**
80
- * Extract indexes from a DynamoTable
81
- */
82
- type TableIndexes<T extends AnyDynamoTable> = T extends DynamoTable<any, any, any, infer TIndexes> ? TIndexes : T extends {
83
- indexes: infer TIndexes;
84
- } ? TIndexes : never;
85
65
  /**
86
66
  * Procedure types
87
67
  */
@@ -89,8 +69,8 @@ type ProcedureType = 'query' | 'mutation';
89
69
  /**
90
70
  * Procedure definition
91
71
  */
92
- interface ProcedureDefinition<TContext, TInput extends z.ZodTypeAny = z.ZodUndefined, TOutput = unknown> {
93
- type: ProcedureType;
72
+ interface ProcedureDefinition<TContext, TInput extends z.ZodTypeAny = z.ZodUndefined, TOutput = unknown, TType extends ProcedureType = ProcedureType> {
73
+ type: TType;
94
74
  inputSchema?: TInput;
95
75
  resolver: (opts: {
96
76
  ctx: TContext & {
@@ -103,7 +83,7 @@ interface ProcedureDefinition<TContext, TInput extends z.ZodTypeAny = z.ZodUndef
103
83
  * Any procedure definition - used for generic constraints
104
84
  * Uses 'any' for input/output to allow covariant assignment
105
85
  */
106
- type AnyProcedureDefinition<TContext> = ProcedureDefinition<TContext, any, any>;
86
+ type AnyProcedureDefinition<TContext> = ProcedureDefinition<TContext, any, any, ProcedureType>;
107
87
  /**
108
88
  * Router definition
109
89
  */
@@ -117,14 +97,13 @@ interface QueryDependency {
117
97
  tableName: string;
118
98
  fieldName: string;
119
99
  fieldValue: string;
120
- indexName?: string;
121
100
  }
122
101
  /**
123
102
  * Transform a router definition into a callable structure (for queries only)
124
103
  */
125
104
  type RouterCaller<TRouter> = {
126
105
  [K in keyof TRouter]: TRouter[K] extends ProcedureDefinition<any, // eslint-disable-line @typescript-eslint/no-explicit-any -- conditional type inference requires `any` for contravariant TContext
127
- infer TInput, infer TOutput> ? TInput extends z.ZodTypeAny ? (input: z.infer<TInput>) => Promise<TOutput> : () => Promise<TOutput> : TRouter[K] extends Record<string, unknown> ? RouterCaller<TRouter[K]> : never;
106
+ infer TInput, infer TOutput, infer TType> ? TType extends 'query' ? TInput extends z.ZodTypeAny ? (input: z.infer<TInput>) => Promise<TOutput> : () => Promise<TOutput> : never : TRouter[K] extends Record<string, unknown> ? RouterCaller<TRouter[K]> : never;
128
107
  };
129
108
  /**
130
109
  * Tracked query operation (for dependency extraction and stream processing)
@@ -133,10 +112,9 @@ interface TrackedQueryOperation {
133
112
  tableName: string;
134
113
  filters: FilterCondition[];
135
114
  indexName?: string;
136
- /** Primary key field name for the table */
137
- pkField: string;
138
- /** Sort key field name for the table (if any) */
139
- skField?: string;
115
+ /** Field names selected by useIndex, used to preserve sparse membership. */
116
+ indexPkField?: string;
117
+ indexSkField?: string;
140
118
  /** Sort field for ordering results */
141
119
  sortField?: string;
142
120
  /** Sort direction */
@@ -163,7 +141,7 @@ declare class ProcedureBuilder<TContext, TInput extends z.ZodType = z.ZodUndefin
163
141
  db: DatabaseContext;
164
142
  };
165
143
  input: z.infer<TInput>;
166
- }) => Promise<TOutput> | TOutput): ProcedureDefinition<TContext, TInput, TOutput>;
144
+ }) => Promise<TOutput> | TOutput): ProcedureDefinition<TContext, TInput, TOutput, 'query'>;
167
145
  /**
168
146
  * Define a mutation procedure (write operation)
169
147
  */
@@ -172,18 +150,8 @@ declare class ProcedureBuilder<TContext, TInput extends z.ZodType = z.ZodUndefin
172
150
  db: DatabaseContext;
173
151
  };
174
152
  input: z.infer<TInput>;
175
- }) => Promise<TOutput> | TOutput): ProcedureDefinition<TContext, TInput, TOutput>;
153
+ }) => Promise<TOutput> | TOutput): ProcedureDefinition<TContext, TInput, TOutput, 'mutation'>;
176
154
  }
177
- /**
178
- * Check if a value is a procedure definition
179
- */
180
- declare function isProcedure(value: unknown): value is ProcedureDefinition<any, any, any>;
181
- /**
182
- * Execute a procedure with the given context and input
183
- */
184
- declare function executeProcedure<TContext, TInput extends z.ZodType, TOutput>(procedure: ProcedureDefinition<TContext, TInput, TOutput>, ctx: TContext & {
185
- db: DatabaseContext;
186
- }, rawInput: unknown): Promise<TOutput>;
187
155
 
188
156
  /**
189
157
  * Router class for organizing procedures
@@ -201,27 +169,7 @@ declare class Router<TContext, TRouter extends RouterDefinition<TContext>> {
201
169
  execute(path: string, ctx: TContext & {
202
170
  db: DatabaseContext;
203
171
  }, input: unknown): Promise<unknown>;
204
- /**
205
- * Get all procedure paths in the router
206
- */
207
- getProcedurePaths(): string[];
208
- /**
209
- * Check if a path is a query procedure
210
- */
211
- isQuery(path: string): boolean;
212
- /**
213
- * Check if a path is a mutation procedure
214
- */
215
- isMutation(path: string): boolean;
216
172
  }
217
- /**
218
- * Create a router from a definition
219
- */
220
- declare function createRouter<TContext, TRouter extends RouterDefinition<TContext>>(definition: TRouter): Router<TContext, TRouter>;
221
- /**
222
- * Merge multiple routers into one
223
- */
224
- declare function mergeRouters<TContext>(...routers: Router<TContext, RouterDefinition<TContext>>[]): Router<TContext, RouterDefinition<TContext>>;
225
173
 
226
174
  /**
227
175
  * ReactiveBuilder - The main builder returned by initReactive
@@ -278,29 +226,17 @@ type InferProcedureOutput<T> = T extends {
278
226
  resolver: (...args: any[]) => infer TOutput;
279
227
  } ? Awaited<TOutput> : unknown;
280
228
 
281
- /**
282
- * Extract dependencies from a tracked query operation
283
- */
284
- declare function extractDependencies(operation: TrackedQueryOperation): QueryDependency[];
285
- /**
286
- * Create a dependency key for the inverted index
287
- * Format: "TableName#FieldName#FieldValue"
288
- */
289
- declare function createDependencyKey(dependency: QueryDependency): string;
290
- /**
291
- * Parse a dependency key back into its components
292
- */
293
- declare function parseDependencyKey(key: string): QueryDependency | null;
294
- /**
295
- * Extract affected dependency keys from a DynamoDB stream record
296
- * This finds all keys that might be affected by a change
297
- */
298
- declare function extractAffectedKeys(tableName: string, item: Record<string, unknown>): string[];
299
- /**
300
- * Convert a TrackedQueryOperation to QueryMetadata for storage.
301
- * Normalizes filter operators for evaluation.
302
- */
303
- declare function operationToQueryMetadata(operation: TrackedQueryOperation): QueryMetadata;
229
+ /** An error whose status and message are safe to return to an API caller. */
230
+ declare class SafeRequestError extends Error {
231
+ readonly statusCode: number;
232
+ constructor(message: string, statusCode: number);
233
+ }
234
+ /** Generic public error for malformed procedure input; Zod details stay private. */
235
+ declare class InvalidInputError extends SafeRequestError {
236
+ constructor();
237
+ }
238
+ declare function isSafeRequestError(error: unknown): error is SafeRequestError;
239
+
304
240
  /**
305
241
  * DependencyTracker - Tracks query operations during procedure execution
306
242
  */
@@ -309,7 +245,7 @@ declare class DependencyTracker {
309
245
  /**
310
246
  * Track a query operation
311
247
  */
312
- track(operation: TrackedQueryOperation): void;
248
+ track(operation: TrackedQueryOperation, result: unknown[]): void;
313
249
  /**
314
250
  * Get all tracked operations
315
251
  */
@@ -318,27 +254,15 @@ declare class DependencyTracker {
318
254
  * Extract all dependencies from tracked operations
319
255
  */
320
256
  extractAll(): QueryDependency[];
321
- /**
322
- * Get all dependency keys for the inverted index
323
- */
324
- getDependencyKeys(): string[];
325
257
  /**
326
258
  * Get query metadata for the first tracked operation.
327
259
  * Used for storing subscription state.
328
260
  */
329
261
  getQueryMetadata(): QueryMetadata | null;
330
- /**
331
- * Get the primary key field from the first operation
332
- */
333
- getPkField(): string | null;
334
- /**
335
- * Get the sort key field from the first operation
336
- */
337
- getSkField(): string | undefined;
338
- /**
339
- * Clear tracked operations
340
- */
341
- clear(): void;
262
+ getCapturedResult(): {
263
+ reference: unknown[];
264
+ snapshot: unknown[];
265
+ } | null;
342
266
  }
343
267
 
344
268
  /**
@@ -346,6 +270,7 @@ declare class DependencyTracker {
346
270
  */
347
271
  interface DbContextConfig {
348
272
  client?: DynamoDBClient;
273
+ docClient?: DynamoDBDocumentClient;
349
274
  region?: string;
350
275
  endpoint?: string;
351
276
  }
@@ -354,109 +279,12 @@ interface DbContextConfig {
354
279
  */
355
280
  declare function createDbContext(config: DbContextConfig, dependencyTracker?: DependencyTracker): DatabaseContext;
356
281
 
357
- /**
358
- * Query execution function type
359
- */
360
- type QueryExecutor<TTable extends AnyDynamoTable> = (operation: TrackedQueryOperation, options: QueryOptions) => Promise<TableItem<TTable>[]>;
361
- /**
362
- * Query options
363
- */
364
- interface QueryOptions {
365
- limit?: number;
366
- startKey?: Record<string, unknown>;
367
- ascending: boolean;
368
- }
369
- /**
370
- * Implementation of QueryBuilder
371
- */
372
- declare class QueryBuilderImpl<TTable extends AnyDynamoTable> implements QueryBuilder<TTable> {
373
- private table;
374
- private filters;
375
- private indexName?;
376
- private limit?;
377
- private startKey?;
378
- private ascending;
379
- private executor;
380
- private operationTracker?;
381
- constructor(table: TTable, executor: QueryExecutor<TTable>, operationTracker?: (op: TrackedQueryOperation) => void);
382
- filter(fn: (q: FilterBuilder<TTable>) => FilterCondition): QueryBuilder<TTable>;
383
- useIndex(indexName: string): QueryBuilder<TTable>;
384
- take(limit: number): QueryBuilder<TTable>;
385
- startFrom(key: TableKeyInput<TTable>): QueryBuilder<TTable>;
386
- sortAscending(): QueryBuilder<TTable>;
387
- sortDescending(): QueryBuilder<TTable>;
388
- execute(): Promise<TableItem<TTable>[]>;
389
- /**
390
- * Get the current operation without executing
391
- * Used for dependency extraction
392
- */
393
- getOperation(): TrackedQueryOperation;
394
- }
395
- /**
396
- * Create a filter builder instance
397
- */
398
- declare function createFilterBuilder<TTable extends AnyDynamoTable>(): FilterBuilder<TTable>;
399
-
400
- /**
401
- * PartiQL statement with parameters
402
- */
403
- interface PartiQLStatement {
404
- statement: string;
405
- parameters: unknown[];
406
- }
407
- /**
408
- * Build a PartiQL SELECT statement from a query operation
409
- */
410
- declare function buildSelectStatement(operation: TrackedQueryOperation): PartiQLStatement;
411
- /**
412
- * Build a PartiQL INSERT statement
413
- */
414
- declare function buildInsertStatement(tableName: string, item: Record<string, unknown>): PartiQLStatement;
415
- /**
416
- * Build a PartiQL UPDATE statement
417
- */
418
- declare function buildUpdateStatement(tableName: string, key: Record<string, unknown>, updates: Record<string, unknown>): PartiQLStatement;
419
- /**
420
- * Build a PartiQL DELETE statement
421
- */
422
- declare function buildDeleteStatement(tableName: string, key: Record<string, unknown>): PartiQLStatement;
423
- /**
424
- * Build a PartiQL GET statement (for single item by key)
425
- */
426
- declare function buildGetStatement(tableName: string, key: Record<string, unknown>): PartiQLStatement;
427
-
428
- /**
429
- * Generate JSON patches between two objects
430
- * Uses RFC 6902 JSON Patch format
431
- */
432
- declare function generatePatches(oldValue: unknown, newValue: unknown): JsonPatch[];
433
- /**
434
- * Apply JSON patches to an object
435
- * Returns the patched result
436
- */
437
- declare function applyPatches<T>(document: T, patches: JsonPatch[]): T;
438
- /**
439
- * Check if there are any changes between two values
440
- */
441
- declare function hasChanges(oldValue: unknown, newValue: unknown): boolean;
442
- /**
443
- * Create a minimal patch that only includes necessary operations
444
- * Optimizes the patch by removing redundant operations
445
- */
446
- declare function optimizePatches(patches: JsonPatch[]): JsonPatch[];
447
- /**
448
- * Batch multiple patch sets into a single set
449
- */
450
- declare function batchPatches(patchSets: JsonPatch[][]): JsonPatch[];
451
-
452
- /**
453
- * Request types for the reactive handler.
454
- * All requests include connectionId from the WebSocket connection.
455
- */
456
282
  interface SubscribeRequest {
457
283
  type: 'subscribe';
458
284
  connectionId: string;
459
285
  subscriptionId: string;
286
+ generation: number;
287
+ registrationId: string;
460
288
  path: string;
461
289
  input: unknown;
462
290
  }
@@ -464,6 +292,8 @@ interface UnsubscribeRequest {
464
292
  type: 'unsubscribe';
465
293
  connectionId: string;
466
294
  subscriptionId: string;
295
+ generation: number;
296
+ registrationId: string;
467
297
  }
468
298
  interface CallRequest {
469
299
  type: 'call';
@@ -472,18 +302,12 @@ interface CallRequest {
472
302
  input: unknown;
473
303
  }
474
304
  type ReactiveRequest = SubscribeRequest | UnsubscribeRequest | CallRequest;
475
- /**
476
- * Response types for the reactive handler
477
- */
478
305
  interface SnapshotResponse {
479
306
  type: 'snapshot';
480
307
  subscriptionId: string;
481
- data: unknown;
482
- }
483
- interface PatchResponse {
484
- type: 'patch';
485
- subscriptionId: string;
486
- patches: unknown[];
308
+ generation: number;
309
+ version: number;
310
+ data: unknown[];
487
311
  }
488
312
  interface ResultResponse {
489
313
  type: 'result';
@@ -492,35 +316,27 @@ interface ResultResponse {
492
316
  interface ErrorResponse {
493
317
  type: 'error';
494
318
  message: string;
495
- /** HTTP status code (e.g., 400, 403, 404, 500) */
496
319
  code?: number;
497
320
  subscriptionId?: string;
498
321
  }
499
- type ReactiveResponse = SnapshotResponse | PatchResponse | ResultResponse | ErrorResponse;
500
- /**
501
- * Request info passed to getContext for extracting user context
502
- */
322
+ type ReactiveResponse = SnapshotResponse | ResultResponse | ErrorResponse;
503
323
  interface RequestInfo {
504
324
  connectionId: string;
505
- /** Headers from the HTTP request (for auth, user info, etc.) */
506
325
  headers?: Record<string, string>;
507
326
  }
508
- /**
509
- * Configuration for the reactive handler
510
- */
327
+ interface ConnectionAuthorization<TContext> {
328
+ context: TContext;
329
+ connection: ConnectionEntry;
330
+ requestInfo: RequestInfo;
331
+ }
511
332
  interface ReactiveHandlerConfig<TContext, TRouter extends RouterDefinition<TContext> = RouterDefinition<TContext>> {
512
333
  router: Router<TContext, TRouter>;
513
334
  dbConfig?: DbContextConfig;
514
335
  getContext: (requestInfo: RequestInfo) => Promise<TContext>;
336
+ authorizeConnection: (authorization: ConnectionAuthorization<TContext>) => boolean | Promise<boolean>;
515
337
  ttlSeconds?: number;
516
- /** Prefix for system table names (e.g., 'TodoApp' creates 'TodoApp-ReactiveConnections') */
517
- tablePrefix?: string;
338
+ tablePrefix: string;
518
339
  }
519
- /**
520
- * Create a reactive handler for Next.js API routes or other HTTP servers.
521
- * This handler is used for subscribe/call requests and stores queryMetadata
522
- * for the stream handler to use later.
523
- */
524
340
  declare function createReactiveHandler<TContext, TRouter extends RouterDefinition<TContext>>(config: ReactiveHandlerConfig<TContext, TRouter>): {
525
341
  handleRequest: (request: ReactiveRequest, headers?: Record<string, string>) => Promise<ReactiveResponse>;
526
342
  registerConnection: (connectionId: string, context?: Record<string, unknown>) => Promise<void>;
@@ -529,91 +345,20 @@ declare function createReactiveHandler<TContext, TRouter extends RouterDefinitio
529
345
  createCaller: () => RouterCaller<TRouter>;
530
346
  };
531
347
 
532
- /**
533
- * Configuration for the stream handler.
534
- * NOTE: Router is no longer required - stream processing uses stored query metadata.
535
- */
536
- interface StreamHandlerConfig {
348
+ interface LambdaHandlersConfig {
537
349
  dbConfig?: DbContextConfig;
538
- apiGatewayEndpoint: string;
350
+ apiClient?: ApiGatewayManagementApiClient;
539
351
  connectionsTableName?: string;
540
352
  dependenciesTableName?: string;
541
353
  queriesTableName?: string;
354
+ apiGatewayEndpoint?: string;
542
355
  }
543
- /**
544
- * Create a DynamoDB stream handler for AWS Lambda.
545
- * Uses stored query metadata to re-execute queries WITHOUT router code.
546
- */
547
- declare function createStreamHandler(config: StreamHandlerConfig): {
548
- handler: (event: DynamoDBStreamEvent) => Promise<void>;
549
- };
550
- /**
551
- * WebSocket connection handler for $connect
552
- */
553
- declare function createConnectHandler(config: Pick<StreamHandlerConfig, 'dbConfig' | 'connectionsTableName'>): (event: {
554
- requestContext: {
555
- connectionId: string;
556
- authorizer?: Record<string, unknown>;
557
- };
558
- }) => Promise<{
559
- statusCode: number;
560
- }>;
561
- /**
562
- * WebSocket disconnection handler for $disconnect.
563
- * Fully cleans up connection entry, subscriptions, and dependencies.
564
- */
565
- declare function createDisconnectHandler(config: Pick<StreamHandlerConfig, 'dbConfig' | 'connectionsTableName' | 'queriesTableName' | 'dependenciesTableName' | 'apiGatewayEndpoint'>): (event: {
566
- requestContext: {
567
- connectionId: string;
568
- };
569
- }) => Promise<{
570
- statusCode: number;
571
- }>;
572
-
573
- /**
574
- * Lambda handler implementations for the reactive WebSocket system.
575
- *
576
- * These handlers process WebSocket events and DynamoDB stream events
577
- * WITHOUT requiring user router code at runtime.
578
- *
579
- * Stream processing uses stored query metadata to evaluate changes
580
- * directly, rather than re-executing queries through a router.
581
- */
582
-
583
- /**
584
- * Create all Lambda handlers.
585
- * No user code required - all configuration comes from environment variables.
586
- * The stream handler uses stored query metadata (PartiQL), not router code.
587
- */
588
- declare function createLambdaHandlers(): {
356
+ declare function createLambdaHandlers(config?: LambdaHandlersConfig): {
589
357
  connectHandler: (event: APIGatewayProxyEvent) => Promise<APIGatewayProxyResult>;
590
358
  disconnectHandler: (event: APIGatewayProxyEvent) => Promise<APIGatewayProxyResult>;
591
359
  messageHandler: (event: APIGatewayProxyEvent) => Promise<APIGatewayProxyResult>;
592
- streamHandler: (event: DynamoDBStreamEvent) => Promise<void>;
360
+ streamHandler: (event: DynamoDBStreamEvent) => Promise<aws_lambda.DynamoDBBatchResponse>;
593
361
  };
594
362
 
595
- /**
596
- * Filter evaluator for evaluating FilterCondition against DynamoDB records.
597
- * Used by the stream handler to determine if a record matches a subscription's query.
598
- */
599
-
600
- /**
601
- * Evaluate a filter condition against a record.
602
- * Returns true if the record matches the filter.
603
- */
604
- declare function evaluateFilter(filter: FilterCondition, record: Record<string, unknown>): boolean;
605
- /**
606
- * Evaluate multiple filter conditions (all must match - AND logic).
607
- */
608
- declare function evaluateFilters(filters: FilterCondition[], record: Record<string, unknown>): boolean;
609
- /**
610
- * Sort records by a field.
611
- */
612
- declare function sortRecords(records: Record<string, unknown>[], sortField?: string, sortOrder?: 'asc' | 'desc'): Record<string, unknown>[];
613
- /**
614
- * Find the primary key value(s) from a record.
615
- * Used to identify records for update/removal.
616
- */
617
- declare function getRecordKey(record: Record<string, unknown>, pkField: string, skField?: string): string;
618
-
619
- export { AnyDynamoTable, type AnyProcedureDefinition, type CallRequest, type DatabaseContext, type DbContextConfig, DependencyTracker, type ErrorResponse, type FilterBuilder, FilterCondition, type InferProcedureInput, type InferProcedureOutput, type InferRouterType, type PartiQLStatement, type PatchResponse, ProcedureBuilder, type ProcedureContext, type ProcedureDefinition, type ProcedureType, type QueryBuilder, QueryBuilderImpl, type QueryDependency, type ReactiveBuilder, type ReactiveHandlerConfig, type ReactiveRequest, type ReactiveResponse, type RequestInfo, type ResultResponse, Router, type RouterDefinition, type SnapshotResponse, type StreamHandlerConfig, type SubscribeRequest, type TableItem, type TableKeyInput, type TrackedQueryOperation, type UnsubscribeRequest, applyPatches, batchPatches, buildDeleteStatement, buildGetStatement, buildInsertStatement, buildSelectStatement, buildUpdateStatement, createConnectHandler, createDbContext, createDependencyKey, createDisconnectHandler, createFilterBuilder, createLambdaHandlers, createReactiveHandler, createRouter, createStreamHandler, evaluateFilter, evaluateFilters, executeProcedure, extractAffectedKeys, extractDependencies, generatePatches, getRecordKey, hasChanges, initReactive, isProcedure, mergeRouters, operationToQueryMetadata, optimizePatches, parseDependencyKey, sortRecords };
363
+ export { AnyDynamoTable, FilterCondition, InvalidInputError, SafeRequestError, createDbContext, createLambdaHandlers, createReactiveHandler, initReactive, isSafeRequestError };
364
+ export type { AnyProcedureDefinition, CallRequest, DatabaseContext, DbContextConfig, ErrorResponse, FilterBuilder, InferProcedureInput, InferProcedureOutput, InferRouterType, LambdaHandlersConfig, ProcedureDefinition, ProcedureType, QueryBuilder, ReactiveBuilder, ReactiveHandlerConfig, ReactiveRequest, ReactiveResponse, RequestInfo, ResultResponse, RouterDefinition, SnapshotResponse, SubscribeRequest, TableItem, TableKeyInput, UnsubscribeRequest };