effect-dynamodb 1.9.3 → 1.9.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"Aggregate.d.ts","sourceRoot":"","sources":["../src/Aggregate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Aggregate.d.ts","sourceRoot":"","sources":["../src/Aggregate.ts"],"names":[],"mappings":"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"}
package/dist/Aggregate.js CHANGED
@@ -12,11 +12,12 @@ import { TypeId as SchemaAggregateTypeId } from "@effect-dynamodb/schema/Aggrega
12
12
  import * as DynamoModel from "@effect-dynamodb/schema/DynamoModel.js";
13
13
  import { composeCollectionKey, composeKey } from "@effect-dynamodb/schema/DynamoSchema.js";
14
14
  import { AggregateAssemblyError, AggregateTransactionOverflow, RefNotFound, TransactionCancelled, ValidationError, } from "@effect-dynamodb/schema/Errors.js";
15
- import { buildDateTransform, validateNoTransformOverride, } from "@effect-dynamodb/schema/internal/EntitySchemas.js";
15
+ import { buildDateTransform, substituteSchemaDeep, validateNoTransformOverride, } from "@effect-dynamodb/schema/internal/EntitySchemas.js";
16
16
  import * as KeyComposer from "@effect-dynamodb/schema/KeyComposer.js";
17
17
  import { Effect, Schema, SchemaAST } from "effect";
18
18
  import * as Batch from "./Batch.js";
19
19
  import { DynamoClient } from "./DynamoClient.js";
20
+ import { fromDefinition as entityFromDefinition } from "./Entity.js";
20
21
  import { fromAttributeMap, toAttributeMap, toAttributeValue } from "./Marshaller.js";
21
22
  // Internal modules (decomposed from Aggregate.ts)
22
23
  export { isManyEdge, isOneEdge, isRefEdge, many, one, ref, } from "@effect-dynamodb/schema/internal/AggregateEdges.js";
@@ -129,6 +130,46 @@ const inferDateEncoding = (ast) => {
129
130
  }
130
131
  return undefined;
131
132
  };
133
+ /**
134
+ * Build per-field date ENCODERS for a schema's own date fields. Encoders convert
135
+ * a domain date value to its wire primitive on the WRITE path — decompose works
136
+ * from the schema-decoded domain object, so EVERY date field (Pattern A self-date
137
+ * AND Pattern B transform) must serialize for storage. The READ path is handled
138
+ * entirely by the aggregate's tolerant `decodeSchema` (see `makeAggregate`), so
139
+ * no separate decoders are needed.
140
+ */
141
+ const buildDateEncoders = (fields) => {
142
+ const encoders = {};
143
+ if (fields) {
144
+ for (const field of Object.keys(fields)) {
145
+ const fieldSchema = fields[field];
146
+ // Precedence: explicit `DynamoModel.storedAs` annotation > inferred default
147
+ // for standard Effect date schemas (handles `Schema.optional()` wrappers).
148
+ const encoding = DynamoModel.getEncoding(fieldSchema) ?? inferDateEncoding(fieldSchema.ast);
149
+ if (!encoding)
150
+ continue;
151
+ const encode = Schema.encodeUnknownSync(buildDateTransform(encoding));
152
+ encoders[field] = (value) => encode(value);
153
+ }
154
+ }
155
+ return encoders;
156
+ };
157
+ /** A schema's declared fields, if it exposes them (Schema.Struct / Schema.Class). */
158
+ const fieldsOf = (schema) => schema?.fields;
159
+ /**
160
+ * Apply a node's date encoders in place — converts the node entity's own domain
161
+ * date fields to their wire primitives before the decomposed item is marshalled
162
+ * (issue #72: without this, an edge's `DateTime` field marshals to `{M:{}}` and
163
+ * the subsequent `get`/assemble fails decoding it as a string).
164
+ */
165
+ const applyNodeDateEncoders = (attrs, encoders) => {
166
+ if (!encoders)
167
+ return;
168
+ for (const [field, encode] of Object.entries(encoders)) {
169
+ if (field in attrs && attrs[field] != null)
170
+ attrs[field] = encode(attrs[field]);
171
+ }
172
+ };
132
173
  // ---------------------------------------------------------------------------
133
174
  // Top-level aggregate construction
134
175
  // ---------------------------------------------------------------------------
@@ -152,8 +193,6 @@ const makeAggregate = (schema, config) => {
152
193
  // (e.g. `Schema.DateTimeUtcFromString`) cannot be combined with a
153
194
  // `DynamoModel.storedAs(...)` annotation that conflicts with the
154
195
  // transform's wire kind — same rule as Entity.
155
- const dateEncoders = {};
156
- const dateDecoders = {};
157
196
  const schemaFields = schema.fields;
158
197
  if (schemaFields) {
159
198
  // Reject transform + storedAs annotation conflicts (Option (b) policy).
@@ -161,29 +200,46 @@ const makeAggregate = (schema, config) => {
161
200
  // so we pass an empty `configuredAttributes` map — only the schema-level
162
201
  // annotation conflict is checked.
163
202
  validateNoTransformOverride(schemaFields, {});
164
- for (const field of Object.keys(schemaFields)) {
165
- const fieldSchema = schemaFields[field];
166
- const explicit = DynamoModel.getEncoding(fieldSchema);
167
- let encoding;
168
- if (explicit) {
169
- encoding = explicit;
170
- }
171
- else {
172
- // Infer for standard Effect date schemas (Schema.Date, DateTime, etc.)
173
- // For optional fields (Union with Undefined), unwrap to find the inner type.
174
- const inferred = inferDateEncoding(fieldSchema.ast);
175
- if (inferred)
176
- encoding = inferred;
177
- }
178
- if (encoding) {
179
- const transform = buildDateTransform(encoding);
180
- const encode = Schema.encodeUnknownSync(transform);
181
- const decode = Schema.decodeUnknownSync(transform);
182
- dateEncoders[field] = (value) => encode(value);
183
- dateDecoders[field] = (stored) => decode(stored);
184
- }
185
- }
186
203
  }
204
+ // Date ENCODERS for the write path: decompose works from the schema-decoded
205
+ // domain object, so every root date field (Pattern A self-date AND Pattern B
206
+ // transform) is serialized to its wire primitive for storage.
207
+ const dateEncoders = buildDateEncoders(schemaFields);
208
+ // Decode schema for read/assemble + input validation. Mirrors the raw `schema`
209
+ // but recursively substitutes EVERY date / Redacted leaf — root and nested,
210
+ // Pattern A and Pattern B — with a TOLERANT transform. This is the single
211
+ // decode path for get / create / update:
212
+ // - reads supply the stored wire form (string/number) → lifted to domain;
213
+ // - update re-decodes the mutated state, which carries domain `DateTime`
214
+ // values → accepted as-is (a strict `*FromString` decoder would reject
215
+ // them). It is decode-only, so making transforms tolerant is safe — the
216
+ // stored wire format is still produced by `dateEncoders` / node encoders.
217
+ // Nested edge / ref classes round-trip with their class instance identity
218
+ // preserved (Option A). Returns the raw `schema` unchanged when it carries no
219
+ // date / Redacted leaf at all (zero overhead).
220
+ //
221
+ // SINGLE ref/one edge fields carry the opaque `DynamoModel.ref` annotation, so
222
+ // the substitution can't introspect them — `resolveRef` re-points each to its
223
+ // edge target model (unwrapping `DynamoModel.configure`). MANY edges are
224
+ // excluded: their model field is a `Schema.Array(...)` (or a wrapper class) that
225
+ // `substituteSchemaDeep` introspects directly — re-pointing it at the element
226
+ // model would drop the `Array` and yield "Expected object, got []" on assemble.
227
+ const edgeRefModels = new Map();
228
+ for (const [edgeName, edge] of Object.entries(config.edges)) {
229
+ if (!("_tag" in edge))
230
+ continue;
231
+ if (edge._tag !== "RefEdge" && edge._tag !== "OneEdge")
232
+ continue;
233
+ const entity = edge.entity;
234
+ const model = entity?.model;
235
+ if (!model)
236
+ continue;
237
+ edgeRefModels.set(edgeName, DynamoModel.isConfiguredModel(model) ? model.model : model);
238
+ }
239
+ const decodeSchema = substituteSchemaDeep(schema, {
240
+ tolerantTransforms: true,
241
+ resolveRef: (name) => edgeRefModels.get(name),
242
+ });
187
243
  // Build optics at construction time (once per aggregate definition)
188
244
  const classToPlain = Schema.toIso(schema);
189
245
  const opticRoot = Schema.toIsoFocus(schema);
@@ -226,7 +282,7 @@ const makeAggregate = (schema, config) => {
226
282
  key,
227
283
  });
228
284
  }
229
- const result = yield* assembleAggregate(schema, rootNode, allItems, contextFields, dateDecoders, key, aggregateName);
285
+ const result = yield* assembleAggregate(decodeSchema, rootNode, allItems, contextFields, key, aggregateName);
230
286
  return result;
231
287
  }),
232
288
  create: (input) => Effect.gen(function* () {
@@ -234,8 +290,10 @@ const makeAggregate = (schema, config) => {
234
290
  const tableConfig = yield* config.table.Tag;
235
291
  // 1. Hydrate refs from edges
236
292
  const hydrated = yield* hydrateAggregateRefs(input, config.edges, aggregateName);
237
- // 2. Validate via schema decode
238
- const decoded = yield* Schema.decodeUnknownEffect(schema)(hydrated).pipe(Effect.mapError((cause) => new ValidationError({
293
+ // 2. Validate via schema decode (decodeSchema substitutes nested edge
294
+ // self-date/Redacted leaves — Option A — and is identical to `schema`
295
+ // when no edge needs it).
296
+ const decoded = yield* Schema.decodeUnknownEffect(decodeSchema)(hydrated).pipe(Effect.mapError((cause) => new ValidationError({
239
297
  entityType: aggregateName,
240
298
  operation: "aggregate.create",
241
299
  cause,
@@ -248,10 +306,10 @@ const makeAggregate = (schema, config) => {
248
306
  const groups = yield* decomposeAggregate(assembled, rootNode, contextFields, dateEncoders, aggregateName);
249
307
  // 5. Compose collection SK composites for root item
250
308
  const collectionSkComposites = KeyComposer.extractComposites(config.collection.sk.composite, assembled);
251
- // 6. Build DynamoDB items with composed keys
309
+ // 6. Build DynamoDB items with composed keys (create only ever PUTs)
252
310
  const dynamoGroups = buildDynamoItems(groups, config, pkValue, collectionSkComposites);
253
311
  // 7. Write via sub-aggregate transactions
254
- yield* writeTransactionGroups(client, tableConfig.name, dynamoGroups, aggregateName);
312
+ yield* writeTransactionGroups(client, tableConfig.name, dynamoGroups.map((g) => ({ group: g.group, puts: g.items, deletes: [] })), aggregateName);
255
313
  return decoded;
256
314
  }),
257
315
  update: (key, mutationFn) => Effect.gen(function* () {
@@ -264,7 +322,7 @@ const makeAggregate = (schema, config) => {
264
322
  });
265
323
  }
266
324
  // 1. Assemble current state
267
- const current = yield* assembleAggregate(schema, rootNode, allItems, contextFields, dateDecoders, key, aggregateName);
325
+ const current = yield* assembleAggregate(decodeSchema, rootNode, allItems, contextFields, key, aggregateName);
268
326
  // 2. Apply mutation — provide optics context for composable updates
269
327
  const state = classToPlain.get(current);
270
328
  const updated = mutationFn({
@@ -273,8 +331,12 @@ const makeAggregate = (schema, config) => {
273
331
  optic: opticRoot,
274
332
  current: current,
275
333
  });
276
- // 3. Validate updated state via schema decode
277
- const decoded = yield* Schema.decodeUnknownEffect(schema)(updated).pipe(Effect.mapError((cause) => new ValidationError({
334
+ // 3. Validate the mutated state via `decodeSchema` — its tolerant date
335
+ // transforms accept the domain `DateTime` values the mutation yields
336
+ // for every date field (root + nested edges, Pattern A and Pattern B),
337
+ // so update no longer trips the "Expected string, got DateTime" decode
338
+ // that a strict `*FromString` schema would raise (#72 update path).
339
+ const decoded = yield* Schema.decodeUnknownEffect(decodeSchema)(updated).pipe(Effect.mapError((cause) => new ValidationError({
278
340
  entityType: aggregateName,
279
341
  operation: "aggregate.update",
280
342
  cause,
@@ -284,7 +346,14 @@ const makeAggregate = (schema, config) => {
284
346
  // 4. Decompose both old and new
285
347
  const oldGroups = yield* decomposeAggregate(assembledOld, rootNode, contextFields, dateEncoders, aggregateName);
286
348
  const newGroups = yield* decomposeAggregate(assembledNew, rootNode, contextFields, dateEncoders, aggregateName);
287
- // 5. Diff: determine which transaction groups changed
349
+ // 5. Diff at the ITEM (primary-key) level, not just the group level.
350
+ // A `many`-edge element — and a cleared `one` edge — lives in its PARENT's
351
+ // transaction group, so removing it SHRINKS a group rather than dropping a
352
+ // whole group. A group-level diff would rewrite the group's surviving PUTs
353
+ // but never DELETE the removed row, leaving an orphan that re-appears on
354
+ // read (#74). We therefore compute, per changed group, both the items to
355
+ // PUT (new) and the items to DELETE (in old, absent from the entire new
356
+ // state), and apply them together in one transaction.
288
357
  const oldGroupMap = new Map(oldGroups.map((g) => [g.name, g]));
289
358
  const newGroupMap = new Map(newGroups.map((g) => [g.name, g]));
290
359
  // Check if context fields changed — if so, ALL groups must be rewritten
@@ -295,23 +364,47 @@ const makeAggregate = (schema, config) => {
295
364
  break;
296
365
  }
297
366
  }
298
- const groupsToWrite = [];
299
- for (const [name, newGroup] of newGroupMap) {
300
- if (contextChanged) {
301
- groupsToWrite.push(newGroup);
302
- continue;
303
- }
367
+ // 6. Build the full new + old DynamoDB item sets (with composed keys). The
368
+ // collection SK composites only affect the LSI/GSI mirror attributes,
369
+ // never the (pk, sk) identity used to PUT or DELETE, so the old set's
370
+ // composites are irrelevant — we read only its (pk, sk) for deletes.
371
+ const newDynamo = buildDynamoItems(newGroups, config, pkValue, KeyComposer.extractComposites(config.collection.sk.composite, assembledNew));
372
+ const oldDynamo = buildDynamoItems(oldGroups, config, pkValue, KeyComposer.extractComposites(config.collection.sk.composite, assembledOld));
373
+ const skOf = (item) => item.sk?.S ?? "";
374
+ const newItemsByGroup = new Map(newDynamo.map((g) => [g.group, g.items]));
375
+ const oldItemsByGroup = new Map(oldDynamo.map((g) => [g.group, g.items]));
376
+ // Every sk that survives anywhere in the new decomposition — an old item is
377
+ // an orphan to DELETE only if its key appears in no new group at all.
378
+ const survivingSks = new Set();
379
+ for (const g of newDynamo) {
380
+ for (const item of g.items)
381
+ survivingSks.add(skOf(item));
382
+ }
383
+ // 7. Per group (union of old + new names), collect PUTs + orphan DELETEs.
384
+ const groupWrites = [];
385
+ const groupNames = new Set([...newGroupMap.keys(), ...oldGroupMap.keys()]);
386
+ for (const name of groupNames) {
304
387
  const oldGroup = oldGroupMap.get(name);
305
- if (!oldGroup || !deepEqualGroups(oldGroup, newGroup)) {
306
- groupsToWrite.push(newGroup);
307
- }
388
+ const newGroup = newGroupMap.get(name);
389
+ const changed = contextChanged ||
390
+ oldGroup === undefined ||
391
+ newGroup === undefined ||
392
+ !deepEqualGroups(oldGroup, newGroup);
393
+ if (!changed)
394
+ continue;
395
+ const puts = newItemsByGroup.get(name) ?? [];
396
+ const deletes = (oldItemsByGroup.get(name) ?? [])
397
+ .filter((item) => !survivingSks.has(skOf(item)))
398
+ .map((item) => ({
399
+ [config.pk.field]: item[config.pk.field],
400
+ sk: item.sk,
401
+ }));
402
+ if (puts.length === 0 && deletes.length === 0)
403
+ continue;
404
+ groupWrites.push({ group: name, puts, deletes });
308
405
  }
309
- if (groupsToWrite.length > 0) {
310
- // 6. Compose collection SK composites
311
- const collectionSkComposites = KeyComposer.extractComposites(config.collection.sk.composite, assembledNew);
312
- // 7. Build and write changed groups
313
- const dynamoGroups = buildDynamoItems(groupsToWrite, config, pkValue, collectionSkComposites);
314
- yield* writeTransactionGroups(client, tableConfig.name, dynamoGroups, aggregateName);
406
+ if (groupWrites.length > 0) {
407
+ yield* writeTransactionGroups(client, tableConfig.name, groupWrites, aggregateName);
315
408
  }
316
409
  return decoded;
317
410
  }),
@@ -385,7 +478,7 @@ const makeAggregate = (schema, config) => {
385
478
  const { allItems } = yield* fetchPartition(key);
386
479
  if (allItems.length === 0)
387
480
  return undefined;
388
- const result = yield* assembleAggregate(schema, rootNode, allItems, contextFields, dateDecoders, key, aggregateName);
481
+ const result = yield* assembleAggregate(decodeSchema, rootNode, allItems, contextFields, key, aggregateName);
389
482
  return result;
390
483
  });
391
484
  if (assembled !== undefined)
@@ -461,7 +554,7 @@ const deepEqualGroups = (a, b) => {
461
554
  // ---------------------------------------------------------------------------
462
555
  // Internal: Resolve the graph
463
556
  // ---------------------------------------------------------------------------
464
- const resolveNode = (fieldName, entityType, cardinality, edges, discriminator, assemble, decompose, ownDiscriminator) => {
557
+ const resolveNode = (fieldName, entityType, cardinality, edges, discriminator, assemble, decompose, ownDiscriminator, dateEncoders) => {
465
558
  const children = [];
466
559
  for (const [field, edge] of Object.entries(edges)) {
467
560
  if ("_tag" in edge) {
@@ -470,14 +563,19 @@ const resolveNode = (fieldName, entityType, cardinality, edges, discriminator, a
470
563
  const mergedDisc = edge.discriminator
471
564
  ? { ...(discriminator ?? {}), ...edge.discriminator }
472
565
  : discriminator;
473
- children.push(resolveNode(field, edge.entityType, "one", {}, mergedDisc, undefined, undefined, edge.discriminator));
566
+ children.push(resolveNode(field, edge.entityType, "one", {}, mergedDisc, undefined, undefined, edge.discriminator,
567
+ // Encode this edge entity's own date fields on write (issue #72).
568
+ buildDateEncoders(fieldsOf(edge.entity?.model))));
474
569
  }
475
570
  else if (edge._tag === "ManyEdge") {
476
- children.push(resolveNode(field, edge.entityType, "many", {}, discriminator, edge.assemble, edge.decompose));
571
+ children.push(resolveNode(field, edge.entityType, "many", {}, discriminator, edge.assemble, edge.decompose, undefined, buildDateEncoders(fieldsOf(edge.entity?.model))));
477
572
  }
478
573
  else if (edge._tag === "BoundSubAggregate") {
479
574
  const bound = edge;
480
- const subChildren = resolveNode(field, bound.aggregate.root.entityType, "one", bound.aggregate.edges, bound.discriminator, undefined, undefined, bound.discriminator);
575
+ const subChildren = resolveNode(field, bound.aggregate.root.entityType, "one", bound.aggregate.edges, bound.discriminator, undefined, undefined, bound.discriminator,
576
+ // The sub-aggregate root item carries the sub-schema's own (non-edge)
577
+ // date fields; its child edges get their own encoders via recursion.
578
+ buildDateEncoders(fieldsOf(bound.aggregate.schema)));
481
579
  children.push(subChildren);
482
580
  }
483
581
  }
@@ -491,6 +589,7 @@ const resolveNode = (fieldName, entityType, cardinality, edges, discriminator, a
491
589
  children,
492
590
  assemble,
493
591
  decompose,
592
+ dateEncoders,
494
593
  };
495
594
  };
496
595
  // ---------------------------------------------------------------------------
@@ -521,7 +620,7 @@ const queryAllItems = (client, tableName, indexName, pkField, pkValue) => Effect
521
620
  // ---------------------------------------------------------------------------
522
621
  // Internal: Assembly algorithm
523
622
  // ---------------------------------------------------------------------------
524
- const assembleAggregate = (schema, rootNode, allItems, _contextFields, dateDecoders, key, aggregateName) => Effect.gen(function* () {
623
+ const assembleAggregate = (decodeSchema, rootNode, allItems, _contextFields, key, aggregateName) => Effect.gen(function* () {
525
624
  // Find the root item
526
625
  const rootItems = allItems.filter((item) => item.__edd_e__ === rootNode.entityType);
527
626
  if (rootItems.length === 0) {
@@ -574,19 +673,12 @@ const assembleAggregate = (schema, rootNode, allItems, _contextFields, dateDecod
574
673
  continue;
575
674
  rootFields[fieldKey] = value;
576
675
  }
577
- // Deserialize date context fields from DynamoDB storage primitives to domain values.
578
- // Schema.decodeUnknownEffect expects domain types (Date, DateTime), not encoded strings.
579
- // The decoder is the substituted bidirectional date schema built at make() time —
580
- // identical wire format to the legacy `deserializeDateFromDynamo` helper.
581
- for (const [field, decode] of Object.entries(dateDecoders)) {
582
- if (field in rootFields && rootFields[field] != null) {
583
- rootFields[field] = decode(rootFields[field]);
584
- }
585
- }
586
- // Merge root fields with assembled edge values
676
+ // Merge raw (wire-form) root fields with assembled edge items.
587
677
  const assembled = { ...rootFields, ...edgeValues };
588
- // Decode through the aggregate's Schema.Class
589
- const decoded = yield* Schema.decodeUnknownEffect(schema)(assembled).pipe(Effect.mapError((cause) => new ValidationError({
678
+ // Decode through `decodeSchema` — a tolerant clone of the aggregate schema
679
+ // that lifts every date / Redacted leaf (root + nested edges) from the stored
680
+ // wire form to its domain value in a single pass (#72 + Option A).
681
+ const decoded = yield* Schema.decodeUnknownEffect(decodeSchema)(assembled).pipe(Effect.mapError((cause) => new ValidationError({
590
682
  entityType: aggregateName,
591
683
  operation: "aggregate.assemble",
592
684
  cause,
@@ -716,15 +808,22 @@ const hydrateAggregateRefs = (input, edges, aggregateName) => Effect.gen(functio
716
808
  const identifierName = idField?.name ?? "id";
717
809
  // Deduplicate IDs for this entity type
718
810
  const uniqueIds = [...new Set(reqs.map((r) => r.id))];
719
- // `RefEntity` is the pure structural bound (no `get` — issue #66) so that
720
- // aggregate edges can be authored from AWS-free entity definitions. Ref
721
- // hydration is a runtime operation, so narrow back to the get-bearing
722
- // runtime entity here — the runtime path always supplies a real entity.
723
- const runtimeEntity = entity;
811
+ // `RefEntity` is the pure structural bound (no `get` — issue #66): aggregate
812
+ // edges can be authored from AWS-free `@effect-dynamodb/schema` definitions,
813
+ // which carry no runtime `.get`/operations. Ref hydration is a runtime
814
+ // operation, so promote a pure edge target to a full operational Entity (a
815
+ // thin op-attach over its retained `_data`); runtime-authored targets already
816
+ // carry `.get` and pass through untouched. Mirrors `DynamoClient.make()`'s
817
+ // entity binding. The promoted entity also exposes `.schemas`, used by the
818
+ // encode-back below (issue #72). The loop is already grouped by entity type,
819
+ // so this promotes once per distinct edge entity type per hydrate (issue #71).
820
+ const runtimeEntity = (typeof entity.get === "function"
821
+ ? entity
822
+ : entityFromDefinition(entity));
724
823
  // Build EntityGet intermediates for batch fetching
725
824
  const getOps = uniqueIds.map((id) => runtimeEntity.get({ [identifierName]: id }));
726
825
  const results = yield* Batch.get(getOps);
727
- // Map results back to lookup, failing on missing refs
826
+ // Map results back to lookup, failing on missing refs.
728
827
  for (let i = 0; i < uniqueIds.length; i++) {
729
828
  const id = uniqueIds[i];
730
829
  const result = results[i];
@@ -736,7 +835,19 @@ const hydrateAggregateRefs = (input, edges, aggregateName) => Effect.gen(functio
736
835
  refId: id,
737
836
  });
738
837
  }
739
- hydratedLookup.set(`${entityType}:${id}`, { ...result });
838
+ // `Batch.get` returns the DECODED record — transform fields are lifted to
839
+ // their domain form (e.g. `Schema.DateTimeUtcFromString` → `DateTime`). The
840
+ // denormalized ref is spliced into `input` and decoded again by the
841
+ // aggregate's strict `schema`, whose nested edge field is the ORIGINAL ref
842
+ // class expecting the wire form. Re-encode through the ref's substituted
843
+ // `recordSchema` so the spliced value is wire-form and decoded exactly once
844
+ // (issue #72) — this also keeps it marshall-safe for decompose.
845
+ const wire = yield* Schema.encodeUnknownEffect(runtimeEntity.schemas.recordSchema)(result).pipe(Effect.mapError((cause) => new ValidationError({
846
+ entityType: aggregateName,
847
+ operation: "aggregate.hydrateRefs.encode",
848
+ cause,
849
+ })));
850
+ hydratedLookup.set(`${entityType}:${id}`, wire);
740
851
  }
741
852
  }
742
853
  // Walk the input again and replace IDs with hydrated data
@@ -963,6 +1074,8 @@ const decomposeNode = (items, node, value, contextValues, parentGroup, parentDis
963
1074
  continue;
964
1075
  subRootAttrs[key] = val;
965
1076
  }
1077
+ // Serialize this node's own date fields to their wire primitive (#72).
1078
+ applyNodeDateEncoders(subRootAttrs, node.dateEncoders);
966
1079
  // Inject context and discriminator
967
1080
  mergeContextValues(subRootAttrs, contextValues);
968
1081
  if (node.discriminator) {
@@ -986,6 +1099,8 @@ const decomposeNode = (items, node, value, contextValues, parentGroup, parentDis
986
1099
  else if (node.cardinality === "one") {
987
1100
  // Simple one-to-one edge (no children)
988
1101
  const attrs = { ...value };
1102
+ // Serialize this edge entity's own date fields to their wire primitive (#72).
1103
+ applyNodeDateEncoders(attrs, node.dateEncoders);
989
1104
  mergeContextValues(attrs, contextValues);
990
1105
  if (node.discriminator) {
991
1106
  for (const [k, v] of Object.entries(node.discriminator)) {
@@ -1015,6 +1130,8 @@ const decomposeNode = (items, node, value, contextValues, parentGroup, parentDis
1015
1130
  : [];
1016
1131
  for (const elem of arrayItems) {
1017
1132
  const attrs = { ...elem };
1133
+ // Serialize this edge entity's own date fields to their wire primitive (#72).
1134
+ applyNodeDateEncoders(attrs, node.dateEncoders);
1018
1135
  mergeContextValues(attrs, contextValues);
1019
1136
  if (node.discriminator) {
1020
1137
  for (const [k, v] of Object.entries(node.discriminator)) {
@@ -1116,22 +1233,33 @@ const buildDynamoItems = (groups, config, pkValue, rootCollectionSkComposites) =
1116
1233
  // Internal: Write transaction groups to DynamoDB
1117
1234
  // ---------------------------------------------------------------------------
1118
1235
  const writeTransactionGroups = (client, tableName, groups, aggregateName) => Effect.gen(function* () {
1236
+ // Validate ALL group sizes BEFORE writing any group. Each group is its own
1237
+ // transaction (DynamoDB: 100 items per TransactWriteItems), and the per-group
1238
+ // count now spans Puts AND Deletes together — so an `update` that both adds and
1239
+ // removes many edges roughly doubles the count. Checking up front means an
1240
+ // oversized later group fails fast instead of partially committing earlier ones.
1119
1241
  for (const group of groups) {
1120
- // Check transaction size limit
1121
- if (group.items.length > 100) {
1242
+ const itemCount = group.puts.length + group.deletes.length;
1243
+ if (itemCount > 100) {
1122
1244
  return yield* new AggregateTransactionOverflow({
1123
1245
  aggregate: aggregateName,
1124
1246
  subgraph: group.group,
1125
- itemCount: group.items.length,
1247
+ itemCount,
1126
1248
  limit: 100,
1127
1249
  });
1128
1250
  }
1129
- if (group.items.length === 0)
1251
+ }
1252
+ for (const group of groups) {
1253
+ // Each group is one transaction — Puts AND Deletes applied atomically, so an
1254
+ // edge add and a sibling edge removal in the same sub-aggregate commit together.
1255
+ const itemCount = group.puts.length + group.deletes.length;
1256
+ if (itemCount === 0)
1130
1257
  continue;
1131
- // Build TransactWriteItems request
1132
- const transactItems = group.items.map((item) => ({
1133
- Put: { TableName: tableName, Item: item },
1134
- }));
1258
+ // Build TransactWriteItems request — Puts first, then Deletes for orphans.
1259
+ const transactItems = [
1260
+ ...group.puts.map((item) => ({ Put: { TableName: tableName, Item: item } })),
1261
+ ...group.deletes.map((key) => ({ Delete: { TableName: tableName, Key: key } })),
1262
+ ];
1135
1263
  yield* client.transactWriteItems({ TransactItems: transactItems }).pipe(Effect.mapError((error) => {
1136
1264
  if (error.cause != null &&
1137
1265
  typeof error.cause === "object" &&