effect-dynamodb 1.35.0 → 1.36.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.
- package/dist/Aggregate.d.ts +1 -1
- package/dist/Aggregate.d.ts.map +1 -1
- package/dist/Aggregate.js +22 -6
- package/dist/Aggregate.js.map +1 -1
- package/dist/Batch.d.ts +1 -1
- package/dist/Batch.d.ts.map +1 -1
- package/dist/Batch.js +7 -5
- package/dist/Batch.js.map +1 -1
- package/dist/ConsumedCapacity.d.ts +107 -0
- package/dist/ConsumedCapacity.d.ts.map +1 -0
- package/dist/ConsumedCapacity.js +86 -0
- package/dist/ConsumedCapacity.js.map +1 -0
- package/dist/DynamoClient.d.ts.map +1 -1
- package/dist/DynamoClient.js +6 -1
- package/dist/DynamoClient.js.map +1 -1
- package/dist/Entity.d.ts +1 -1
- package/dist/Entity.d.ts.map +1 -1
- package/dist/Entity.js +76 -42
- package/dist/Entity.js.map +1 -1
- package/dist/EventStore.d.ts +1 -1
- package/dist/EventStore.d.ts.map +1 -1
- package/dist/EventStore.js +35 -18
- package/dist/EventStore.js.map +1 -1
- package/dist/Query.d.ts +15 -0
- package/dist/Query.d.ts.map +1 -1
- package/dist/Query.js +23 -8
- package/dist/Query.js.map +1 -1
- package/dist/Transaction.d.ts +1 -1
- package/dist/Transaction.d.ts.map +1 -1
- package/dist/Transaction.js +7 -5
- package/dist/Transaction.js.map +1 -1
- package/dist/change-feed/ChangeFeed.d.ts.map +1 -1
- package/dist/change-feed/ChangeFeed.js +7 -4
- package/dist/change-feed/ChangeFeed.js.map +1 -1
- package/dist/change-feed/CheckpointStore.d.ts +1 -1
- package/dist/change-feed/CheckpointStore.d.ts.map +1 -1
- package/dist/change-feed/CheckpointStore.js +11 -3
- package/dist/change-feed/CheckpointStore.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/BoundCrud.js +3 -3
- package/dist/internal/BoundCrud.js.map +1 -1
- package/dist/internal/BoundQuery.d.ts +16 -0
- package/dist/internal/BoundQuery.d.ts.map +1 -1
- package/dist/internal/BoundQuery.js +21 -4
- package/dist/internal/BoundQuery.js.map +1 -1
- package/dist/internal/BoundVectorQuery.d.ts +1 -1
- package/dist/internal/BoundVectorQuery.d.ts.map +1 -1
- package/dist/internal/BoundVectorQuery.js +4 -3
- package/dist/internal/BoundVectorQuery.js.map +1 -1
- package/dist/internal/Capacity.d.ts +254 -0
- package/dist/internal/Capacity.d.ts.map +1 -0
- package/dist/internal/Capacity.js +653 -0
- package/dist/internal/Capacity.js.map +1 -0
- package/dist/internal/EntityCombinators.d.ts.map +1 -1
- package/dist/internal/EntityCombinators.js +4 -4
- package/dist/internal/EntityCombinators.js.map +1 -1
- package/dist/internal/EntityOps.d.ts +10 -1
- package/dist/internal/EntityOps.d.ts.map +1 -1
- package/dist/internal/EntityOps.js +22 -4
- package/dist/internal/EntityOps.js.map +1 -1
- package/dist/internal/EventProjection.d.ts.map +1 -1
- package/dist/internal/EventProjection.js +12 -8
- package/dist/internal/EventProjection.js.map +1 -1
- package/dist/internal/MultiProjection.d.ts.map +1 -1
- package/dist/internal/MultiProjection.js +11 -8
- package/dist/internal/MultiProjection.js.map +1 -1
- package/dist/internal/ProjectionEngine.d.ts.map +1 -1
- package/dist/internal/ProjectionEngine.js +5 -5
- package/dist/internal/ProjectionEngine.js.map +1 -1
- package/dist/internal/TransactPlan.d.ts.map +1 -1
- package/dist/internal/TransactPlan.js +5 -3
- package/dist/internal/TransactPlan.js.map +1 -1
- package/package.json +2 -2
package/dist/Entity.js
CHANGED
|
@@ -17,10 +17,10 @@ import * as KeyComposer from "@effect-dynamodb/schema/KeyComposer.js";
|
|
|
17
17
|
import { normalizeGsiConfig } from "@effect-dynamodb/schema/KeyComposer.js";
|
|
18
18
|
import { deriveSourceText } from "@effect-dynamodb/schema/VectorIndex.js";
|
|
19
19
|
import { Cause, Context, Crypto, Data, DateTime, Effect, Equal, Option, Schema, Stream, } from "effect";
|
|
20
|
-
import { DynamoClient } from "./DynamoClient.js";
|
|
21
20
|
import { attributeValueEquals } from "./internal/AttributeValueEquals.js";
|
|
22
21
|
import { isBoundOp, makeBoundAppend, makeBoundDelete, makeBoundGet, makeBoundPut, makeBoundUpdate, } from "./internal/BoundCrud.js";
|
|
23
22
|
import { BoundQueryImpl, entityNaming, } from "./internal/BoundQuery.js";
|
|
23
|
+
import * as Capacity from "./internal/Capacity.js";
|
|
24
24
|
import { compileExpr, createConditionOps, emptyPartProblem, isExpr, nonEmptyCondition, parseShorthand, parseSimpleShorthand, toExpr, } from "./internal/Expr.js";
|
|
25
25
|
import { countOperators, expressionFits } from "./internal/ExpressionLimits.js";
|
|
26
26
|
import { BASE_DELAY_MS, MAX_RETRIES } from "./internal/Hydrate.js";
|
|
@@ -199,6 +199,11 @@ const compileCondition = (cond, resolveDbNameFn) => {
|
|
|
199
199
|
return compileExpr(expr, resolveDbNameFn);
|
|
200
200
|
};
|
|
201
201
|
/** Attempts a guarded put makes before it reports a lost race (#133). */
|
|
202
|
+
/** Name a get- or delete-shaped op for consumed-capacity reports (its builder carries it). */
|
|
203
|
+
const namedOp = (op, name) => {
|
|
204
|
+
Capacity.nameBuilder(op._builder, name);
|
|
205
|
+
return op;
|
|
206
|
+
};
|
|
202
207
|
const GUARDED_PUT_ATTEMPTS = 3;
|
|
203
208
|
/**
|
|
204
209
|
* @internal A delete's item was deleted between its read and its write, with
|
|
@@ -1458,7 +1463,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
1458
1463
|
const needsFullSource = needing.some(([logicalName, definition]) => withVectors?.[logicalName] === undefined &&
|
|
1459
1464
|
definition.sourceFields.some((field) => !(field in merged)));
|
|
1460
1465
|
if (needsFullSource) {
|
|
1461
|
-
const client = yield*
|
|
1466
|
+
const client = yield* Capacity.client;
|
|
1462
1467
|
const current = yield* client.getItem({ TableName: tableName, Key: marshalledKey });
|
|
1463
1468
|
if (current.Item) {
|
|
1464
1469
|
const currentDomain = fromAttributeMap(current.Item);
|
|
@@ -1766,7 +1771,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
1766
1771
|
* update still WAS applied: {@link UpdateAppliedButUnreadable}.
|
|
1767
1772
|
*/
|
|
1768
1773
|
const readRetainPostImage = (tableName, marshalledKey, replaced, ourVersion, ourIncarnation, derivedSets, derivedRemoves, ttlAttrName, encodedKey) => Effect.gen(function* () {
|
|
1769
|
-
const client = yield*
|
|
1774
|
+
const client = yield* Capacity.client;
|
|
1770
1775
|
const ours = (item) => item !== undefined &&
|
|
1771
1776
|
(incarnationAttr === undefined ||
|
|
1772
1777
|
attributeValueEquals(item[incarnationAttr], ourIncarnation));
|
|
@@ -1962,7 +1967,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
1962
1967
|
* a digit, a segment with a composite name — so a key range bounds them.
|
|
1963
1968
|
*/
|
|
1964
1969
|
const legacyHistory = (args) => Effect.gen(function* () {
|
|
1965
|
-
const client = yield*
|
|
1970
|
+
const client = yield* Capacity.client;
|
|
1966
1971
|
const primary = config.indexes.primary;
|
|
1967
1972
|
const prefix = args.kind === "version"
|
|
1968
1973
|
? DynamoSchema.composeVersionKeyPrefix(schema, entityType)
|
|
@@ -2016,7 +2021,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
2016
2021
|
* without a segment, whichever is later (its own on a tie).
|
|
2017
2022
|
*/
|
|
2018
2023
|
const latestTombstone = (tableName, pk, liveSk) => Effect.gen(function* () {
|
|
2019
|
-
const client = yield*
|
|
2024
|
+
const client = yield* Capacity.client;
|
|
2020
2025
|
const primary = config.indexes.primary;
|
|
2021
2026
|
const own = (yield* client.query({
|
|
2022
2027
|
TableName: tableName,
|
|
@@ -2144,7 +2149,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
2144
2149
|
const ownedSentinels = (tableName, candidates, owner) => Effect.gen(function* () {
|
|
2145
2150
|
if (candidates.length === 0)
|
|
2146
2151
|
return [];
|
|
2147
|
-
const client = yield*
|
|
2152
|
+
const client = yield* Capacity.client;
|
|
2148
2153
|
const pkField = config.indexes.primary.pk.field;
|
|
2149
2154
|
const skField = config.indexes.primary.sk.field;
|
|
2150
2155
|
const ownerPk = toAttributeValue(owner.pk);
|
|
@@ -2208,7 +2213,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
2208
2213
|
* overwriting its earlier incarnation's history.
|
|
2209
2214
|
*/
|
|
2210
2215
|
const highestRetainedVersion = (tableName, pk, liveSk) => Effect.gen(function* () {
|
|
2211
|
-
const client = yield*
|
|
2216
|
+
const client = yield* Capacity.client;
|
|
2212
2217
|
const primary = config.indexes.primary;
|
|
2213
2218
|
const { Items } = yield* client.query({
|
|
2214
2219
|
TableName: tableName,
|
|
@@ -2260,7 +2265,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
2260
2265
|
* is final.
|
|
2261
2266
|
*/
|
|
2262
2267
|
const planPut = (args) => Effect.gen(function* () {
|
|
2263
|
-
const client = yield*
|
|
2268
|
+
const client = yield* Capacity.client;
|
|
2264
2269
|
const pkField = config.indexes.primary.pk.field;
|
|
2265
2270
|
const skField = config.indexes.primary.sk.field;
|
|
2266
2271
|
const item = { ...args.item };
|
|
@@ -2470,7 +2475,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
2470
2475
|
* concurrency error.
|
|
2471
2476
|
*/
|
|
2472
2477
|
const runGuardedPut = (args) => Effect.gen(function* () {
|
|
2473
|
-
const client = yield*
|
|
2478
|
+
const client = yield* Capacity.client;
|
|
2474
2479
|
let lost;
|
|
2475
2480
|
for (let attempt = 0; attempt < GUARDED_PUT_ATTEMPTS; attempt++) {
|
|
2476
2481
|
const plan = yield* planPut(args);
|
|
@@ -2601,7 +2606,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
2601
2606
|
const executeCascade = (cascadeConfig, sourceDomainData, sourceIdValue) => Effect.gen(function* () {
|
|
2602
2607
|
const { targets, filter, mode } = cascadeConfig;
|
|
2603
2608
|
const sourceEntityType = entityType;
|
|
2604
|
-
const client = yield*
|
|
2609
|
+
const client = yield* Capacity.client;
|
|
2605
2610
|
if (!sourceIdentifierField)
|
|
2606
2611
|
return undefined;
|
|
2607
2612
|
const allUpdateOps = [];
|
|
@@ -2788,7 +2793,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
2788
2793
|
// dereference `self` when called by users, after make() has returned
|
|
2789
2794
|
let self;
|
|
2790
2795
|
const put = (input) => new EntityPutImpl((mode, opts) => Effect.gen(function* () {
|
|
2791
|
-
const client = yield*
|
|
2796
|
+
const client = yield* Capacity.client;
|
|
2792
2797
|
const tc = yield* tableTag;
|
|
2793
2798
|
const tableName = tc.name;
|
|
2794
2799
|
const ttlAttrName = resolveTtlAttributeName(tc);
|
|
@@ -2974,7 +2979,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
2974
2979
|
// get operation
|
|
2975
2980
|
// ---------------------------------------------------------------------------
|
|
2976
2981
|
const get = (key) => new EntityGetImpl((mode, opts) => Effect.gen(function* () {
|
|
2977
|
-
const client = yield*
|
|
2982
|
+
const client = yield* Capacity.client;
|
|
2978
2983
|
const { name: tableName } = yield* tableTag;
|
|
2979
2984
|
// Caller key: Type side in, ENCODED out (see `encodeKey`).
|
|
2980
2985
|
const encodedKey = yield* encodeKey(key, "get.decode");
|
|
@@ -3091,7 +3096,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
3091
3096
|
// The caller's condition, ANDed onto `patch`'s exists guard — a guard
|
|
3092
3097
|
// no `.condition()` can replace (#133).
|
|
3093
3098
|
const userCond = withGuard(uState.patch ? { attributeExists: [config.indexes.primary.pk.field] } : undefined, uState.condition);
|
|
3094
|
-
const client = yield*
|
|
3099
|
+
const client = yield* Capacity.client;
|
|
3095
3100
|
const tc = yield* tableTag;
|
|
3096
3101
|
const tableName = tc.name;
|
|
3097
3102
|
const ttlAttrName = resolveTtlAttributeName(tc);
|
|
@@ -4574,7 +4579,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
4574
4579
|
// so the row is read here, and a missing row is answered to the op as
|
|
4575
4580
|
// its write would have been answered: it takes the same path.
|
|
4576
4581
|
if (!recorded.readOwnRow && items.length > 0) {
|
|
4577
|
-
const client = yield*
|
|
4582
|
+
const client = yield* Capacity.client;
|
|
4578
4583
|
const { name: tableName } = yield* tableTag;
|
|
4579
4584
|
const read = yield* client.getItem({
|
|
4580
4585
|
TableName: tableName,
|
|
@@ -4760,7 +4765,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
4760
4765
|
// delete operation
|
|
4761
4766
|
// ---------------------------------------------------------------------------
|
|
4762
4767
|
const del = (key) => new EntityDeleteImpl((opts) => Effect.gen(function* () {
|
|
4763
|
-
const client = yield*
|
|
4768
|
+
const client = yield* Capacity.client;
|
|
4764
4769
|
const tc = yield* tableTag;
|
|
4765
4770
|
const tableName = tc.name;
|
|
4766
4771
|
const ttlAttrName = resolveTtlAttributeName(tc);
|
|
@@ -5151,7 +5156,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
5151
5156
|
* itself fails the upsert, as it fails an update.
|
|
5152
5157
|
*/
|
|
5153
5158
|
const guardedUpsert = (input, mode, opts) => Effect.gen(function* () {
|
|
5154
|
-
const client = yield*
|
|
5159
|
+
const client = yield* Capacity.client;
|
|
5155
5160
|
const { name: tableName } = yield* tableTag;
|
|
5156
5161
|
yield* checkWithVectorNames(opts.withVectors, "upsert");
|
|
5157
5162
|
// Required fields are required whether or not the item exists.
|
|
@@ -5252,7 +5257,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
5252
5257
|
omitsIndexedDefault(input)) {
|
|
5253
5258
|
return yield* guardedUpsert(input, mode, opts);
|
|
5254
5259
|
}
|
|
5255
|
-
const client = yield*
|
|
5260
|
+
const client = yield* Capacity.client;
|
|
5256
5261
|
const { name: tableName } = yield* tableTag;
|
|
5257
5262
|
// Clock-backed time source for createdAt/updatedAt SET clauses.
|
|
5258
5263
|
const now = yield* DateTime.now;
|
|
@@ -5561,7 +5566,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
5561
5566
|
// `ValidationError("append.followUp")`. Undetected on skipFollowUp path.
|
|
5562
5567
|
// ---------------------------------------------------------------------------
|
|
5563
5568
|
const timeSeriesConfig = config.timeSeries;
|
|
5564
|
-
const
|
|
5569
|
+
const appendCore = (input, givenCondition, skipFollowUp = false, removeAttrs) => Effect.gen(function* () {
|
|
5565
5570
|
if (!timeSeriesConfig) {
|
|
5566
5571
|
return yield* new ValidationError({
|
|
5567
5572
|
entityType,
|
|
@@ -5590,7 +5595,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
5590
5595
|
cause: `append: ${emptyPart} Nothing was sent.`,
|
|
5591
5596
|
});
|
|
5592
5597
|
}
|
|
5593
|
-
const client = yield*
|
|
5598
|
+
const client = yield* Capacity.client;
|
|
5594
5599
|
const tc = yield* tableTag;
|
|
5595
5600
|
const tableName = tc.name;
|
|
5596
5601
|
const ttlAttrName = resolveTtlAttributeName(tc);
|
|
@@ -5962,6 +5967,8 @@ const makeImpl = (config, precomputedData) => {
|
|
|
5962
5967
|
// ---------------------------------------------------------------------------
|
|
5963
5968
|
// history operation — BoundQuery for event items only
|
|
5964
5969
|
// ---------------------------------------------------------------------------
|
|
5970
|
+
// The public `append`: the core as the named operation (consumed capacity, #174).
|
|
5971
|
+
const append = (input, givenCondition, skipFollowUp = false, removeAttrs) => Capacity.operation("Entity.append", { target: entityType }, appendCore(input, givenCondition, skipFollowUp, removeAttrs));
|
|
5965
5972
|
const history = (key) => {
|
|
5966
5973
|
if (!timeSeriesConfig) {
|
|
5967
5974
|
throw new Error(`[EDD-9010] Entity "${entityType}": .history() requires timeSeries config on the entity.`);
|
|
@@ -6061,7 +6068,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
6061
6068
|
// getVersion operation
|
|
6062
6069
|
// ---------------------------------------------------------------------------
|
|
6063
6070
|
const getVersion = (key, versionNumber) => new EntityGetImpl((mode, opts) => Effect.gen(function* () {
|
|
6064
|
-
const client = yield*
|
|
6071
|
+
const client = yield* Capacity.client;
|
|
6065
6072
|
const { name: tableName } = yield* tableTag;
|
|
6066
6073
|
// Caller key: Type side in, ENCODED out (see `encodeKey`).
|
|
6067
6074
|
const encodedKey = yield* encodeKey(key, "getVersion.decode");
|
|
@@ -6113,7 +6120,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
6113
6120
|
const legacy = yield* legacyHistory({ tableName, pk: pkValue, liveSk, kind: "version" });
|
|
6114
6121
|
if (legacy.length === 0)
|
|
6115
6122
|
return {};
|
|
6116
|
-
const client = yield*
|
|
6123
|
+
const client = yield* Capacity.client;
|
|
6117
6124
|
const own = new Set();
|
|
6118
6125
|
let start;
|
|
6119
6126
|
do {
|
|
@@ -6244,7 +6251,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
6244
6251
|
// restore operation
|
|
6245
6252
|
// ---------------------------------------------------------------------------
|
|
6246
6253
|
const restore = (key) => new EntityGetImpl((mode, _opts) => Effect.gen(function* () {
|
|
6247
|
-
const client = yield*
|
|
6254
|
+
const client = yield* Capacity.client;
|
|
6248
6255
|
const tc = yield* tableTag;
|
|
6249
6256
|
const tableName = tc.name;
|
|
6250
6257
|
const ttlAttrName = resolveTtlAttributeName(tc);
|
|
@@ -6446,7 +6453,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
6446
6453
|
"delete(key).condition(...) instead.",
|
|
6447
6454
|
});
|
|
6448
6455
|
}
|
|
6449
|
-
const client = yield*
|
|
6456
|
+
const client = yield* Capacity.client;
|
|
6450
6457
|
const { name: tableName } = yield* tableTag;
|
|
6451
6458
|
// Caller key: Type side in, ENCODED out (see `encodeKey`).
|
|
6452
6459
|
const encodedKey = yield* encodeKey(key, "purge.decode");
|
|
@@ -6743,7 +6750,7 @@ const makeImpl = (config, precomputedData) => {
|
|
|
6743
6750
|
_liveRows: liveRows,
|
|
6744
6751
|
_attachPrototype: attachPrototype,
|
|
6745
6752
|
_overTombstone: (tableName, item) => Effect.gen(function* () {
|
|
6746
|
-
const client = yield*
|
|
6753
|
+
const client = yield* Capacity.client;
|
|
6747
6754
|
return yield* overTombstone(self, client, tableName, item);
|
|
6748
6755
|
}),
|
|
6749
6756
|
_configure: (injectedSchema, injectedTableTag) => {
|
|
@@ -6776,11 +6783,16 @@ const makeImpl = (config, precomputedData) => {
|
|
|
6776
6783
|
deleteIfExists,
|
|
6777
6784
|
upsert,
|
|
6778
6785
|
scan,
|
|
6779
|
-
|
|
6786
|
+
// Lifecycle ops reuse the get / delete carriers; their builders carry the
|
|
6787
|
+
// operation name consumed-capacity reports use (#174).
|
|
6788
|
+
getVersion: (key, versionNumber) => namedOp(getVersion(key, versionNumber), "Entity.getVersion"),
|
|
6780
6789
|
versions,
|
|
6781
|
-
restore,
|
|
6782
|
-
purge,
|
|
6783
|
-
deleted: {
|
|
6790
|
+
restore: (key) => namedOp(restore(key), "Entity.restore"),
|
|
6791
|
+
purge: (key) => namedOp(purge(key), "Entity.purge"),
|
|
6792
|
+
deleted: {
|
|
6793
|
+
get: (key) => namedOp(deletedGet(key), "Entity.deleted.get"),
|
|
6794
|
+
list: deletedList,
|
|
6795
|
+
},
|
|
6784
6796
|
append,
|
|
6785
6797
|
history,
|
|
6786
6798
|
set,
|
|
@@ -6821,7 +6833,8 @@ export const bind = (entity) => Effect.gen(function* () {
|
|
|
6821
6833
|
// Crypto-requiring entity ops typecheck. A platform override supplied via
|
|
6822
6834
|
// `DynamoClient.make({ crypto })` is already in `baseCtx` and is respected
|
|
6823
6835
|
// (we only fill the default when absent). See `DESIGN.md`.
|
|
6824
|
-
|
|
6836
|
+
// Detached: no current operation or parent span is pinned for later calls (#174).
|
|
6837
|
+
const baseCtx = Capacity.detachContext(yield* Effect.context());
|
|
6825
6838
|
const ctx = Option.isSome(Context.getOption(baseCtx, Crypto.Crypto))
|
|
6826
6839
|
? baseCtx
|
|
6827
6840
|
: Context.add(baseCtx, Crypto.Crypto, makeDefaultCrypto());
|
|
@@ -6849,12 +6862,13 @@ export const bind = (entity) => Effect.gen(function* () {
|
|
|
6849
6862
|
// pre-resolved provide. Used by `versions` and `deleted.list` accessors so consumers
|
|
6850
6863
|
// get the same fluent .collect() / .fetch() / .paginate() / .reverse() / .limit() /
|
|
6851
6864
|
// .filter() ergonomics they get from index accessors and `.scan()`.
|
|
6852
|
-
const wrapAsBoundQuery = (q) => {
|
|
6865
|
+
const wrapAsBoundQuery = (q, operation) => {
|
|
6853
6866
|
const bqConfig = {
|
|
6854
6867
|
pathBuilder: createPathBuilder(),
|
|
6855
6868
|
conditionOps: createConditionOps(),
|
|
6856
6869
|
provide,
|
|
6857
6870
|
...entityNaming(entity._resolveDbName),
|
|
6871
|
+
operation: { name: operation, target: entity.entityType },
|
|
6858
6872
|
};
|
|
6859
6873
|
return new BoundQueryImpl(q, bqConfig);
|
|
6860
6874
|
};
|
|
@@ -6880,10 +6894,10 @@ export const bind = (entity) => Effect.gen(function* () {
|
|
|
6880
6894
|
const primary = entity.indexes.primary;
|
|
6881
6895
|
const boundEntityVersion = entity._entityVersion;
|
|
6882
6896
|
const concurrency = options?.concurrency ?? 4;
|
|
6883
|
-
return provide(Effect.gen(function* () {
|
|
6897
|
+
return provide(Capacity.operation("Entity.reembed", { target: entity.entityType }, Effect.gen(function* () {
|
|
6884
6898
|
if (vectorDefs.length === 0)
|
|
6885
6899
|
return 0;
|
|
6886
|
-
const client = yield*
|
|
6900
|
+
const client = yield* Capacity.client;
|
|
6887
6901
|
const { name: tableName } = yield* entity._tableTag;
|
|
6888
6902
|
const reembedItem = (marshalled) => Effect.gen(function* () {
|
|
6889
6903
|
const raw = fromAttributeMap(marshalled);
|
|
@@ -6982,7 +6996,7 @@ export const bind = (entity) => Effect.gen(function* () {
|
|
|
6982
6996
|
exclusiveStartKey = page.LastEvaluatedKey;
|
|
6983
6997
|
} while (exclusiveStartKey !== undefined);
|
|
6984
6998
|
return updated;
|
|
6985
|
-
}));
|
|
6999
|
+
})));
|
|
6986
7000
|
};
|
|
6987
7001
|
return {
|
|
6988
7002
|
// CRUD — fluent bound builders (yieldable, no .run() terminal)
|
|
@@ -6996,13 +7010,13 @@ export const bind = (entity) => Effect.gen(function* () {
|
|
|
6996
7010
|
patch: (key) => makeBoundUpdate(entity.patch(key), boundCrudConfig),
|
|
6997
7011
|
deleteIfExists: (key) => makeBoundDelete(entity.deleteIfExists(key), boundCrudConfig),
|
|
6998
7012
|
// Lifecycle
|
|
6999
|
-
getVersion: (key, version) => provide(entity.getVersion(key, version).
|
|
7000
|
-
versions: (key) => wrapAsBoundQuery(entity.versions(key)),
|
|
7001
|
-
restore: (key) => provide(entity.restore(key).
|
|
7013
|
+
getVersion: (key, version) => provide(entity.getVersion(key, version)._exec("record")),
|
|
7014
|
+
versions: (key) => wrapAsBoundQuery(entity.versions(key), "Entity.versions"),
|
|
7015
|
+
restore: (key) => provide(entity.restore(key)._exec("record")),
|
|
7002
7016
|
purge: (key) => provide(entity.purge(key).asEffect()),
|
|
7003
7017
|
deleted: {
|
|
7004
|
-
get: (key) => provide(entity.deleted.get(key).
|
|
7005
|
-
list: (key) => wrapAsBoundQuery(entity.deleted.list(key)),
|
|
7018
|
+
get: (key) => provide(entity.deleted.get(key)._exec("record")),
|
|
7019
|
+
list: (key) => wrapAsBoundQuery(entity.deleted.list(key), "Entity.deleted.list"),
|
|
7006
7020
|
},
|
|
7007
7021
|
// Time-series (no-ops when entity is not configured; runtime check in
|
|
7008
7022
|
// the entity-level `append` returns a ValidationError).
|
|
@@ -7061,17 +7075,37 @@ export const bind = (entity) => Effect.gen(function* () {
|
|
|
7061
7075
|
skFields: orderBy ? [orderBy] : [],
|
|
7062
7076
|
composeSkCondition,
|
|
7063
7077
|
...entityNaming(entity._resolveDbName),
|
|
7078
|
+
operation: { name: "Entity.history", target: entity.entityType },
|
|
7064
7079
|
};
|
|
7065
7080
|
return new BoundQueryImpl(q, bqConfig);
|
|
7066
7081
|
},
|
|
7067
7082
|
// Query execution
|
|
7083
|
+
// Each helper is a named operation, inside `provide` (consumed capacity, #174).
|
|
7068
7084
|
paginate: (q, ...combinators) => {
|
|
7069
7085
|
const final = applyQuery(q, combinators);
|
|
7070
|
-
|
|
7086
|
+
const options = {
|
|
7087
|
+
...Query.operationOptions(final),
|
|
7088
|
+
target: entity.entityType,
|
|
7089
|
+
};
|
|
7090
|
+
return Stream.unwrap(provide(Effect.flatMap(Query.paginate(final), (pages) => Capacity.operationStream("Entity.paginate", options, pages)))).pipe(Stream.flatMap((page) => Stream.fromIterable(page)));
|
|
7091
|
+
},
|
|
7092
|
+
collect: (q, ...combinators) => {
|
|
7093
|
+
const final = applyQuery(q, combinators);
|
|
7094
|
+
const options = {
|
|
7095
|
+
...Query.operationOptions(final),
|
|
7096
|
+
target: entity.entityType,
|
|
7097
|
+
};
|
|
7098
|
+
return provide(Capacity.operation("Entity.collect", options, Query.collect(final)));
|
|
7099
|
+
},
|
|
7100
|
+
fetch: (q, ...combinators) => {
|
|
7101
|
+
const final = applyQuery(q, combinators);
|
|
7102
|
+
const options = {
|
|
7103
|
+
...Query.operationOptions(final),
|
|
7104
|
+
target: entity.entityType,
|
|
7105
|
+
};
|
|
7106
|
+
return provide(Capacity.operation("Entity.fetch", options, Query.execute(final)));
|
|
7071
7107
|
},
|
|
7072
|
-
|
|
7073
|
-
fetch: (q, ...combinators) => provide(Query.execute(applyQuery(q, combinators))),
|
|
7074
|
-
scanFetch: (...combinators) => provide(Query.execute(applyQuery(entity.scan(), combinators))),
|
|
7108
|
+
scanFetch: (...combinators) => provide(Capacity.operation("Entity.scan", { target: entity.entityType }, Query.execute(applyQuery(entity.scan(), combinators)))),
|
|
7075
7109
|
};
|
|
7076
7110
|
});
|
|
7077
7111
|
const tagged = (tags) => (e) => typeof e === "object" && e !== null && "_tag" in e && tags.has(String(e._tag));
|