effect-dynamodb 1.22.0 → 1.24.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 (68) hide show
  1. package/dist/Aggregate.d.ts +9 -4
  2. package/dist/Aggregate.d.ts.map +1 -1
  3. package/dist/Aggregate.js +644 -219
  4. package/dist/Aggregate.js.map +1 -1
  5. package/dist/Batch.d.ts +7 -0
  6. package/dist/Batch.d.ts.map +1 -1
  7. package/dist/Batch.js +132 -7
  8. package/dist/Batch.js.map +1 -1
  9. package/dist/Collection.d.ts.map +1 -1
  10. package/dist/Collection.js +13 -31
  11. package/dist/Collection.js.map +1 -1
  12. package/dist/DynamoClient.d.ts +40 -3
  13. package/dist/DynamoClient.d.ts.map +1 -1
  14. package/dist/DynamoClient.js +70 -19
  15. package/dist/DynamoClient.js.map +1 -1
  16. package/dist/Entity.d.ts +138 -55
  17. package/dist/Entity.d.ts.map +1 -1
  18. package/dist/Entity.js +3061 -626
  19. package/dist/Entity.js.map +1 -1
  20. package/dist/EventStore.d.ts +729 -53
  21. package/dist/EventStore.d.ts.map +1 -1
  22. package/dist/EventStore.js +1216 -231
  23. package/dist/EventStore.js.map +1 -1
  24. package/dist/Query.d.ts +75 -3
  25. package/dist/Query.d.ts.map +1 -1
  26. package/dist/Query.js +228 -30
  27. package/dist/Query.js.map +1 -1
  28. package/dist/Transaction.d.ts +13 -2
  29. package/dist/Transaction.d.ts.map +1 -1
  30. package/dist/Transaction.js +48 -38
  31. package/dist/Transaction.js.map +1 -1
  32. package/dist/index.d.ts +3 -3
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +1 -1
  35. package/dist/index.js.map +1 -1
  36. package/dist/internal/BoundCrud.d.ts +31 -20
  37. package/dist/internal/BoundCrud.d.ts.map +1 -1
  38. package/dist/internal/BoundCrud.js +1 -1
  39. package/dist/internal/BoundCrud.js.map +1 -1
  40. package/dist/internal/BoundQuery.d.ts +47 -2
  41. package/dist/internal/BoundQuery.d.ts.map +1 -1
  42. package/dist/internal/BoundQuery.js +182 -18
  43. package/dist/internal/BoundQuery.js.map +1 -1
  44. package/dist/internal/EntityCombinators.d.ts +32 -10
  45. package/dist/internal/EntityCombinators.d.ts.map +1 -1
  46. package/dist/internal/EntityCombinators.js +16 -7
  47. package/dist/internal/EntityCombinators.js.map +1 -1
  48. package/dist/internal/EntityOps.d.ts +44 -10
  49. package/dist/internal/EntityOps.d.ts.map +1 -1
  50. package/dist/internal/EntityOps.js +48 -5
  51. package/dist/internal/EntityOps.js.map +1 -1
  52. package/dist/internal/Expr.d.ts +23 -0
  53. package/dist/internal/Expr.d.ts.map +1 -1
  54. package/dist/internal/Expr.js +84 -9
  55. package/dist/internal/Expr.js.map +1 -1
  56. package/dist/internal/ItemSize.d.ts +38 -0
  57. package/dist/internal/ItemSize.d.ts.map +1 -0
  58. package/dist/internal/ItemSize.js +62 -0
  59. package/dist/internal/ItemSize.js.map +1 -0
  60. package/dist/internal/TransactWriteOps.d.ts +112 -19
  61. package/dist/internal/TransactWriteOps.d.ts.map +1 -1
  62. package/dist/internal/TransactWriteOps.js +210 -33
  63. package/dist/internal/TransactWriteOps.js.map +1 -1
  64. package/dist/internal/TransactableOps.d.ts +33 -14
  65. package/dist/internal/TransactableOps.d.ts.map +1 -1
  66. package/dist/internal/TransactableOps.js +46 -19
  67. package/dist/internal/TransactableOps.js.map +1 -1
  68. package/package.json +2 -2
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @internal Item sizes by DynamoDB's item-size rules, shared by `Batch.write`'s
3
+ * versioned transactions (chunked by size) and the client-side size check of
4
+ * `Transaction.transactWrite` and `EventStore.append` (#133).
5
+ */
6
+ /**
7
+ * DynamoDB's limit on the aggregate size of the items in one
8
+ * `TransactWriteItems` request: 4 MB, in the binary megabytes DynamoDB uses
9
+ * for every size limit (an item's 400 KB is 409,600 bytes).
10
+ */
11
+ export const TRANSACT_WRITE_MAX_BYTES = 4 * 1024 * 1024;
12
+ export const utf8Bytes = (text) => new TextEncoder().encode(text).length;
13
+ /** A number's significant digits: sign, point and exponent dropped, zeros trimmed. */
14
+ const significantDigits = (n) => {
15
+ const mantissa = n.split(/[eE]/)[0] ?? "";
16
+ const digits = mantissa.replace(/[-+.]/g, "").replace(/^0+/, "").replace(/0+$/, "");
17
+ return digits.length;
18
+ };
19
+ const numberBytes = (n, bound) => {
20
+ if (bound === "upper")
21
+ return n.length + 1;
22
+ // Zero has no significant digits, and is stored in one byte.
23
+ const digits = significantDigits(n);
24
+ return digits === 0 ? 1 : Math.ceil(digits / 2) + 1;
25
+ };
26
+ /** An attribute value's size toward its item's, erring the way `bound` says. */
27
+ export const attributeBytes = (value, bound = "lower") => {
28
+ if (value.S !== undefined)
29
+ return utf8Bytes(value.S);
30
+ if (value.N !== undefined)
31
+ return numberBytes(value.N, bound);
32
+ if (value.B !== undefined)
33
+ return value.B.byteLength;
34
+ if (value.SS !== undefined)
35
+ return value.SS.reduce((sum, v) => sum + utf8Bytes(v), 0);
36
+ if (value.NS !== undefined)
37
+ return value.NS.reduce((sum, v) => sum + numberBytes(v, bound), 0);
38
+ if (value.BS !== undefined)
39
+ return value.BS.reduce((sum, v) => sum + v.byteLength, 0);
40
+ const overhead = bound === "upper";
41
+ if (value.L !== undefined) {
42
+ return value.L.reduce((sum, v) => sum + attributeBytes(v, bound) + (overhead ? 1 : 0), overhead ? 3 : 0);
43
+ }
44
+ if (value.M !== undefined)
45
+ return itemBytes(value.M, bound) + (overhead ? 3 : 0);
46
+ return 1;
47
+ };
48
+ /** An item's size: its attribute names plus their values. */
49
+ export const itemBytes = (item, bound = "lower") => Object.entries(item).reduce((sum, [name, value]) => sum + utf8Bytes(name) + attributeBytes(value, bound), 0);
50
+ /**
51
+ * A lower bound on what one transact entry contributes to its transaction's
52
+ * size, as far as the request shows it: a Put's whole item; a Delete's,
53
+ * ConditionCheck's or Update's key. (An Update's values aren't counted: some
54
+ * may be its condition's, and the item it writes is the stored one updated,
55
+ * which the request does not carry.)
56
+ */
57
+ export const transactItemBytes = (item) => {
58
+ if (item.Put !== undefined)
59
+ return itemBytes(item.Put.Item ?? {});
60
+ return itemBytes(item.Delete?.Key ?? item.Update?.Key ?? item.ConditionCheck?.Key ?? {});
61
+ };
62
+ //# sourceMappingURL=ItemSize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ItemSize.js","sourceRoot":"","sources":["../../src/internal/ItemSize.ts"],"names":[],"mappings":"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"}
@@ -2,18 +2,21 @@
2
2
  * @internal Shared `TransactWriteItems` item-building for `Transaction.transactWrite`
3
3
  * and `EventStore.append`'s `additionalItems`.
4
4
  *
5
- * The builder is a pure compile step — its `R` is `TableConfig` only (no
6
- * `DynamoClient`) — so both call sites can assemble items before deciding what
7
- * to do with them (execute directly, or merge into a larger transaction).
5
+ * Both call sites assemble items before deciding what to do with them
6
+ * (execute directly, or merge into a larger transaction). A put of a versioned
7
+ * or unique-constrained entity reads the item it replaces (#133), so the
8
+ * builder needs `DynamoClient` as well as `TableConfig`.
8
9
  *
9
10
  * Keeping one builder is what lets `EventStore.append({ additionalItems })` and
10
11
  * `Transaction.transactWrite` accept exactly the same op union: they cannot
11
12
  * drift, and support added here (e.g. `EntityUpdate`) lands for both at once.
12
13
  */
13
14
  import type { TransactWriteItem } from "@aws-sdk/client-dynamodb";
15
+ import type { ConcurrentModification, OptimisticLockError, UniqueConstraintViolation } from "@effect-dynamodb/schema/Errors.js";
14
16
  import { ValidationError } from "@effect-dynamodb/schema/Errors.js";
15
17
  import { Effect } from "effect";
16
- import type { Entity, EntityDelete, EntityPut } from "../Entity.js";
18
+ import type { DynamoClient, DynamoClientError } from "../DynamoClient.js";
19
+ import type { Entity, EntityDelete, EntityPut, PutPlan, PutVerdict, WriteCancellationReason } from "../Entity.js";
17
20
  import type { ExpressionResult } from "../Expression.js";
18
21
  import { type TableConfig } from "../Table.js";
19
22
  import type { BoundWriteOp } from "./BoundCrud.js";
@@ -44,46 +47,136 @@ export type { TransactWriteItem };
44
47
  * AWS-free `@effect-dynamodb/schema` `Entity.make` (#100).
45
48
  */
46
49
  export type TransactWriteOp = EntityPut<any, any, any, any> | EntityDelete<any, any> | BoundWriteOp | ConditionCheckOp;
50
+ /**
51
+ * Refuse a transaction whose items exceed DynamoDB's 4 MB aggregate limit —
52
+ * BEFORE it is sent, with the entity that contributes most named, rather
53
+ * than DynamoDB's bare `ValidationException`. Sizes are a LOWER bound by
54
+ * DynamoDB's item-size rules ({@link transactItemBytes}), so a transaction
55
+ * DynamoDB would accept is never refused; a retain put counts twice — its
56
+ * item and its snapshot carry the same attributes.
57
+ */
58
+ export declare const refuseOversizedTransaction: (items: ReadonlyArray<TransactWriteItem>, targets: ReadonlyArray<TransactItemTarget>, operation: string) => Effect.Effect<void, ValidationError>;
47
59
  /**
48
60
  * What an emitted transact item was produced by, so a positional cancellation
49
61
  * reason can be attributed back to the caller op that caused it.
50
62
  *
51
63
  * Before #113 this was implicit: one caller op produced exactly one item, so
52
- * `itemIndex === opIndex`. A `put` of an entity with `unique` / `retain` now
53
- * expands into several items, and the mapping has to be carried rather than
54
- * assumed — that is what this array is for.
64
+ * `itemIndex === opIndex`. A guarded put (#133) expands into several items,
65
+ * and the mapping has to be carried rather than assumed — that is what this
66
+ * array is for.
55
67
  */
56
68
  export interface ItemProvenance {
57
69
  /** Index into the caller's `operations` array. */
58
70
  readonly opIndex: number;
59
- readonly kind: "main" | "sentinel" | "snapshot";
60
- /** Set for `kind: "sentinel"` — which `unique` constraint the item reserves. */
61
- readonly constraintName?: string | undefined;
62
- /** Set for `kind: "sentinel"` — the values reserved, for `UniqueConstraintViolation`. */
63
- readonly fields?: Record<string, string> | undefined;
71
+ /**
72
+ * `"main"`: the op's own item. `"guarded"`: one of the items of a guarded put
73
+ * — see {@link GuardedPut}, which reads their cancellation reasons.
74
+ */
75
+ readonly kind: "main" | "guarded";
64
76
  /** The entity the op targeted, so consumers can name it in an error. */
65
77
  readonly entityType: string;
66
78
  }
79
+ /**
80
+ * A put of a versioned or unique-constrained entity, planned from a fresh read
81
+ * of its item (#133) exactly as the entity's own `put` plans it: the item
82
+ * continued (or created past any retained history), its sentinels rotated —
83
+ * releasing only those it owns — and its retain snapshot.
84
+ */
85
+ export interface GuardedPut {
86
+ /** Index into the caller's `operations` array. */
87
+ readonly opIndex: number;
88
+ /** Where the plan's items start in `items`. */
89
+ readonly start: number;
90
+ readonly plan: PutPlan;
91
+ }
67
92
  /** Compiled items plus the caller-op attribution for each one. */
68
93
  export interface BuiltTransactWriteItems {
69
94
  readonly items: Array<TransactWriteItem>;
70
95
  /** Parallel to `items`: `provenance[i]` describes `items[i]`. */
71
96
  readonly provenance: Array<ItemProvenance>;
97
+ /** Parallel to `items`: the item each one writes, for {@link refuseRepeatedItems}. */
98
+ readonly targets: Array<TransactItemTarget>;
99
+ readonly guarded: ReadonlyArray<GuardedPut>;
100
+ }
101
+ /** The item a transact entry writes or checks, and how to name it in an error. */
102
+ export interface TransactItemTarget {
103
+ /** Its table and primary key, as one comparable string. */
104
+ readonly identity: string;
105
+ /** The entity (or stream) it belongs to. */
106
+ readonly entityType: string;
107
+ /** What put it in the transaction: `operation 2 (User)`, `the event at version 4`. */
108
+ readonly source: string;
109
+ /** The key, readable: `pk=…, sk=…`. */
110
+ readonly key: string;
72
111
  }
112
+ /**
113
+ * The target of a transact entry in `tableName`, keyed by `keyFields` (the
114
+ * table's primary key attributes): read from a Put's item, or any other
115
+ * entry's `Key`.
116
+ */
117
+ export declare const transactItemTarget: (item: TransactWriteItem, tableName: string, keyFields: ReadonlyArray<string>, entityType: string, source: string) => TransactItemTarget;
118
+ /**
119
+ * Refuse a transaction that writes (or checks) one item more than once —
120
+ * BEFORE it is sent. DynamoDB allows one operation per item in a transaction
121
+ * and rejects the whole request otherwise; worse, the reasons it reports for
122
+ * a guarded put can read as a lost race (`[None, ConditionalCheckFailed]`), so
123
+ * the put would be retried and finally misreported as `OptimisticLockError`
124
+ * on one backend, and as a raw validation error on another. The targets
125
+ * include the items an op derives — uniqueness sentinels (reserved or
126
+ * released) and version snapshots — so two items swapping unique values, which
127
+ * release and claim the same sentinels, are refused too.
128
+ */
129
+ export declare const refuseRepeatedItems: (targets: ReadonlyArray<TransactItemTarget>, operation: string) => Effect.Effect<void, ValidationError>;
73
130
  /**
74
131
  * Compile a list of Entity write ops into marshalled `TransactWriteItems` entries,
75
132
  * preserving caller order.
76
133
  *
77
- * **One caller op may emit several items.** A `put` of an entity with `unique`
78
- * constraints or `versioned: { retain: true }` expands into the main item plus
79
- * one guarded sentinel per satisfiable constraint plus the v1 snapshot — all
80
- * derived from the payload, so no read is needed (#113). `provenance` records
81
- * which caller op each emitted item belongs to; consumers that map cancellation
82
- * reasons positionally MUST use it instead of assuming 1:1.
134
+ * **One caller op may emit several items.** A put of a versioned or
135
+ * unique-constrained entity is a guarded put (#133): it reads the item, and
136
+ * emits the item guarded on what was read, plus its sentinel reservations and
137
+ * releases and its retain snapshot (see {@link GuardedPut}). `provenance`
138
+ * records which caller op each emitted item belongs to; consumers that map
139
+ * cancellation reasons positionally MUST use it instead of assuming 1:1, and
140
+ * read a guarded put's reasons through {@link judgeCancellation}.
141
+ *
142
+ * Refuses items that repeat one item ({@link refuseRepeatedItems}) among those
143
+ * it builds; a caller adding items of its own checks them against `targets`.
83
144
  *
84
145
  * Does NOT enforce `TRANSACT_WRITE_ITEMS_LIMIT` — the caller counts, because the
85
146
  * total may include items this builder never sees (event puts, dedup sentinels).
86
147
  * Callers must count the EXPANDED `items.length`, not `operations.length`.
87
148
  */
88
- export declare const buildTransactWriteItems: (operations: ReadonlyArray<TransactWriteOp>, operation: string) => Effect.Effect<BuiltTransactWriteItems, ValidationError, TableConfig>;
149
+ export declare const buildTransactWriteItems: (operations: ReadonlyArray<TransactWriteOp>, operation: string) => Effect.Effect<BuiltTransactWriteItems, ValidationError | DynamoClientError, TableConfig | DynamoClient>;
150
+ /** Attempts a transaction with guarded puts makes before it reports a lost race. */
151
+ export declare const GUARDED_TRANSACTION_ATTEMPTS = 3;
152
+ /**
153
+ * What a cancelled transaction of {@link buildTransactWriteItems} items means,
154
+ * from its positional reasons (`offset`: where those items start in the
155
+ * request). In order of precedence:
156
+ *
157
+ * - `fail` — a guarded put's final verdict: a unique value is taken
158
+ * (`UniqueConstraintViolation`) or its history conflicts (`ValidationError`).
159
+ * Never a caller-condition error: the caller set none.
160
+ * - `conditions` — the caller ops whose OWN condition (`.condition()`,
161
+ * `create()`'s, `Transaction.check`'s) rejected the write.
162
+ * - `retry` — a guarded put lost a race to a concurrent write (or met retained
163
+ * history its read did not see): build and write the transaction again. Its
164
+ * `error` is what to report when every attempt loses.
165
+ *
166
+ * `undefined`: no conditional failure among these items explains it.
167
+ */
168
+ export declare const judgeCancellation: (built: BuiltTransactWriteItems, reasons: ReadonlyArray<WriteCancellationReason | undefined>, offset?: number) => {
169
+ readonly _tag: "fail";
170
+ readonly opIndex: number;
171
+ readonly error: UniqueConstraintViolation | ValidationError;
172
+ } | {
173
+ readonly _tag: "conditions";
174
+ readonly opIndices: ReadonlyArray<number>;
175
+ } | {
176
+ readonly _tag: "retry";
177
+ readonly error: OptimisticLockError | ConcurrentModification;
178
+ readonly stored: Extract<PutVerdict, {
179
+ readonly _tag: "Retry";
180
+ }>["stored"];
181
+ } | undefined;
89
182
  //# sourceMappingURL=TransactWriteOps.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TransactWriteOps.d.ts","sourceRoot":"","sources":["../../src/internal/TransactWriteOps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAEnE,OAAO,KAAK,EAAkB,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExE,OAAO,EAA2B,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAalD,gBAAgB;AAChB,eAAO,MAAM,oBAAoB,EAAE,OAAO,MAAqD,CAAA;AAC/F,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAA;AAE9D;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;IACrD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACtC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAA;CACtC;AAED,gEAAgE;AAChE,YAAY,EAAE,iBAAiB,EAAE,CAAA;AAEjC;;;;;;;;;GASG;AACH,MAAM,MAAM,eAAe,GACvB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAC7B,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,GACtB,YAAY,GACZ,gBAAgB,CAAA;AAqCpB;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,CAAA;IAC/C,gFAAgF;IAChF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5C,yFAAyF;IACzF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;IACpD,wEAAwE;IACxE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,kEAAkE;AAClE,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACxC,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,CAAA;CAC3C;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,GAClC,YAAY,aAAa,CAAC,eAAe,CAAC,EAC1C,WAAW,MAAM,KAChB,MAAM,CAAC,MAAM,CAAC,uBAAuB,EAAE,eAAe,EAAE,WAAW,CA2IlE,CAAA"}
1
+ {"version":3,"file":"TransactWriteOps.d.ts","sourceRoot":"","sources":["../../src/internal/TransactWriteOps.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,10 @@
2
2
  * @internal Shared `TransactWriteItems` item-building for `Transaction.transactWrite`
3
3
  * and `EventStore.append`'s `additionalItems`.
4
4
  *
5
- * The builder is a pure compile step — its `R` is `TableConfig` only (no
6
- * `DynamoClient`) — so both call sites can assemble items before deciding what
7
- * to do with them (execute directly, or merge into a larger transaction).
5
+ * Both call sites assemble items before deciding what to do with them
6
+ * (execute directly, or merge into a larger transaction). A put of a versioned
7
+ * or unique-constrained entity reads the item it replaces (#133), so the
8
+ * builder needs `DynamoClient` as well as `TableConfig`.
8
9
  *
9
10
  * Keeping one builder is what lets `EventStore.append({ additionalItems })` and
10
11
  * `Transaction.transactWrite` accept exactly the same op union: they cannot
@@ -15,7 +16,8 @@ import { Effect } from "effect";
15
16
  import { extractTransactable } from "../Entity.js";
16
17
  import { toAttributeMap } from "../Marshaller.js";
17
18
  import { resolveTtlAttributeName } from "../Table.js";
18
- import { compileExpr, isExpr, parseShorthand } from "./Expr.js";
19
+ import { compileExpr, emptyPartProblem, isExpr, parseShorthand } from "./Expr.js";
20
+ import { TRANSACT_WRITE_MAX_BYTES, transactItemBytes } from "./ItemSize.js";
19
21
  import { composePrimaryKey, rejectUnsupportedOp, resolveTableNames, validateAndBuildPutItem, } from "./TransactableOps.js";
20
22
  // ---------------------------------------------------------------------------
21
23
  // ConditionCheck — composable from EntityGet + condition expression
@@ -33,6 +35,22 @@ const compileOpCondition = (entity, cond) => {
33
35
  const expr = isExpr(cond) ? cond : parseShorthand(cond);
34
36
  return compileExpr(expr, entity._resolveDbName);
35
37
  };
38
+ /**
39
+ * An op's condition with an empty part where none may be (#133) is refused
40
+ * before anything is sent — see `emptyPartProblem`.
41
+ */
42
+ const refuseEmptyParts = (entity, operation, opType, cond) => {
43
+ const problem = cond === undefined
44
+ ? undefined
45
+ : emptyPartProblem(isExpr(cond) ? cond : parseShorthand(cond));
46
+ return problem === undefined
47
+ ? Effect.void
48
+ : Effect.fail(new ValidationError({
49
+ entityType: entity.entityType,
50
+ operation: `${operation}.condition`,
51
+ cause: `${operation} (${opType}): ${problem} Nothing was sent.`,
52
+ }));
53
+ };
36
54
  /**
37
55
  * Spread a compiled condition onto a `Put` / `Delete` / `ConditionCheck` entry.
38
56
  * `ExpressionAttributeValues` is omitted when empty — DynamoDB rejects an empty
@@ -48,16 +66,102 @@ const conditionFields = (condition) => condition === undefined
48
66
  ? { ExpressionAttributeValues: condition.values }
49
67
  : {}),
50
68
  };
69
+ /**
70
+ * Refuse a transaction whose items exceed DynamoDB's 4 MB aggregate limit —
71
+ * BEFORE it is sent, with the entity that contributes most named, rather
72
+ * than DynamoDB's bare `ValidationException`. Sizes are a LOWER bound by
73
+ * DynamoDB's item-size rules ({@link transactItemBytes}), so a transaction
74
+ * DynamoDB would accept is never refused; a retain put counts twice — its
75
+ * item and its snapshot carry the same attributes.
76
+ */
77
+ export const refuseOversizedTransaction = (items, targets, operation) => {
78
+ let total = 0;
79
+ let largest = { index: 0, bytes: -1 };
80
+ for (const [index, item] of items.entries()) {
81
+ const bytes = transactItemBytes(item);
82
+ total += bytes;
83
+ if (bytes > largest.bytes)
84
+ largest = { index, bytes };
85
+ }
86
+ if (total <= TRANSACT_WRITE_MAX_BYTES)
87
+ return Effect.void;
88
+ const target = targets[largest.index];
89
+ return Effect.fail(new ValidationError({
90
+ entityType: target?.entityType ?? "unknown",
91
+ operation,
92
+ cause: `${operation}: the transaction's ${items.length} items total at least ${total} bytes ` +
93
+ `by DynamoDB's item-size rules, over its limit of ${TRANSACT_WRITE_MAX_BYTES} bytes (4 MB) for one ` +
94
+ "transaction. The largest is " +
95
+ (target === undefined ? "" : `${target.source}'s, at ${target.key}, `) +
96
+ `${largest.bytes} bytes. A put of a retain entity counts twice: its item and its ` +
97
+ "version snapshot. Split the operations into smaller transactions. Nothing was written.",
98
+ }));
99
+ };
100
+ /**
101
+ * The target of a transact entry in `tableName`, keyed by `keyFields` (the
102
+ * table's primary key attributes): read from a Put's item, or any other
103
+ * entry's `Key`.
104
+ */
105
+ export const transactItemTarget = (item, tableName, keyFields, entityType, source) => {
106
+ const attributes = item.Put?.Item ?? item.Delete?.Key ?? item.Update?.Key ?? item.ConditionCheck?.Key;
107
+ const parts = keyFields.map((field) => {
108
+ const value = attributes?.[field];
109
+ return { field, value, text: value?.S ?? value?.N ?? JSON.stringify(value ?? null) };
110
+ });
111
+ return {
112
+ identity: [
113
+ tableName,
114
+ ...parts.map((p) => `${p.field}=${JSON.stringify(p.value ?? null)}`),
115
+ ].join("\u0000"),
116
+ entityType,
117
+ source,
118
+ key: parts.map((p) => `${p.field}=${p.text}`).join(", "),
119
+ };
120
+ };
121
+ /**
122
+ * Refuse a transaction that writes (or checks) one item more than once —
123
+ * BEFORE it is sent. DynamoDB allows one operation per item in a transaction
124
+ * and rejects the whole request otherwise; worse, the reasons it reports for
125
+ * a guarded put can read as a lost race (`[None, ConditionalCheckFailed]`), so
126
+ * the put would be retried and finally misreported as `OptimisticLockError`
127
+ * on one backend, and as a raw validation error on another. The targets
128
+ * include the items an op derives — uniqueness sentinels (reserved or
129
+ * released) and version snapshots — so two items swapping unique values, which
130
+ * release and claim the same sentinels, are refused too.
131
+ */
132
+ export const refuseRepeatedItems = (targets, operation) => {
133
+ const seen = new Map();
134
+ for (const target of targets) {
135
+ const first = seen.get(target.identity);
136
+ if (first === undefined) {
137
+ seen.set(target.identity, target);
138
+ continue;
139
+ }
140
+ return Effect.fail(new ValidationError({
141
+ entityType: first.entityType,
142
+ operation,
143
+ cause: `${operation}: the transaction touches one item more than once — ${first.source} and ` +
144
+ `${target.source} both target the item at ${target.key}. DynamoDB allows one ` +
145
+ "operation per item in a transaction, counting the uniqueness sentinels and version " +
146
+ "snapshots a put writes. Split the operations into separate writes. Nothing was written.",
147
+ }));
148
+ }
149
+ return Effect.void;
150
+ };
51
151
  /**
52
152
  * Compile a list of Entity write ops into marshalled `TransactWriteItems` entries,
53
153
  * preserving caller order.
54
154
  *
55
- * **One caller op may emit several items.** A `put` of an entity with `unique`
56
- * constraints or `versioned: { retain: true }` expands into the main item plus
57
- * one guarded sentinel per satisfiable constraint plus the v1 snapshot — all
58
- * derived from the payload, so no read is needed (#113). `provenance` records
59
- * which caller op each emitted item belongs to; consumers that map cancellation
60
- * reasons positionally MUST use it instead of assuming 1:1.
155
+ * **One caller op may emit several items.** A put of a versioned or
156
+ * unique-constrained entity is a guarded put (#133): it reads the item, and
157
+ * emits the item guarded on what was read, plus its sentinel reservations and
158
+ * releases and its retain snapshot (see {@link GuardedPut}). `provenance`
159
+ * records which caller op each emitted item belongs to; consumers that map
160
+ * cancellation reasons positionally MUST use it instead of assuming 1:1, and
161
+ * read a guarded put's reasons through {@link judgeCancellation}.
162
+ *
163
+ * Refuses items that repeat one item ({@link refuseRepeatedItems}) among those
164
+ * it builds; a caller adding items of its own checks them against `targets`.
61
165
  *
62
166
  * Does NOT enforce `TRANSACT_WRITE_ITEMS_LIMIT` — the caller counts, because the
63
167
  * total may include items this builder never sees (event puts, dedup sentinels).
@@ -65,13 +169,22 @@ const conditionFields = (condition) => condition === undefined
65
169
  */
66
170
  export const buildTransactWriteItems = (operations, operation) => Effect.gen(function* () {
67
171
  if (operations.length === 0)
68
- return { items: [], provenance: [] };
172
+ return { items: [], provenance: [], targets: [], guarded: [] };
69
173
  const opInfos = [];
70
174
  for (let opIndex = 0; opIndex < operations.length; opIndex++) {
71
175
  const op = operations[opIndex];
72
176
  // Check for ConditionCheckOp first (has its own TypeId)
73
177
  if (op != null && typeof op === "object" && ConditionCheckTypeId in op) {
74
178
  const checkOp = op;
179
+ // A check that asserts nothing (`Expression.condition({})`) would be
180
+ // sent as an empty ConditionExpression, which DynamoDB rejects (#134).
181
+ if (checkOp._condition.expression.trim() === "") {
182
+ return yield* new ValidationError({
183
+ entityType: checkOp._entity.entityType,
184
+ operation: `${operation}.check`,
185
+ cause: `${operation}: Transaction.check() was given an empty condition. Nothing was sent.`,
186
+ });
187
+ }
75
188
  opInfos.push({
76
189
  type: "conditionCheck",
77
190
  entity: checkOp._entity,
@@ -91,8 +204,10 @@ export const buildTransactWriteItems = (operations, operation) => Effect.gen(fun
91
204
  }
92
205
  if (info.opType === "put") {
93
206
  yield* rejectUnsupportedOp(info.entity, operation, "put", info.putKind, info.input);
207
+ yield* refuseEmptyParts(info.entity, operation, "put", info.condition);
94
208
  opInfos.push({
95
209
  type: "put",
210
+ putKind: info.putKind,
96
211
  entity: info.entity,
97
212
  opIndex,
98
213
  input: info.input,
@@ -101,6 +216,7 @@ export const buildTransactWriteItems = (operations, operation) => Effect.gen(fun
101
216
  }
102
217
  else if (info.opType === "delete") {
103
218
  yield* rejectUnsupportedOp(info.entity, operation, "delete", undefined);
219
+ yield* refuseEmptyParts(info.entity, operation, "delete", info.condition);
104
220
  opInfos.push({
105
221
  type: "delete",
106
222
  entity: info.entity,
@@ -120,14 +236,39 @@ export const buildTransactWriteItems = (operations, operation) => Effect.gen(fun
120
236
  const tableNames = yield* resolveTableNames(opInfos);
121
237
  const items = [];
122
238
  const provenance = [];
123
- const push = (item, from) => {
239
+ const targets = [];
240
+ const guarded = [];
241
+ let tableName = "";
242
+ let keyFields = [];
243
+ const push = (item, from, derived = false) => {
124
244
  items.push(item);
125
245
  provenance.push(from);
246
+ targets.push(transactItemTarget(item, tableName, keyFields, from.entityType, `operation ${from.opIndex} (${from.entityType}${derived ? ", through a uniqueness sentinel or version snapshot it writes" : ""})`));
126
247
  };
127
248
  for (const op of opInfos) {
128
- const tableName = tableNames.get(op.entity);
249
+ tableName = tableNames.get(op.entity);
250
+ const primary = op.entity.indexes.primary;
251
+ keyFields = [primary.pk.field, primary.sk.field];
129
252
  if (op.type === "put") {
130
253
  const built = yield* validateAndBuildPutItem(op.entity, op.input, `${operation}.put`);
254
+ if (op.entity._incarnationToken || op.entity._multiItemWriteFeatures.includes("unique")) {
255
+ const plan = yield* op.entity._planPut({
256
+ tableName,
257
+ ttlAttrName: resolveTtlAttributeName(yield* op.entity._tableTag),
258
+ now: built.now,
259
+ item: built.item,
260
+ createdAtSupplied: built.createdAtSupplied,
261
+ userCondition: op.condition,
262
+ create: op.putKind === "create",
263
+ operation,
264
+ key: op.input,
265
+ });
266
+ guarded.push({ opIndex: op.opIndex, start: items.length, plan });
267
+ for (const [i, item] of plan.items.entries()) {
268
+ push(item, { opIndex: op.opIndex, kind: "guarded", entityType: op.entity.entityType }, i > 0);
269
+ }
270
+ continue;
271
+ }
131
272
  push({
132
273
  Put: {
133
274
  TableName: tableName,
@@ -135,25 +276,6 @@ export const buildTransactWriteItems = (operations, operation) => Effect.gen(fun
135
276
  ...conditionFields(op.condition),
136
277
  },
137
278
  }, { opIndex: op.opIndex, kind: "main", entityType: op.entity.entityType });
138
- // Uniqueness sentinels + the v1 retain snapshot. Emitted immediately
139
- // after their item so a reader of the request sees them as one group;
140
- // `provenance` is what actually carries the association.
141
- const ttlAttrName = resolveTtlAttributeName(yield* op.entity._tableTag);
142
- for (const side of op.entity._buildPutSideItems(built.item, built.now, ttlAttrName)) {
143
- push({
144
- Put: {
145
- TableName: tableName,
146
- Item: toAttributeMap(side.item),
147
- ...(side.guard ?? {}),
148
- },
149
- }, {
150
- opIndex: op.opIndex,
151
- kind: side.kind,
152
- constraintName: side.constraintName,
153
- fields: side.fields,
154
- entityType: op.entity.entityType,
155
- });
156
- }
157
279
  }
158
280
  else if (op.type === "delete") {
159
281
  push({
@@ -175,6 +297,61 @@ export const buildTransactWriteItems = (operations, operation) => Effect.gen(fun
175
297
  }, { opIndex: op.opIndex, kind: "main", entityType: op.entity.entityType });
176
298
  }
177
299
  }
178
- return { items, provenance };
300
+ yield* refuseRepeatedItems(targets, operation);
301
+ return { items, provenance, targets, guarded };
179
302
  });
303
+ // ---------------------------------------------------------------------------
304
+ // judgeCancellation
305
+ // ---------------------------------------------------------------------------
306
+ /** Attempts a transaction with guarded puts makes before it reports a lost race. */
307
+ export const GUARDED_TRANSACTION_ATTEMPTS = 3;
308
+ /**
309
+ * What a cancelled transaction of {@link buildTransactWriteItems} items means,
310
+ * from its positional reasons (`offset`: where those items start in the
311
+ * request). In order of precedence:
312
+ *
313
+ * - `fail` — a guarded put's final verdict: a unique value is taken
314
+ * (`UniqueConstraintViolation`) or its history conflicts (`ValidationError`).
315
+ * Never a caller-condition error: the caller set none.
316
+ * - `conditions` — the caller ops whose OWN condition (`.condition()`,
317
+ * `create()`'s, `Transaction.check`'s) rejected the write.
318
+ * - `retry` — a guarded put lost a race to a concurrent write (or met retained
319
+ * history its read did not see): build and write the transaction again. Its
320
+ * `error` is what to report when every attempt loses.
321
+ *
322
+ * `undefined`: no conditional failure among these items explains it.
323
+ */
324
+ export const judgeCancellation = (built, reasons, offset = 0) => {
325
+ const conditions = new Set();
326
+ let retry;
327
+ const inGuarded = new Set();
328
+ for (const { opIndex, start, plan } of built.guarded) {
329
+ for (let i = 0; i < plan.items.length; i++)
330
+ inGuarded.add(start + i);
331
+ const verdict = plan.verdict(reasons.slice(offset + start, offset + start + plan.items.length));
332
+ if (verdict === undefined)
333
+ continue;
334
+ if (verdict._tag === "Fail")
335
+ return { _tag: "fail", opIndex, error: verdict.error };
336
+ if (verdict._tag === "Condition")
337
+ conditions.add(opIndex);
338
+ else
339
+ retry ??= verdict;
340
+ }
341
+ for (let i = 0; i < built.items.length; i++) {
342
+ if (inGuarded.has(i))
343
+ continue;
344
+ if (reasons[offset + i]?.Code !== "ConditionalCheckFailed")
345
+ continue;
346
+ const from = built.provenance[i];
347
+ if (from !== undefined)
348
+ conditions.add(from.opIndex);
349
+ }
350
+ if (conditions.size > 0) {
351
+ return { _tag: "conditions", opIndices: [...conditions].sort((a, b) => a - b) };
352
+ }
353
+ if (retry !== undefined)
354
+ return { _tag: "retry", error: retry.error, stored: retry.stored };
355
+ return undefined;
356
+ };
180
357
  //# sourceMappingURL=TransactWriteOps.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TransactWriteOps.js","sourceRoot":"","sources":["../../src/internal/TransactWriteOps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TransactWriteOps.js","sourceRoot":"","sources":["../../src/internal/TransactWriteOps.ts"],"names":[],"mappings":"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"}