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
@@ -0,0 +1,157 @@
1
+ export { D as DynamoTable } from './table-BijJ73pX.js';
2
+ import { a as FilterCondition } from './types-LMLk8JVC.js';
3
+ export { A as AnyDynamoTable, C as ConnectionEntry, b as DependencyEntry, D as DynamoTableConfig, F as FieldRef, I as IndexDefinition, J as JsonPatch, P as PendingDelivery, c as QueryEntry, Q as QueryMetadata, S as SupportedSchema } from './types-LMLk8JVC.js';
4
+ import { z } from 'zod';
5
+
6
+ declare const FilterConditionSchema: z.ZodType<FilterCondition>;
7
+ declare const QueryMetadataSchema: z.ZodObject<{
8
+ planVersion: z.ZodLiteral<1>;
9
+ tableName: z.ZodString;
10
+ indexName: z.ZodOptional<z.ZodString>;
11
+ indexPkField: z.ZodOptional<z.ZodString>;
12
+ indexSkField: z.ZodOptional<z.ZodString>;
13
+ filterConditions: z.ZodArray<z.ZodType<FilterCondition, unknown, z.core.$ZodTypeInternals<FilterCondition, unknown>>>;
14
+ sortField: z.ZodOptional<z.ZodString>;
15
+ sortOrder: z.ZodOptional<z.ZodEnum<{
16
+ asc: "asc";
17
+ desc: "desc";
18
+ }>>;
19
+ limit: z.ZodOptional<z.ZodNumber>;
20
+ }, z.core.$strict>;
21
+ declare const PendingDeliverySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
22
+ generation: z.ZodNumber;
23
+ fromVersion: z.ZodNumber;
24
+ toVersion: z.ZodNumber;
25
+ messageId: z.ZodString;
26
+ type: z.ZodLiteral<"patch">;
27
+ patches: z.ZodArray<z.ZodObject<{
28
+ op: z.ZodEnum<{
29
+ add: "add";
30
+ remove: "remove";
31
+ replace: "replace";
32
+ move: "move";
33
+ copy: "copy";
34
+ test: "test";
35
+ }>;
36
+ path: z.ZodString;
37
+ value: z.ZodOptional<z.ZodUnknown>;
38
+ from: z.ZodOptional<z.ZodString>;
39
+ }, z.core.$strip>>;
40
+ }, z.core.$strip>, z.ZodObject<{
41
+ generation: z.ZodNumber;
42
+ fromVersion: z.ZodNumber;
43
+ toVersion: z.ZodNumber;
44
+ messageId: z.ZodString;
45
+ type: z.ZodLiteral<"resync">;
46
+ }, z.core.$strict>], "type">;
47
+ /**
48
+ * System table schemas for the reactive engine
49
+ */
50
+ declare const SystemSchemas: {
51
+ /**
52
+ * ReactiveConnectionsV2 - Tracks active WebSocket connections
53
+ */
54
+ connections: z.ZodObject<{
55
+ connectionId: z.ZodString;
56
+ status: z.ZodEnum<{
57
+ open: "open";
58
+ closed: "closed";
59
+ }>;
60
+ context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
61
+ authorizerContext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
62
+ requestIdentity: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
63
+ connectedAt: z.ZodNumber;
64
+ ttl: z.ZodNumber;
65
+ }, z.core.$strip>;
66
+ /**
67
+ * ReactiveDependenciesV2 - The inverted index for O(1) lookups
68
+ */
69
+ dependencies: z.ZodObject<{
70
+ pk: z.ZodString;
71
+ sk: z.ZodString;
72
+ connectionId: z.ZodString;
73
+ subscriptionId: z.ZodString;
74
+ tableName: z.ZodString;
75
+ fieldName: z.ZodString;
76
+ fieldValue: z.ZodString;
77
+ generation: z.ZodNumber;
78
+ registrationId: z.ZodString;
79
+ ttl: z.ZodNumber;
80
+ }, z.core.$strip>;
81
+ /**
82
+ * ReactiveConnectionQueriesV2 - Stores subscription state for diffing
83
+ */
84
+ queries: z.ZodObject<{
85
+ pk: z.ZodString;
86
+ sk: z.ZodString;
87
+ connectionId: z.ZodString;
88
+ subscriptionId: z.ZodString;
89
+ status: z.ZodEnum<{
90
+ registering: "registering";
91
+ active: "active";
92
+ cancelled: "cancelled";
93
+ faulted: "faulted";
94
+ }>;
95
+ generation: z.ZodNumber;
96
+ registrationId: z.ZodString;
97
+ queryMetadata: z.ZodObject<{
98
+ planVersion: z.ZodLiteral<1>;
99
+ tableName: z.ZodString;
100
+ indexName: z.ZodOptional<z.ZodString>;
101
+ indexPkField: z.ZodOptional<z.ZodString>;
102
+ indexSkField: z.ZodOptional<z.ZodString>;
103
+ filterConditions: z.ZodArray<z.ZodType<FilterCondition, unknown, z.core.$ZodTypeInternals<FilterCondition, unknown>>>;
104
+ sortField: z.ZodOptional<z.ZodString>;
105
+ sortOrder: z.ZodOptional<z.ZodEnum<{
106
+ asc: "asc";
107
+ desc: "desc";
108
+ }>>;
109
+ limit: z.ZodOptional<z.ZodNumber>;
110
+ }, z.core.$strict>;
111
+ lastResult: z.ZodArray<z.ZodUnknown>;
112
+ dependencies: z.ZodArray<z.ZodString>;
113
+ version: z.ZodNumber;
114
+ pendingDelivery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
115
+ generation: z.ZodNumber;
116
+ fromVersion: z.ZodNumber;
117
+ toVersion: z.ZodNumber;
118
+ messageId: z.ZodString;
119
+ type: z.ZodLiteral<"patch">;
120
+ patches: z.ZodArray<z.ZodObject<{
121
+ op: z.ZodEnum<{
122
+ add: "add";
123
+ remove: "remove";
124
+ replace: "replace";
125
+ move: "move";
126
+ copy: "copy";
127
+ test: "test";
128
+ }>;
129
+ path: z.ZodString;
130
+ value: z.ZodOptional<z.ZodUnknown>;
131
+ from: z.ZodOptional<z.ZodString>;
132
+ }, z.core.$strip>>;
133
+ }, z.core.$strip>, z.ZodObject<{
134
+ generation: z.ZodNumber;
135
+ fromVersion: z.ZodNumber;
136
+ toVersion: z.ZodNumber;
137
+ messageId: z.ZodString;
138
+ type: z.ZodLiteral<"resync">;
139
+ }, z.core.$strict>], "type">>;
140
+ createdAt: z.ZodNumber;
141
+ updatedAt: z.ZodNumber;
142
+ ttl: z.ZodNumber;
143
+ }, z.core.$strip>;
144
+ };
145
+ /** Storage/protocol generation used by all reactive system tables. */
146
+ declare const SYSTEM_TABLE_PROTOCOL_VERSION: 2;
147
+ /**
148
+ * Versioned system table names. The V2 suffix intentionally prevents state
149
+ * written by the incompatible 0.1.x dependency protocol from being reused.
150
+ */
151
+ declare const SystemTableNames: {
152
+ readonly connections: "ReactiveConnectionsV2";
153
+ readonly dependencies: "ReactiveDependenciesV2";
154
+ readonly queries: "ReactiveConnectionQueriesV2";
155
+ };
156
+
157
+ export { FilterCondition, FilterConditionSchema, PendingDeliverySchema, QueryMetadataSchema, SYSTEM_TABLE_PROTOCOL_VERSION, SystemSchemas, SystemTableNames };
package/dist/index.d.ts CHANGED
@@ -1,66 +1,70 @@
1
- import { D as DynamoTable } from './table-tN3D4Tm-.js';
2
- export { I as InferSchema, T as TableFields, a as TableIndexes, b as TablePk, c as TableSk } from './table-tN3D4Tm-.js';
3
- import { S as SupportedSchema, I as IndexDefinition } from './types-ISMJfyIv.js';
4
- export { A as AnyDynamoTable, C as ConnectionEntry, b as DependencyEntry, D as DynamoTableConfig, F as FieldRef, a as FilterCondition, c as InferSupportedSchema, J as JsonPatch, d as QueryEntry, Q as QueryMetadata, e as SubscriptionMessage } from './types-ISMJfyIv.js';
1
+ export { D as DynamoTable } from './table-BijJ73pX.js';
2
+ import { a as FilterCondition } from './types-LMLk8JVC.js';
3
+ export { A as AnyDynamoTable, C as ConnectionEntry, b as DependencyEntry, D as DynamoTableConfig, F as FieldRef, I as IndexDefinition, J as JsonPatch, P as PendingDelivery, c as QueryEntry, Q as QueryMetadata, S as SupportedSchema } from './types-LMLk8JVC.js';
5
4
  import { z } from 'zod';
6
5
 
7
- /**
8
- * Helper function to define a schema with type inference
9
- * This provides a cleaner API for defining tables
10
- *
11
- * Supports both ZodObject and ZodDiscriminatedUnion schemas.
12
- *
13
- * @example
14
- * ```ts
15
- * // Simple schema
16
- * const TodoTable = defineSchema({
17
- * tableName: 'prod-todo-table',
18
- * schema: z.object({
19
- * id: z.string(),
20
- * taskListId: z.string(),
21
- * text: z.string(),
22
- * isDone: z.boolean(),
23
- * }),
24
- * pk: 'id',
25
- * indexes: {
26
- * byTaskId: { name: 'gsi_by_task_id', pk: 'taskListId' }
27
- * }
28
- * });
29
- *
30
- * // Discriminated union for single-table design
31
- * const MultiEntityTable = defineSchema({
32
- * tableName: 'prod-entities',
33
- * schema: z.discriminatedUnion('entityType', [
34
- * z.object({ PK: z.string(), SK: z.string(), entityType: z.literal('USER'), name: z.string() }),
35
- * z.object({ PK: z.string(), SK: z.string(), entityType: z.literal('ITEM'), title: z.string() }),
36
- * ]),
37
- * pk: 'PK',
38
- * sk: 'SK',
39
- * });
40
- * ```
41
- */
42
- declare function defineSchema<TSchema extends SupportedSchema, TPk extends keyof z.infer<TSchema> & string, TSk extends (keyof z.infer<TSchema> & string) | undefined = undefined, TIndexes extends Record<string, IndexDefinition> = Record<string, IndexDefinition>>(config: {
43
- tableName: string;
44
- schema: TSchema;
45
- pk: TPk;
46
- sk?: TSk;
47
- indexes?: TIndexes;
48
- }): DynamoTable<TSchema, TPk, TSk, TIndexes>;
6
+ declare const FilterConditionSchema: z.ZodType<FilterCondition>;
7
+ declare const QueryMetadataSchema: z.ZodObject<{
8
+ planVersion: z.ZodLiteral<1>;
9
+ tableName: z.ZodString;
10
+ indexName: z.ZodOptional<z.ZodString>;
11
+ indexPkField: z.ZodOptional<z.ZodString>;
12
+ indexSkField: z.ZodOptional<z.ZodString>;
13
+ filterConditions: z.ZodArray<z.ZodType<FilterCondition, unknown, z.core.$ZodTypeInternals<FilterCondition, unknown>>>;
14
+ sortField: z.ZodOptional<z.ZodString>;
15
+ sortOrder: z.ZodOptional<z.ZodEnum<{
16
+ asc: "asc";
17
+ desc: "desc";
18
+ }>>;
19
+ limit: z.ZodOptional<z.ZodNumber>;
20
+ }, z.core.$strict>;
21
+ declare const PendingDeliverySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
22
+ generation: z.ZodNumber;
23
+ fromVersion: z.ZodNumber;
24
+ toVersion: z.ZodNumber;
25
+ messageId: z.ZodString;
26
+ type: z.ZodLiteral<"patch">;
27
+ patches: z.ZodArray<z.ZodObject<{
28
+ op: z.ZodEnum<{
29
+ add: "add";
30
+ remove: "remove";
31
+ replace: "replace";
32
+ move: "move";
33
+ copy: "copy";
34
+ test: "test";
35
+ }>;
36
+ path: z.ZodString;
37
+ value: z.ZodOptional<z.ZodUnknown>;
38
+ from: z.ZodOptional<z.ZodString>;
39
+ }, z.core.$strip>>;
40
+ }, z.core.$strip>, z.ZodObject<{
41
+ generation: z.ZodNumber;
42
+ fromVersion: z.ZodNumber;
43
+ toVersion: z.ZodNumber;
44
+ messageId: z.ZodString;
45
+ type: z.ZodLiteral<"resync">;
46
+ }, z.core.$strict>], "type">;
49
47
  /**
50
48
  * System table schemas for the reactive engine
51
49
  */
52
50
  declare const SystemSchemas: {
53
51
  /**
54
- * ReactiveConnections - Tracks active WebSocket connections
52
+ * ReactiveConnectionsV2 - Tracks active WebSocket connections
55
53
  */
56
54
  connections: z.ZodObject<{
57
55
  connectionId: z.ZodString;
56
+ status: z.ZodEnum<{
57
+ open: "open";
58
+ closed: "closed";
59
+ }>;
58
60
  context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
61
+ authorizerContext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
62
+ requestIdentity: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
59
63
  connectedAt: z.ZodNumber;
60
64
  ttl: z.ZodNumber;
61
65
  }, z.core.$strip>;
62
66
  /**
63
- * ReactiveDependencies - The inverted index for O(1) lookups
67
+ * ReactiveDependenciesV2 - The inverted index for O(1) lookups
64
68
  */
65
69
  dependencies: z.ZodObject<{
66
70
  pk: z.ZodString;
@@ -70,41 +74,84 @@ declare const SystemSchemas: {
70
74
  tableName: z.ZodString;
71
75
  fieldName: z.ZodString;
72
76
  fieldValue: z.ZodString;
77
+ generation: z.ZodNumber;
78
+ registrationId: z.ZodString;
73
79
  ttl: z.ZodNumber;
74
80
  }, z.core.$strip>;
75
81
  /**
76
- * ReactiveConnectionQueries - Stores subscription state for diffing
82
+ * ReactiveConnectionQueriesV2 - Stores subscription state for diffing
77
83
  */
78
84
  queries: z.ZodObject<{
79
85
  pk: z.ZodString;
80
86
  sk: z.ZodString;
81
87
  connectionId: z.ZodString;
82
88
  subscriptionId: z.ZodString;
89
+ status: z.ZodEnum<{
90
+ registering: "registering";
91
+ active: "active";
92
+ cancelled: "cancelled";
93
+ faulted: "faulted";
94
+ }>;
95
+ generation: z.ZodNumber;
96
+ registrationId: z.ZodString;
83
97
  queryMetadata: z.ZodObject<{
98
+ planVersion: z.ZodLiteral<1>;
84
99
  tableName: z.ZodString;
85
100
  indexName: z.ZodOptional<z.ZodString>;
86
- filterConditions: z.ZodArray<z.ZodUnknown>;
101
+ indexPkField: z.ZodOptional<z.ZodString>;
102
+ indexSkField: z.ZodOptional<z.ZodString>;
103
+ filterConditions: z.ZodArray<z.ZodType<FilterCondition, unknown, z.core.$ZodTypeInternals<FilterCondition, unknown>>>;
87
104
  sortField: z.ZodOptional<z.ZodString>;
88
105
  sortOrder: z.ZodOptional<z.ZodEnum<{
89
106
  asc: "asc";
90
107
  desc: "desc";
91
108
  }>>;
92
109
  limit: z.ZodOptional<z.ZodNumber>;
93
- }, z.core.$strip>;
110
+ }, z.core.$strict>;
94
111
  lastResult: z.ZodArray<z.ZodUnknown>;
95
112
  dependencies: z.ZodArray<z.ZodString>;
113
+ version: z.ZodNumber;
114
+ pendingDelivery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
115
+ generation: z.ZodNumber;
116
+ fromVersion: z.ZodNumber;
117
+ toVersion: z.ZodNumber;
118
+ messageId: z.ZodString;
119
+ type: z.ZodLiteral<"patch">;
120
+ patches: z.ZodArray<z.ZodObject<{
121
+ op: z.ZodEnum<{
122
+ add: "add";
123
+ remove: "remove";
124
+ replace: "replace";
125
+ move: "move";
126
+ copy: "copy";
127
+ test: "test";
128
+ }>;
129
+ path: z.ZodString;
130
+ value: z.ZodOptional<z.ZodUnknown>;
131
+ from: z.ZodOptional<z.ZodString>;
132
+ }, z.core.$strip>>;
133
+ }, z.core.$strip>, z.ZodObject<{
134
+ generation: z.ZodNumber;
135
+ fromVersion: z.ZodNumber;
136
+ toVersion: z.ZodNumber;
137
+ messageId: z.ZodString;
138
+ type: z.ZodLiteral<"resync">;
139
+ }, z.core.$strict>], "type">>;
96
140
  createdAt: z.ZodNumber;
97
141
  updatedAt: z.ZodNumber;
98
142
  ttl: z.ZodNumber;
99
143
  }, z.core.$strip>;
100
144
  };
145
+ /** Storage/protocol generation used by all reactive system tables. */
146
+ declare const SYSTEM_TABLE_PROTOCOL_VERSION: 2;
101
147
  /**
102
- * System table names
148
+ * Versioned system table names. The V2 suffix intentionally prevents state
149
+ * written by the incompatible 0.1.x dependency protocol from being reused.
103
150
  */
104
151
  declare const SystemTableNames: {
105
- readonly connections: "ReactiveConnections";
106
- readonly dependencies: "ReactiveDependencies";
107
- readonly queries: "ReactiveConnectionQueries";
152
+ readonly connections: "ReactiveConnectionsV2";
153
+ readonly dependencies: "ReactiveDependenciesV2";
154
+ readonly queries: "ReactiveConnectionQueriesV2";
108
155
  };
109
156
 
110
- export { DynamoTable, IndexDefinition, SupportedSchema, SystemSchemas, SystemTableNames, defineSchema };
157
+ export { FilterCondition, FilterConditionSchema, PendingDeliverySchema, QueryMetadataSchema, SYSTEM_TABLE_PROTOCOL_VERSION, SystemSchemas, SystemTableNames };
package/dist/index.js CHANGED
@@ -1,3 +1,224 @@
1
- export { DynamoTable, SystemSchemas, SystemTableNames, defineSchema } from './chunk-ZAJA4KBE.js';
1
+ import { z } from 'zod';
2
+
3
+ // ../core/src/schema.ts
4
+ var FilterConditionSchema = z.lazy(() => {
5
+ const comparison = z.object({
6
+ type: z.literal("comparison"),
7
+ operator: z.enum(["eq", "ne", "gt", "gte", "lt", "lte"]),
8
+ field: z.string().min(1),
9
+ value: z.unknown()
10
+ }).strict();
11
+ const queryFunction = z.union([
12
+ z.object({
13
+ type: z.literal("function"),
14
+ operator: z.literal("between"),
15
+ field: z.string().min(1),
16
+ value: z.unknown(),
17
+ value2: z.unknown()
18
+ }).strict(),
19
+ z.object({
20
+ type: z.literal("function"),
21
+ operator: z.enum(["beginsWith", "contains"]),
22
+ field: z.string().min(1),
23
+ value: z.unknown()
24
+ }).strict()
25
+ ]);
26
+ const logical = z.object({
27
+ type: z.literal("logical"),
28
+ operator: z.enum(["and", "or", "not"]),
29
+ conditions: z.array(FilterConditionSchema).min(1)
30
+ }).strict().superRefine((condition, context) => {
31
+ if (condition.operator === "not" && condition.conditions.length !== 1) {
32
+ context.addIssue({
33
+ code: "custom",
34
+ path: ["conditions"],
35
+ message: "not requires exactly one condition"
36
+ });
37
+ }
38
+ });
39
+ return z.union([comparison, queryFunction, logical]);
40
+ });
41
+ var QueryMetadataSchema = z.object({
42
+ planVersion: z.literal(1),
43
+ tableName: z.string().min(1),
44
+ indexName: z.string().min(1).optional(),
45
+ indexPkField: z.string().min(1).optional(),
46
+ indexSkField: z.string().min(1).optional(),
47
+ filterConditions: z.array(FilterConditionSchema),
48
+ sortField: z.string().min(1).optional(),
49
+ sortOrder: z.enum(["asc", "desc"]).optional(),
50
+ limit: z.number().int().positive().optional()
51
+ }).strict().superRefine((metadata, context) => {
52
+ if (metadata.indexName && !metadata.indexPkField) {
53
+ context.addIssue({
54
+ code: "custom",
55
+ path: ["indexPkField"],
56
+ message: "Index metadata requires its partition key field"
57
+ });
58
+ }
59
+ if (!metadata.indexName && (metadata.indexPkField || metadata.indexSkField)) {
60
+ context.addIssue({
61
+ code: "custom",
62
+ path: ["indexName"],
63
+ message: "Index key fields require an index name"
64
+ });
65
+ }
66
+ if (Boolean(metadata.sortField) !== Boolean(metadata.sortOrder)) {
67
+ context.addIssue({
68
+ code: "custom",
69
+ path: ["sortOrder"],
70
+ message: "Sort field and order must be specified together"
71
+ });
72
+ }
73
+ });
74
+ var DeliveryVersionSchema = z.object({
75
+ generation: z.number().int().nonnegative(),
76
+ fromVersion: z.number().int().nonnegative(),
77
+ toVersion: z.number().int().positive(),
78
+ messageId: z.string().min(1)
79
+ });
80
+ var PendingDeliverySchema = z.discriminatedUnion("type", [
81
+ DeliveryVersionSchema.extend({
82
+ type: z.literal("patch"),
83
+ patches: z.array(
84
+ z.object({
85
+ op: z.enum(["add", "remove", "replace", "move", "copy", "test"]),
86
+ path: z.string(),
87
+ value: z.unknown().optional(),
88
+ from: z.string().optional()
89
+ })
90
+ )
91
+ }),
92
+ DeliveryVersionSchema.extend({
93
+ type: z.literal("resync")
94
+ }).strict()
95
+ ]);
96
+ var SystemSchemas = {
97
+ /**
98
+ * ReactiveConnectionsV2 - Tracks active WebSocket connections
99
+ */
100
+ connections: z.object({
101
+ connectionId: z.string(),
102
+ status: z.enum(["open", "closed"]),
103
+ context: z.record(z.string(), z.unknown()).optional(),
104
+ authorizerContext: z.record(z.string(), z.unknown()).optional(),
105
+ requestIdentity: z.record(z.string(), z.unknown()).optional(),
106
+ connectedAt: z.number(),
107
+ ttl: z.number()
108
+ }),
109
+ /**
110
+ * ReactiveDependenciesV2 - The inverted index for O(1) lookups
111
+ */
112
+ dependencies: z.object({
113
+ pk: z.string(),
114
+ // Versioned encoded dependency key
115
+ sk: z.string(),
116
+ // ConnectionID#SubscriptionID
117
+ connectionId: z.string(),
118
+ subscriptionId: z.string(),
119
+ tableName: z.string(),
120
+ fieldName: z.string(),
121
+ fieldValue: z.string(),
122
+ generation: z.number().int().nonnegative(),
123
+ registrationId: z.string().min(1),
124
+ ttl: z.number()
125
+ }),
126
+ /**
127
+ * ReactiveConnectionQueriesV2 - Stores subscription state for diffing
128
+ */
129
+ queries: z.object({
130
+ pk: z.string(),
131
+ // ConnectionID
132
+ sk: z.string(),
133
+ // SubscriptionID
134
+ connectionId: z.string(),
135
+ subscriptionId: z.string(),
136
+ status: z.enum(["registering", "active", "cancelled", "faulted"]),
137
+ generation: z.number().int().nonnegative(),
138
+ registrationId: z.string().min(1),
139
+ queryMetadata: QueryMetadataSchema,
140
+ lastResult: z.array(z.unknown()),
141
+ dependencies: z.array(z.string()),
142
+ version: z.number().int().nonnegative(),
143
+ pendingDelivery: PendingDeliverySchema.optional(),
144
+ createdAt: z.number(),
145
+ updatedAt: z.number(),
146
+ ttl: z.number()
147
+ })
148
+ };
149
+ var SYSTEM_TABLE_PROTOCOL_VERSION = 2;
150
+ var SystemTableNames = {
151
+ connections: "ReactiveConnectionsV2",
152
+ dependencies: "ReactiveDependenciesV2",
153
+ queries: "ReactiveConnectionQueriesV2"
154
+ };
155
+
156
+ // ../core/src/table.ts
157
+ function getSchemaFields(schema) {
158
+ const fields = /* @__PURE__ */ new Set();
159
+ if ("options" in schema && Array.isArray(schema.options)) {
160
+ for (const option of schema.options) {
161
+ if ("shape" in option && typeof option.shape === "object") {
162
+ for (const key of Object.keys(option.shape)) {
163
+ fields.add(key);
164
+ }
165
+ }
166
+ }
167
+ } else if ("shape" in schema && typeof schema.shape === "object") {
168
+ for (const key of Object.keys(schema.shape)) {
169
+ fields.add(key);
170
+ }
171
+ }
172
+ return fields;
173
+ }
174
+ var DynamoTable = class {
175
+ tableName;
176
+ schema;
177
+ pk;
178
+ sk;
179
+ indexes;
180
+ field;
181
+ constructor(config) {
182
+ this.tableName = config.tableName;
183
+ this.schema = config.schema;
184
+ this.pk = config.pk;
185
+ this.sk = config.sk;
186
+ this.indexes = config.indexes ?? {};
187
+ this.field = this.createFieldRefs();
188
+ }
189
+ createFieldRefs() {
190
+ const fields = getSchemaFields(this.schema);
191
+ const refs = {};
192
+ for (const key of fields) {
193
+ refs[key] = {
194
+ fieldName: key,
195
+ _type: void 0
196
+ };
197
+ }
198
+ return refs;
199
+ }
200
+ /**
201
+ * Validate an item against the schema
202
+ */
203
+ validate(item) {
204
+ return this.schema.parse(item);
205
+ }
206
+ /**
207
+ * Safely validate an item, returning a result object
208
+ */
209
+ safeParse(item) {
210
+ return this.schema.safeParse(item);
211
+ }
212
+ /**
213
+ * Get the list of field names in the schema
214
+ */
215
+ getFieldNames() {
216
+ return Array.from(
217
+ getSchemaFields(this.schema)
218
+ );
219
+ }
220
+ };
221
+
222
+ export { DynamoTable, FilterConditionSchema, PendingDeliverySchema, QueryMetadataSchema, SYSTEM_TABLE_PROTOCOL_VERSION, SystemSchemas, SystemTableNames };
2
223
  //# sourceMappingURL=index.js.map
3
224
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
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"]}