effect-dynamodb 1.8.1 → 1.9.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.
Files changed (107) hide show
  1. package/dist/Aggregate.d.ts +9 -9
  2. package/dist/Aggregate.d.ts.map +1 -1
  3. package/dist/Aggregate.js +9 -9
  4. package/dist/Aggregate.js.map +1 -1
  5. package/dist/Batch.d.ts +1 -1
  6. package/dist/Batch.d.ts.map +1 -1
  7. package/dist/Batch.js +1 -1
  8. package/dist/Batch.js.map +1 -1
  9. package/dist/Collection.d.ts +3 -3
  10. package/dist/Collection.d.ts.map +1 -1
  11. package/dist/Collection.js +3 -3
  12. package/dist/Collection.js.map +1 -1
  13. package/dist/Collections.d.ts +1 -1
  14. package/dist/Collections.d.ts.map +1 -1
  15. package/dist/Collections.js +1 -1
  16. package/dist/Collections.js.map +1 -1
  17. package/dist/DynamoClient.d.ts +12 -8
  18. package/dist/DynamoClient.d.ts.map +1 -1
  19. package/dist/DynamoClient.js +23 -7
  20. package/dist/DynamoClient.js.map +1 -1
  21. package/dist/Entity.d.ts +41 -19
  22. package/dist/Entity.d.ts.map +1 -1
  23. package/dist/Entity.js +185 -58
  24. package/dist/Entity.js.map +1 -1
  25. package/dist/EventStore.d.ts +1 -1
  26. package/dist/EventStore.d.ts.map +1 -1
  27. package/dist/EventStore.js +6 -5
  28. package/dist/EventStore.js.map +1 -1
  29. package/dist/Marshaller.d.ts +1 -1
  30. package/dist/Marshaller.d.ts.map +1 -1
  31. package/dist/Query.d.ts +1 -1
  32. package/dist/Query.d.ts.map +1 -1
  33. package/dist/Query.js +1 -1
  34. package/dist/Query.js.map +1 -1
  35. package/dist/Table.d.ts +2 -2
  36. package/dist/Table.d.ts.map +1 -1
  37. package/dist/Table.js.map +1 -1
  38. package/dist/Transaction.d.ts +1 -1
  39. package/dist/Transaction.d.ts.map +1 -1
  40. package/dist/Transaction.js +1 -1
  41. package/dist/Transaction.js.map +1 -1
  42. package/dist/index.d.ts +9 -9
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +5 -5
  45. package/dist/index.js.map +1 -1
  46. package/dist/internal/BoundQuery.d.ts +1 -1
  47. package/dist/internal/BoundQuery.d.ts.map +1 -1
  48. package/dist/internal/BoundQuery.js.map +1 -1
  49. package/dist/internal/EntityCombinators.d.ts +1 -1
  50. package/dist/internal/EntityCombinators.d.ts.map +1 -1
  51. package/dist/internal/EntityCombinators.js.map +1 -1
  52. package/dist/internal/EntityOps.d.ts +2 -2
  53. package/dist/internal/EntityOps.d.ts.map +1 -1
  54. package/dist/internal/EntityOps.js.map +1 -1
  55. package/dist/internal/TransactableOps.d.ts +16 -4
  56. package/dist/internal/TransactableOps.d.ts.map +1 -1
  57. package/dist/internal/TransactableOps.js +24 -13
  58. package/dist/internal/TransactableOps.js.map +1 -1
  59. package/package.json +7 -6
  60. package/dist/DynamoModel.d.ts +0 -370
  61. package/dist/DynamoModel.d.ts.map +0 -1
  62. package/dist/DynamoModel.js +0 -562
  63. package/dist/DynamoModel.js.map +0 -1
  64. package/dist/DynamoSchema.d.ts +0 -137
  65. package/dist/DynamoSchema.d.ts.map +0 -1
  66. package/dist/DynamoSchema.js +0 -188
  67. package/dist/DynamoSchema.js.map +0 -1
  68. package/dist/Errors.d.ts +0 -387
  69. package/dist/Errors.d.ts.map +0 -1
  70. package/dist/Errors.js +0 -218
  71. package/dist/Errors.js.map +0 -1
  72. package/dist/KeyComposer.d.ts +0 -264
  73. package/dist/KeyComposer.d.ts.map +0 -1
  74. package/dist/KeyComposer.js +0 -516
  75. package/dist/KeyComposer.js.map +0 -1
  76. package/dist/Projection.d.ts +0 -28
  77. package/dist/Projection.d.ts.map +0 -1
  78. package/dist/Projection.js +0 -39
  79. package/dist/Projection.js.map +0 -1
  80. package/dist/internal/AggregateCursor.d.ts +0 -44
  81. package/dist/internal/AggregateCursor.d.ts.map +0 -1
  82. package/dist/internal/AggregateCursor.js +0 -18
  83. package/dist/internal/AggregateCursor.js.map +0 -1
  84. package/dist/internal/AggregateEdges.d.ts +0 -77
  85. package/dist/internal/AggregateEdges.d.ts.map +0 -1
  86. package/dist/internal/AggregateEdges.js +0 -41
  87. package/dist/internal/AggregateEdges.js.map +0 -1
  88. package/dist/internal/AggregateSchemas.d.ts +0 -60
  89. package/dist/internal/AggregateSchemas.d.ts.map +0 -1
  90. package/dist/internal/AggregateSchemas.js +0 -201
  91. package/dist/internal/AggregateSchemas.js.map +0 -1
  92. package/dist/internal/AggregateTypes.d.ts +0 -94
  93. package/dist/internal/AggregateTypes.d.ts.map +0 -1
  94. package/dist/internal/AggregateTypes.js +0 -7
  95. package/dist/internal/AggregateTypes.js.map +0 -1
  96. package/dist/internal/EntityConfig.d.ts +0 -134
  97. package/dist/internal/EntityConfig.d.ts.map +0 -1
  98. package/dist/internal/EntityConfig.js +0 -7
  99. package/dist/internal/EntityConfig.js.map +0 -1
  100. package/dist/internal/EntitySchemas.d.ts +0 -190
  101. package/dist/internal/EntitySchemas.d.ts.map +0 -1
  102. package/dist/internal/EntitySchemas.js +0 -794
  103. package/dist/internal/EntitySchemas.js.map +0 -1
  104. package/dist/internal/EntityTypes.d.ts +0 -208
  105. package/dist/internal/EntityTypes.d.ts.map +0 -1
  106. package/dist/internal/EntityTypes.js +0 -7
  107. package/dist/internal/EntityTypes.js.map +0 -1
@@ -1,562 +0,0 @@
1
- /**
2
- * DynamoModel — Schema annotations, date schemas, and model configuration for effect-dynamodb.
3
- *
4
- * Provides:
5
- * - `configure` — per-field DynamoDB overrides (field rename, storage encoding, immutable, identifier, ref)
6
- * - `Hidden` annotation — marks fields as excluded from default decode (asModel/asRecord)
7
- * - `DynamoEncoding` annotation — controls how date fields are stored in DynamoDB
8
- * - Date schemas — wire ↔ domain ↔ storage transformations for DateTime.Utc, DateTime.Zoned, Date
9
- * - `storedAs` modifier — overrides DynamoDB storage format via annotation
10
- * - `SparseMap()` — opt a `Schema.Record` field into flattened storage (one
11
- * top-level attribute per entry)
12
- *
13
- * See docs/design-dynamo-model.md for the three-layer model (wire → domain → storage).
14
- */
15
- import { DateTime, Effect, Option, Schema, SchemaAST, SchemaGetter, SchemaIssue } from "effect";
16
- // ---------------------------------------------------------------------------
17
- // Identifier annotation
18
- // ---------------------------------------------------------------------------
19
- /** Unique symbol for the Identifier annotation */
20
- const IdentifierId = Symbol.for("effect-dynamodb/Identifier");
21
- /**
22
- * Mark a schema field as the primary identifier for ref resolution.
23
- *
24
- * Entities that can be referenced via `DynamoModel.ref` must annotate exactly
25
- * one field with `identifier`. The annotated field should be a string or
26
- * branded string type.
27
- */
28
- export const identifier = (schema) => schema.pipe(Schema.annotate({ [IdentifierId]: true }));
29
- /**
30
- * Check if a schema field has the Identifier annotation.
31
- */
32
- export const isIdentifier = (schema) => SchemaAST.resolve(schema.ast)?.[IdentifierId] ?? false;
33
- /**
34
- * Find the identifier field in a schema with `.fields` (Schema.Class or Schema.Struct).
35
- * Checks both schema-level `DynamoModel.identifier` annotations and ConfiguredModel
36
- * `identifier: true` overrides.
37
- *
38
- * Returns the field name and schema, or undefined if no field has the identifier annotation.
39
- */
40
- export const getIdentifierField = (model) => {
41
- // Check ConfiguredModel attributes first (configure-level overrides take precedence)
42
- if (isConfiguredModel(model)) {
43
- const configured = model;
44
- for (const [name, attr] of Object.entries(configured.attributes)) {
45
- if (attr.identifier) {
46
- const rawModel = configured.model;
47
- if ("fields" in rawModel &&
48
- typeof rawModel.fields === "object") {
49
- const fields = rawModel
50
- .fields;
51
- const fieldSchema = fields[name];
52
- if (fieldSchema)
53
- return { name, schema: fieldSchema };
54
- }
55
- // Fallback: return with a generic string schema
56
- return { name, schema: Schema.String };
57
- }
58
- }
59
- // Fall through to check schema-level annotations on the inner model
60
- return getIdentifierField(configured.model);
61
- }
62
- if (!("fields" in model) ||
63
- typeof model.fields !== "object")
64
- return undefined;
65
- const fields = model.fields;
66
- for (const [name, fieldSchema] of Object.entries(fields)) {
67
- if (isIdentifier(fieldSchema))
68
- return { name, schema: fieldSchema };
69
- }
70
- return undefined;
71
- };
72
- // ---------------------------------------------------------------------------
73
- // Ref annotation
74
- // ---------------------------------------------------------------------------
75
- /** Unique symbol for the Ref annotation */
76
- const RefId = Symbol.for("effect-dynamodb/Ref");
77
- /**
78
- * Mark a schema field as a denormalized reference to another entity.
79
- *
80
- * Ref fields:
81
- * - In `Entity.Input`, become ID fields (e.g., `team: Team` → `teamId: string`)
82
- * - In `Entity.Record`, remain the full entity domain type
83
- * - In `Entity.Update`, become optional ID fields
84
- * - In DynamoDB, store the entity's core domain data as an embedded map
85
- *
86
- * The referenced entity's model must have exactly one `DynamoModel.identifier`-annotated field.
87
- */
88
- export const ref = (schema) => {
89
- // Extract Schema.Class identifier if available (e.g., "Team" from Schema.Class<Team>("Team"))
90
- // In Effect v4, Schema.Class exposes `identifier` (not `_tag`) as the class name
91
- const s = schema;
92
- const refSchemaId = "identifier" in schema && typeof s.identifier === "string"
93
- ? s.identifier
94
- : "_tag" in schema && typeof s._tag === "string"
95
- ? s._tag
96
- : undefined;
97
- return schema.pipe(Schema.annotate({ [RefId]: { _tag: "Ref", refSchemaId } }));
98
- };
99
- /**
100
- * Check if a schema field has the Ref annotation.
101
- */
102
- export const isRef = (schema) => {
103
- const ann = SchemaAST.resolve(schema.ast)?.[RefId];
104
- return ann != null && typeof ann === "object" && ann._tag === "Ref";
105
- };
106
- /**
107
- * Check if a field is a ref, considering both schema-level annotations and
108
- * ConfiguredModel overrides. Use this when you have access to the configured model.
109
- */
110
- export const isRefField = (fieldName, model) => {
111
- // Check ConfiguredModel attributes
112
- if (isConfiguredModel(model)) {
113
- const configured = model;
114
- if (configured.attributes[fieldName]?.ref)
115
- return true;
116
- // Fall through to check schema-level annotation on the inner model
117
- return isRefField(fieldName, configured.model);
118
- }
119
- // Check schema-level annotation
120
- if ("fields" in model &&
121
- typeof model.fields === "object") {
122
- const fields = model.fields;
123
- const fieldSchema = fields[fieldName];
124
- if (fieldSchema)
125
- return isRef(fieldSchema);
126
- }
127
- return false;
128
- };
129
- /**
130
- * Get the full Ref annotation metadata from a schema field.
131
- * Returns undefined if the field is not ref-annotated.
132
- */
133
- export const getRefAnnotation = (schema) => {
134
- const ann = SchemaAST.resolve(schema.ast)?.[RefId];
135
- if (ann != null && typeof ann === "object" && ann._tag === "Ref") {
136
- return ann;
137
- }
138
- return undefined;
139
- };
140
- // ---------------------------------------------------------------------------
141
- // Hidden annotation
142
- // ---------------------------------------------------------------------------
143
- /** Unique symbol for the Hidden annotation */
144
- const HiddenId = Symbol.for("effect-dynamodb/Hidden");
145
- /**
146
- * Mark a schema field as hidden from default decode modes (asModel, asRecord).
147
- *
148
- * Hidden fields:
149
- * - Stored in DynamoDB normally
150
- * - Visible in asItem and asNative decode modes
151
- * - Stripped from asModel and asRecord decode modes
152
- *
153
- * Use for internal/infrastructure fields that shouldn't leak into application code.
154
- */
155
- export const Hidden = (schema) => schema.pipe(Schema.annotate({ [HiddenId]: true }));
156
- /**
157
- * Check if a schema field has the Hidden annotation.
158
- */
159
- export const isHidden = (schema) => SchemaAST.resolve(schema.ast)?.[HiddenId] ?? false;
160
- // ---------------------------------------------------------------------------
161
- // DynamoEncoding annotation
162
- // ---------------------------------------------------------------------------
163
- /** Unique symbol for the DynamoEncoding annotation */
164
- export const DynamoEncodingKey = Symbol.for("effect-dynamodb/DynamoEncoding");
165
- /**
166
- * Read the DynamoEncoding annotation from a schema, if present.
167
- */
168
- export const getEncoding = (schema) => SchemaAST.resolve(schema.ast)?.[DynamoEncodingKey];
169
- // ---------------------------------------------------------------------------
170
- // Date schemas — DateTime.Utc domain
171
- // ---------------------------------------------------------------------------
172
- /**
173
- * Wire: ISO 8601 string ↔ Domain: DateTime.Utc
174
- *
175
- * Default storage: ISO string (`S`).
176
- * This is a thin wrapper around `Schema.DateTimeUtcFromString` with the DynamoEncoding annotation.
177
- */
178
- export const DateString = Schema.DateTimeUtcFromString.pipe(Schema.annotate({
179
- [DynamoEncodingKey]: { storage: "string", domain: "DateTime.Utc" },
180
- }));
181
- /**
182
- * Wire: epoch milliseconds (number) ↔ Domain: DateTime.Utc
183
- *
184
- * Default storage: epoch ms (`N`).
185
- */
186
- export const DateEpochMs = Schema.Number.pipe(Schema.decodeTo(Schema.DateTimeUtc, {
187
- decode: SchemaGetter.transform((n) => DateTime.makeUnsafe(n)),
188
- encode: SchemaGetter.transform((dt) => DateTime.toEpochMillis(dt)),
189
- }), Schema.annotate({
190
- [DynamoEncodingKey]: { storage: "epochMs", domain: "DateTime.Utc" },
191
- }));
192
- /**
193
- * Wire: epoch seconds (number) ↔ Domain: DateTime.Utc
194
- *
195
- * Default storage: epoch seconds (`N`).
196
- * DynamoDB TTL requires this format.
197
- */
198
- export const DateEpochSeconds = Schema.Number.pipe(Schema.decodeTo(Schema.DateTimeUtc, {
199
- decode: SchemaGetter.transform((n) => DateTime.makeUnsafe(n * 1000)),
200
- encode: SchemaGetter.transform((dt) => Math.floor(DateTime.toEpochMillis(dt) / 1000)),
201
- }), Schema.annotate({
202
- [DynamoEncodingKey]: {
203
- storage: "epochSeconds",
204
- domain: "DateTime.Utc",
205
- },
206
- }));
207
- /**
208
- * Wire: auto-detect epoch ms or seconds ↔ Domain: DateTime.Utc
209
- *
210
- * Uses a minimum threshold to disambiguate: if the value interpreted as ms
211
- * produces a date before `minimum`, it tries seconds instead.
212
- *
213
- * @param options.minimum - Threshold date for disambiguation
214
- * @param options.encode - Epoch schema for wire encoding (default: DateEpochMs)
215
- */
216
- export const DateEpoch = (options) => {
217
- const minEpochMs = typeof options.minimum === "string"
218
- ? new Date(options.minimum).getTime()
219
- : DateTime.toEpochMillis(DateTime.makeUnsafe(options.minimum));
220
- const encodeSchema = options.encode ?? DateEpochMs;
221
- const encodeEncoding = getEncoding(encodeSchema);
222
- return Schema.Number.pipe(Schema.decodeTo(Schema.DateTimeUtc, {
223
- decode: SchemaGetter.transformOrFail((n) => {
224
- // Try milliseconds first
225
- try {
226
- const asMs = DateTime.makeUnsafe(n);
227
- if (DateTime.toEpochMillis(asMs) >= minEpochMs) {
228
- return Effect.succeed(asMs);
229
- }
230
- }
231
- catch {
232
- // fall through
233
- }
234
- // Fall back to seconds
235
- try {
236
- const asSec = DateTime.makeUnsafe(n * 1000);
237
- if (DateTime.toEpochMillis(asSec) >= minEpochMs) {
238
- return Effect.succeed(asSec);
239
- }
240
- }
241
- catch {
242
- // fall through
243
- }
244
- return Effect.fail(new SchemaIssue.InvalidType(Schema.Number.ast, Option.some(n)));
245
- }),
246
- encode: SchemaGetter.transform((dt) => Schema.encodeSync(encodeSchema)(dt)),
247
- }), Schema.annotate({
248
- [DynamoEncodingKey]: {
249
- storage: encodeEncoding?.storage ?? "epochMs",
250
- domain: "DateTime.Utc",
251
- },
252
- }));
253
- };
254
- // ---------------------------------------------------------------------------
255
- // Date schemas — DateTime.Zoned domain
256
- // ---------------------------------------------------------------------------
257
- /**
258
- * Wire: ISO 8601 string with offset/zone ↔ Domain: DateTime.Zoned
259
- *
260
- * Default storage: extended ISO with zone (`S`).
261
- * Format: `2024-01-01T15:00:00+09:00[Asia/Tokyo]`
262
- *
263
- * Cannot use epoch storage — timezone information would be lost (enforced at type level via storedAs).
264
- */
265
- export const DateTimeZoned = Schema.String.pipe(Schema.decodeTo(Schema.DateTimeZoned, {
266
- decode: SchemaGetter.transformOrFail((s) => {
267
- // Parse extended ISO format: "2024-01-01T15:00:00+09:00[Asia/Tokyo]"
268
- const match = s.match(/^(.+)\[(.+)\]$/);
269
- if (match) {
270
- const dateStr = match[1];
271
- const tzName = match[2];
272
- try {
273
- const utc = DateTime.makeUnsafe(dateStr);
274
- return Effect.succeed(DateTime.makeZonedUnsafe(utc, { timeZone: tzName }));
275
- }
276
- catch {
277
- return Effect.fail(new SchemaIssue.InvalidType(Schema.String.ast, Option.some(s)));
278
- }
279
- }
280
- // Try parsing as offset-only: "2024-01-01T15:00:00+09:00"
281
- try {
282
- const utc = DateTime.makeUnsafe(s);
283
- return Effect.succeed(DateTime.makeZonedUnsafe(utc, { timeZone: "UTC" }));
284
- }
285
- catch {
286
- return Effect.fail(new SchemaIssue.InvalidType(Schema.String.ast, Option.some(s)));
287
- }
288
- }),
289
- encode: SchemaGetter.transform((dt) => DateTime.formatIsoZoned(dt)),
290
- }), Schema.annotate({
291
- [DynamoEncodingKey]: { storage: "string", domain: "DateTime.Zoned" },
292
- }));
293
- // ---------------------------------------------------------------------------
294
- // Unsafe date schemas — native Date domain
295
- // ---------------------------------------------------------------------------
296
- /**
297
- * Wire: ISO 8601 string ↔ Domain: native Date (mutable)
298
- *
299
- * Default storage: ISO string (`S`).
300
- * For interop with non-Effect code that expects native JS Date objects.
301
- */
302
- export const UnsafeDateString = Schema.String.pipe(Schema.decodeTo(Schema.DateValid, {
303
- decode: SchemaGetter.transform((s) => new Date(s)),
304
- encode: SchemaGetter.transform((d) => d.toISOString()),
305
- }), Schema.annotate({
306
- [DynamoEncodingKey]: { storage: "string", domain: "Date" },
307
- }));
308
- /**
309
- * Wire: epoch milliseconds (number) ↔ Domain: native Date (mutable)
310
- *
311
- * Default storage: epoch ms (`N`).
312
- */
313
- export const UnsafeDateEpochMs = Schema.Number.pipe(Schema.decodeTo(Schema.DateValid, {
314
- decode: SchemaGetter.transform((ms) => new Date(ms)),
315
- encode: SchemaGetter.transform((d) => d.getTime()),
316
- }), Schema.annotate({
317
- [DynamoEncodingKey]: { storage: "epochMs", domain: "Date" },
318
- }));
319
- /**
320
- * Wire: epoch seconds (number) ↔ Domain: native Date (mutable)
321
- *
322
- * Default storage: epoch seconds (`N`).
323
- */
324
- export const UnsafeDateEpochSeconds = Schema.Number.pipe(Schema.decodeTo(Schema.DateValid, {
325
- decode: SchemaGetter.transform((s) => new Date(s * 1000)),
326
- encode: SchemaGetter.transform((d) => Math.floor(d.getTime() / 1000)),
327
- }), Schema.annotate({
328
- [DynamoEncodingKey]: {
329
- storage: "epochSeconds",
330
- domain: "Date",
331
- },
332
- }));
333
- // ---------------------------------------------------------------------------
334
- // TTL alias
335
- // ---------------------------------------------------------------------------
336
- /**
337
- * Alias for `DateEpochSeconds`. DynamoDB TTL requires epoch seconds.
338
- * A named alias makes intent clear at the call site.
339
- */
340
- export const TTL = DateEpochSeconds;
341
- // ---------------------------------------------------------------------------
342
- // storedAs modifier
343
- // ---------------------------------------------------------------------------
344
- /**
345
- * Override the DynamoDB storage format for a date field.
346
- *
347
- * `storedAs` reads the DynamoEncoding annotation from the target storage schema
348
- * and applies its storage format to the field schema. The domain type must match
349
- * (enforced at the type level via the `A` constraint).
350
- *
351
- * @example
352
- * ```typescript
353
- * // Wire: ISO string, DynamoDB: epoch seconds (for TTL)
354
- * DynamoModel.DateString.pipe(DynamoModel.storedAs(DynamoModel.DateEpochSeconds))
355
- *
356
- * // Wire: epoch ms, DynamoDB: ISO string
357
- * DynamoModel.DateEpochMs.pipe(DynamoModel.storedAs(DynamoModel.DateString))
358
- * ```
359
- *
360
- * Type-safe: incompatible domain types produce a compile error:
361
- * ```typescript
362
- * // Type error — DateTime.Zoned ≠ DateTime.Utc
363
- * DynamoModel.DateTimeZoned.pipe(DynamoModel.storedAs(DynamoModel.DateEpochMs))
364
- * ```
365
- */
366
- export const storedAs = (storageSchema) => {
367
- const storageEncoding = getEncoding(storageSchema);
368
- if (!storageEncoding) {
369
- throw new Error("storedAs: target schema has no DynamoEncoding annotation");
370
- }
371
- return (fieldSchema) => {
372
- const currentEncoding = getEncoding(fieldSchema);
373
- return fieldSchema.pipe(Schema.annotate({
374
- [DynamoEncodingKey]: {
375
- storage: storageEncoding.storage,
376
- domain: currentEncoding?.domain ?? storageEncoding.domain,
377
- },
378
- }));
379
- };
380
- };
381
- // ---------------------------------------------------------------------------
382
- // ConfiguredModel
383
- // ---------------------------------------------------------------------------
384
- /** Unique symbol identifying a ConfiguredModel wrapper */
385
- export const ConfiguredModelTag = Symbol.for("effect-dynamodb/ConfiguredModel");
386
- /** Brand symbol identifying a {@link SparseMapConfig} produced by {@link SparseMap}. */
387
- const SparseMapTag = Symbol.for("effect-dynamodb/SparseMap");
388
- /**
389
- * Opt a `Schema.Record` field into sparse map storage.
390
- *
391
- * Each Record entry becomes an independently addressable top-level DynamoDB
392
- * attribute (`<prefix>#<key>`) — concurrent writers to disjoint buckets
393
- * never race, counters can `ADD` on a fresh item with no parent-map dance,
394
- * and `attribute_exists`/`attribute_not_exists` work natively per entry.
395
- *
396
- * @example
397
- * ```ts
398
- * DynamoModel.configure(Page, {
399
- * metrics: { storedAs: DynamoModel.SparseMap() },
400
- * totals: { storedAs: DynamoModel.SparseMap({ prefix: "t" }) },
401
- * })
402
- * ```
403
- *
404
- * @param options.prefix - Override the top-level attribute name prefix.
405
- * Defaults to the model field name. Distinct sparse fields on the same
406
- * entity must have distinct prefixes (EDD-9023).
407
- *
408
- * See `DESIGN.md §7.5 Sparse Map Storage`.
409
- */
410
- export const SparseMap = (options) => {
411
- const cfg = { [SparseMapTag]: true };
412
- if (options?.prefix !== undefined) {
413
- return { ...cfg, prefix: options.prefix };
414
- }
415
- return cfg;
416
- };
417
- /** Type guard — returns true iff `value` is a {@link SparseMapConfig}. */
418
- export const isSparseMapConfig = (value) => typeof value === "object" &&
419
- value !== null &&
420
- value[SparseMapTag] === true;
421
- /**
422
- * Check if a value is a ConfiguredModel.
423
- */
424
- export const isConfiguredModel = (value) => typeof value === "object" &&
425
- value !== null &&
426
- value[ConfiguredModelTag] === true;
427
- /**
428
- * Resolve sparse-map configuration for every field on a model that is marked
429
- * `storedAs: DynamoModel.SparseMap()` via {@link configure}.
430
- *
431
- * Returns `Record<fieldName, SparseConfig>`. Empty when no sparse fields are
432
- * configured.
433
- *
434
- * Walks `ConfiguredModel.attributes` only — schema-level annotations are not
435
- * supported for sparse (it's a deployment concern, not a domain one).
436
- */
437
- export const getSparseFields = (model) => {
438
- if (!isConfiguredModel(model))
439
- return {};
440
- const out = {};
441
- for (const [name, attr] of Object.entries(model.attributes)) {
442
- if (attr.sparse)
443
- out[name] = attr.sparse;
444
- }
445
- return out;
446
- };
447
- /**
448
- * Inspect a Schema field to determine whether it is shaped like a `Schema.Record`.
449
- *
450
- * Effect v4 `Schema.Record(K, V)` produces an AST `Objects` node with no
451
- * `propertySignatures` and a single `indexSignatures` entry (string-keyed).
452
- *
453
- * Returns the value AST on match, otherwise `undefined`. Used by
454
- * `Entity.make()` to validate sparse-map fields and detect nested sparse
455
- * (a Record whose value is itself a Record).
456
- */
457
- export const isRecordSchema = (schema) => {
458
- const ast = schema.ast;
459
- if (!ast || ast._tag !== "Objects")
460
- return undefined;
461
- const propertySignatures = ast.propertySignatures;
462
- const indexSignatures = ast.indexSignatures;
463
- if (!Array.isArray(propertySignatures) || !Array.isArray(indexSignatures))
464
- return undefined;
465
- if (propertySignatures.length !== 0 || indexSignatures.length !== 1)
466
- return undefined;
467
- const sig = indexSignatures[0];
468
- return { valueAst: sig.type };
469
- };
470
- /** True iff `schema` is shaped like `Schema.Record(K, V)`. */
471
- export const isRecord = (schema) => isRecordSchema(schema) !== undefined;
472
- /** True iff `valueAst` (raw AST from a Record value position) is itself a Record AST. */
473
- export const isRecordAst = (valueAst) => {
474
- if (!valueAst || typeof valueAst !== "object")
475
- return false;
476
- const ast = valueAst;
477
- if (ast._tag !== "Objects")
478
- return false;
479
- return (Array.isArray(ast.propertySignatures) &&
480
- Array.isArray(ast.indexSignatures) &&
481
- ast.propertySignatures.length === 0 &&
482
- ast.indexSignatures.length === 1);
483
- };
484
- /**
485
- * Create a configured model with per-field DynamoDB overrides.
486
- *
487
- * Separates DynamoDB infrastructure (storage format, field renaming) from
488
- * the domain model, enabling pure models that work across storage backends.
489
- *
490
- * @example
491
- * ```typescript
492
- * class Order extends Schema.Class<Order>("Order")({
493
- * orderId: Schema.String,
494
- * placedAt: Schema.DateTimeUtcFromString,
495
- * expiresAt: Schema.DateTimeUtcFromString,
496
- * }) {}
497
- *
498
- * const OrderModel = DynamoModel.configure(Order, {
499
- * expiresAt: { field: "ttl", storedAs: DynamoModel.DateEpochSeconds },
500
- * })
501
- * ```
502
- */
503
- export const configure = (model, attributes) => {
504
- const resolved = {};
505
- for (const [key, config] of Object.entries(attributes)) {
506
- const entry = {};
507
- if (config.field)
508
- entry.field = config.field;
509
- if (config.immutable)
510
- entry.immutable = true;
511
- if (config.identifier)
512
- entry.identifier = true;
513
- if (config.ref)
514
- entry.ref = true;
515
- if (isSparseMapConfig(config.storedAs)) {
516
- // Sparse Map storage: each entry is stored as a top-level attribute named
517
- // `<prefix>#<key>`. Validation that the field is a Schema.Record happens
518
- // at Entity.make() time (EDD-9020) — configure() can't introspect the
519
- // model's schema field types reliably without committing to a single
520
- // representation, so we keep configure() permissive and defer enforcement.
521
- const prefix = config.storedAs.prefix ?? key;
522
- if (typeof prefix !== "string" || prefix.length === 0) {
523
- throw new Error(`DynamoModel.configure: sparse field "${key}" must have a non-empty string prefix`);
524
- }
525
- if (prefix.includes("#")) {
526
- throw new Error(`DynamoModel.configure: sparse field "${key}" prefix "${prefix}" must not contain '#'`);
527
- }
528
- entry.sparse = { prefix };
529
- }
530
- else if (config.storedAs !== undefined) {
531
- const encoding = getEncoding(config.storedAs);
532
- if (!encoding) {
533
- throw new Error(`DynamoModel.configure: storedAs schema for "${key}" has no DynamoEncoding annotation`);
534
- }
535
- entry.encoding = encoding;
536
- }
537
- resolved[key] = entry;
538
- }
539
- // Validate: no field rename targets collide with existing model field names
540
- const modelFields = new Set();
541
- if ("fields" in model &&
542
- typeof model.fields === "object") {
543
- for (const fieldName of Object.keys(model.fields)) {
544
- modelFields.add(fieldName);
545
- }
546
- }
547
- if (modelFields.size > 0) {
548
- for (const [sourceField, config] of Object.entries(resolved)) {
549
- if (config.field && config.field !== sourceField && modelFields.has(config.field)) {
550
- throw new Error(`[EDD-9007] DynamoModel.configure: renaming "${sourceField}" to "${config.field}" collides with existing model field "${config.field}". ` +
551
- `This would cause both fields to map to the same DynamoDB attribute.`);
552
- }
553
- }
554
- }
555
- return {
556
- [ConfiguredModelTag]: true,
557
- model,
558
- _attributes: attributes,
559
- attributes: resolved,
560
- };
561
- };
562
- //# sourceMappingURL=DynamoModel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DynamoModel.js","sourceRoot":"","sources":["../src/DynamoModel.ts"],"names":[],"mappings":"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"}