@farukada/aws-langgraph-dynamodb-ts 0.8.0 → 0.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.
- package/README.md +1 -1
- package/dist/checkpointer/actions/list.d.ts.map +1 -1
- package/dist/checkpointer/actions/list.js +7 -0
- package/dist/checkpointer/actions/list.js.map +1 -1
- package/dist/checkpointer/actions/put-writes.d.ts.map +1 -1
- package/dist/checkpointer/actions/put-writes.js +2 -1
- package/dist/checkpointer/actions/put-writes.js.map +1 -1
- package/dist/checkpointer/internal/item-reader.d.ts +14 -0
- package/dist/checkpointer/internal/item-reader.d.ts.map +1 -1
- package/dist/checkpointer/internal/item-reader.js +15 -1
- package/dist/checkpointer/internal/item-reader.js.map +1 -1
- package/dist/checkpointer/internal/item-writer.d.ts.map +1 -1
- package/dist/checkpointer/internal/item-writer.js +2 -1
- package/dist/checkpointer/internal/item-writer.js.map +1 -1
- package/dist/checkpointer/internal/special-write-cas.d.ts +30 -0
- package/dist/checkpointer/internal/special-write-cas.d.ts.map +1 -0
- package/dist/checkpointer/internal/special-write-cas.js +104 -0
- package/dist/checkpointer/internal/special-write-cas.js.map +1 -0
- package/dist/checkpointer/internal/special-write-cleanup.d.ts +18 -12
- package/dist/checkpointer/internal/special-write-cleanup.d.ts.map +1 -1
- package/dist/checkpointer/internal/special-write-cleanup.js +31 -86
- package/dist/checkpointer/internal/special-write-cleanup.js.map +1 -1
- package/dist/checkpointer/internal/special-write-verify.d.ts +54 -0
- package/dist/checkpointer/internal/special-write-verify.d.ts.map +1 -0
- package/dist/checkpointer/internal/special-write-verify.js +65 -0
- package/dist/checkpointer/internal/special-write-verify.js.map +1 -0
- package/dist/checkpointer/internal/write-guard.d.ts +0 -8
- package/dist/checkpointer/internal/write-guard.d.ts.map +1 -1
- package/dist/checkpointer/internal/write-guard.js +0 -9
- package/dist/checkpointer/internal/write-guard.js.map +1 -1
- package/dist/checkpointer/internal/write-index.d.ts +8 -0
- package/dist/checkpointer/internal/write-index.d.ts.map +1 -1
- package/dist/checkpointer/internal/write-index.js +6 -2
- package/dist/checkpointer/internal/write-index.js.map +1 -1
- package/dist/checkpointer/types.d.ts +6 -0
- package/dist/checkpointer/types.d.ts.map +1 -1
- package/dist/shared/constants.d.ts +15 -0
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/constants.js +16 -1
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/dynamodb/conditional-put.d.ts +51 -0
- package/dist/shared/dynamodb/conditional-put.d.ts.map +1 -0
- package/dist/shared/dynamodb/conditional-put.js +59 -0
- package/dist/shared/dynamodb/conditional-put.js.map +1 -0
- package/dist/shared/logging/redaction.d.ts +5 -1
- package/dist/shared/logging/redaction.d.ts.map +1 -1
- package/dist/shared/logging/redaction.js.map +1 -1
- package/dist/shared/logging/secret-patterns.d.ts +33 -0
- package/dist/shared/logging/secret-patterns.d.ts.map +1 -1
- package/dist/shared/logging/secret-patterns.js +35 -2
- package/dist/shared/logging/secret-patterns.js.map +1 -1
- package/dist/store/actions/put.d.ts.map +1 -1
- package/dist/store/actions/put.js +4 -16
- package/dist/store/actions/put.js.map +1 -1
- package/dist/store/internal/backend-search.d.ts.map +1 -1
- package/dist/store/internal/backend-search.js +2 -1
- package/dist/store/internal/backend-search.js.map +1 -1
- package/dist/store/internal/filter.d.ts.map +1 -1
- package/dist/store/internal/filter.js +25 -5
- package/dist/store/internal/filter.js.map +1 -1
- package/dist/store/internal/index-reconcile.d.ts.map +1 -1
- package/dist/store/internal/index-reconcile.js +8 -2
- package/dist/store/internal/index-reconcile.js.map +1 -1
- package/dist/store/internal/item-mapper.d.ts +1 -0
- package/dist/store/internal/item-mapper.d.ts.map +1 -1
- package/dist/store/internal/item-mapper.js +2 -0
- package/dist/store/internal/item-mapper.js.map +1 -1
- package/dist/store/internal/overwrite-swap.d.ts +33 -0
- package/dist/store/internal/overwrite-swap.d.ts.map +1 -0
- package/dist/store/internal/overwrite-swap.js +62 -0
- package/dist/store/internal/overwrite-swap.js.map +1 -0
- package/dist/store/internal/persist.d.ts +22 -6
- package/dist/store/internal/persist.d.ts.map +1 -1
- package/dist/store/internal/persist.js +42 -17
- package/dist/store/internal/persist.js.map +1 -1
- package/dist/store/internal/read-existing.d.ts +19 -0
- package/dist/store/internal/read-existing.d.ts.map +1 -0
- package/dist/store/internal/read-existing.js +29 -0
- package/dist/store/internal/read-existing.js.map +1 -0
- package/dist/store/internal/score-direction.d.ts +32 -0
- package/dist/store/internal/score-direction.d.ts.map +1 -0
- package/dist/store/internal/score-direction.js +39 -0
- package/dist/store/internal/score-direction.js.map +1 -0
- package/dist/store/internal/setup.d.ts +2 -0
- package/dist/store/internal/setup.d.ts.map +1 -1
- package/dist/store/internal/setup.js +41 -1
- package/dist/store/internal/setup.js.map +1 -1
- package/dist/store/internal/write-verify.d.ts +20 -7
- package/dist/store/internal/write-verify.d.ts.map +1 -1
- package/dist/store/internal/write-verify.js +22 -9
- package/dist/store/internal/write-verify.js.map +1 -1
- package/dist/store/types.d.ts +16 -0
- package/dist/store/types.d.ts.map +1 -1
- package/dist/store/vector-backend.d.ts +6 -6
- package/package.json +1 -1
|
@@ -11,22 +11,10 @@ const index_sync_1 = require("../internal/index-sync");
|
|
|
11
11
|
const item_mapper_1 = require("../internal/item-mapper");
|
|
12
12
|
const keys_1 = require("../internal/keys");
|
|
13
13
|
const persist_1 = require("../internal/persist");
|
|
14
|
+
const read_existing_1 = require("../internal/read-existing");
|
|
14
15
|
const semantic_search_1 = require("../internal/semantic-search");
|
|
15
16
|
const validation_1 = require("../internal/validation");
|
|
16
17
|
const write_verify_1 = require("../internal/write-verify");
|
|
17
|
-
async function readExisting(context, pk, sk) {
|
|
18
|
-
const existing = await (0, retry_1.withDynamoDBRetry)(() => context.client.get({
|
|
19
|
-
TableName: context.tableName,
|
|
20
|
-
Key: { PK: pk, SK: sk },
|
|
21
|
-
ConsistentRead: true,
|
|
22
|
-
ProjectionExpression: '#c, #v',
|
|
23
|
-
ExpressionAttributeNames: { '#c': 'createdAt', '#v': 'value' },
|
|
24
|
-
}));
|
|
25
|
-
return {
|
|
26
|
-
createdAt: existing.Item?.createdAt,
|
|
27
|
-
value: existing.Item?.value,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
18
|
/**
|
|
31
19
|
* Delete the item and, when a vector backend is configured, drop its vector.
|
|
32
20
|
*
|
|
@@ -39,7 +27,7 @@ async function readExisting(context, pk, sk) {
|
|
|
39
27
|
* failure, or a row still present, propagates unchanged.
|
|
40
28
|
*/
|
|
41
29
|
async function deleteStoreItem(context, op, pk, sk) {
|
|
42
|
-
const existing = context.offloader ? await readExisting(context, pk, sk) : undefined;
|
|
30
|
+
const existing = context.offloader ? await (0, read_existing_1.readExisting)(context, pk, sk) : undefined;
|
|
43
31
|
try {
|
|
44
32
|
await (0, retry_1.withDynamoDBRetry)(() => context.client.delete({ TableName: context.tableName, Key: { PK: pk, SK: sk } }));
|
|
45
33
|
}
|
|
@@ -79,7 +67,7 @@ async function putItem(context, op) {
|
|
|
79
67
|
}
|
|
80
68
|
const value = op.value;
|
|
81
69
|
const timestamp = (0, clock_1.nowIso)();
|
|
82
|
-
const existing = await readExisting(context, pk, sk);
|
|
70
|
+
const existing = await (0, read_existing_1.readExisting)(context, pk, sk);
|
|
83
71
|
const embedding = await resolveEmbedding(context, op, value);
|
|
84
72
|
const ttlTimestamp = context.ttl ? (0, ttl_1.calculateTtlTimestamp)(context.ttl) : undefined;
|
|
85
73
|
const record = await (0, item_mapper_1.buildStoreItem)(context, op.namespace, op.key, value, {
|
|
@@ -89,7 +77,7 @@ async function putItem(context, op) {
|
|
|
89
77
|
ttlTimestamp,
|
|
90
78
|
nonce: (0, node_crypto_1.randomUUID)(),
|
|
91
79
|
});
|
|
92
|
-
await (0, persist_1.persistRecord)(context, record, existing
|
|
80
|
+
await (0, persist_1.persistRecord)(context, record, existing);
|
|
93
81
|
if (context.vectorBackend) {
|
|
94
82
|
await (0, index_sync_1.syncVectorIndex)(context.vectorBackend, op.namespace, op.key, embedding, context.logger);
|
|
95
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"put.js","sourceRoot":"","sources":["../../../src/store/actions/put.ts"],"names":[],"mappings":";;;AAAA,6CAAyC;AAIzC,8CAA4C;
|
|
1
|
+
{"version":3,"file":"put.js","sourceRoot":"","sources":["../../../src/store/actions/put.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-search.d.ts","sourceRoot":"","sources":["../../../src/store/internal/backend-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAEX,UAAU,EACV,eAAe,EAChB,MAAM,iCAAiC,CAAC;AAIzC,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"backend-search.d.ts","sourceRoot":"","sources":["../../../src/store/internal/backend-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAEX,UAAU,EACV,eAAe,EAChB,MAAM,iCAAiC,CAAC;AAIzC,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,mBAAmB,CAAC;AAIpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA4C5C,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,WAAW,EAClB,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,EAAE,CAAC,CA6BvB"}
|
|
@@ -4,6 +4,7 @@ exports.searchViaBackend = searchViaBackend;
|
|
|
4
4
|
const errors_1 = require("../../shared/errors/errors");
|
|
5
5
|
const get_1 = require("../actions/get");
|
|
6
6
|
const keys_1 = require("./keys");
|
|
7
|
+
const score_direction_1 = require("./score-direction");
|
|
7
8
|
const search_filter_1 = require("./search-filter");
|
|
8
9
|
/**
|
|
9
10
|
* Warn when a backend's own ordering disagrees with its scores. A backend
|
|
@@ -48,7 +49,7 @@ async function searchViaBackend(context, backend, index, op, offset, limit) {
|
|
|
48
49
|
let topK = Math.min(need, context.maxSearchCandidates);
|
|
49
50
|
let results;
|
|
50
51
|
for (;;) {
|
|
51
|
-
const matches = await backend.query(op.namespacePrefix, queryVector, topK);
|
|
52
|
+
const matches = (0, score_direction_1.toRelevanceScores)(await backend.query(op.namespacePrefix, queryVector, topK), context.vectorScoreDirection);
|
|
52
53
|
warnOnNonDescendingScores(context, matches, op.namespacePrefix);
|
|
53
54
|
results = [];
|
|
54
55
|
for (const match of matches) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-search.js","sourceRoot":"","sources":["../../../src/store/internal/backend-search.ts"],"names":[],"mappings":";;;AAOA,uDAA6D;AAC7D,wCAAyC;AAEzC,iCAAgD;AAChD,mDAA+C;AAG/C;;;;;;GAMG;AACH,SAAS,yBAAyB,CAChC,OAAqB,EACrB,OAAsB,EACtB,eAAyB;IAEzB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAC9B,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAClF,CAAC;IACF,IAAI,UAAU;QAAE,OAAO;IACvB,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,yFAAyF;QACvF,0FAA0F,EAC5F,EAAE,eAAe,EAAE,CACpB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,UAAU,CAAC,OAAqB,EAAE,KAAkB;IACjE,IAAI,CAAC;QACH,OAAO,MAAM,IAAA,aAAO,EAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,iDAAiD,EAAE;YACrE,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,MAAM,EAAG,KAAe,CAAC,IAAI;SAC9B,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAEM,KAAK,2BACV,OAAqB,EACrB,OAAsB,EACtB,KAAkB,EAClB,EAAmB,EACnB,MAAc,EACd,KAAa;IAEb,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,KAAe,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC;IAC5B,IAAI,IAAI,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACvC,MAAM,IAAI,wBAAe,CACvB,0BAA0B,MAAM,YAAY,KAAK,MAAM,IAAI,gCAAgC;YACzF,IAAI,OAAO,CAAC,mBAAmB,iDAAiD,EAClF,qBAAqB,CACtB,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACvD,IAAI,OAAqB,CAAC;IAC1B,SAAS,CAAC;QACR,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"backend-search.js","sourceRoot":"","sources":["../../../src/store/internal/backend-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../src/store/internal/filter.ts"],"names":[],"mappings":"AAEA,8DAA8D;AAC9D,MAAM,MAAM,SAAS,GACnB,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../src/store/internal/filter.ts"],"names":[],"mappings":"AAEA,8DAA8D;AAC9D,MAAM,MAAM,SAAS,GACnB,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAyFhF;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAChC,OAAO,CAMT"}
|
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.matchesStoreFilter = matchesStoreFilter;
|
|
4
4
|
const node_util_1 = require("node:util");
|
|
5
|
+
/**
|
|
6
|
+
* Three-way order for a like-typed pair, or `undefined` when the pair is
|
|
7
|
+
* *unordered*. `NaN` compares `false` against everything including itself, so a
|
|
8
|
+
* bare `===`/`>` ternary silently reports it as "less than" — which let a
|
|
9
|
+
* stored `NaN` satisfy `$lt`/`$lte` against any number, contradicting
|
|
10
|
+
* {@link compareOrdered}'s own contract.
|
|
11
|
+
*/
|
|
12
|
+
function orderOf(actual, expected) {
|
|
13
|
+
if (actual < expected)
|
|
14
|
+
return -1;
|
|
15
|
+
if (actual > expected)
|
|
16
|
+
return 1;
|
|
17
|
+
return actual === expected ? 0 : undefined;
|
|
18
|
+
}
|
|
19
|
+
/** Apply `test` to a resolved order; an unordered pair never matches. */
|
|
20
|
+
function testOrder(order, test) {
|
|
21
|
+
return order !== undefined && test(order);
|
|
22
|
+
}
|
|
5
23
|
/**
|
|
6
24
|
* Ordered comparison over like-typed values only: numbers compare numerically,
|
|
7
25
|
* strings lexicographically, and a mismatched or unordered pair never matches.
|
|
@@ -14,11 +32,13 @@ const node_util_1 = require("node:util");
|
|
|
14
32
|
* directly is well-defined in both cases.
|
|
15
33
|
*/
|
|
16
34
|
function compareOrdered(actual, expected, test) {
|
|
17
|
-
|
|
18
|
-
(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
35
|
+
if (typeof actual === 'number' && typeof expected === 'number') {
|
|
36
|
+
return testOrder(orderOf(actual, expected), test);
|
|
37
|
+
}
|
|
38
|
+
if (typeof actual === 'string' && typeof expected === 'string') {
|
|
39
|
+
return testOrder(orderOf(actual, expected), test);
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
22
42
|
}
|
|
23
43
|
const COMPARATORS = {
|
|
24
44
|
$eq: (actual, expected) => (0, node_util_1.isDeepStrictEqual)(actual, expected),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../src/store/internal/filter.ts"],"names":[],"mappings":";;;AAAA,yCAA8C;AAM9C
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../src/store/internal/filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-reconcile.d.ts","sourceRoot":"","sources":["../../../src/store/internal/index-reconcile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index-reconcile.d.ts","sourceRoot":"","sources":["../../../src/store/internal/index-reconcile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAMlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACjC;AAOD;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,eAAe,EAAE,CAAC,CAqB5B;AAED,6EAA6E;AAC7E,wBAAsB,cAAc,CAClC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,eAAe,EAAE,GACzB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE,CAO5F;AAeD,8EAA8E;AAC9E,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,eAAe,EAAE,GACtB,OAAO,CAAC,MAAM,CAAC,CA6BjB"}
|
|
@@ -28,8 +28,14 @@ async function collectReconcileTargets(context, prefix) {
|
|
|
28
28
|
maxItems: context.maxScanItems,
|
|
29
29
|
});
|
|
30
30
|
for await (const raw of source) {
|
|
31
|
-
const record = raw;
|
|
32
|
-
if (!record
|
|
31
|
+
const record = (0, item_mapper_1.narrowStoreRecord)(raw);
|
|
32
|
+
if (!record) {
|
|
33
|
+
context.logger.warn('reconcileVectorIndex: skipped a row that is not a store item', {
|
|
34
|
+
sortKey: raw.SK,
|
|
35
|
+
});
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (!(0, keys_1.namespaceMatchesPrefix)(record.namespace, prefix))
|
|
33
39
|
continue;
|
|
34
40
|
const item = await (0, item_mapper_1.readStoreItem)(context, record);
|
|
35
41
|
const embedding = await (0, semantic_search_1.embedValue)(context, item.value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-reconcile.js","sourceRoot":"","sources":["../../../src/store/internal/index-reconcile.ts"],"names":[],"mappings":";;;;;;AAAA,6DAA+D;
|
|
1
|
+
{"version":3,"file":"index-reconcile.js","sourceRoot":"","sources":["../../../src/store/internal/index-reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ export interface BuildItemOptions {
|
|
|
15
15
|
updatedAt: string;
|
|
16
16
|
embedding?: number[];
|
|
17
17
|
ttlTimestamp?: number;
|
|
18
|
+
/** Per-call nonce: uniquifies the S3 key and becomes the row's revision token. */
|
|
18
19
|
nonce?: string;
|
|
19
20
|
}
|
|
20
21
|
/** Encode a value into the DynamoDB record for a stored item. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-mapper.d.ts","sourceRoot":"","sources":["../../../src/store/internal/item-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAG5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAE3E;AAOD,uFAAuF;AACvF,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,iEAAiE;AACjE,wBAAsB,cAAc,CAClC,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,MAAM,EAAE,EACnB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAChC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"item-mapper.d.ts","sourceRoot":"","sources":["../../../src/store/internal/item-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAG5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAE3E;AAOD,uFAAuF;AACvF,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,iEAAiE;AACjE,wBAAsB,cAAc,CAClC,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,MAAM,EAAE,EACnB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAChC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAkB1B;AAED,+DAA+D;AAC/D,wBAAsB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAYjG"}
|
|
@@ -35,6 +35,8 @@ async function buildStoreItem(context, namespace, key, value, options) {
|
|
|
35
35
|
record.embedding = options.embedding;
|
|
36
36
|
if (options.ttlTimestamp !== undefined)
|
|
37
37
|
record.ttl = options.ttlTimestamp;
|
|
38
|
+
if (options.nonce !== undefined)
|
|
39
|
+
record.rev = options.nonce;
|
|
38
40
|
return record;
|
|
39
41
|
}
|
|
40
42
|
/** Decode a DynamoDB record back into a store {@link Item}. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-mapper.js","sourceRoot":"","sources":["../../../src/store/internal/item-mapper.ts"],"names":[],"mappings":";;;;;AAEA,oDAAwF;AAIxF,iCAA+C;AAG/C;;;;GAIG;AACH,2BAAkC,GAAY;IAC5C,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,GAAuB,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,CAAC;AAED,sDAAsD;AACtD,SAAS,cAAc,CAAC,OAAqB;IAC3C,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;AAClG,CAAC;
|
|
1
|
+
{"version":3,"file":"item-mapper.js","sourceRoot":"","sources":["../../../src/store/internal/item-mapper.ts"],"names":[],"mappings":";;;;;AAEA,oDAAwF;AAIxF,iCAA+C;AAG/C;;;;GAIG;AACH,2BAAkC,GAAY;IAC5C,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,GAAuB,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,CAAC;AAED,sDAAsD;AACtD,SAAS,cAAc,CAAC,OAAqB;IAC3C,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;AAClG,CAAC;AAYD,iEAAiE;AAC1D,KAAK,yBACV,OAAqB,EACrB,SAAmB,EACnB,GAAW,EACX,KAAgC,EAChC,OAAyB;IAEzB,MAAM,UAAU,GAAG,MAAM,IAAA,qBAAa,EAAC,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE;QACrE,QAAQ,EACN,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC;KACzF,CAAC,CAAC;IACH,MAAM,MAAM,GAAoB;QAC9B,EAAE,EAAE,IAAA,mBAAY,EAAC,SAAS,CAAC;QAC3B,EAAE,EAAE,IAAA,cAAO,EAAC,SAAS,EAAE,GAAG,CAAC;QAC3B,SAAS;QACT,GAAG;QACH,KAAK,EAAE,UAAU;QACjB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC;IACF,IAAI,OAAO,CAAC,SAAS;QAAE,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAC5D,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS;QAAE,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC;IAC1E,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+DAA+D;AACxD,KAAK,wBAAwB,OAAqB,EAAE,MAAuB;IAChF,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAC/B,MAAM,CAAC,KAAK,EACZ,cAAc,CAAC,OAAO,CAAC,CACxB,CAAC;IACF,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,KAAK;QACL,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QACrC,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;KACtC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { StoreItemRecord } from '../types';
|
|
2
|
+
import { type ExistingRecordMeta } from './read-existing';
|
|
3
|
+
import type { StoreContext } from './setup';
|
|
4
|
+
/**
|
|
5
|
+
* Commit `record`, re-reading and retrying while another writer holds the row,
|
|
6
|
+
* and return the state this write actually superseded — the only descriptor
|
|
7
|
+
* safe to delete afterwards.
|
|
8
|
+
*
|
|
9
|
+
* Without the swap both racers read the same previous descriptor, both commit,
|
|
10
|
+
* and both delete it, orphaning the loser's own upload. Retrying against the
|
|
11
|
+
* *re-read* state is what makes each writer supersede exactly one payload.
|
|
12
|
+
*
|
|
13
|
+
* A rejection is not proof a competitor won: `withDynamoDBRetry` retries
|
|
14
|
+
* transient errors, so an attempt can commit server-side, its response can be
|
|
15
|
+
* lost, and the retried put can hit the row it just wrote and fail the same
|
|
16
|
+
* guard — indistinguishable from a competitor's win by the rejection alone.
|
|
17
|
+
* Each attempt's pinned observation is captured in `attempted` before the
|
|
18
|
+
* put, so that when a re-read finds the row already holding *this call's
|
|
19
|
+
* own* `rev`, the swap returns whatever `attempted` held — never this
|
|
20
|
+
* record's own just-committed value, which would strand the live row
|
|
21
|
+
* pointing at a deleted object. That comparison is guarded on `rev` being
|
|
22
|
+
* set: `rev` is optional on the record type, and an unnonced record against a
|
|
23
|
+
* pre-0.9.0 revision-less row would otherwise match `undefined === undefined`
|
|
24
|
+
* and claim a race it never entered.
|
|
25
|
+
*
|
|
26
|
+
* On exhaustion the write proceeds unconditionally and warns. That is
|
|
27
|
+
* deliberate: the fallback is precisely the pre-0.9.0 behaviour — one possible
|
|
28
|
+
* orphan, reclaimed by a lifecycle rule — so pathological contention degrades
|
|
29
|
+
* instead of turning a working put into an error. `createdAt` is refreshed from
|
|
30
|
+
* each re-read so a row created by whoever won keeps its true creation time.
|
|
31
|
+
*/
|
|
32
|
+
export declare function putWithRevisionSwap(context: StoreContext, record: StoreItemRecord, existing: ExistingRecordMeta): Promise<ExistingRecordMeta>;
|
|
33
|
+
//# sourceMappingURL=overwrite-swap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overwrite-swap.d.ts","sourceRoot":"","sources":["../../../src/store/internal/overwrite-swap.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAAgB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAc5C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAqB7B"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.putWithRevisionSwap = putWithRevisionSwap;
|
|
4
|
+
const conditional_put_1 = require("../../shared/dynamodb/conditional-put");
|
|
5
|
+
const retry_1 = require("../../shared/dynamodb/retry");
|
|
6
|
+
const read_existing_1 = require("./read-existing");
|
|
7
|
+
/** Put the record, optionally pinned to the revision the caller observed. */
|
|
8
|
+
async function put(context, record, observed) {
|
|
9
|
+
const guard = observed ? (0, conditional_put_1.revisionGuard)(conditional_put_1.REVISION_ATTRIBUTE, observed) : {};
|
|
10
|
+
await (0, retry_1.withDynamoDBRetry)(() => context.client.put({ TableName: context.tableName, Item: record, ...guard }));
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Commit `record`, re-reading and retrying while another writer holds the row,
|
|
14
|
+
* and return the state this write actually superseded — the only descriptor
|
|
15
|
+
* safe to delete afterwards.
|
|
16
|
+
*
|
|
17
|
+
* Without the swap both racers read the same previous descriptor, both commit,
|
|
18
|
+
* and both delete it, orphaning the loser's own upload. Retrying against the
|
|
19
|
+
* *re-read* state is what makes each writer supersede exactly one payload.
|
|
20
|
+
*
|
|
21
|
+
* A rejection is not proof a competitor won: `withDynamoDBRetry` retries
|
|
22
|
+
* transient errors, so an attempt can commit server-side, its response can be
|
|
23
|
+
* lost, and the retried put can hit the row it just wrote and fail the same
|
|
24
|
+
* guard — indistinguishable from a competitor's win by the rejection alone.
|
|
25
|
+
* Each attempt's pinned observation is captured in `attempted` before the
|
|
26
|
+
* put, so that when a re-read finds the row already holding *this call's
|
|
27
|
+
* own* `rev`, the swap returns whatever `attempted` held — never this
|
|
28
|
+
* record's own just-committed value, which would strand the live row
|
|
29
|
+
* pointing at a deleted object. That comparison is guarded on `rev` being
|
|
30
|
+
* set: `rev` is optional on the record type, and an unnonced record against a
|
|
31
|
+
* pre-0.9.0 revision-less row would otherwise match `undefined === undefined`
|
|
32
|
+
* and claim a race it never entered.
|
|
33
|
+
*
|
|
34
|
+
* On exhaustion the write proceeds unconditionally and warns. That is
|
|
35
|
+
* deliberate: the fallback is precisely the pre-0.9.0 behaviour — one possible
|
|
36
|
+
* orphan, reclaimed by a lifecycle rule — so pathological contention degrades
|
|
37
|
+
* instead of turning a working put into an error. `createdAt` is refreshed from
|
|
38
|
+
* each re-read so a row created by whoever won keeps its true creation time.
|
|
39
|
+
*/
|
|
40
|
+
async function putWithRevisionSwap(context, record, existing) {
|
|
41
|
+
let observed = existing;
|
|
42
|
+
for (let attempt = 1; attempt <= conditional_put_1.OVERWRITE_CAS_MAX_ATTEMPTS; attempt++) {
|
|
43
|
+
const attempted = observed;
|
|
44
|
+
try {
|
|
45
|
+
await put(context, record, attempted);
|
|
46
|
+
return attempted;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (!(0, conditional_put_1.isConditionalCheckFailed)(error))
|
|
50
|
+
throw error;
|
|
51
|
+
observed = await (0, read_existing_1.readExisting)(context, record.PK, record.SK);
|
|
52
|
+
if (record.rev !== undefined && observed.revision === record.rev)
|
|
53
|
+
return attempted;
|
|
54
|
+
record.createdAt = observed.createdAt ?? record.createdAt;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
context.logger.warn('store.put: compare-and-swap exhausted; overwriting unconditionally, which can orphan one ' +
|
|
58
|
+
'S3 object under a concurrent put (reclaimed by ensureS3LifecycleRule)', { namespace: record.namespace, key: record.key, attempts: conditional_put_1.OVERWRITE_CAS_MAX_ATTEMPTS });
|
|
59
|
+
await put(context, record);
|
|
60
|
+
return observed;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=overwrite-swap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overwrite-swap.js","sourceRoot":"","sources":["../../../src/store/internal/overwrite-swap.ts"],"names":[],"mappings":";;;AAAA,2EAK+C;AAC/C,uDAAgE;AAEhE,mDAAwE;AAGxE,6EAA6E;AAC7E,KAAK,UAAU,GAAG,CAChB,OAAqB,EACrB,MAAuB,EACvB,QAA6B;IAE7B,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAA,+BAAa,EAAC,oCAAkB,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAC3B,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC,CAC7E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACI,KAAK,8BACV,OAAqB,EACrB,MAAuB,EACvB,QAA4B;IAE5B,IAAI,QAAQ,GAAG,QAAQ,CAAC;IACxB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,4CAA0B,EAAE,OAAO,EAAE,EAAE,CAAC;QACvE,MAAM,SAAS,GAAG,QAAQ,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;YACtC,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,IAAA,0CAAwB,EAAC,KAA0B,CAAC;gBAAE,MAAM,KAAK,CAAC;YACvE,QAAQ,GAAG,MAAM,IAAA,4BAAY,EAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAC7D,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,QAAQ,CAAC,QAAQ,KAAK,MAAM,CAAC,GAAG;gBAAE,OAAO,SAAS,CAAC;YACnF,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC;QAC5D,CAAC;IACH,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,2FAA2F;QACzF,uEAAuE,EACzE,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,4CAA0B,EAAE,CACvF,CAAC;IACF,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC3B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1,11 +1,27 @@
|
|
|
1
|
-
import { type PayloadDescriptor } from '../../shared/codec/codec';
|
|
2
1
|
import type { StoreItemRecord } from '../types';
|
|
2
|
+
import type { ExistingRecordMeta } from './read-existing';
|
|
3
3
|
import type { StoreContext } from './setup';
|
|
4
4
|
/**
|
|
5
|
-
* Put the record
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Put the record and clean up whichever side is now dead.
|
|
6
|
+
*
|
|
7
|
+
* The compare-and-swap path runs **only when an offloader is configured**:
|
|
8
|
+
* without one there is no S3 object to orphan, so a plain last-write-wins put
|
|
9
|
+
* stays correct and costs no extra write capacity (DynamoDB charges for a
|
|
10
|
+
* failed conditional write too). With one, the swap is what lets this call
|
|
11
|
+
* delete exactly the payload it superseded rather than a descriptor a racer may
|
|
12
|
+
* already have replaced.
|
|
13
|
+
*
|
|
14
|
+
* Every failure reaching the catch arrives after at least one put was issued —
|
|
15
|
+
* `putWithRevisionSwap` only re-reads from inside its own catch — so none of
|
|
16
|
+
* them proves a non-commit on its own: a put can commit server-side and lose
|
|
17
|
+
* its response, and a `ConditionalCheckFailedException` is as consistent with
|
|
18
|
+
* hitting the row this call just wrote as with a competitor's win. The row is
|
|
19
|
+
* therefore read back (`verifyWriteLanded`) before anything is deleted. Only a
|
|
20
|
+
* confirmed `'not-landed'` deletes this record's own nonced object; a confirmed
|
|
21
|
+
* `'landed'` cleans up the previous object like the success path and swallows
|
|
22
|
+
* the error, and an `'unverified'` read deletes nothing and rethrows — leaking
|
|
23
|
+
* one object at worst rather than stranding a live row pointing at a deleted
|
|
24
|
+
* one. An inline payload has no object to leak, so it needs no read.
|
|
9
25
|
*/
|
|
10
|
-
export declare function persistRecord(context: StoreContext, record: StoreItemRecord,
|
|
26
|
+
export declare function persistRecord(context: StoreContext, record: StoreItemRecord, existing: ExistingRecordMeta): Promise<void>;
|
|
11
27
|
//# sourceMappingURL=persist.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../../src/store/internal/persist.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../../src/store/internal/persist.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAa5C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAmBf"}
|
|
@@ -5,30 +5,55 @@ const codec_1 = require("../../shared/codec/codec");
|
|
|
5
5
|
const descriptor_keys_1 = require("../../shared/codec/descriptor-keys");
|
|
6
6
|
const orphans_1 = require("../../shared/codec/s3/orphans");
|
|
7
7
|
const retry_1 = require("../../shared/dynamodb/retry");
|
|
8
|
+
const overwrite_swap_1 = require("./overwrite-swap");
|
|
8
9
|
const write_verify_1 = require("./write-verify");
|
|
10
|
+
/** Best-effort delete of one descriptor's S3 object. */
|
|
11
|
+
async function cleanUp(context, descriptor, label) {
|
|
12
|
+
if (!context.offloader || !descriptor)
|
|
13
|
+
return;
|
|
14
|
+
await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)([descriptor]), label, context.logger);
|
|
15
|
+
}
|
|
9
16
|
/**
|
|
10
|
-
* Put the record
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
17
|
+
* Put the record and clean up whichever side is now dead.
|
|
18
|
+
*
|
|
19
|
+
* The compare-and-swap path runs **only when an offloader is configured**:
|
|
20
|
+
* without one there is no S3 object to orphan, so a plain last-write-wins put
|
|
21
|
+
* stays correct and costs no extra write capacity (DynamoDB charges for a
|
|
22
|
+
* failed conditional write too). With one, the swap is what lets this call
|
|
23
|
+
* delete exactly the payload it superseded rather than a descriptor a racer may
|
|
24
|
+
* already have replaced.
|
|
25
|
+
*
|
|
26
|
+
* Every failure reaching the catch arrives after at least one put was issued —
|
|
27
|
+
* `putWithRevisionSwap` only re-reads from inside its own catch — so none of
|
|
28
|
+
* them proves a non-commit on its own: a put can commit server-side and lose
|
|
29
|
+
* its response, and a `ConditionalCheckFailedException` is as consistent with
|
|
30
|
+
* hitting the row this call just wrote as with a competitor's win. The row is
|
|
31
|
+
* therefore read back (`verifyWriteLanded`) before anything is deleted. Only a
|
|
32
|
+
* confirmed `'not-landed'` deletes this record's own nonced object; a confirmed
|
|
33
|
+
* `'landed'` cleans up the previous object like the success path and swallows
|
|
34
|
+
* the error, and an `'unverified'` read deletes nothing and rethrows — leaking
|
|
35
|
+
* one object at worst rather than stranding a live row pointing at a deleted
|
|
36
|
+
* one. An inline payload has no object to leak, so it needs no read.
|
|
14
37
|
*/
|
|
15
|
-
async function persistRecord(context, record,
|
|
38
|
+
async function persistRecord(context, record, existing) {
|
|
39
|
+
let superseded = existing;
|
|
16
40
|
try {
|
|
17
|
-
|
|
41
|
+
if (context.offloader) {
|
|
42
|
+
superseded = await (0, overwrite_swap_1.putWithRevisionSwap)(context, record, existing);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
await (0, retry_1.withDynamoDBRetry)(() => context.client.put({ TableName: context.tableName, Item: record }));
|
|
46
|
+
}
|
|
18
47
|
}
|
|
19
48
|
catch (error) {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
49
|
+
const verdict = record.value.location === codec_1.PayloadLocation.S3
|
|
50
|
+
? await (0, write_verify_1.verifyWriteLanded)(context, record, record.value.s3Key)
|
|
51
|
+
: 'not-landed';
|
|
52
|
+
if (verdict === 'not-landed')
|
|
53
|
+
await cleanUp(context, record.value, 'store.put');
|
|
54
|
+
if (verdict !== 'landed')
|
|
27
55
|
throw error;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
if (context.offloader && previousValue) {
|
|
31
|
-
await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)([previousValue]), 'store.put.overwrite', context.logger);
|
|
32
56
|
}
|
|
57
|
+
await cleanUp(context, superseded.value, 'store.put.overwrite');
|
|
33
58
|
}
|
|
34
59
|
//# sourceMappingURL=persist.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persist.js","sourceRoot":"","sources":["../../../src/store/internal/persist.ts"],"names":[],"mappings":";;;AAAA,oDAAmF;AACnF,wEAAmE;AACnE,2DAAiE;AACjE,uDAAgE;
|
|
1
|
+
{"version":3,"file":"persist.js","sourceRoot":"","sources":["../../../src/store/internal/persist.ts"],"names":[],"mappings":";;;AAAA,oDAAmF;AACnF,wEAAmE;AACnE,2DAAiE;AACjE,uDAAgE;AAEhE,qDAAuD;AAGvD,iDAAsE;AAEtE,wDAAwD;AACxD,KAAK,UAAU,OAAO,CACpB,OAAqB,EACrB,UAAyC,EACzC,KAAa;IAEb,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,UAAU;QAAE,OAAO;IAC9C,MAAM,IAAA,0BAAgB,EAAC,OAAO,CAAC,SAAS,EAAE,IAAA,+BAAa,EAAC,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAChG,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACI,KAAK,wBACV,OAAqB,EACrB,MAAuB,EACvB,QAA4B;IAE5B,IAAI,UAAU,GAAG,QAAQ,CAAC;IAC1B,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,UAAU,GAAG,MAAM,IAAA,oCAAmB,EAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAC3B,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CACnE,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GACX,MAAM,CAAC,KAAK,CAAC,QAAQ,KAAK,uBAAe,CAAC,EAAE;YAC1C,CAAC,CAAC,MAAM,IAAA,gCAAiB,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YAC9D,CAAC,CAAC,YAAY,CAAC;QACnB,IAAI,OAAO,KAAK,YAAY;YAAE,MAAM,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAChF,IAAI,OAAO,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAC;IACxC,CAAC;IACD,MAAM,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PayloadDescriptor } from '../../shared/codec/codec';
|
|
2
|
+
import type { StoreContext } from './setup';
|
|
3
|
+
/** The previous row's createdAt, payload descriptor and revision. */
|
|
4
|
+
export interface ExistingRecordMeta {
|
|
5
|
+
exists: boolean;
|
|
6
|
+
createdAt?: string;
|
|
7
|
+
value?: PayloadDescriptor;
|
|
8
|
+
revision?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Read the fields a put needs from the row it is about to replace, in one
|
|
12
|
+
* strongly-consistent projection: `createdAt` to preserve, `value` to clean up
|
|
13
|
+
* afterwards, and the revision the compare-and-swap pins.
|
|
14
|
+
*
|
|
15
|
+
* Lives apart from `actions/put.ts` so `persist.ts` can re-read on a lost swap
|
|
16
|
+
* without importing its own caller.
|
|
17
|
+
*/
|
|
18
|
+
export declare function readExisting(context: StoreContext, pk: string, sk: string): Promise<ExistingRecordMeta>;
|
|
19
|
+
//# sourceMappingURL=read-existing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-existing.d.ts","sourceRoot":"","sources":["../../../src/store/internal/read-existing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,EACrB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,kBAAkB,CAAC,CAgB7B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readExisting = readExisting;
|
|
4
|
+
const conditional_put_1 = require("../../shared/dynamodb/conditional-put");
|
|
5
|
+
const retry_1 = require("../../shared/dynamodb/retry");
|
|
6
|
+
/**
|
|
7
|
+
* Read the fields a put needs from the row it is about to replace, in one
|
|
8
|
+
* strongly-consistent projection: `createdAt` to preserve, `value` to clean up
|
|
9
|
+
* afterwards, and the revision the compare-and-swap pins.
|
|
10
|
+
*
|
|
11
|
+
* Lives apart from `actions/put.ts` so `persist.ts` can re-read on a lost swap
|
|
12
|
+
* without importing its own caller.
|
|
13
|
+
*/
|
|
14
|
+
async function readExisting(context, pk, sk) {
|
|
15
|
+
const existing = await (0, retry_1.withDynamoDBRetry)(() => context.client.get({
|
|
16
|
+
TableName: context.tableName,
|
|
17
|
+
Key: { PK: pk, SK: sk },
|
|
18
|
+
ConsistentRead: true,
|
|
19
|
+
ProjectionExpression: '#c, #v, #r',
|
|
20
|
+
ExpressionAttributeNames: { '#c': 'createdAt', '#v': 'value', '#r': conditional_put_1.REVISION_ATTRIBUTE },
|
|
21
|
+
}));
|
|
22
|
+
return {
|
|
23
|
+
exists: existing.Item !== undefined,
|
|
24
|
+
createdAt: existing.Item?.createdAt,
|
|
25
|
+
value: existing.Item?.value,
|
|
26
|
+
revision: existing.Item?.[conditional_put_1.REVISION_ATTRIBUTE],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=read-existing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-existing.js","sourceRoot":"","sources":["../../../src/store/internal/read-existing.ts"],"names":[],"mappings":";;;AACA,2EAA2E;AAC3E,uDAAgE;AAWhE;;;;;;;GAOG;AACI,KAAK,uBACV,OAAqB,EACrB,EAAU,EACV,EAAU;IAEV,MAAM,QAAQ,GAAG,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAC5C,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;QACjB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;QACvB,cAAc,EAAE,IAAI;QACpB,oBAAoB,EAAE,YAAY;QAClC,wBAAwB,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,oCAAkB,EAAE;KACzF,CAAC,CACH,CAAC;IACF,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,IAAI,KAAK,SAAS;QACnC,SAAS,EAAE,QAAQ,CAAC,IAAI,EAAE,SAA+B;QACzD,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAsC;QAC5D,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,oCAAkB,CAAuB;KACpE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { VectorMatch } from '../vector-backend';
|
|
2
|
+
/** Which direction a {@link VectorBackend} reports its score in. */
|
|
3
|
+
export type VectorScoreDirection = 'relevance' | 'distance';
|
|
4
|
+
/** Every direction {@link toRelevanceScores} recognises, for validating input. */
|
|
5
|
+
export declare const VECTOR_SCORE_DIRECTIONS: readonly VectorScoreDirection[];
|
|
6
|
+
/**
|
|
7
|
+
* Normalise a backend's matches to the relevance direction upstream
|
|
8
|
+
* `SearchItem.score` documents — "higher scores indicate better matches",
|
|
9
|
+
* typically a cosine similarity between -1 and 1.
|
|
10
|
+
*
|
|
11
|
+
* A distance is converted by **negation** rather than `1 / (1 + d)`: negation
|
|
12
|
+
* is monotone over the whole real line, needs no non-negativity precondition,
|
|
13
|
+
* and is exactly invertible, so the original distance is simply `-score`. A
|
|
14
|
+
* reciprocal would silently imply a different `(0, 1]` scale and is undefined
|
|
15
|
+
* at `d === -1`. Negative scores are already in range for this contract, so
|
|
16
|
+
* nothing is lost by producing them.
|
|
17
|
+
*
|
|
18
|
+
* Results are re-sorted after conversion so a backend that returns its matches
|
|
19
|
+
* in some other order still ranks correctly. Anything that is not `'distance'`
|
|
20
|
+
* is returned untouched — its own order stays authoritative, exactly as before.
|
|
21
|
+
*
|
|
22
|
+
* The test is for `'distance'` rather than against `'relevance'` on purpose:
|
|
23
|
+
* converting is the destructive branch, so only the exact value that asks for
|
|
24
|
+
* it may reach it. Testing the other way round made every unrecognised
|
|
25
|
+
* string — `'Distance'`, a typo, a value read from a config file — reverse the
|
|
26
|
+
* ranking silently, with no error and no warning (the ascending-score warning
|
|
27
|
+
* lives downstream of this conversion, so it could never fire). `setUpStore`
|
|
28
|
+
* rejects such a value outright; this keeps the failure harmless for any
|
|
29
|
+
* caller that reaches the function some other way.
|
|
30
|
+
*/
|
|
31
|
+
export declare function toRelevanceScores(matches: VectorMatch[], direction: VectorScoreDirection): VectorMatch[];
|
|
32
|
+
//# sourceMappingURL=score-direction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score-direction.d.ts","sourceRoot":"","sources":["../../../src/store/internal/score-direction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,oEAAoE;AACpE,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,UAAU,CAAC;AAE5D,kFAAkF;AAClF,eAAO,MAAM,uBAAuB,EAAE,SAAS,oBAAoB,EAA8B,CAAC;AAElG;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,WAAW,EAAE,EACtB,SAAS,EAAE,oBAAoB,GAC9B,WAAW,EAAE,CAKf"}
|