@farukada/aws-langgraph-dynamodb-ts 0.6.0 → 0.8.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 +63 -9
- package/dist/checkpointer/actions/delete-thread.d.ts +3 -4
- package/dist/checkpointer/actions/delete-thread.d.ts.map +1 -1
- package/dist/checkpointer/actions/delete-thread.js +21 -41
- package/dist/checkpointer/actions/delete-thread.js.map +1 -1
- package/dist/checkpointer/actions/list.d.ts.map +1 -1
- package/dist/checkpointer/actions/list.js +31 -4
- 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 +14 -24
- package/dist/checkpointer/actions/put-writes.js.map +1 -1
- package/dist/checkpointer/actions/put.d.ts.map +1 -1
- package/dist/checkpointer/actions/put.js +2 -0
- package/dist/checkpointer/actions/put.js.map +1 -1
- package/dist/checkpointer/internal/item-reader.d.ts +31 -0
- package/dist/checkpointer/internal/item-reader.d.ts.map +1 -1
- package/dist/checkpointer/internal/item-reader.js +49 -1
- package/dist/checkpointer/internal/item-reader.js.map +1 -1
- package/dist/checkpointer/internal/item-writer.d.ts +0 -8
- package/dist/checkpointer/internal/item-writer.d.ts.map +1 -1
- package/dist/checkpointer/internal/item-writer.js +15 -21
- package/dist/checkpointer/internal/item-writer.js.map +1 -1
- package/dist/checkpointer/internal/keys.d.ts +19 -3
- package/dist/checkpointer/internal/keys.d.ts.map +1 -1
- package/dist/checkpointer/internal/keys.js +41 -6
- package/dist/checkpointer/internal/keys.js.map +1 -1
- package/dist/checkpointer/internal/special-write-cleanup.d.ts.map +1 -1
- package/dist/checkpointer/internal/special-write-cleanup.js +6 -12
- package/dist/checkpointer/internal/special-write-cleanup.js.map +1 -1
- package/dist/checkpointer/internal/validation.d.ts +8 -4
- package/dist/checkpointer/internal/validation.d.ts.map +1 -1
- package/dist/checkpointer/internal/validation.js +12 -10
- package/dist/checkpointer/internal/validation.js.map +1 -1
- package/dist/checkpointer/internal/write-guard.d.ts +21 -0
- package/dist/checkpointer/internal/write-guard.d.ts.map +1 -0
- package/dist/checkpointer/internal/write-guard.js +48 -0
- package/dist/checkpointer/internal/write-guard.js.map +1 -0
- package/dist/checkpointer/internal/write-index.d.ts +29 -0
- package/dist/checkpointer/internal/write-index.d.ts.map +1 -0
- package/dist/checkpointer/internal/write-index.js +38 -0
- package/dist/checkpointer/internal/write-index.js.map +1 -0
- package/dist/checkpointer/types.d.ts +2 -0
- package/dist/checkpointer/types.d.ts.map +1 -1
- package/dist/history/actions/add-messages.d.ts.map +1 -1
- package/dist/history/actions/add-messages.js +24 -4
- package/dist/history/actions/add-messages.js.map +1 -1
- package/dist/history/actions/clear.d.ts +4 -6
- package/dist/history/actions/clear.d.ts.map +1 -1
- package/dist/history/actions/clear.js +18 -33
- package/dist/history/actions/clear.js.map +1 -1
- package/dist/history/actions/get-messages.d.ts +2 -1
- package/dist/history/actions/get-messages.d.ts.map +1 -1
- package/dist/history/actions/get-messages.js +28 -2
- package/dist/history/actions/get-messages.js.map +1 -1
- package/dist/history/actions/list-sessions.d.ts +2 -1
- package/dist/history/actions/list-sessions.d.ts.map +1 -1
- package/dist/history/actions/list-sessions.js +21 -2
- package/dist/history/actions/list-sessions.js.map +1 -1
- package/dist/history/actions/reconcile-count.d.ts.map +1 -1
- package/dist/history/actions/reconcile-count.js +2 -2
- package/dist/history/actions/reconcile-count.js.map +1 -1
- package/dist/history/internal/append-saga.d.ts.map +1 -1
- package/dist/history/internal/append-saga.js +2 -78
- package/dist/history/internal/append-saga.js.map +1 -1
- package/dist/history/internal/compensation.d.ts +21 -0
- package/dist/history/internal/compensation.d.ts.map +1 -0
- package/dist/history/internal/compensation.js +84 -0
- package/dist/history/internal/compensation.js.map +1 -0
- package/dist/history/internal/keys.d.ts +10 -2
- package/dist/history/internal/keys.d.ts.map +1 -1
- package/dist/history/internal/keys.js +32 -5
- package/dist/history/internal/keys.js.map +1 -1
- package/dist/history/internal/message-chunker.d.ts.map +1 -1
- package/dist/history/internal/message-chunker.js +13 -5
- package/dist/history/internal/message-chunker.js.map +1 -1
- package/dist/history/internal/session-count.d.ts +21 -0
- package/dist/history/internal/session-count.d.ts.map +1 -1
- package/dist/history/internal/session-count.js +51 -0
- package/dist/history/internal/session-count.js.map +1 -1
- package/dist/history/internal/session-title.d.ts +20 -0
- package/dist/history/internal/session-title.d.ts.map +1 -0
- package/dist/history/internal/session-title.js +44 -0
- package/dist/history/internal/session-title.js.map +1 -0
- package/dist/history/internal/setup.d.ts +2 -1
- package/dist/history/internal/setup.d.ts.map +1 -1
- package/dist/history/internal/setup.js +1 -0
- package/dist/history/internal/setup.js.map +1 -1
- package/dist/history/internal/title-generator.d.ts +8 -2
- package/dist/history/internal/title-generator.d.ts.map +1 -1
- package/dist/history/internal/title-generator.js +12 -3
- package/dist/history/internal/title-generator.js.map +1 -1
- package/dist/history/internal/validation.d.ts +9 -0
- package/dist/history/internal/validation.d.ts.map +1 -0
- package/dist/history/internal/validation.js +16 -0
- package/dist/history/internal/validation.js.map +1 -0
- package/dist/history/types.d.ts +12 -0
- package/dist/history/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/shared/codec/s3/offloader.d.ts +7 -1
- package/dist/shared/codec/s3/offloader.d.ts.map +1 -1
- package/dist/shared/codec/s3/offloader.js +14 -1
- package/dist/shared/codec/s3/offloader.js.map +1 -1
- package/dist/shared/dynamodb/batch-write.d.ts.map +1 -1
- package/dist/shared/dynamodb/batch-write.js +8 -6
- package/dist/shared/dynamodb/batch-write.js.map +1 -1
- package/dist/shared/dynamodb/drain-unprocessed.d.ts +5 -1
- package/dist/shared/dynamodb/drain-unprocessed.d.ts.map +1 -1
- package/dist/shared/dynamodb/drain-unprocessed.js +20 -11
- package/dist/shared/dynamodb/drain-unprocessed.js.map +1 -1
- package/dist/shared/dynamodb/partition-delete.d.ts +33 -0
- package/dist/shared/dynamodb/partition-delete.d.ts.map +1 -0
- package/dist/shared/dynamodb/partition-delete.js +70 -0
- package/dist/shared/dynamodb/partition-delete.js.map +1 -0
- package/dist/shared/dynamodb/retry-classifier.d.ts.map +1 -1
- package/dist/shared/dynamodb/retry-classifier.js +9 -1
- package/dist/shared/dynamodb/retry-classifier.js.map +1 -1
- package/dist/shared/errors/errors.d.ts +5 -2
- package/dist/shared/errors/errors.d.ts.map +1 -1
- package/dist/shared/errors/errors.js +6 -3
- package/dist/shared/errors/errors.js.map +1 -1
- package/dist/shared/logging/redaction-walk.d.ts +23 -0
- package/dist/shared/logging/redaction-walk.d.ts.map +1 -0
- package/dist/shared/logging/redaction-walk.js +92 -0
- package/dist/shared/logging/redaction-walk.js.map +1 -0
- package/dist/shared/logging/redaction.d.ts +22 -10
- package/dist/shared/logging/redaction.d.ts.map +1 -1
- package/dist/shared/logging/redaction.js +24 -36
- package/dist/shared/logging/redaction.js.map +1 -1
- package/dist/shared/logging/secret-patterns.d.ts +41 -0
- package/dist/shared/logging/secret-patterns.d.ts.map +1 -0
- package/dist/shared/logging/secret-patterns.js +74 -0
- package/dist/shared/logging/secret-patterns.js.map +1 -0
- package/dist/shared/validation/primitives.d.ts +9 -1
- package/dist/shared/validation/primitives.d.ts.map +1 -1
- package/dist/shared/validation/primitives.js +13 -0
- package/dist/shared/validation/primitives.js.map +1 -1
- package/dist/store/actions/get.d.ts.map +1 -1
- package/dist/store/actions/get.js +15 -1
- package/dist/store/actions/get.js.map +1 -1
- package/dist/store/actions/list-namespaces.d.ts.map +1 -1
- package/dist/store/actions/list-namespaces.js +1 -0
- package/dist/store/actions/list-namespaces.js.map +1 -1
- package/dist/store/actions/put.d.ts.map +1 -1
- package/dist/store/actions/put.js +20 -2
- package/dist/store/actions/put.js.map +1 -1
- package/dist/store/actions/search.d.ts.map +1 -1
- package/dist/store/actions/search.js +4 -35
- package/dist/store/actions/search.js.map +1 -1
- package/dist/store/internal/backend-search.d.ts +5 -0
- package/dist/store/internal/backend-search.d.ts.map +1 -0
- package/dist/store/internal/backend-search.js +67 -0
- package/dist/store/internal/backend-search.js.map +1 -0
- package/dist/store/internal/filter.d.ts.map +1 -1
- package/dist/store/internal/filter.js +26 -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 +33 -3
- package/dist/store/internal/index-reconcile.js.map +1 -1
- package/dist/store/internal/keys.d.ts +1 -1
- package/dist/store/internal/keys.d.ts.map +1 -1
- package/dist/store/internal/keys.js +8 -2
- package/dist/store/internal/keys.js.map +1 -1
- package/dist/store/internal/persist.d.ts.map +1 -1
- package/dist/store/internal/persist.js +1 -5
- package/dist/store/internal/persist.js.map +1 -1
- package/dist/store/internal/search-filter.d.ts +4 -0
- package/dist/store/internal/search-filter.d.ts.map +1 -0
- package/dist/store/internal/search-filter.js +11 -0
- package/dist/store/internal/search-filter.js.map +1 -0
- package/dist/store/internal/setup.d.ts +11 -1
- package/dist/store/internal/setup.d.ts.map +1 -1
- package/dist/store/internal/setup.js +17 -1
- package/dist/store/internal/setup.js.map +1 -1
- package/dist/store/internal/validation.d.ts +8 -2
- package/dist/store/internal/validation.d.ts.map +1 -1
- package/dist/store/internal/validation.js +15 -6
- package/dist/store/internal/validation.js.map +1 -1
- package/dist/store/internal/write-verify.d.ts +12 -0
- package/dist/store/internal/write-verify.d.ts.map +1 -1
- package/dist/store/internal/write-verify.js +27 -0
- package/dist/store/internal/write-verify.js.map +1 -1
- package/dist/store/vector-backend.d.ts +17 -0
- package/dist/store/vector-backend.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.codecDeps = codecDeps;
|
|
4
|
-
exports.resolveWriteIndex = resolveWriteIndex;
|
|
5
4
|
exports.buildCheckpointItems = buildCheckpointItems;
|
|
6
5
|
exports.buildWriteItems = buildWriteItems;
|
|
7
|
-
const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
|
|
8
6
|
const codec_1 = require("../../shared/codec/codec");
|
|
9
7
|
const keys_1 = require("./keys");
|
|
8
|
+
const write_index_1 = require("./write-index");
|
|
10
9
|
/** Map a context to the codec collaborators. */
|
|
11
10
|
function codecDeps(context) {
|
|
12
11
|
return { serde: context.serde, compression: context.compression, offloader: context.offloader };
|
|
@@ -16,16 +15,6 @@ function withTtl(item, ttlTimestamp) {
|
|
|
16
15
|
item.ttl = ttlTimestamp;
|
|
17
16
|
return item;
|
|
18
17
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Resolve a write's DynamoDB sort-key index: WRITES_IDX_MAP's slot for a
|
|
21
|
-
* known special channel, else its position. `Object.hasOwn` guards against
|
|
22
|
-
* WRITES_IDX_MAP's own `Object.prototype` chain — a channel literally named
|
|
23
|
-
* `constructor`/`toString`/etc. must fall through to `positional`, not
|
|
24
|
-
* resolve to an inherited function reference.
|
|
25
|
-
*/
|
|
26
|
-
function resolveWriteIndex(channel, positional) {
|
|
27
|
-
return Object.hasOwn(langgraph_checkpoint_1.WRITES_IDX_MAP, channel) ? langgraph_checkpoint_1.WRITES_IDX_MAP[channel] : positional;
|
|
28
|
-
}
|
|
29
18
|
/** Encode a checkpoint + metadata into its META and PAYLOAD items. */
|
|
30
19
|
async function buildCheckpointItems(context, threadId, checkpointNs, checkpoint, metadata, parentCheckpointId, ttlTimestamp) {
|
|
31
20
|
const deps = codecDeps(context);
|
|
@@ -70,24 +59,29 @@ async function buildWriteItems(context, threadId, checkpointNs, checkpointId, ta
|
|
|
70
59
|
const deps = codecDeps(context);
|
|
71
60
|
const pk = (0, keys_1.partitionKey)(threadId);
|
|
72
61
|
const items = [];
|
|
73
|
-
for (
|
|
74
|
-
const [channel, value] = writes[positional];
|
|
62
|
+
for (const { channel, value, index } of (0, write_index_1.resolveWriteIndices)(writes)) {
|
|
75
63
|
/**
|
|
76
|
-
* `
|
|
77
|
-
*
|
|
78
|
-
*
|
|
64
|
+
* `channel` is part of the key as well as the index: two channels can
|
|
65
|
+
* share an index (each channel's first occurrence is 0), so without it
|
|
66
|
+
* their uploads would collide on one S3 object within a single call.
|
|
79
67
|
*/
|
|
80
|
-
const index = resolveWriteIndex(channel, positional);
|
|
81
|
-
const baseKeyParts = [threadId, checkpointNs, checkpointId, taskId, `write-${index}`];
|
|
82
68
|
const descriptor = await (0, codec_1.encodePayload)(value, deps, {
|
|
83
|
-
keyParts: [
|
|
69
|
+
keyParts: [threadId, checkpointNs, checkpointId, taskId, `write-${index}`, channel, nonce],
|
|
84
70
|
});
|
|
85
71
|
const item = {
|
|
86
72
|
PK: pk,
|
|
87
|
-
SK: (0, keys_1.writeSortKey)(checkpointNs, checkpointId, taskId, index),
|
|
73
|
+
SK: (0, keys_1.writeSortKey)(checkpointNs, checkpointId, taskId, index, channel),
|
|
88
74
|
taskId,
|
|
89
75
|
index,
|
|
90
76
|
channel,
|
|
77
|
+
/**
|
|
78
|
+
* Shared by every row this call writes. Positions shift when a retried
|
|
79
|
+
* task's write mix changes, so a channel an earlier call already
|
|
80
|
+
* committed can land at a second index and be replayed twice; the group
|
|
81
|
+
* is what lets the read side tell that apart from a channel a single
|
|
82
|
+
* call legitimately wrote more than once.
|
|
83
|
+
*/
|
|
84
|
+
writeGroup: nonce,
|
|
91
85
|
value: descriptor,
|
|
92
86
|
};
|
|
93
87
|
items.push(withTtl(item, ttlTimestamp));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-writer.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/item-writer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"item-writer.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/item-writer.ts"],"names":[],"mappings":";;;;;AAEA,oDAAyE;AAEzE,iCAAiF;AAEjF,+CAAoD;AAEpD,gDAAgD;AAChD,mBAA0B,OAA4B;IACpD,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;AAClG,CAAC;AAED,SAAS,OAAO,CAA6B,IAAO,EAAE,YAAqB;IACzE,IAAI,YAAY,KAAK,SAAS;QAAE,IAAI,CAAC,GAAG,GAAG,YAAY,CAAC;IACxD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sEAAsE;AAC/D,KAAK,+BACV,OAA4B,EAC5B,QAAgB,EAChB,YAAoB,EACpB,UAAsB,EACtB,QAA4B,EAC5B,kBAA2B,EAC3B,YAAqB;IAErB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,IAAA,mBAAY,EAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,oBAAoB,GAAG,MAAM,IAAA,qBAAa,EAAC,UAAU,EAAE,IAAI,EAAE;QACjE,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,YAAY,CAAC;KAChE,CAAC,CAAC;IACH,MAAM,kBAAkB,GAAG,MAAM,IAAA,qBAAa,EAAC,QAAQ,EAAE,IAAI,EAAE;QAC7D,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC;KAC9D,CAAC,CAAC;IACH,MAAM,IAAI,GAAuB;QAC/B,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,IAAA,kBAAW,EAAC,YAAY,EAAE,UAAU,CAAC,EAAE,CAAC;QAC5C,QAAQ;QACR,YAAY;QACZ,YAAY,EAAE,UAAU,CAAC,EAAE;QAC3B,QAAQ,EAAE,kBAAkB;KAC7B,CAAC;IACF,IAAI,kBAAkB,KAAK,SAAS;QAAE,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IACnF,MAAM,OAAO,GAA0B;QACrC,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,IAAA,qBAAc,EAAC,YAAY,EAAE,UAAU,CAAC,EAAE,CAAC;QAC/C,UAAU,EAAE,oBAAoB;KACjC,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;AACxF,CAAC;AAED;;;;;;;;;;;;GAYG;AACI,KAAK,0BACV,OAA4B,EAC5B,QAAgB,EAChB,YAAoB,EACpB,YAAoB,EACpB,MAAc,EACd,MAAsB,EACtB,KAAa,EACb,YAAqB;IAErB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,IAAA,mBAAY,EAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,KAAK,GAA0B,EAAE,CAAC;IACxC,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,IAAA,iCAAmB,EAAC,MAAM,CAAC,EAAE,CAAC;QACpE;;;;WAIG;QACH,MAAM,UAAU,GAAG,MAAM,IAAA,qBAAa,EAAC,KAAK,EAAE,IAAI,EAAE;YAClD,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC;SAC3F,CAAC,CAAC;QACH,MAAM,IAAI,GAAwB;YAChC,EAAE,EAAE,EAAE;YACN,EAAE,EAAE,IAAA,mBAAY,EAAC,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC;YACpE,MAAM;YACN,KAAK;YACL,OAAO;YACP;;;;;;eAMG;YACH,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE,UAAU;SAClB,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Reserved separator joining sort-key segments; forbidden inside any segment. */
|
|
2
2
|
export declare const SORT_KEY_SEPARATOR = "#";
|
|
3
|
-
/** Partition key for a thread: the thread id
|
|
3
|
+
/** Partition key for a thread: the adapter tag plus the thread id. */
|
|
4
4
|
export declare function partitionKey(threadId: string): string;
|
|
5
5
|
/** Sort key for a checkpoint's lightweight metadata item. */
|
|
6
6
|
export declare function metaSortKey(checkpointNs: string, checkpointId: string): string;
|
|
@@ -8,8 +8,24 @@ export declare function metaSortKey(checkpointNs: string, checkpointId: string):
|
|
|
8
8
|
export declare function metaSortKeyPrefix(checkpointNs: string): string;
|
|
9
9
|
/** Sort key for a checkpoint's heavy payload item. */
|
|
10
10
|
export declare function payloadSortKey(checkpointNs: string, checkpointId: string): string;
|
|
11
|
-
/**
|
|
12
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Sort key for a single pending write. The trailing `channel` segment is what
|
|
13
|
+
* keeps two *different* channels from ever occupying one row: without it, a
|
|
14
|
+
* retried task whose write mix changed could compute an index another
|
|
15
|
+
* channel already holds, and the first-write-wins guard — which cannot tell a
|
|
16
|
+
* genuine retry from an unrelated write — would silently discard it. The
|
|
17
|
+
* channel is appended verbatim as the final segment, so two sort keys collide
|
|
18
|
+
* only when their channels are byte-identical; `writeSortKeyPrefix` stops at
|
|
19
|
+
* the checkpoint id, ahead of this segment, so `begins_with` reads are
|
|
20
|
+
* unaffected.
|
|
21
|
+
*/
|
|
22
|
+
export declare function writeSortKey(checkpointNs: string, checkpointId: string, taskId: string, index: number, channel: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* True when `sortKey` is one this adapter writes. A partition query carries no
|
|
25
|
+
* sort-key condition, so a partition-wide delete uses this to leave any row it
|
|
26
|
+
* does not own in place rather than deleting the whole partition blindly.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isCheckpointerSortKey(sortKey: string): boolean;
|
|
13
29
|
/** `begins_with` prefix selecting every WRITE item for one checkpoint. */
|
|
14
30
|
export declare function writeSortKeyPrefix(checkpointNs: string, checkpointId: string): string;
|
|
15
31
|
//# sourceMappingURL=keys.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/keys.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/keys.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,MAAM,CAAC;AA8BtC,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,MAAM,CAaR;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAI9D;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAErF"}
|
|
@@ -6,7 +6,9 @@ exports.metaSortKey = metaSortKey;
|
|
|
6
6
|
exports.metaSortKeyPrefix = metaSortKeyPrefix;
|
|
7
7
|
exports.payloadSortKey = payloadSortKey;
|
|
8
8
|
exports.writeSortKey = writeSortKey;
|
|
9
|
+
exports.isCheckpointerSortKey = isCheckpointerSortKey;
|
|
9
10
|
exports.writeSortKeyPrefix = writeSortKeyPrefix;
|
|
11
|
+
const errors_1 = require("../../shared/errors/errors");
|
|
10
12
|
/** Reserved separator joining sort-key segments; forbidden inside any segment. */
|
|
11
13
|
exports.SORT_KEY_SEPARATOR = '#';
|
|
12
14
|
/** Fixed digit width for the WRITE index so sort keys order numerically. */
|
|
@@ -24,9 +26,19 @@ var CheckpointItemKind;
|
|
|
24
26
|
CheckpointItemKind["PAYLOAD"] = "PAYLOAD";
|
|
25
27
|
CheckpointItemKind["WRITE"] = "WRITE";
|
|
26
28
|
})(CheckpointItemKind || (CheckpointItemKind = {}));
|
|
27
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Adapter tag prefixed to every checkpointer partition key. Without it a
|
|
31
|
+
* `thread_id` reused as a `sessionId` or a store namespace root — an ordinary
|
|
32
|
+
* design choice — put all three adapters' rows in one partition on a table
|
|
33
|
+
* shared via `DynamoDBFactory.createAll()`, where a partition-wide delete
|
|
34
|
+
* reached another adapter's data and composed sort keys could collide
|
|
35
|
+
* byte-for-byte. The three tags differ in their first character, so the key
|
|
36
|
+
* spaces are disjoint by construction.
|
|
37
|
+
*/
|
|
38
|
+
const ADAPTER_PARTITION_PREFIX = `CHKPT${exports.SORT_KEY_SEPARATOR}`;
|
|
39
|
+
/** Partition key for a thread: the adapter tag plus the thread id. */
|
|
28
40
|
function partitionKey(threadId) {
|
|
29
|
-
return threadId
|
|
41
|
+
return `${ADAPTER_PARTITION_PREFIX}${threadId}`;
|
|
30
42
|
}
|
|
31
43
|
/** Sort key for a checkpoint's lightweight metadata item. */
|
|
32
44
|
function metaSortKey(checkpointNs, checkpointId) {
|
|
@@ -40,10 +52,33 @@ function metaSortKeyPrefix(checkpointNs) {
|
|
|
40
52
|
function payloadSortKey(checkpointNs, checkpointId) {
|
|
41
53
|
return `${CheckpointItemKind.PAYLOAD}${exports.SORT_KEY_SEPARATOR}${checkpointNs}${exports.SORT_KEY_SEPARATOR}${checkpointId}`;
|
|
42
54
|
}
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Sort key for a single pending write. The trailing `channel` segment is what
|
|
57
|
+
* keeps two *different* channels from ever occupying one row: without it, a
|
|
58
|
+
* retried task whose write mix changed could compute an index another
|
|
59
|
+
* channel already holds, and the first-write-wins guard — which cannot tell a
|
|
60
|
+
* genuine retry from an unrelated write — would silently discard it. The
|
|
61
|
+
* channel is appended verbatim as the final segment, so two sort keys collide
|
|
62
|
+
* only when their channels are byte-identical; `writeSortKeyPrefix` stops at
|
|
63
|
+
* the checkpoint id, ahead of this segment, so `begins_with` reads are
|
|
64
|
+
* unaffected.
|
|
65
|
+
*/
|
|
66
|
+
function writeSortKey(checkpointNs, checkpointId, taskId, index, channel) {
|
|
67
|
+
const offsetIndex = index + WRITE_INDEX_OFFSET;
|
|
68
|
+
if (offsetIndex < 0 || offsetIndex.toString().length > WRITE_INDEX_PAD_WIDTH) {
|
|
69
|
+
throw new errors_1.ValidationError(`write index ${index} is outside the range encodable at offset ${WRITE_INDEX_OFFSET} ` +
|
|
70
|
+
`with ${WRITE_INDEX_PAD_WIDTH} digits`, 'index');
|
|
71
|
+
}
|
|
72
|
+
const paddedIndex = offsetIndex.toString().padStart(WRITE_INDEX_PAD_WIDTH, '0');
|
|
73
|
+
return [CheckpointItemKind.WRITE, checkpointNs, checkpointId, taskId, paddedIndex, channel].join(exports.SORT_KEY_SEPARATOR);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* True when `sortKey` is one this adapter writes. A partition query carries no
|
|
77
|
+
* sort-key condition, so a partition-wide delete uses this to leave any row it
|
|
78
|
+
* does not own in place rather than deleting the whole partition blindly.
|
|
79
|
+
*/
|
|
80
|
+
function isCheckpointerSortKey(sortKey) {
|
|
81
|
+
return Object.values(CheckpointItemKind).some((kind) => sortKey.startsWith(`${kind}${exports.SORT_KEY_SEPARATOR}`));
|
|
47
82
|
}
|
|
48
83
|
/** `begins_with` prefix selecting every WRITE item for one checkpoint. */
|
|
49
84
|
function writeSortKeyPrefix(checkpointNs, checkpointId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/keys.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/keys.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,uDAA6D;AAE7D,kFAAkF;AACrE,QAAA,kBAAkB,GAAG,GAAG,CAAC;AAEtC,4EAA4E;AAC5E,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAEjC;;;;GAIG;AACH,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,6EAA6E;AAC7E,IAAK,kBAIJ;AAJD,WAAK,kBAAkB;IACrB,mCAAa,CAAA;IACb,yCAAmB,CAAA;IACnB,qCAAe,CAAA;AACjB,CAAC,EAJI,kBAAkB,KAAlB,kBAAkB,QAItB;AAED;;;;;;;;GAQG;AACH,MAAM,wBAAwB,GAAG,QAAQ,QAAA,kBAAkB,EAAE,CAAC;AAE9D,sEAAsE;AACtE,sBAA6B,QAAgB;IAC3C,OAAO,GAAG,wBAAwB,GAAG,QAAQ,EAAE,CAAC;AAClD,CAAC;AAED,6DAA6D;AAC7D,qBAA4B,YAAoB,EAAE,YAAoB;IACpE,OAAO,GAAG,kBAAkB,CAAC,IAAI,GAAG,QAAA,kBAAkB,GAAG,YAAY,GAAG,QAAA,kBAAkB,GAAG,YAAY,EAAE,CAAC;AAC9G,CAAC;AAED,gFAAgF;AAChF,2BAAkC,YAAoB;IACpD,OAAO,GAAG,kBAAkB,CAAC,IAAI,GAAG,QAAA,kBAAkB,GAAG,YAAY,GAAG,QAAA,kBAAkB,EAAE,CAAC;AAC/F,CAAC;AAED,sDAAsD;AACtD,wBAA+B,YAAoB,EAAE,YAAoB;IACvE,OAAO,GAAG,kBAAkB,CAAC,OAAO,GAAG,QAAA,kBAAkB,GAAG,YAAY,GAAG,QAAA,kBAAkB,GAAG,YAAY,EAAE,CAAC;AACjH,CAAC;AAED;;;;;;;;;;GAUG;AACH,sBACE,YAAoB,EACpB,YAAoB,EACpB,MAAc,EACd,KAAa,EACb,OAAe;IAEf,MAAM,WAAW,GAAG,KAAK,GAAG,kBAAkB,CAAC;IAC/C,IAAI,WAAW,GAAG,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAC7E,MAAM,IAAI,wBAAe,CACvB,eAAe,KAAK,6CAA6C,kBAAkB,GAAG;YACpF,QAAQ,qBAAqB,SAAS,EACxC,OAAO,CACR,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;IAChF,OAAO,CAAC,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,CAC9F,QAAA,kBAAkB,CACnB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,+BAAsC,OAAe;IACnD,OAAO,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACrD,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,QAAA,kBAAkB,EAAE,CAAC,CACnD,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,4BAAmC,YAAoB,EAAE,YAAoB;IAC3E,OAAO,GAAG,kBAAkB,CAAC,KAAK,GAAG,QAAA,kBAAkB,GAAG,YAAY,GAAG,QAAA,kBAAkB,GAAG,YAAY,GAAG,QAAA,kBAAkB,EAAE,CAAC;AACpI,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"special-write-cleanup.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/special-write-cleanup.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"special-write-cleanup.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/special-write-cleanup.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AA4EnD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,mBAAmB,EAC5B,KAAK,EAAE,mBAAmB,EAAE,GAC3B,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAoC5B"}
|
|
@@ -26,28 +26,22 @@ async function readPreviousDescriptors(context, items) {
|
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Split `items` by outcome after a failed batch write (always a
|
|
29
|
-
* BatchWriteAllIncompleteError — batchWriteAll's only throw
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
29
|
+
* BatchWriteAllIncompleteError — batchWriteAll's only throw, and every one of
|
|
30
|
+
* its own failedChunks is in turn always a BatchWriteIncompleteError with an
|
|
31
|
+
* accurate `unprocessed`, whichever of drainUnprocessedWrites's exit paths
|
|
32
|
+
* produced it — see drain-unprocessed.ts): never-committed items are safe to
|
|
33
|
+
* clean up their own upload, every other item its previous one. Uses `.name`,
|
|
34
|
+
* not `instanceof` (banned repo-wide, see base-error.ts).
|
|
34
35
|
*/
|
|
35
36
|
function splitSpecialOutcome(items, error) {
|
|
36
37
|
const neverCommittedSks = new Set();
|
|
37
|
-
let everyChunkTracked = true;
|
|
38
38
|
for (const failedChunk of error.failedChunks) {
|
|
39
|
-
if (failedChunk.name !== 'BatchWriteIncompleteError') {
|
|
40
|
-
everyChunkTracked = false;
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
39
|
for (const request of failedChunk.unprocessed) {
|
|
44
40
|
/** Always a PutRequest echoing this submission — special writes never send DeleteRequests. */
|
|
45
41
|
const { SK } = request.PutRequest.Item;
|
|
46
42
|
neverCommittedSks.add(SK);
|
|
47
43
|
}
|
|
48
44
|
}
|
|
49
|
-
if (!everyChunkTracked)
|
|
50
|
-
return { committed: [], neverCommitted: [] };
|
|
51
45
|
return {
|
|
52
46
|
committed: items.filter((item) => !neverCommittedSks.has(item.SK)),
|
|
53
47
|
neverCommitted: items.filter((item) => neverCommittedSks.has(item.SK)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"special-write-cleanup.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/special-write-cleanup.ts"],"names":[],"mappings":";;;AACA,wEAAmE;AACnE,2DAAiE;AACjE,mEAAkE;AAClE,uDAAgE;AAQhE;;;;GAIG;AACH,KAAK,UAAU,uBAAuB,CACpC,OAA4B,EAC5B,KAA4B;IAE5B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyC,CAAC;IAClE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAC1C,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;YACjB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACjC,cAAc,EAAE,IAAI;YACpB,oBAAoB,EAAE,IAAI;YAC1B,wBAAwB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;SAC5C,CAAC,CACH,CAAC;QACF,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,KAAsC,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"special-write-cleanup.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/special-write-cleanup.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
/** Validate a thread id is a non-empty, separator-free string. */
|
|
1
|
+
/** Validate a thread id is a non-empty, separator- and control-char-free string. */
|
|
2
2
|
export declare function validateThreadId(threadId: string): void;
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Validate a checkpoint namespace. Unlike the other identifiers an empty value
|
|
5
|
+
* is legal — it is the root namespace — so only the separator and
|
|
6
|
+
* control-character rules apply.
|
|
7
|
+
*/
|
|
4
8
|
export declare function validateCheckpointNs(checkpointNs: string): void;
|
|
5
|
-
/** Validate a checkpoint id is a non-empty, separator-free string. */
|
|
9
|
+
/** Validate a checkpoint id is a non-empty, separator- and control-char-free string. */
|
|
6
10
|
export declare function validateCheckpointId(checkpointId: string): void;
|
|
7
|
-
/** Validate a task id is a non-empty, separator-free string. */
|
|
11
|
+
/** Validate a task id is a non-empty, separator- and control-char-free string. */
|
|
8
12
|
export declare function validateTaskId(taskId: string): void;
|
|
9
13
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/validation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/validation.ts"],"names":[],"mappings":"AAOA,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAG/D;AAED,wFAAwF;AACxF,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAE/D;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEnD"}
|
|
@@ -6,23 +6,25 @@ exports.validateCheckpointId = validateCheckpointId;
|
|
|
6
6
|
exports.validateTaskId = validateTaskId;
|
|
7
7
|
const primitives_1 = require("../../shared/validation/primitives");
|
|
8
8
|
const keys_1 = require("./keys");
|
|
9
|
-
/** Validate a thread id is a non-empty, separator-free string. */
|
|
9
|
+
/** Validate a thread id is a non-empty, separator- and control-char-free string. */
|
|
10
10
|
function validateThreadId(threadId) {
|
|
11
|
-
(0, primitives_1.
|
|
12
|
-
(0, primitives_1.assertNoSeparator)(threadId, keys_1.SORT_KEY_SEPARATOR, 'thread_id');
|
|
11
|
+
(0, primitives_1.validateIdentifier)(threadId, keys_1.SORT_KEY_SEPARATOR, 'thread_id');
|
|
13
12
|
}
|
|
14
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Validate a checkpoint namespace. Unlike the other identifiers an empty value
|
|
15
|
+
* is legal — it is the root namespace — so only the separator and
|
|
16
|
+
* control-character rules apply.
|
|
17
|
+
*/
|
|
15
18
|
function validateCheckpointNs(checkpointNs) {
|
|
16
19
|
(0, primitives_1.assertNoSeparator)(checkpointNs, keys_1.SORT_KEY_SEPARATOR, 'checkpoint_ns');
|
|
20
|
+
(0, primitives_1.assertNoControlChars)(checkpointNs, 'checkpoint_ns');
|
|
17
21
|
}
|
|
18
|
-
/** Validate a checkpoint id is a non-empty, separator-free string. */
|
|
22
|
+
/** Validate a checkpoint id is a non-empty, separator- and control-char-free string. */
|
|
19
23
|
function validateCheckpointId(checkpointId) {
|
|
20
|
-
(0, primitives_1.
|
|
21
|
-
(0, primitives_1.assertNoSeparator)(checkpointId, keys_1.SORT_KEY_SEPARATOR, 'checkpoint_id');
|
|
24
|
+
(0, primitives_1.validateIdentifier)(checkpointId, keys_1.SORT_KEY_SEPARATOR, 'checkpoint_id');
|
|
22
25
|
}
|
|
23
|
-
/** Validate a task id is a non-empty, separator-free string. */
|
|
26
|
+
/** Validate a task id is a non-empty, separator- and control-char-free string. */
|
|
24
27
|
function validateTaskId(taskId) {
|
|
25
|
-
(0, primitives_1.
|
|
26
|
-
(0, primitives_1.assertNoSeparator)(taskId, keys_1.SORT_KEY_SEPARATOR, 'taskId');
|
|
28
|
+
(0, primitives_1.validateIdentifier)(taskId, keys_1.SORT_KEY_SEPARATOR, 'taskId');
|
|
27
29
|
}
|
|
28
30
|
//# sourceMappingURL=validation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/validation.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/validation.ts"],"names":[],"mappings":";;;;;;AAAA,mEAI4C;AAC5C,iCAA4C;AAE5C,oFAAoF;AACpF,0BAAiC,QAAgB;IAC/C,IAAA,+BAAkB,EAAC,QAAQ,EAAE,yBAAkB,EAAE,WAAW,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,8BAAqC,YAAoB;IACvD,IAAA,8BAAiB,EAAC,YAAY,EAAE,yBAAkB,EAAE,eAAe,CAAC,CAAC;IACrE,IAAA,iCAAoB,EAAC,YAAY,EAAE,eAAe,CAAC,CAAC;AACtD,CAAC;AAED,wFAAwF;AACxF,8BAAqC,YAAoB;IACvD,IAAA,+BAAkB,EAAC,YAAY,EAAE,yBAAkB,EAAE,eAAe,CAAC,CAAC;AACxE,CAAC;AAED,kFAAkF;AAClF,wBAA+B,MAAc;IAC3C,IAAA,+BAAkB,EAAC,MAAM,EAAE,yBAAkB,EAAE,QAAQ,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CheckpointWriteItem } from '../types';
|
|
2
|
+
import type { CheckpointerContext } from './setup';
|
|
3
|
+
/**
|
|
4
|
+
* True when the guard rejected a write — NOT evidence a competitor won: a
|
|
5
|
+
* `PutCommand` retried after its response was lost can re-hit its own
|
|
6
|
+
* committed row and fail identically; the two cases are indistinguishable.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isConditionalCheckFailed(error: {
|
|
9
|
+
name?: string;
|
|
10
|
+
}): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Report a guard rejection. Sort keys carry their channel, so a rejection
|
|
13
|
+
* normally means this exact (task, channel, occurrence) row is already
|
|
14
|
+
* committed — a genuine duplicate, and the expected outcome of a retry. A row
|
|
15
|
+
* held by a *different* channel is not something this adapter can produce, so
|
|
16
|
+
* it is reported at `warn`: the write was not persisted and something else
|
|
17
|
+
* wrote to this key space. No attributes returned means the outcome cannot be
|
|
18
|
+
* told apart, so it is treated as the ordinary duplicate.
|
|
19
|
+
*/
|
|
20
|
+
export declare function reportGuardRejection(context: CheckpointerContext, item: CheckpointWriteItem, error: Error): void;
|
|
21
|
+
//# sourceMappingURL=write-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-guard.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/write-guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAE1E;AAcD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,mBAAmB,EACzB,KAAK,EAAE,KAAK,GACX,IAAI,CAcN"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isConditionalCheckFailed = isConditionalCheckFailed;
|
|
4
|
+
exports.reportGuardRejection = reportGuardRejection;
|
|
5
|
+
/**
|
|
6
|
+
* True when the guard rejected a write — NOT evidence a competitor won: a
|
|
7
|
+
* `PutCommand` retried after its response was lost can re-hit its own
|
|
8
|
+
* committed row and fail identically; the two cases are indistinguishable.
|
|
9
|
+
*/
|
|
10
|
+
function isConditionalCheckFailed(error) {
|
|
11
|
+
return error.name === 'ConditionalCheckFailedException';
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The channel recorded on the row that turned a write away, or undefined when
|
|
15
|
+
* the service returned no attributes. `ReturnValuesOnConditionCheckFailure:
|
|
16
|
+
* 'ALL_OLD'` attaches the existing item to the exception at no extra round
|
|
17
|
+
* trip, but — verified against real DynamoDB — the document client does not
|
|
18
|
+
* unmarshall an *error* payload the way it unmarshalls a response, so the
|
|
19
|
+
* attribute arrives in raw AttributeValue form.
|
|
20
|
+
*/
|
|
21
|
+
function rejectedChannel(error) {
|
|
22
|
+
return error.Item?.channel?.S;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Report a guard rejection. Sort keys carry their channel, so a rejection
|
|
26
|
+
* normally means this exact (task, channel, occurrence) row is already
|
|
27
|
+
* committed — a genuine duplicate, and the expected outcome of a retry. A row
|
|
28
|
+
* held by a *different* channel is not something this adapter can produce, so
|
|
29
|
+
* it is reported at `warn`: the write was not persisted and something else
|
|
30
|
+
* wrote to this key space. No attributes returned means the outcome cannot be
|
|
31
|
+
* told apart, so it is treated as the ordinary duplicate.
|
|
32
|
+
*/
|
|
33
|
+
function reportGuardRejection(context, item, error) {
|
|
34
|
+
const found = rejectedChannel(error);
|
|
35
|
+
if (found !== undefined && found !== item.channel) {
|
|
36
|
+
context.logger.warn('putWrites: write row held by an unexpected channel; write not persisted', {
|
|
37
|
+
sortKey: item.SK,
|
|
38
|
+
expected: item.channel,
|
|
39
|
+
found,
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
context.logger.debug('putWrites: skipped a write already committed for this task and channel', {
|
|
44
|
+
sortKey: item.SK,
|
|
45
|
+
channel: item.channel,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=write-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-guard.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/write-guard.ts"],"names":[],"mappings":";;;;AAGA;;;;GAIG;AACH,kCAAyC,KAAwB;IAC/D,OAAO,KAAK,CAAC,IAAI,KAAK,iCAAiC,CAAC;AAC1D,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,KAAY;IACnC,OAAQ,KAAiD,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;;;;GAQG;AACH,8BACE,OAA4B,EAC5B,IAAyB,EACzB,KAAY;IAEZ,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;QAClD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,yEAAyE,EAAE;YAC7F,OAAO,EAAE,IAAI,CAAC,EAAE;YAChB,QAAQ,EAAE,IAAI,CAAC,OAAO;YACtB,KAAK;SACN,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wEAAwE,EAAE;QAC7F,OAAO,EAAE,IAAI,CAAC,EAAE;QAChB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { PendingWrite, PendingWriteValue } from '@langchain/langgraph-checkpoint';
|
|
2
|
+
/** One write with its sort-key index resolved exactly once. */
|
|
3
|
+
export interface ResolvedWrite {
|
|
4
|
+
channel: string;
|
|
5
|
+
value: PendingWriteValue;
|
|
6
|
+
index: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Assign every write in one `putWrites` call its sort-key index, in a single
|
|
10
|
+
* pass — nothing recomputes it downstream, which is what used to let the
|
|
11
|
+
* deduped array's positions disagree with the ones the caller's array
|
|
12
|
+
* produced.
|
|
13
|
+
*
|
|
14
|
+
* A regular write's index is its position in the caller's array, exactly as
|
|
15
|
+
* the reference `MemorySaver` computes it: that is what makes stored writes
|
|
16
|
+
* replay in the order the task emitted them. A special channel takes its
|
|
17
|
+
* fixed `WRITES_IDX_MAP` slot instead, and a later duplicate replaces an
|
|
18
|
+
* earlier one (last-write-wins, again matching the reference).
|
|
19
|
+
*
|
|
20
|
+
* Positions are not stable across calls, which is why the *sort key* also
|
|
21
|
+
* carries the channel and each call stamps its rows with a shared
|
|
22
|
+
* `writeGroup` — see {@link buildWriteItems} and `dropSupersededWrites`.
|
|
23
|
+
*
|
|
24
|
+
* `Object.hasOwn` guards WRITES_IDX_MAP's own `Object.prototype` chain — a
|
|
25
|
+
* channel literally named `constructor`/`toString`/etc. must be treated as
|
|
26
|
+
* regular, not resolve to an inherited function reference.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveWriteIndices(writes: PendingWrite[]): ResolvedWrite[];
|
|
29
|
+
//# sourceMappingURL=write-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-index.d.ts","sourceRoot":"","sources":["../../../src/checkpointer/internal/write-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGvF,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,CAY3E"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveWriteIndices = resolveWriteIndices;
|
|
4
|
+
const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
|
|
5
|
+
/**
|
|
6
|
+
* Assign every write in one `putWrites` call its sort-key index, in a single
|
|
7
|
+
* pass — nothing recomputes it downstream, which is what used to let the
|
|
8
|
+
* deduped array's positions disagree with the ones the caller's array
|
|
9
|
+
* produced.
|
|
10
|
+
*
|
|
11
|
+
* A regular write's index is its position in the caller's array, exactly as
|
|
12
|
+
* the reference `MemorySaver` computes it: that is what makes stored writes
|
|
13
|
+
* replay in the order the task emitted them. A special channel takes its
|
|
14
|
+
* fixed `WRITES_IDX_MAP` slot instead, and a later duplicate replaces an
|
|
15
|
+
* earlier one (last-write-wins, again matching the reference).
|
|
16
|
+
*
|
|
17
|
+
* Positions are not stable across calls, which is why the *sort key* also
|
|
18
|
+
* carries the channel and each call stamps its rows with a shared
|
|
19
|
+
* `writeGroup` — see {@link buildWriteItems} and `dropSupersededWrites`.
|
|
20
|
+
*
|
|
21
|
+
* `Object.hasOwn` guards WRITES_IDX_MAP's own `Object.prototype` chain — a
|
|
22
|
+
* channel literally named `constructor`/`toString`/etc. must be treated as
|
|
23
|
+
* regular, not resolve to an inherited function reference.
|
|
24
|
+
*/
|
|
25
|
+
function resolveWriteIndices(writes) {
|
|
26
|
+
const bySpecialIndex = new Map();
|
|
27
|
+
const regular = [];
|
|
28
|
+
writes.forEach(([channel, value], positional) => {
|
|
29
|
+
if (Object.hasOwn(langgraph_checkpoint_1.WRITES_IDX_MAP, channel)) {
|
|
30
|
+
const index = langgraph_checkpoint_1.WRITES_IDX_MAP[channel];
|
|
31
|
+
bySpecialIndex.set(index, { channel, value, index });
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
regular.push({ channel, value, index: positional });
|
|
35
|
+
});
|
|
36
|
+
return [...bySpecialIndex.values(), ...regular];
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=write-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-index.js","sourceRoot":"","sources":["../../../src/checkpointer/internal/write-index.ts"],"names":[],"mappings":";;;AACA,0EAAiE;AASjE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,6BAAoC,MAAsB;IACxD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAyB,CAAC;IACxD,MAAM,OAAO,GAAoB,EAAE,CAAC;IACpC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,EAAE;QAC9C,IAAI,MAAM,CAAC,MAAM,CAAC,qCAAc,EAAE,OAAO,CAAC,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,qCAAc,CAAC,OAAO,CAAC,CAAC;YACtC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/checkpointer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE1E,yCAAyC;AACzC,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GACnD,YAAY,GAAG;IACb,8EAA8E;IAC9E,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AAEJ,2EAA2E;AAC3E,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,iBAAiB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,gEAAgE;AAChE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,iBAAiB,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/checkpointer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE1E,yCAAyC;AACzC,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GACnD,YAAY,GAAG;IACb,8EAA8E;IAC9E,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AAEJ,2EAA2E;AAC3E,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,iBAAiB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,gEAAgE;AAChE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,iBAAiB,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-messages.d.ts","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"add-messages.d.ts","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,0BAA0B,CAAC;AASlC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAmDxD;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAef"}
|
|
@@ -3,13 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.addMessages = addMessages;
|
|
4
4
|
const messages_1 = require("@langchain/core/messages");
|
|
5
5
|
const clock_1 = require("../../shared/clock");
|
|
6
|
-
const
|
|
6
|
+
const descriptor_keys_1 = require("../../shared/codec/descriptor-keys");
|
|
7
|
+
const orphans_1 = require("../../shared/codec/s3/orphans");
|
|
7
8
|
const ttl_1 = require("../../shared/validation/ttl");
|
|
8
9
|
const append_saga_1 = require("../internal/append-saga");
|
|
9
10
|
const item_mapper_1 = require("../internal/item-mapper");
|
|
10
11
|
const message_chunker_1 = require("../internal/message-chunker");
|
|
11
12
|
const title_generator_1 = require("../internal/title-generator");
|
|
12
13
|
const ttl_anchor_1 = require("../internal/ttl-anchor");
|
|
14
|
+
const validation_1 = require("../internal/validation");
|
|
13
15
|
/** Message Puts per append transaction: the 100-item limit, less the metadata Update. */
|
|
14
16
|
const MAX_MESSAGES_PER_TRANSACTION = 99;
|
|
15
17
|
/**
|
|
@@ -18,10 +20,28 @@ const MAX_MESSAGES_PER_TRANSACTION = 99;
|
|
|
18
20
|
* `ITEM_OVERHEAD_BYTES`) cannot push a chunk over the real limit at commit time.
|
|
19
21
|
*/
|
|
20
22
|
const MAX_TRANSACTION_BYTES = 3_500_000;
|
|
23
|
+
/**
|
|
24
|
+
* Encode every message, cleaning up after itself if one fails partway.
|
|
25
|
+
*
|
|
26
|
+
* Offloaded messages upload sequentially here, *before* the append saga's
|
|
27
|
+
* compensation machinery is ever reached, so a failure on message N used to
|
|
28
|
+
* strand messages 1..N-1's already-uploaded S3 objects with no cleanup path —
|
|
29
|
+
* the one gap in this subsystem's otherwise complete no-orphan guarantee.
|
|
30
|
+
* Nothing will ever reference those objects, so they are safe to delete
|
|
31
|
+
* unconditionally on the way out.
|
|
32
|
+
*/
|
|
21
33
|
async function buildItems(context, sessionId, stored, ttlTimestamp) {
|
|
22
34
|
const items = [];
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
try {
|
|
36
|
+
for (const message of stored) {
|
|
37
|
+
items.push(await (0, item_mapper_1.buildMessageItem)(context, sessionId, context.ulid(), message, ttlTimestamp));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (context.offloader) {
|
|
42
|
+
await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)(items.map((item) => item.message)), 'history.addMessages.encode', context.logger);
|
|
43
|
+
}
|
|
44
|
+
throw error;
|
|
25
45
|
}
|
|
26
46
|
return items;
|
|
27
47
|
}
|
|
@@ -38,7 +58,7 @@ async function buildItems(context, sessionId, stored, ttlTimestamp) {
|
|
|
38
58
|
* large payloads become small descriptors and stay well under the limits.
|
|
39
59
|
*/
|
|
40
60
|
async function addMessages(context, sessionId, messages) {
|
|
41
|
-
(0,
|
|
61
|
+
(0, validation_1.validateSessionId)(sessionId);
|
|
42
62
|
if (messages.length === 0)
|
|
43
63
|
return;
|
|
44
64
|
const stored = (0, messages_1.mapChatMessagesToStoredMessages)(messages);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-messages.js","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":";;;AAAA,uDAIkC;AAElC,8CAA4C;AAC5C,
|
|
1
|
+
{"version":3,"file":"add-messages.js","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":";;;AAAA,uDAIkC;AAElC,8CAA4C;AAC5C,wEAAmE;AACnE,2DAAiE;AACjE,qDAAoE;AACpE,yDAAuD;AACvD,yDAA2D;AAC3D,iEAA0D;AAE1D,iEAA0D;AAC1D,uDAA0D;AAC1D,uDAA2D;AAG3D,yFAAyF;AACzF,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAExC;;;;GAIG;AACH,MAAM,qBAAqB,GAAG,SAAS,CAAC;AAExC;;;;;;;;;GASG;AACH,KAAK,UAAU,UAAU,CACvB,OAAuB,EACvB,SAAiB,EACjB,MAAuB,EACvB,YAAqB;IAErB,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,IAAA,8BAAgB,EAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,IAAA,0BAAgB,EACpB,OAAO,CAAC,SAAS,EACjB,IAAA,+BAAa,EAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAChD,4BAA4B,EAC5B,OAAO,CAAC,MAAM,CACf,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACI,KAAK,sBACV,OAAuB,EACvB,SAAiB,EACjB,QAAuB;IAEvB,IAAA,8BAAiB,EAAC,SAAS,CAAC,CAAC;IAC7B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAClC,MAAM,MAAM,GAAG,IAAA,0CAA+B,EAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG;QACxB,CAAC,CAAC,MAAM,IAAA,6BAAgB,EAAC,OAAO,EAAE,SAAS,EAAE,IAAA,2BAAqB,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChF,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,IAAA,6BAAW,EAAC,KAAK,EAAE,4BAA4B,EAAE,qBAAqB,CAAC,CAAC;IACvF,MAAM,IAAA,0BAAY,EAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE;QAC7C,GAAG,EAAE,IAAA,cAAM,GAAE;QACb,KAAK,EAAE,IAAA,6BAAW,EAAC,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,EAAE,YAAY;QAClC,eAAe,EAAE,MAAM,EAAE,OAAO;KACjC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { HistoryContext } from '../internal/setup';
|
|
2
2
|
/**
|
|
3
|
-
* Delete a whole session: every message item plus the metadata item,
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* the in-memory page caps, and never discards already-flushed progress if a
|
|
8
|
-
* later batch fails.
|
|
3
|
+
* Delete a whole session: every message item plus the metadata item, best-effort
|
|
4
|
+
* deleting any offloaded S3 objects. Rows this adapter does not own are left in
|
|
5
|
+
* place and logged, so a shared-table partition holding a foreign row is never
|
|
6
|
+
* collaterally wiped.
|
|
9
7
|
*/
|
|
10
8
|
export declare function clearSession(context: HistoryContext, sessionId: string): Promise<void>;
|
|
11
9
|
//# sourceMappingURL=clear.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clear.d.ts","sourceRoot":"","sources":["../../../src/history/actions/clear.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"clear.d.ts","sourceRoot":"","sources":["../../../src/history/actions/clear.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAQxD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAY5F"}
|