@farukada/aws-langgraph-dynamodb-ts 1.0.0-rc.1 → 1.0.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 +1820 -290
- package/dist/cjs/backfill/backfill.d.ts +171 -0
- package/dist/cjs/backfill/backfill.js +177 -0
- package/dist/cjs/checkpointer/actions/delete-thread.d.ts +50 -0
- package/dist/cjs/checkpointer/actions/delete-thread.js +26 -0
- package/dist/cjs/checkpointer/actions/get-tuple.d.ts +36 -0
- package/dist/cjs/checkpointer/actions/get-tuple.js +22 -0
- package/dist/cjs/checkpointer/actions/list.d.ts +55 -0
- package/dist/cjs/checkpointer/actions/list.js +70 -0
- package/dist/cjs/checkpointer/actions/put-writes.d.ts +49 -0
- package/dist/cjs/checkpointer/actions/put-writes.js +21 -0
- package/dist/cjs/checkpointer/actions/put.d.ts +95 -0
- package/dist/cjs/checkpointer/actions/put.js +79 -0
- package/dist/cjs/checkpointer/internal/delta-history.d.ts +124 -0
- package/dist/cjs/checkpointer/internal/delta-history.js +131 -0
- package/dist/cjs/checkpointer/internal/listing.d.ts +149 -0
- package/dist/cjs/checkpointer/internal/listing.js +104 -0
- package/dist/cjs/checkpointer/internal/parse.d.ts +298 -0
- package/dist/cjs/checkpointer/internal/parse.js +184 -0
- package/dist/cjs/checkpointer/internal/pending-writes.d.ts +314 -0
- package/dist/cjs/checkpointer/internal/pending-writes.js +241 -0
- package/dist/cjs/checkpointer/internal/read.d.ts +135 -0
- package/dist/cjs/checkpointer/internal/read.js +132 -0
- package/dist/cjs/checkpointer/internal/rows.d.ts +644 -0
- package/dist/cjs/checkpointer/internal/rows.js +356 -0
- package/dist/cjs/checkpointer/internal/setup.d.ts +47 -0
- package/dist/cjs/checkpointer/internal/setup.js +25 -0
- package/dist/cjs/checkpointer/saver.d.ts +306 -0
- package/dist/cjs/checkpointer/saver.js +56 -0
- package/dist/cjs/checkpointer/types.d.ts +51 -0
- package/dist/cjs/factory/factory.d.ts +154 -0
- package/dist/cjs/factory/factory.js +137 -0
- package/dist/{factory → cjs/factory}/types.d.ts +33 -14
- package/dist/cjs/history/actions/add-messages.d.ts +51 -0
- package/dist/cjs/history/actions/add-messages.js +17 -0
- package/dist/cjs/history/actions/clear.d.ts +52 -0
- package/dist/cjs/history/actions/clear.js +29 -0
- package/dist/cjs/history/actions/get-messages.d.ts +60 -0
- package/dist/cjs/history/actions/get-messages.js +58 -0
- package/dist/cjs/history/actions/list-sessions.d.ts +55 -0
- package/dist/cjs/history/actions/list-sessions.js +67 -0
- package/dist/cjs/history/actions/reconcile-count.d.ts +49 -0
- package/dist/cjs/history/actions/reconcile-count.js +8 -0
- package/dist/cjs/history/chat-message-history.d.ts +267 -0
- package/dist/cjs/history/chat-message-history.js +61 -0
- package/dist/cjs/history/internal/append.d.ts +244 -0
- package/dist/cjs/history/internal/append.js +267 -0
- package/dist/cjs/history/internal/message-read.d.ts +84 -0
- package/dist/cjs/history/internal/message-read.js +93 -0
- package/dist/cjs/history/internal/parse.d.ts +153 -0
- package/dist/cjs/history/internal/parse.js +113 -0
- package/dist/cjs/history/internal/rows.d.ts +196 -0
- package/dist/cjs/history/internal/rows.js +96 -0
- package/dist/cjs/history/internal/session.d.ts +350 -0
- package/dist/cjs/history/internal/session.js +296 -0
- package/dist/cjs/history/internal/setup.d.ts +64 -0
- package/dist/cjs/history/internal/setup.js +60 -0
- package/dist/cjs/history/session-adapter.d.ts +112 -0
- package/dist/cjs/history/session-adapter.js +38 -0
- package/dist/cjs/history/types.d.ts +102 -0
- package/dist/cjs/index.d.ts +53 -0
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/shared/adapter.d.ts +146 -0
- package/dist/cjs/shared/adapter.js +70 -0
- package/dist/cjs/shared/clock.d.ts +52 -0
- package/dist/cjs/shared/clock.js +14 -0
- package/dist/cjs/shared/codec/codec.d.ts +336 -0
- package/dist/cjs/shared/codec/codec.js +162 -0
- package/dist/cjs/shared/codec/compression.d.ts +66 -0
- package/dist/cjs/shared/codec/compression.js +45 -0
- package/dist/cjs/shared/codec/json-serde.d.ts +80 -0
- package/dist/cjs/shared/codec/json-serde.js +58 -0
- package/dist/{shared → cjs/shared}/codec/s3/client-types.d.ts +22 -2
- package/dist/{shared → cjs/shared}/codec/s3/client-types.js +0 -1
- package/dist/cjs/shared/codec/s3/client.d.ts +63 -0
- package/dist/cjs/shared/codec/s3/client.js +78 -0
- package/dist/cjs/shared/codec/s3/config.d.ts +260 -0
- package/dist/cjs/shared/codec/s3/config.js +92 -0
- package/dist/cjs/shared/codec/s3/lifecycle.d.ts +220 -0
- package/dist/cjs/shared/codec/s3/lifecycle.js +223 -0
- package/dist/cjs/shared/codec/s3/offloader.d.ts +428 -0
- package/dist/cjs/shared/codec/s3/offloader.js +289 -0
- package/dist/cjs/shared/concurrency.d.ts +43 -0
- package/dist/{shared → cjs/shared}/concurrency.js +10 -9
- package/dist/cjs/shared/dynamodb/abort.d.ts +47 -0
- package/dist/cjs/shared/dynamodb/abort.js +16 -0
- package/dist/cjs/shared/dynamodb/batch-write.d.ts +86 -0
- package/dist/cjs/shared/dynamodb/batch-write.js +79 -0
- package/dist/cjs/shared/dynamodb/cancellation.d.ts +124 -0
- package/dist/cjs/shared/dynamodb/cancellation.js +37 -0
- package/dist/cjs/shared/dynamodb/client.d.ts +177 -0
- package/dist/{shared → cjs/shared}/dynamodb/client.js +12 -14
- package/dist/cjs/shared/dynamodb/idempotent-write.d.ts +596 -0
- package/dist/cjs/shared/dynamodb/idempotent-write.js +173 -0
- package/dist/cjs/shared/dynamodb/paginate.d.ts +111 -0
- package/dist/cjs/shared/dynamodb/paginate.js +90 -0
- package/dist/cjs/shared/dynamodb/partition-delete.d.ts +204 -0
- package/dist/cjs/shared/dynamodb/partition-delete.js +177 -0
- package/dist/cjs/shared/dynamodb/recency-index.d.ts +243 -0
- package/dist/cjs/shared/dynamodb/recency-index.js +146 -0
- package/dist/cjs/shared/dynamodb/retry.d.ts +317 -0
- package/dist/cjs/shared/dynamodb/retry.js +193 -0
- package/dist/cjs/shared/dynamodb/row-size.d.ts +33 -0
- package/dist/cjs/shared/dynamodb/row-size.js +30 -0
- package/dist/cjs/shared/dynamodb/table-schema.d.ts +199 -0
- package/dist/cjs/shared/dynamodb/table-schema.js +52 -0
- package/dist/cjs/shared/errors/base-error.d.ts +231 -0
- package/dist/cjs/shared/errors/base-error.js +73 -0
- package/dist/cjs/shared/errors/boundary.d.ts +86 -0
- package/dist/cjs/shared/errors/boundary.js +61 -0
- package/dist/cjs/shared/errors/classify.d.ts +206 -0
- package/dist/cjs/shared/errors/classify.js +232 -0
- package/dist/cjs/shared/errors/error-code.d.ts +95 -0
- package/dist/{shared → cjs/shared}/errors/error-code.js +12 -2
- package/dist/cjs/shared/errors/errors.d.ts +233 -0
- package/dist/cjs/shared/errors/errors.js +123 -0
- package/dist/cjs/shared/logging/logger.d.ts +80 -0
- package/dist/cjs/shared/logging/logger.js +30 -0
- package/dist/cjs/shared/logging/redaction.d.ts +123 -0
- package/dist/cjs/shared/logging/redaction.js +145 -0
- package/dist/cjs/shared/logging/secret-patterns.d.ts +227 -0
- package/dist/cjs/shared/logging/secret-patterns.js +93 -0
- package/dist/cjs/shared/logging/truncate.d.ts +197 -0
- package/dist/cjs/shared/logging/truncate.js +31 -0
- package/dist/cjs/shared/options.d.ts +100 -0
- package/dist/cjs/shared/ulid.d.ts +80 -0
- package/dist/{shared → cjs/shared}/ulid.js +7 -21
- package/dist/cjs/shared/validation/collaborators.d.ts +160 -0
- package/dist/cjs/shared/validation/collaborators.js +79 -0
- package/dist/cjs/shared/validation/option-shape.d.ts +91 -0
- package/dist/cjs/shared/validation/option-shape.js +31 -0
- package/dist/cjs/shared/validation/options.d.ts +145 -0
- package/dist/cjs/shared/validation/options.js +166 -0
- package/dist/cjs/shared/validation/primitives.d.ts +292 -0
- package/dist/cjs/shared/validation/primitives.js +114 -0
- package/dist/cjs/shared/validation/ttl.d.ts +94 -0
- package/dist/cjs/shared/validation/ttl.js +52 -0
- package/dist/cjs/store/actions/list-namespaces.d.ts +79 -0
- package/dist/cjs/store/actions/list-namespaces.js +92 -0
- package/dist/cjs/store/actions/put.d.ts +43 -0
- package/dist/cjs/store/actions/put.js +49 -0
- package/dist/cjs/store/actions/reconcile-vector-index.d.ts +38 -0
- package/dist/cjs/store/actions/reconcile-vector-index.js +13 -0
- package/dist/cjs/store/actions/search.d.ts +38 -0
- package/dist/cjs/store/actions/search.js +26 -0
- package/dist/cjs/store/internal/batch-plan.d.ts +56 -0
- package/dist/cjs/store/internal/batch-plan.js +32 -0
- package/dist/cjs/store/internal/filter.d.ts +43 -0
- package/dist/cjs/store/internal/filter.js +64 -0
- package/dist/cjs/store/internal/get-item.d.ts +77 -0
- package/dist/cjs/store/internal/get-item.js +58 -0
- package/dist/cjs/store/internal/item-write.d.ts +270 -0
- package/dist/cjs/store/internal/item-write.js +181 -0
- package/dist/cjs/store/internal/parse.d.ts +230 -0
- package/dist/cjs/store/internal/parse.js +180 -0
- package/dist/cjs/store/internal/rows.d.ts +359 -0
- package/dist/cjs/store/internal/rows.js +166 -0
- package/dist/cjs/store/internal/semantic-search.d.ts +168 -0
- package/dist/{store/internal/text-path.js → cjs/store/internal/semantic-search.js} +92 -28
- package/dist/cjs/store/internal/setup.d.ts +96 -0
- package/dist/cjs/store/internal/setup.js +103 -0
- package/dist/cjs/store/internal/table-search.d.ts +100 -0
- package/dist/cjs/store/internal/table-search.js +123 -0
- package/dist/cjs/store/internal/vector-index.d.ts +258 -0
- package/dist/cjs/store/internal/vector-index.js +269 -0
- package/dist/cjs/store/store.d.ts +329 -0
- package/dist/cjs/store/store.js +97 -0
- package/dist/cjs/store/types.d.ts +111 -0
- package/dist/cjs/store/vector-backend.d.ts +104 -0
- package/dist/cjs/store/vector-backend.js +4 -0
- package/dist/esm/backfill/backfill.d.ts +171 -0
- package/dist/esm/backfill/backfill.js +170 -0
- package/dist/esm/checkpointer/actions/delete-thread.d.ts +50 -0
- package/dist/esm/checkpointer/actions/delete-thread.js +23 -0
- package/dist/esm/checkpointer/actions/get-tuple.d.ts +36 -0
- package/dist/esm/checkpointer/actions/get-tuple.js +19 -0
- package/dist/esm/checkpointer/actions/list.d.ts +55 -0
- package/dist/esm/checkpointer/actions/list.js +67 -0
- package/dist/esm/checkpointer/actions/put-writes.d.ts +49 -0
- package/dist/esm/checkpointer/actions/put-writes.js +18 -0
- package/dist/esm/checkpointer/actions/put.d.ts +95 -0
- package/dist/esm/checkpointer/actions/put.js +75 -0
- package/dist/esm/checkpointer/internal/delta-history.d.ts +124 -0
- package/dist/esm/checkpointer/internal/delta-history.js +126 -0
- package/dist/esm/checkpointer/internal/listing.d.ts +149 -0
- package/dist/esm/checkpointer/internal/listing.js +95 -0
- package/dist/esm/checkpointer/internal/parse.d.ts +298 -0
- package/dist/esm/checkpointer/internal/parse.js +169 -0
- package/dist/esm/checkpointer/internal/pending-writes.d.ts +314 -0
- package/dist/esm/checkpointer/internal/pending-writes.js +229 -0
- package/dist/esm/checkpointer/internal/read.d.ts +135 -0
- package/dist/esm/checkpointer/internal/read.js +125 -0
- package/dist/esm/checkpointer/internal/rows.d.ts +644 -0
- package/dist/esm/checkpointer/internal/rows.js +323 -0
- package/dist/esm/checkpointer/internal/setup.d.ts +47 -0
- package/dist/esm/checkpointer/internal/setup.js +21 -0
- package/dist/esm/checkpointer/saver.d.ts +306 -0
- package/dist/esm/checkpointer/saver.js +52 -0
- package/dist/esm/checkpointer/types.d.ts +51 -0
- package/dist/esm/checkpointer/types.js +1 -0
- package/dist/esm/factory/factory.d.ts +154 -0
- package/dist/esm/factory/factory.js +133 -0
- package/dist/esm/factory/types.d.ts +76 -0
- package/dist/esm/factory/types.js +1 -0
- package/dist/esm/history/actions/add-messages.d.ts +51 -0
- package/dist/esm/history/actions/add-messages.js +14 -0
- package/dist/esm/history/actions/clear.d.ts +52 -0
- package/dist/esm/history/actions/clear.js +26 -0
- package/dist/esm/history/actions/get-messages.d.ts +60 -0
- package/dist/esm/history/actions/get-messages.js +55 -0
- package/dist/esm/history/actions/list-sessions.d.ts +55 -0
- package/dist/esm/history/actions/list-sessions.js +64 -0
- package/dist/esm/history/actions/reconcile-count.d.ts +49 -0
- package/dist/esm/history/actions/reconcile-count.js +5 -0
- package/dist/esm/history/chat-message-history.d.ts +267 -0
- package/dist/esm/history/chat-message-history.js +57 -0
- package/dist/esm/history/internal/append.d.ts +244 -0
- package/dist/esm/history/internal/append.js +259 -0
- package/dist/esm/history/internal/message-read.d.ts +84 -0
- package/dist/esm/history/internal/message-read.js +89 -0
- package/dist/esm/history/internal/parse.d.ts +153 -0
- package/dist/esm/history/internal/parse.js +105 -0
- package/dist/esm/history/internal/rows.d.ts +196 -0
- package/dist/esm/history/internal/rows.js +83 -0
- package/dist/esm/history/internal/session.d.ts +350 -0
- package/dist/esm/history/internal/session.js +285 -0
- package/dist/esm/history/internal/setup.d.ts +64 -0
- package/dist/esm/history/internal/setup.js +56 -0
- package/dist/esm/history/session-adapter.d.ts +112 -0
- package/dist/esm/history/session-adapter.js +34 -0
- package/dist/esm/history/types.d.ts +102 -0
- package/dist/esm/history/types.js +1 -0
- package/dist/esm/index.d.ts +53 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/shared/adapter.d.ts +146 -0
- package/dist/esm/shared/adapter.js +65 -0
- package/dist/esm/shared/clock.d.ts +52 -0
- package/dist/esm/shared/clock.js +9 -0
- package/dist/esm/shared/codec/codec.d.ts +336 -0
- package/dist/esm/shared/codec/codec.js +150 -0
- package/dist/esm/shared/codec/compression.d.ts +66 -0
- package/dist/esm/shared/codec/compression.js +40 -0
- package/dist/esm/shared/codec/json-serde.d.ts +80 -0
- package/dist/esm/shared/codec/json-serde.js +54 -0
- package/dist/esm/shared/codec/s3/client-types.d.ts +54 -0
- package/dist/esm/shared/codec/s3/client-types.js +3 -0
- package/dist/esm/shared/codec/s3/client.d.ts +63 -0
- package/dist/esm/shared/codec/s3/client.js +40 -0
- package/dist/esm/shared/codec/s3/config.d.ts +260 -0
- package/dist/esm/shared/codec/s3/config.js +79 -0
- package/dist/esm/shared/codec/s3/lifecycle.d.ts +220 -0
- package/dist/esm/shared/codec/s3/lifecycle.js +214 -0
- package/dist/esm/shared/codec/s3/offloader.d.ts +428 -0
- package/dist/esm/shared/codec/s3/offloader.js +278 -0
- package/dist/esm/shared/concurrency.d.ts +43 -0
- package/dist/esm/shared/concurrency.js +27 -0
- package/dist/esm/shared/dynamodb/abort.d.ts +47 -0
- package/dist/esm/shared/dynamodb/abort.js +12 -0
- package/dist/esm/shared/dynamodb/batch-write.d.ts +86 -0
- package/dist/esm/shared/dynamodb/batch-write.js +74 -0
- package/dist/esm/shared/dynamodb/cancellation.d.ts +124 -0
- package/dist/esm/shared/dynamodb/cancellation.js +30 -0
- package/dist/esm/shared/dynamodb/client.d.ts +177 -0
- package/dist/esm/shared/dynamodb/client.js +35 -0
- package/dist/esm/shared/dynamodb/idempotent-write.d.ts +596 -0
- package/dist/esm/shared/dynamodb/idempotent-write.js +153 -0
- package/dist/esm/shared/dynamodb/paginate.d.ts +111 -0
- package/dist/esm/shared/dynamodb/paginate.js +84 -0
- package/dist/esm/shared/dynamodb/partition-delete.d.ts +204 -0
- package/dist/esm/shared/dynamodb/partition-delete.js +171 -0
- package/dist/esm/shared/dynamodb/recency-index.d.ts +243 -0
- package/dist/esm/shared/dynamodb/recency-index.js +136 -0
- package/dist/esm/shared/dynamodb/retry.d.ts +317 -0
- package/dist/esm/shared/dynamodb/retry.js +180 -0
- package/dist/esm/shared/dynamodb/row-size.d.ts +33 -0
- package/dist/esm/shared/dynamodb/row-size.js +26 -0
- package/dist/esm/shared/dynamodb/table-schema.d.ts +199 -0
- package/dist/esm/shared/dynamodb/table-schema.js +43 -0
- package/dist/esm/shared/errors/base-error.d.ts +231 -0
- package/dist/esm/shared/errors/base-error.js +64 -0
- package/dist/esm/shared/errors/boundary.d.ts +86 -0
- package/dist/esm/shared/errors/boundary.js +54 -0
- package/dist/esm/shared/errors/classify.d.ts +206 -0
- package/dist/esm/shared/errors/classify.js +220 -0
- package/dist/esm/shared/errors/error-code.d.ts +95 -0
- package/dist/esm/shared/errors/error-code.js +24 -0
- package/dist/esm/shared/errors/errors.d.ts +233 -0
- package/dist/esm/shared/errors/errors.js +110 -0
- package/dist/esm/shared/logging/logger.d.ts +80 -0
- package/dist/esm/shared/logging/logger.js +25 -0
- package/dist/esm/shared/logging/redaction.d.ts +123 -0
- package/dist/esm/shared/logging/redaction.js +140 -0
- package/dist/esm/shared/logging/secret-patterns.d.ts +227 -0
- package/dist/esm/shared/logging/secret-patterns.js +83 -0
- package/dist/esm/shared/logging/truncate.d.ts +197 -0
- package/dist/esm/shared/logging/truncate.js +25 -0
- package/dist/esm/shared/options.d.ts +100 -0
- package/dist/esm/shared/options.js +1 -0
- package/dist/esm/shared/ulid.d.ts +80 -0
- package/dist/esm/shared/ulid.js +77 -0
- package/dist/esm/shared/validation/collaborators.d.ts +160 -0
- package/dist/esm/shared/validation/collaborators.js +70 -0
- package/dist/esm/shared/validation/option-shape.d.ts +91 -0
- package/dist/esm/shared/validation/option-shape.js +24 -0
- package/dist/esm/shared/validation/options.d.ts +145 -0
- package/dist/esm/shared/validation/options.js +156 -0
- package/dist/esm/shared/validation/primitives.d.ts +292 -0
- package/dist/esm/shared/validation/primitives.js +100 -0
- package/dist/esm/shared/validation/ttl.d.ts +94 -0
- package/dist/esm/shared/validation/ttl.js +46 -0
- package/dist/esm/store/actions/list-namespaces.d.ts +79 -0
- package/dist/esm/store/actions/list-namespaces.js +86 -0
- package/dist/esm/store/actions/put.d.ts +43 -0
- package/dist/esm/store/actions/put.js +46 -0
- package/dist/esm/store/actions/reconcile-vector-index.d.ts +38 -0
- package/dist/esm/store/actions/reconcile-vector-index.js +10 -0
- package/dist/esm/store/actions/search.d.ts +38 -0
- package/dist/esm/store/actions/search.js +23 -0
- package/dist/esm/store/internal/batch-plan.d.ts +56 -0
- package/dist/esm/store/internal/batch-plan.js +28 -0
- package/dist/esm/store/internal/filter.d.ts +43 -0
- package/dist/esm/store/internal/filter.js +60 -0
- package/dist/esm/store/internal/get-item.d.ts +77 -0
- package/dist/esm/store/internal/get-item.js +54 -0
- package/dist/esm/store/internal/item-write.d.ts +270 -0
- package/dist/esm/store/internal/item-write.js +173 -0
- package/dist/esm/store/internal/parse.d.ts +230 -0
- package/dist/esm/store/internal/parse.js +169 -0
- package/dist/esm/store/internal/rows.d.ts +359 -0
- package/dist/esm/store/internal/rows.js +147 -0
- package/dist/esm/store/internal/semantic-search.d.ts +168 -0
- package/dist/esm/store/internal/semantic-search.js +200 -0
- package/dist/esm/store/internal/setup.d.ts +96 -0
- package/dist/esm/store/internal/setup.js +98 -0
- package/dist/esm/store/internal/table-search.d.ts +100 -0
- package/dist/esm/store/internal/table-search.js +119 -0
- package/dist/esm/store/internal/vector-index.d.ts +258 -0
- package/dist/esm/store/internal/vector-index.js +256 -0
- package/dist/esm/store/store.d.ts +329 -0
- package/dist/esm/store/store.js +93 -0
- package/dist/esm/store/types.d.ts +111 -0
- package/dist/esm/store/types.js +1 -0
- package/dist/esm/store/vector-backend.d.ts +104 -0
- package/dist/esm/store/vector-backend.js +1 -0
- package/package.json +68 -46
- package/dist/checkpointer/actions/delete-thread.d.ts +0 -10
- package/dist/checkpointer/actions/delete-thread.js +0 -38
- package/dist/checkpointer/actions/get-tuple.d.ts +0 -11
- package/dist/checkpointer/actions/get-tuple.js +0 -25
- package/dist/checkpointer/actions/list.d.ts +0 -20
- package/dist/checkpointer/actions/list.js +0 -113
- package/dist/checkpointer/actions/put-writes.d.ts +0 -15
- package/dist/checkpointer/actions/put-writes.js +0 -62
- package/dist/checkpointer/actions/put.d.ts +0 -17
- package/dist/checkpointer/actions/put.js +0 -73
- package/dist/checkpointer/internal/assemble.d.ts +0 -17
- package/dist/checkpointer/internal/assemble.js +0 -38
- package/dist/checkpointer/internal/checkpoint-write-verify.d.ts +0 -24
- package/dist/checkpointer/internal/checkpoint-write-verify.js +0 -67
- package/dist/checkpointer/internal/configurable.d.ts +0 -12
- package/dist/checkpointer/internal/configurable.js +0 -24
- package/dist/checkpointer/internal/fetch.d.ts +0 -19
- package/dist/checkpointer/internal/fetch.js +0 -88
- package/dist/checkpointer/internal/filter-match.d.ts +0 -13
- package/dist/checkpointer/internal/filter-match.js +0 -15
- package/dist/checkpointer/internal/item-reader.d.ts +0 -66
- package/dist/checkpointer/internal/item-reader.js +0 -113
- package/dist/checkpointer/internal/item-writer.d.ts +0 -35
- package/dist/checkpointer/internal/item-writer.js +0 -107
- package/dist/checkpointer/internal/keys.d.ts +0 -41
- package/dist/checkpointer/internal/keys.js +0 -117
- package/dist/checkpointer/internal/list-scope.d.ts +0 -61
- package/dist/checkpointer/internal/list-scope.js +0 -108
- package/dist/checkpointer/internal/pending-sends.d.ts +0 -13
- package/dist/checkpointer/internal/pending-sends.js +0 -29
- package/dist/checkpointer/internal/query.d.ts +0 -21
- package/dist/checkpointer/internal/query.js +0 -42
- package/dist/checkpointer/internal/regular-write.d.ts +0 -28
- package/dist/checkpointer/internal/regular-write.js +0 -66
- package/dist/checkpointer/internal/setup.d.ts +0 -33
- package/dist/checkpointer/internal/setup.js +0 -38
- package/dist/checkpointer/internal/special-write-cas.d.ts +0 -29
- package/dist/checkpointer/internal/special-write-cas.js +0 -104
- package/dist/checkpointer/internal/special-write-cleanup.d.ts +0 -23
- package/dist/checkpointer/internal/special-write-cleanup.js +0 -50
- package/dist/checkpointer/internal/special-write-verify.d.ts +0 -53
- package/dist/checkpointer/internal/special-write-verify.js +0 -80
- package/dist/checkpointer/internal/stored-channels.d.ts +0 -31
- package/dist/checkpointer/internal/stored-channels.js +0 -70
- package/dist/checkpointer/internal/validation.d.ts +0 -18
- package/dist/checkpointer/internal/validation.js +0 -40
- package/dist/checkpointer/internal/write-guard.d.ts +0 -20
- package/dist/checkpointer/internal/write-guard.js +0 -48
- package/dist/checkpointer/internal/write-index.d.ts +0 -36
- package/dist/checkpointer/internal/write-index.js +0 -41
- package/dist/checkpointer/saver.d.ts +0 -70
- package/dist/checkpointer/saver.js +0 -105
- package/dist/checkpointer/types.d.ts +0 -58
- package/dist/factory/factory.d.ts +0 -40
- package/dist/factory/factory.js +0 -87
- package/dist/history/actions/add-messages.d.ts +0 -15
- package/dist/history/actions/add-messages.js +0 -77
- package/dist/history/actions/clear.d.ts +0 -10
- package/dist/history/actions/clear.js +0 -34
- package/dist/history/actions/get-messages.d.ts +0 -17
- package/dist/history/actions/get-messages.js +0 -79
- package/dist/history/actions/list-sessions.d.ts +0 -13
- package/dist/history/actions/list-sessions.js +0 -53
- package/dist/history/actions/reconcile-count.d.ts +0 -12
- package/dist/history/actions/reconcile-count.js +0 -64
- package/dist/history/chat-message-history.d.ts +0 -73
- package/dist/history/chat-message-history.js +0 -111
- package/dist/history/internal/append-saga.d.ts +0 -25
- package/dist/history/internal/append-saga.js +0 -79
- package/dist/history/internal/compensation.d.ts +0 -25
- package/dist/history/internal/compensation.js +0 -92
- package/dist/history/internal/item-mapper.d.ts +0 -9
- package/dist/history/internal/item-mapper.js +0 -27
- package/dist/history/internal/keys.d.ts +0 -16
- package/dist/history/internal/keys.js +0 -48
- package/dist/history/internal/message-chunker.d.ts +0 -13
- package/dist/history/internal/message-chunker.js +0 -67
- package/dist/history/internal/message-transaction.d.ts +0 -25
- package/dist/history/internal/message-transaction.js +0 -61
- package/dist/history/internal/message-window.d.ts +0 -17
- package/dist/history/internal/message-window.js +0 -49
- package/dist/history/internal/query.d.ts +0 -23
- package/dist/history/internal/query.js +0 -39
- package/dist/history/internal/session-count.d.ts +0 -47
- package/dist/history/internal/session-count.js +0 -115
- package/dist/history/internal/session-title.d.ts +0 -19
- package/dist/history/internal/session-title.js +0 -43
- package/dist/history/internal/session-update.d.ts +0 -27
- package/dist/history/internal/session-update.js +0 -69
- package/dist/history/internal/setup.d.ts +0 -31
- package/dist/history/internal/setup.js +0 -43
- package/dist/history/internal/title-generator.d.ts +0 -12
- package/dist/history/internal/title-generator.js +0 -41
- package/dist/history/internal/ttl-anchor.d.ts +0 -24
- package/dist/history/internal/ttl-anchor.js +0 -38
- package/dist/history/internal/validation.d.ts +0 -25
- package/dist/history/internal/validation.js +0 -53
- package/dist/history/session-adapter.d.ts +0 -29
- package/dist/history/session-adapter.js +0 -35
- package/dist/history/types.d.ts +0 -69
- package/dist/index.d.ts +0 -29
- package/dist/index.js +0 -32
- package/dist/shared/clock.d.ts +0 -8
- package/dist/shared/clock.js +0 -16
- package/dist/shared/codec/codec.d.ts +0 -53
- package/dist/shared/codec/codec.js +0 -66
- package/dist/shared/codec/compression.d.ts +0 -24
- package/dist/shared/codec/compression.js +0 -48
- package/dist/shared/codec/descriptor-keys.d.ts +0 -12
- package/dist/shared/codec/descriptor-keys.js +0 -14
- package/dist/shared/codec/encode.d.ts +0 -13
- package/dist/shared/codec/encode.js +0 -43
- package/dist/shared/codec/json-serde.d.ts +0 -7
- package/dist/shared/codec/json-serde.js +0 -17
- package/dist/shared/codec/payload-loss.d.ts +0 -12
- package/dist/shared/codec/payload-loss.js +0 -38
- package/dist/shared/codec/s3/adapter-config.d.ts +0 -13
- package/dist/shared/codec/s3/adapter-config.js +0 -22
- package/dist/shared/codec/s3/bounded-body.d.ts +0 -14
- package/dist/shared/codec/s3/bounded-body.js +0 -47
- package/dist/shared/codec/s3/client.d.ts +0 -18
- package/dist/shared/codec/s3/client.js +0 -46
- package/dist/shared/codec/s3/config.d.ts +0 -51
- package/dist/shared/codec/s3/config.js +0 -58
- package/dist/shared/codec/s3/delete.d.ts +0 -7
- package/dist/shared/codec/s3/delete.js +0 -28
- package/dist/shared/codec/s3/key-scope.d.ts +0 -23
- package/dist/shared/codec/s3/key-scope.js +0 -44
- package/dist/shared/codec/s3/lifecycle.d.ts +0 -14
- package/dist/shared/codec/s3/lifecycle.js +0 -63
- package/dist/shared/codec/s3/offloader.d.ts +0 -44
- package/dist/shared/codec/s3/offloader.js +0 -118
- package/dist/shared/codec/s3/orphans.d.ts +0 -23
- package/dist/shared/codec/s3/orphans.js +0 -71
- package/dist/shared/codec/s3/read-write.d.ts +0 -18
- package/dist/shared/codec/s3/read-write.js +0 -51
- package/dist/shared/codec/s3/retry.d.ts +0 -5
- package/dist/shared/codec/s3/retry.js +0 -22
- package/dist/shared/concurrency.d.ts +0 -6
- package/dist/shared/constants.d.ts +0 -112
- package/dist/shared/constants.js +0 -115
- package/dist/shared/dynamodb/abort.d.ts +0 -9
- package/dist/shared/dynamodb/abort.js +0 -27
- package/dist/shared/dynamodb/backoff.d.ts +0 -15
- package/dist/shared/dynamodb/backoff.js +0 -48
- package/dist/shared/dynamodb/batch-write.d.ts +0 -22
- package/dist/shared/dynamodb/batch-write.js +0 -53
- package/dist/shared/dynamodb/cancellation.d.ts +0 -6
- package/dist/shared/dynamodb/cancellation.js +0 -7
- package/dist/shared/dynamodb/client.d.ts +0 -28
- package/dist/shared/dynamodb/conditional-put.d.ts +0 -67
- package/dist/shared/dynamodb/conditional-put.js +0 -76
- package/dist/shared/dynamodb/drain-unprocessed.d.ts +0 -21
- package/dist/shared/dynamodb/drain-unprocessed.js +0 -43
- package/dist/shared/dynamodb/expiry.d.ts +0 -16
- package/dist/shared/dynamodb/expiry.js +0 -29
- package/dist/shared/dynamodb/paginate-core.d.ts +0 -24
- package/dist/shared/dynamodb/paginate-core.js +0 -82
- package/dist/shared/dynamodb/paginate.d.ts +0 -14
- package/dist/shared/dynamodb/paginate.js +0 -19
- package/dist/shared/dynamodb/partition-delete.d.ts +0 -39
- package/dist/shared/dynamodb/partition-delete.js +0 -71
- package/dist/shared/dynamodb/retry-classifier.d.ts +0 -17
- package/dist/shared/dynamodb/retry-classifier.js +0 -118
- package/dist/shared/dynamodb/retry-policy.d.ts +0 -26
- package/dist/shared/dynamodb/retry-policy.js +0 -22
- package/dist/shared/dynamodb/retry.d.ts +0 -31
- package/dist/shared/dynamodb/retry.js +0 -57
- package/dist/shared/dynamodb/scan.d.ts +0 -14
- package/dist/shared/dynamodb/scan.js +0 -19
- package/dist/shared/dynamodb/types.d.ts +0 -23
- package/dist/shared/errors/base-error.d.ts +0 -30
- package/dist/shared/errors/base-error.js +0 -27
- package/dist/shared/errors/boundary.d.ts +0 -18
- package/dist/shared/errors/boundary.js +0 -46
- package/dist/shared/errors/error-code.d.ts +0 -13
- package/dist/shared/errors/errors.d.ts +0 -68
- package/dist/shared/errors/errors.js +0 -114
- package/dist/shared/errors/upstream-error.d.ts +0 -16
- package/dist/shared/errors/upstream-error.js +0 -27
- package/dist/shared/errors/wrap-error.d.ts +0 -7
- package/dist/shared/errors/wrap-error.js +0 -15
- package/dist/shared/logging/logger.d.ts +0 -18
- package/dist/shared/logging/logger.js +0 -15
- package/dist/shared/logging/redaction-walk.d.ts +0 -23
- package/dist/shared/logging/redaction-walk.js +0 -112
- package/dist/shared/logging/redaction.d.ts +0 -39
- package/dist/shared/logging/redaction.js +0 -75
- package/dist/shared/logging/secret-patterns.d.ts +0 -92
- package/dist/shared/logging/secret-patterns.js +0 -133
- package/dist/shared/options.d.ts +0 -37
- package/dist/shared/ulid.d.ts +0 -23
- package/dist/shared/validation/options.d.ts +0 -8
- package/dist/shared/validation/options.js +0 -90
- package/dist/shared/validation/primitives.d.ts +0 -29
- package/dist/shared/validation/primitives.js +0 -82
- package/dist/shared/validation/ttl.d.ts +0 -28
- package/dist/shared/validation/ttl.js +0 -52
- package/dist/store/actions/get.d.ts +0 -13
- package/dist/store/actions/get.js +0 -73
- package/dist/store/actions/list-namespaces.d.ts +0 -8
- package/dist/store/actions/list-namespaces.js +0 -59
- package/dist/store/actions/put.d.ts +0 -10
- package/dist/store/actions/put.js +0 -96
- package/dist/store/actions/reconcile-vector-index.d.ts +0 -18
- package/dist/store/actions/reconcile-vector-index.js +0 -26
- package/dist/store/actions/search.d.ts +0 -9
- package/dist/store/actions/search.js +0 -34
- package/dist/store/internal/backend-search.d.ts +0 -4
- package/dist/store/internal/backend-search.js +0 -74
- package/dist/store/internal/batch-plan.d.ts +0 -11
- package/dist/store/internal/batch-plan.js +0 -52
- package/dist/store/internal/candidates.d.ts +0 -23
- package/dist/store/internal/candidates.js +0 -94
- package/dist/store/internal/filter.d.ts +0 -9
- package/dist/store/internal/filter.js +0 -85
- package/dist/store/internal/index-reconcile.d.ts +0 -21
- package/dist/store/internal/index-reconcile.js +0 -118
- package/dist/store/internal/index-sync.d.ts +0 -10
- package/dist/store/internal/index-sync.js +0 -25
- package/dist/store/internal/item-mapper.d.ts +0 -27
- package/dist/store/internal/item-mapper.js +0 -61
- package/dist/store/internal/keys.d.ts +0 -17
- package/dist/store/internal/keys.js +0 -41
- package/dist/store/internal/namespace-match.d.ts +0 -11
- package/dist/store/internal/namespace-match.js +0 -40
- package/dist/store/internal/option-validation.d.ts +0 -13
- package/dist/store/internal/option-validation.js +0 -77
- package/dist/store/internal/overwrite-swap.d.ts +0 -32
- package/dist/store/internal/overwrite-swap.js +0 -68
- package/dist/store/internal/persist.d.ts +0 -28
- package/dist/store/internal/persist.js +0 -64
- package/dist/store/internal/query.d.ts +0 -11
- package/dist/store/internal/query.js +0 -48
- package/dist/store/internal/ranker.d.ts +0 -18
- package/dist/store/internal/ranker.js +0 -39
- package/dist/store/internal/read-existing.d.ts +0 -23
- package/dist/store/internal/read-existing.js +0 -41
- package/dist/store/internal/score-direction.d.ts +0 -31
- package/dist/store/internal/score-direction.js +0 -38
- package/dist/store/internal/search-filter.d.ts +0 -3
- package/dist/store/internal/search-filter.js +0 -10
- package/dist/store/internal/semantic-search.d.ts +0 -34
- package/dist/store/internal/semantic-search.js +0 -87
- package/dist/store/internal/setup.d.ts +0 -36
- package/dist/store/internal/setup.js +0 -40
- package/dist/store/internal/text-path.d.ts +0 -17
- package/dist/store/internal/validation.d.ts +0 -18
- package/dist/store/internal/validation.js +0 -51
- package/dist/store/internal/write-verify.d.ts +0 -42
- package/dist/store/internal/write-verify.js +0 -71
- package/dist/store/store.d.ts +0 -61
- package/dist/store/store.js +0 -107
- package/dist/store/types.d.ts +0 -50
- package/dist/store/types.js +0 -2
- package/dist/store/vector-backend.d.ts +0 -43
- package/dist/store/vector-backend.js +0 -2
- /package/dist/{checkpointer → cjs/checkpointer}/types.js +0 -0
- /package/dist/{factory → cjs/factory}/types.js +0 -0
- /package/dist/{history → cjs/history}/types.js +0 -0
- /package/dist/{shared → cjs/shared}/options.js +0 -0
- /package/dist/{shared/dynamodb → cjs/store}/types.js +0 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides how one `putWrites` call's rows commit, and which uploads each outcome
|
|
3
|
+
* releases.
|
|
4
|
+
*
|
|
5
|
+
* A positional write is first-write-wins: a retried task must not overwrite
|
|
6
|
+
* what its first run committed, and a rejection is the expected outcome of a
|
|
7
|
+
* retry, not a failure. A special channel's write overwrites, as every reference
|
|
8
|
+
* checkpointer does, under a compare-and-swap on the row's `writeGroup` so two
|
|
9
|
+
* concurrent calls cannot both release the same superseded payload. Around both,
|
|
10
|
+
* an upload is released only when a read, or the row a rejection returned,
|
|
11
|
+
* proves no live row names it — never on an outcome nothing confirmed.
|
|
12
|
+
*/
|
|
13
|
+
import { type PayloadDescriptor } from '../../shared/codec/codec.js';
|
|
14
|
+
import { type RowProbe } from '../../shared/dynamodb/idempotent-write.js';
|
|
15
|
+
import type { ThreadId } from './parse.js';
|
|
16
|
+
import { type CheckpointWriteRow } from './rows.js';
|
|
17
|
+
import type { CheckpointerContext } from './setup.js';
|
|
18
|
+
/** One call's rows, ready to commit. */
|
|
19
|
+
export interface PendingWriteBatch {
|
|
20
|
+
/** The caller's thread, which scopes every superseded object this commit may release. */
|
|
21
|
+
readonly threadId: ThreadId;
|
|
22
|
+
readonly items: CheckpointWriteRow[];
|
|
23
|
+
readonly signal: AbortSignal | undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Commit one call's pending-write rows, then release the uploads the outcome
|
|
27
|
+
* proves dead.
|
|
28
|
+
*
|
|
29
|
+
* Accepts: `batch` — the call's thread, its encoded rows (positional and
|
|
30
|
+
* special together, in any order), and its signal.
|
|
31
|
+
*
|
|
32
|
+
* Returns: nothing, once every write has settled and the cleanup has run.
|
|
33
|
+
*
|
|
34
|
+
* Throws: the first genuine write failure, after every write has settled and
|
|
35
|
+
* the cleanup has run. A first-write-wins rejection is not a failure.
|
|
36
|
+
*/
|
|
37
|
+
export declare function commitPendingWrites(context: CheckpointerContext, batch: PendingWriteBatch): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Overwrite one special row, pinned to the `writeGroup` this call observed, and
|
|
40
|
+
* report the descriptor it superseded.
|
|
41
|
+
*
|
|
42
|
+
* Overwriting is correct for special channels — every reference implementation
|
|
43
|
+
* does it — but two concurrent calls to the same channel both read the same
|
|
44
|
+
* previous descriptor and both delete it, orphaning the loser's upload. Pinning
|
|
45
|
+
* the observed `writeGroup` and re-reading on rejection makes each call
|
|
46
|
+
* supersede exactly one payload.
|
|
47
|
+
*
|
|
48
|
+
* `BatchWriteItem` cannot carry conditions, which is why this path issues
|
|
49
|
+
* individual puts; a call holds at most one row per special channel, so that is
|
|
50
|
+
* four writes at worst.
|
|
51
|
+
*
|
|
52
|
+
* The compare-and-swap runs only when an offloader is configured — matching
|
|
53
|
+
* `store/internal/item-write.ts` — because without one there is no S3 object to
|
|
54
|
+
* orphan, so a plain unconditional put stays correct and costs no extra
|
|
55
|
+
* ConsistentRead or write capacity (see {@link writeWithoutOffloader}).
|
|
56
|
+
*
|
|
57
|
+
* A failure of the first read, before any put, is no verdict read from the row,
|
|
58
|
+
* and this call releases its own upload only on one. It is therefore reported
|
|
59
|
+
* the way every unverified outcome is: `committed: true` with the error, so the
|
|
60
|
+
* caller keeps the upload and leaves it to the lifecycle rule.
|
|
61
|
+
*
|
|
62
|
+
* Accepts: `item` — one special-channel row, carrying this call's `writeGroup`.
|
|
63
|
+
* `signal` — aborts the attempts.
|
|
64
|
+
*
|
|
65
|
+
* Returns: whether this item's upload must be kept (see
|
|
66
|
+
* {@link SpecialWriteOutcome}), the descriptor it superseded when the write
|
|
67
|
+
* committed, and the failure when there was one.
|
|
68
|
+
*
|
|
69
|
+
* Throws: nothing. The caller runs this concurrently with the regular writes
|
|
70
|
+
* under `Promise.all`, whose own cleanup depends on every branch resolving
|
|
71
|
+
* rather than short-circuiting.
|
|
72
|
+
*
|
|
73
|
+
* Guarantees: each call supersedes exactly one payload, so two concurrent calls
|
|
74
|
+
* to the same channel cannot both delete the same object and orphan the loser's
|
|
75
|
+
* upload.
|
|
76
|
+
*/
|
|
77
|
+
export declare function writeSpecialRow(context: CheckpointerContext, item: CheckpointWriteRow, signal?: AbortSignal): Promise<SpecialWriteOutcome>;
|
|
78
|
+
/** What a special item's row held before this call tried to overwrite it. */
|
|
79
|
+
export interface SpecialRowState {
|
|
80
|
+
exists: boolean;
|
|
81
|
+
value?: PayloadDescriptor;
|
|
82
|
+
revision?: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Outcome of one special item's conditional write. Never thrown, always returned.
|
|
86
|
+
*
|
|
87
|
+
* `committed` is true whenever this call's own upload must be kept: a confirmed
|
|
88
|
+
* commit, or an outcome nothing confirmed, which then also carries `error`. It
|
|
89
|
+
* is false only when the write is confirmed not to have committed, or when no
|
|
90
|
+
* offloader is configured and there is no upload to keep.
|
|
91
|
+
*/
|
|
92
|
+
export interface SpecialWriteOutcome {
|
|
93
|
+
committed: boolean;
|
|
94
|
+
superseded?: PayloadDescriptor;
|
|
95
|
+
error?: Error;
|
|
96
|
+
}
|
|
97
|
+
/** What a post-failure verification read established about the attempt. */
|
|
98
|
+
export interface VerifiedFailure {
|
|
99
|
+
outcome: SpecialWriteOutcome;
|
|
100
|
+
/**
|
|
101
|
+
* Present only when the attempt is confirmed not to have landed: the row's
|
|
102
|
+
* state, for a compare-and-swap to re-pin to.
|
|
103
|
+
*/
|
|
104
|
+
observed?: SpecialRowState;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The probe that recognises a write row's own write on its row — a special
|
|
108
|
+
* channel's row or a regular one, both of which carry a `writeGroup`.
|
|
109
|
+
*
|
|
110
|
+
* Accepts: `item` — the row this call tried to write, carrying its own
|
|
111
|
+
* `writeGroup`.
|
|
112
|
+
*
|
|
113
|
+
* Returns: the probe, which projects the guard attribute and the descriptor —
|
|
114
|
+
* the descriptor because a caller that has to re-pin a compare-and-swap needs
|
|
115
|
+
* the value it lost to, not just the fact that it lost.
|
|
116
|
+
*
|
|
117
|
+
* Throws: nothing.
|
|
118
|
+
*/
|
|
119
|
+
export declare function writeRowProbe(item: CheckpointWriteRow): RowProbe;
|
|
120
|
+
/**
|
|
121
|
+
* Read a special row's current descriptor and the writeGroup guarding it.
|
|
122
|
+
*
|
|
123
|
+
* Accepts: `item` — the row to read, by its key.
|
|
124
|
+
*
|
|
125
|
+
* Returns: the row's state, with `exists: false` when there is none — which is
|
|
126
|
+
* what a first writer pins its compare-and-swap to.
|
|
127
|
+
*
|
|
128
|
+
* Throws: whatever the read throws. Deliberately not swallowed: the caller
|
|
129
|
+
* reports that failure with its own cause rather than guessing at the row's
|
|
130
|
+
* state, which is why this is separate from {@link verifyAfterFailure}.
|
|
131
|
+
*/
|
|
132
|
+
export declare function readSpecialRow(context: CheckpointerContext, item: CheckpointWriteRow): Promise<SpecialRowState>;
|
|
133
|
+
/**
|
|
134
|
+
* Read the row back after a put failed, and report what that failure actually
|
|
135
|
+
* did — never assuming it did nothing.
|
|
136
|
+
*
|
|
137
|
+
* A guard rejection already carries the row that turned it away (see
|
|
138
|
+
* `rejectedRow`), so the strongly-consistent read is spent only for a failure
|
|
139
|
+
* that does not: a lost response, or a rejection whose row vanished since.
|
|
140
|
+
*
|
|
141
|
+
* Five answers are possible:
|
|
142
|
+
* - the row holds this item's own `writeGroup`: the write landed, and the
|
|
143
|
+
* descriptor this attempt pinned is the dead one.
|
|
144
|
+
* - the row no longer satisfies this attempt's condition — it holds some other
|
|
145
|
+
* group than the one the attempt was pinned to, or it is absent while the
|
|
146
|
+
* attempt was pinned to a revision (`#rev = :rev`): the write is confirmed
|
|
147
|
+
* not to be what is live and can no longer apply, so this item's own upload
|
|
148
|
+
* is dead — its key ends in this call's own group, which no row names.
|
|
149
|
+
* `observed` is returned so a rejected compare-and-swap can re-pin and try
|
|
150
|
+
* again.
|
|
151
|
+
* - the row does not hold this item's group but still satisfies this attempt's
|
|
152
|
+
* condition — it holds exactly the state the attempt was pinned to; or the
|
|
153
|
+
* attempt was pinned to "no revision" and the row is absent, which that
|
|
154
|
+
* `attribute_not_exists` guard admits too; or this attempt was never pinned
|
|
155
|
+
* at all (the unconditional overwrite, which fits any row, a third writer's
|
|
156
|
+
* included) — and the failure may
|
|
157
|
+
* still land: any attempt of its budget got no answer (a cancel, a timeout,
|
|
158
|
+
* a dropped connection), or DynamoDB answered that an earlier attempt under
|
|
159
|
+
* this same token is still being processed, or with a server error (5xx).
|
|
160
|
+
* Nothing is confirmed either way, so this is `'unverified'` rather than
|
|
161
|
+
* `'not-landed'`, and the outcome reports a commit and keeps the upload.
|
|
162
|
+
* - the row still fits this attempt, but the failure was an answer that leaves
|
|
163
|
+
* nothing in flight (a refusal, a throttle, a spent budget of such answers):
|
|
164
|
+
* the write did not land, so this is `'not-landed'` and the upload is dead.
|
|
165
|
+
* - the read itself fails: nothing is confirmed, so the outcome still reports a
|
|
166
|
+
* commit and keeps the originating error. That leaks one S3 object at worst
|
|
167
|
+
* (reclaimed by `ensureS3LifecycleRule`) where the alternative strands a live
|
|
168
|
+
* row — the same trade `store/internal/item-write.ts` makes.
|
|
169
|
+
*
|
|
170
|
+
* Accepts: `attempted` — the state this attempt pinned, whose descriptor is the
|
|
171
|
+
* one superseded if the write did land. `error` — the failure being explained.
|
|
172
|
+
* `pinned` — false for the unconditional overwrite, whose attempt can land
|
|
173
|
+
* over any row.
|
|
174
|
+
*
|
|
175
|
+
* Returns: the outcome, and the row's observed state whenever the attempt is
|
|
176
|
+
* confirmed not to have landed, so a rejected compare-and-swap can re-pin and
|
|
177
|
+
* try again.
|
|
178
|
+
*
|
|
179
|
+
* Throws: nothing. It exists to turn a failure into a decision.
|
|
180
|
+
*
|
|
181
|
+
* Guarantees: a guard rejection already carries the row that turned it away, so
|
|
182
|
+
* the strongly-consistent read is spent only for a failure that does not — a
|
|
183
|
+
* lost response, or a rejection whose row vanished since.
|
|
184
|
+
*/
|
|
185
|
+
export declare function verifyAfterFailure(context: CheckpointerContext, item: CheckpointWriteRow, attempted: SpecialRowState, error: Error, pinned?: boolean): Promise<VerifiedFailure>;
|
|
186
|
+
/**
|
|
187
|
+
* Write special (negative-index) rows, then clean up the correct side of each.
|
|
188
|
+
*
|
|
189
|
+
* Overwrite is correct here, matching every reference checkpointer. Each item
|
|
190
|
+
* is written with a compare-and-swap on its row's `writeGroup` (see
|
|
191
|
+
* {@link writeSpecialRow}) so a concurrent call to the same special channel
|
|
192
|
+
* cannot make both callers delete the same superseded object and orphan one
|
|
193
|
+
* upload. A committed item cleans up the payload it actually superseded, and an
|
|
194
|
+
* item confirmed never to have committed cleans up its own new upload. Neither
|
|
195
|
+
* reads the row again first: every call uploads under its own `writeGroup`, so
|
|
196
|
+
* a row another call writes never names this item's upload, and this item's
|
|
197
|
+
* row names only that upload, never the payload it superseded.
|
|
198
|
+
*
|
|
199
|
+
* "Confirmed" is load-bearing, and {@link writeSpecialRow} is what earns it:
|
|
200
|
+
* an ambiguous failure, or a first read of the row that failed, is reported as
|
|
201
|
+
* committed unless a read proves otherwise. Deleting on *unknown* would strand
|
|
202
|
+
* a live row pointing at a deleted object; leaking one object instead is
|
|
203
|
+
* recoverable.
|
|
204
|
+
*
|
|
205
|
+
* Accepts: `items` — this call's special-channel rows; empty writes nothing.
|
|
206
|
+
* `threadId` — the caller's, which scopes every object this cleanup may delete.
|
|
207
|
+
*
|
|
208
|
+
* Returns: the first failure, or undefined when every item committed.
|
|
209
|
+
*
|
|
210
|
+
* Throws: nothing — a failure is reported via the return value, because the
|
|
211
|
+
* caller runs this concurrently with `writeRegularRows` under `Promise.all`,
|
|
212
|
+
* whose own cleanup depends on every branch resolving rather than
|
|
213
|
+
* short-circuiting.
|
|
214
|
+
*
|
|
215
|
+
* Guarantees: a superseded payload is released only once the item that
|
|
216
|
+
* superseded it committed, and an item's own upload only once a read, or the
|
|
217
|
+
* row returned with its rejected write, shows that the item's write is not what
|
|
218
|
+
* the row holds and can no longer land there: the row no longer satisfies the
|
|
219
|
+
* attempt's condition, or the failure left no attempt in flight (see
|
|
220
|
+
* {@link verifyAfterFailure}).
|
|
221
|
+
*/
|
|
222
|
+
export declare function writeSpecialRowsWithCleanup(context: CheckpointerContext, threadId: ThreadId, items: CheckpointWriteRow[], signal?: AbortSignal): Promise<Error | undefined>;
|
|
223
|
+
/**
|
|
224
|
+
* Outcome of {@link writeRegularRows}: never rejects. `deadUploads` holds
|
|
225
|
+
* exactly the items whose own S3 upload is confirmed unreferenced by this
|
|
226
|
+
* call's row — a verified non-commit, a guard rejection whose returned row
|
|
227
|
+
* provably belongs to another call, or a write the caller's signal came
|
|
228
|
+
* before, which was never sent at all. Everything else either committed, was
|
|
229
|
+
* turned away by a row this call may have written itself, or could not be
|
|
230
|
+
* verified; none of those may be cleaned up.
|
|
231
|
+
*
|
|
232
|
+
* No other row is consulted before an upload in `deadUploads` is released: its
|
|
233
|
+
* key ends in this call's own `writeGroup`, which no row of another call names.
|
|
234
|
+
*/
|
|
235
|
+
export interface RegularWriteOutcome {
|
|
236
|
+
deadUploads: CheckpointWriteRow[];
|
|
237
|
+
error?: Error;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Regular pending writes one `putWrites` call keeps in flight. A `Send`
|
|
241
|
+
* fan-out can name a thousand of them, and the SDK's HTTP agent holds 50
|
|
242
|
+
* sockets by default: past that, a request waits for a socket, and the
|
|
243
|
+
* request timeout counts the wait, so a wide enough fan-out, larger values,
|
|
244
|
+
* or an injected client with a shorter request timeout can time out healthy
|
|
245
|
+
* writes that the retry layer then re-sends. Thirty-two in flight stays
|
|
246
|
+
* under the socket pool and still overlaps the round trips.
|
|
247
|
+
*/
|
|
248
|
+
export declare const REGULAR_WRITE_CONCURRENCY = 32;
|
|
249
|
+
/**
|
|
250
|
+
* Write regular rows with a first-write-wins guard. Every write fully settles,
|
|
251
|
+
* at most {@link REGULAR_WRITE_CONCURRENCY} at a time, before this resolves,
|
|
252
|
+
* and it never rejects; a genuine failure is reported via `error`, not thrown.
|
|
253
|
+
* The fan-out is one call per item whichever shape {@link commitWriteRow}
|
|
254
|
+
* gives that item's write.
|
|
255
|
+
*
|
|
256
|
+
* A failure is not proof of a non-commit: `withDynamoDBRetry` re-issues a put
|
|
257
|
+
* whose response was lost, and the re-issues can time out at the transport, so
|
|
258
|
+
* the budget is spent on a `RETRY_EXHAUSTED` error while the row is live.
|
|
259
|
+
* Treating that as "never reached DynamoDB" deleted the object the live row
|
|
260
|
+
* pointed at, making the checkpoint's pending writes unreadable forever. Each
|
|
261
|
+
* such failure is therefore verified against the row before it is classified,
|
|
262
|
+
* and a committed one is not an error at all.
|
|
263
|
+
*
|
|
264
|
+
* Accepts: `items` — this call's regular write rows; empty writes nothing.
|
|
265
|
+
* `signal` — aborts the puts.
|
|
266
|
+
*
|
|
267
|
+
* Returns: which items are known not to have committed — whose own uploads are
|
|
268
|
+
* therefore dead — and the first genuine failure, if any; a write the caller's
|
|
269
|
+
* signal came before is not sent, and its upload is dead.
|
|
270
|
+
*
|
|
271
|
+
* Throws: nothing. Every put settles before this resolves, because the caller
|
|
272
|
+
* runs it beside the special writes under `Promise.all` and its cleanup depends
|
|
273
|
+
* on every branch resolving rather than short-circuiting.
|
|
274
|
+
*
|
|
275
|
+
* Guarantees: first-write-wins. A rejection means the row is already held, which
|
|
276
|
+
* is the expected outcome of a retry, not a failure.
|
|
277
|
+
*/
|
|
278
|
+
export declare function writeRegularRows(context: CheckpointerContext, items: CheckpointWriteRow[], signal?: AbortSignal): Promise<RegularWriteOutcome>;
|
|
279
|
+
/**
|
|
280
|
+
* Report a guard rejection. Sort keys carry their channel, so a rejection
|
|
281
|
+
* normally means this exact (task, channel, occurrence) row is already
|
|
282
|
+
* committed — a genuine duplicate, and the expected outcome of a retry. A row
|
|
283
|
+
* held by a *different* channel is not something this adapter can produce, so
|
|
284
|
+
* it is reported at `warn`: the write was not persisted and something else
|
|
285
|
+
* wrote to this key space.
|
|
286
|
+
*
|
|
287
|
+
* Accepts: `error` — the rejection, which carries the row that caused it when
|
|
288
|
+
* the service returned attributes. No attributes means the two cases cannot be
|
|
289
|
+
* told apart, and the ordinary duplicate is the one assumed: warning on every
|
|
290
|
+
* unattributed rejection would cry wolf on the expected outcome of a retry.
|
|
291
|
+
*
|
|
292
|
+
* Returns: nothing. A rejection is not a failure here — first-write-wins means
|
|
293
|
+
* losing is a normal outcome — so it is reported, not thrown.
|
|
294
|
+
*
|
|
295
|
+
* Throws: nothing.
|
|
296
|
+
*/
|
|
297
|
+
export declare function reportGuardRejection(context: CheckpointerContext, item: CheckpointWriteRow, error: Error): void;
|
|
298
|
+
/**
|
|
299
|
+
* Whether the rejection's returned row provably belongs to another `putWrites`
|
|
300
|
+
* call.
|
|
301
|
+
*
|
|
302
|
+
* Accepts: `error` — the rejection. `item` — the row this call tried to write,
|
|
303
|
+
* carrying its own `writeGroup`.
|
|
304
|
+
*
|
|
305
|
+
* Returns: whether the row that won carries a *different* group, which is the
|
|
306
|
+
* only evidence that this call's own upload is dead and safe to delete. A
|
|
307
|
+
* retried put whose response was lost can be rejected by the row it wrote
|
|
308
|
+
* itself, so an equal group — or no attributes at all — proves nothing and is
|
|
309
|
+
* answered `false`: the object is then left to the lifecycle rule rather than
|
|
310
|
+
* deleted out from under a live row.
|
|
311
|
+
*
|
|
312
|
+
* Throws: nothing.
|
|
313
|
+
*/
|
|
314
|
+
export declare function rejectionProvesForeignRow(item: CheckpointWriteRow, error: Error): boolean;
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { collectS3Keys } from '../../shared/codec/codec.js';
|
|
2
|
+
import { cleanUpS3Orphans } from '../../shared/codec/s3/offloader.js';
|
|
3
|
+
import { mapWithConcurrency } from '../../shared/concurrency.js';
|
|
4
|
+
import { abortErrorFrom } from '../../shared/dynamodb/abort.js';
|
|
5
|
+
import { commitRow, isConditionalCheckFailed, OVERWRITE_CAS_MAX_ATTEMPTS, readRow, rejectedRow, revisionGuard, settledVerdict, verdictFor, verifyRow, } from '../../shared/dynamodb/idempotent-write.js';
|
|
6
|
+
import { withDynamoDBRetry, retryFor } from '../../shared/dynamodb/retry.js';
|
|
7
|
+
import { PARTITION_KEY_ATTRIBUTE, rowKeyOf } from '../../shared/dynamodb/table-schema.js';
|
|
8
|
+
import { truncateForLog } from '../../shared/logging/truncate.js';
|
|
9
|
+
import { WRITE_GROUP_ATTRIBUTE } from './rows.js';
|
|
10
|
+
export async function commitPendingWrites(context, batch) {
|
|
11
|
+
const special = batch.items.filter((item) => item.index < 0);
|
|
12
|
+
const regular = batch.items.filter((item) => item.index >= 0);
|
|
13
|
+
const [specialError, regularOutcome] = await Promise.all([
|
|
14
|
+
writeSpecialRowsWithCleanup(context, batch.threadId, special, batch.signal),
|
|
15
|
+
writeRegularRows(context, regular, batch.signal),
|
|
16
|
+
]);
|
|
17
|
+
await releaseDeadUploads(context, regularOutcome.deadUploads);
|
|
18
|
+
const firstError = specialError ?? regularOutcome.error;
|
|
19
|
+
if (firstError)
|
|
20
|
+
throw firstError;
|
|
21
|
+
}
|
|
22
|
+
async function releaseDeadUploads(context, dead) {
|
|
23
|
+
if (!context.offloader)
|
|
24
|
+
return;
|
|
25
|
+
await cleanUpS3Orphans(context.offloader, {
|
|
26
|
+
keys: collectS3Keys(dead.map((item) => item.value)),
|
|
27
|
+
operation: 'putWrites',
|
|
28
|
+
logger: context.logger,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async function commitSpecialRow(context, item, guard, signal) {
|
|
32
|
+
await commitRow(context, item, item.value, { guard, signal });
|
|
33
|
+
}
|
|
34
|
+
async function attemptCasWrites(context, item, initial, signal) {
|
|
35
|
+
let observed = initial;
|
|
36
|
+
for (let attempt = 1; attempt <= OVERWRITE_CAS_MAX_ATTEMPTS; attempt++) {
|
|
37
|
+
if (signal?.aborted) {
|
|
38
|
+
return { done: true, outcome: { committed: false, error: abortErrorFrom(signal) } };
|
|
39
|
+
}
|
|
40
|
+
const attempted = observed;
|
|
41
|
+
try {
|
|
42
|
+
await commitSpecialRow(context, item, revisionGuard(WRITE_GROUP_ATTRIBUTE, attempted), signal);
|
|
43
|
+
return { done: true, outcome: { committed: true, superseded: attempted.value } };
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const verified = await verifyAfterFailure(context, item, attempted, error);
|
|
47
|
+
if (!verified.observed || !isConditionalCheckFailed(error)) {
|
|
48
|
+
return { done: true, outcome: verified.outcome };
|
|
49
|
+
}
|
|
50
|
+
observed = verified.observed;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { done: false, observed };
|
|
54
|
+
}
|
|
55
|
+
async function overwriteUnconditionally(context, item, observed, signal) {
|
|
56
|
+
if (signal?.aborted)
|
|
57
|
+
return { committed: false, error: abortErrorFrom(signal) };
|
|
58
|
+
try {
|
|
59
|
+
await commitSpecialRow(context, item, undefined, signal);
|
|
60
|
+
return { committed: true, superseded: observed.value };
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
return (await verifyAfterFailure(context, item, observed, error, false)).outcome;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function writeWithoutOffloader(context, item, signal) {
|
|
67
|
+
try {
|
|
68
|
+
await withDynamoDBRetry((request) => context.client.put({ TableName: context.tableName, Item: item }, request), retryFor(context, signal));
|
|
69
|
+
return { committed: true };
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return { committed: false, error: error };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export async function writeSpecialRow(context, item, signal) {
|
|
76
|
+
if (!context.offloader)
|
|
77
|
+
return writeWithoutOffloader(context, item, signal);
|
|
78
|
+
try {
|
|
79
|
+
const initial = await readSpecialRow(context, item);
|
|
80
|
+
const attempt = await attemptCasWrites(context, item, initial, signal);
|
|
81
|
+
if (attempt.done)
|
|
82
|
+
return attempt.outcome;
|
|
83
|
+
context.logger.warn('putWrites: special-write compare-and-swap exhausted; overwriting unconditionally, which ' +
|
|
84
|
+
'can orphan one S3 object under a concurrent call (reclaimed by ensureS3LifecycleRule)', { sortKey: item.SK, channel: item.channel, attempts: OVERWRITE_CAS_MAX_ATTEMPTS });
|
|
85
|
+
return await overwriteUnconditionally(context, item, attempt.observed, signal);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
return { committed: true, error: error };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export function writeRowProbe(item) {
|
|
92
|
+
return {
|
|
93
|
+
key: rowKeyOf(item),
|
|
94
|
+
kind: 'attribute',
|
|
95
|
+
attribute: WRITE_GROUP_ATTRIBUTE,
|
|
96
|
+
expected: item.writeGroup,
|
|
97
|
+
also: ['value'],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function stateOf(row) {
|
|
101
|
+
if (!row)
|
|
102
|
+
return { exists: false };
|
|
103
|
+
return {
|
|
104
|
+
exists: true,
|
|
105
|
+
value: row.value,
|
|
106
|
+
revision: row[WRITE_GROUP_ATTRIBUTE],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export async function readSpecialRow(context, item) {
|
|
110
|
+
return stateOf(await readRow(context, writeRowProbe(item)));
|
|
111
|
+
}
|
|
112
|
+
export async function verifyAfterFailure(context, item, attempted, error, pinned = true) {
|
|
113
|
+
const probe = writeRowProbe(item);
|
|
114
|
+
const rejected = isConditionalCheckFailed(error) ? rejectedRow(error) : undefined;
|
|
115
|
+
const read = rejected
|
|
116
|
+
? { verdict: verdictFor(probe, rejected), row: rejected }
|
|
117
|
+
: await verifyRow(context, probe);
|
|
118
|
+
const verdict = rejected === undefined && (!pinned || stillPinned(attempted, read.row))
|
|
119
|
+
? settledVerdict(read.verdict, error)
|
|
120
|
+
: read.verdict;
|
|
121
|
+
if (verdict === 'landed')
|
|
122
|
+
return { outcome: { committed: true, superseded: attempted.value } };
|
|
123
|
+
if (verdict === 'unverified')
|
|
124
|
+
return { outcome: { committed: true, error } };
|
|
125
|
+
return { outcome: { committed: false, error }, observed: stateOf(read.row) };
|
|
126
|
+
}
|
|
127
|
+
function stillPinned(attempted, row) {
|
|
128
|
+
const current = stateOf(row);
|
|
129
|
+
if (current.revision !== attempted.revision)
|
|
130
|
+
return false;
|
|
131
|
+
if (current.exists === attempted.exists)
|
|
132
|
+
return true;
|
|
133
|
+
return !current.exists && attempted.revision === undefined;
|
|
134
|
+
}
|
|
135
|
+
async function deleteDescriptors(context, descriptors, label, scope) {
|
|
136
|
+
if (!context.offloader)
|
|
137
|
+
return;
|
|
138
|
+
await cleanUpS3Orphans(context.offloader, {
|
|
139
|
+
keys: collectS3Keys(descriptors.filter((ref) => Boolean(ref))),
|
|
140
|
+
operation: label,
|
|
141
|
+
logger: context.logger,
|
|
142
|
+
...(scope === undefined ? {} : { scope }),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
export async function writeSpecialRowsWithCleanup(context, threadId, items, signal) {
|
|
146
|
+
if (items.length === 0)
|
|
147
|
+
return undefined;
|
|
148
|
+
const outcomes = await Promise.all(items.map(async (item) => [
|
|
149
|
+
item,
|
|
150
|
+
await writeSpecialRow(context, item, signal),
|
|
151
|
+
]));
|
|
152
|
+
await deleteDescriptors(context, outcomes.filter(([, o]) => o.committed).map(([, o]) => o.superseded), 'putWrites.special.previous', [threadId]);
|
|
153
|
+
await deleteDescriptors(context, outcomes.filter(([, o]) => !o.committed).map(([item]) => item.value), 'putWrites.special.newUpload');
|
|
154
|
+
return outcomes.find(([, o]) => o.error)?.[1].error;
|
|
155
|
+
}
|
|
156
|
+
const FIRST_WRITE_WINS = {
|
|
157
|
+
ConditionExpression: `attribute_not_exists(${PARTITION_KEY_ATTRIBUTE})`,
|
|
158
|
+
ReturnValuesOnConditionCheckFailure: 'ALL_OLD',
|
|
159
|
+
};
|
|
160
|
+
async function commitWriteRow(context, item, signal) {
|
|
161
|
+
await commitRow(context, item, item.value, { guard: FIRST_WRITE_WINS, signal });
|
|
162
|
+
}
|
|
163
|
+
async function verifyFailure(context, item) {
|
|
164
|
+
if (!context.offloader)
|
|
165
|
+
return { verdict: 'not-landed' };
|
|
166
|
+
return verifyRow(context, writeRowProbe(item));
|
|
167
|
+
}
|
|
168
|
+
export const REGULAR_WRITE_CONCURRENCY = 32;
|
|
169
|
+
export async function writeRegularRows(context, items, signal) {
|
|
170
|
+
const settled = await mapWithConcurrency(items, REGULAR_WRITE_CONCURRENCY, async (item) => {
|
|
171
|
+
if (signal?.aborted)
|
|
172
|
+
return { ok: false, reason: abortErrorFrom(signal), sent: false };
|
|
173
|
+
try {
|
|
174
|
+
await commitWriteRow(context, item, signal);
|
|
175
|
+
return { ok: true };
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
return { ok: false, reason: error, sent: true };
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
const outcome = { deadUploads: [] };
|
|
182
|
+
for (const [index, result] of settled.entries()) {
|
|
183
|
+
if (result.ok)
|
|
184
|
+
continue;
|
|
185
|
+
const item = items[index];
|
|
186
|
+
const { reason } = result;
|
|
187
|
+
if (!result.sent) {
|
|
188
|
+
outcome.deadUploads.push(item);
|
|
189
|
+
outcome.error = outcome.error ?? reason;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (isConditionalCheckFailed(reason)) {
|
|
193
|
+
reportGuardRejection(context, item, reason);
|
|
194
|
+
if (rejectionProvesForeignRow(item, reason))
|
|
195
|
+
outcome.deadUploads.push(item);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const { verdict, row } = await verifyFailure(context, item);
|
|
199
|
+
const settledNow = row === undefined ? settledVerdict(verdict, reason) : verdict;
|
|
200
|
+
if (settledNow === 'landed')
|
|
201
|
+
continue;
|
|
202
|
+
if (settledNow === 'not-landed')
|
|
203
|
+
outcome.deadUploads.push(item);
|
|
204
|
+
outcome.error = outcome.error ?? reason;
|
|
205
|
+
}
|
|
206
|
+
return outcome;
|
|
207
|
+
}
|
|
208
|
+
function rejectedChannel(error) {
|
|
209
|
+
return rejectedRow(error)?.channel;
|
|
210
|
+
}
|
|
211
|
+
export function reportGuardRejection(context, item, error) {
|
|
212
|
+
const found = rejectedChannel(error);
|
|
213
|
+
if (found !== undefined && found !== item.channel) {
|
|
214
|
+
context.logger.warn('putWrites: write row held by an unexpected channel; write not persisted', {
|
|
215
|
+
sortKey: item.SK,
|
|
216
|
+
expected: item.channel,
|
|
217
|
+
found: truncateForLog(found),
|
|
218
|
+
});
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
context.logger.debug('putWrites: skipped a write already committed for this task and channel', {
|
|
222
|
+
sortKey: item.SK,
|
|
223
|
+
channel: item.channel,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
export function rejectionProvesForeignRow(item, error) {
|
|
227
|
+
const group = rejectedRow(error)?.writeGroup;
|
|
228
|
+
return group !== undefined && group !== item.writeGroup;
|
|
229
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides which rows a checkpoint read issues, with what consistency, and how a
|
|
3
|
+
* checkpoint an older release wrote is read back.
|
|
4
|
+
*
|
|
5
|
+
* A tuple is a META row, a PAYLOAD row and a checkpoint's WRITE rows, read
|
|
6
|
+
* strongly for `getTuple` and eventually for `list`, with expired rows absent
|
|
7
|
+
* however long DynamoDB's sweep lags, and with a pre-v4 checkpoint's `Send`s
|
|
8
|
+
* migrated from its parent's pending writes. The caller asks for a tuple; which
|
|
9
|
+
* reads that takes, and in what order, is decided here.
|
|
10
|
+
*/
|
|
11
|
+
import { type Checkpoint, type CheckpointMetadata, type CheckpointPendingWrite, type CheckpointTuple } from '@langchain/langgraph-checkpoint';
|
|
12
|
+
import type { ThreadAddress } from './parse.js';
|
|
13
|
+
import { type CheckpointLocation, type CheckpointMetaRow, type CheckpointPayloadRow, type MetaReader } from './rows.js';
|
|
14
|
+
import type { CheckpointerContext } from './setup.js';
|
|
15
|
+
/** The thread and namespace a read was asked for. */
|
|
16
|
+
export interface ThreadLocation {
|
|
17
|
+
readonly threadId: string;
|
|
18
|
+
readonly checkpointNs: string;
|
|
19
|
+
}
|
|
20
|
+
/** A checkpoint's parent, whose pending writes a pre-v4 checkpoint's migration reads. */
|
|
21
|
+
export interface PendingSendsSource extends ThreadLocation {
|
|
22
|
+
readonly parentCheckpointId: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
/** Per-read options for the payload and writes reads. */
|
|
25
|
+
export interface ReadOptions {
|
|
26
|
+
signal?: AbortSignal;
|
|
27
|
+
/** `false` for bulk reads (`list`) that trade read-your-writes for half the read cost. */
|
|
28
|
+
consistent?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The META row a read is about: the one `checkpointId` names, else the newest
|
|
32
|
+
* in the namespace.
|
|
33
|
+
*
|
|
34
|
+
* Accepts: `address` — parsed; its `checkpointId` names the row, and its
|
|
35
|
+
* absence asks for the newest in the namespace. `signal` — aborts the read.
|
|
36
|
+
* `reader` — the public method this read serves, named when a foreign row is
|
|
37
|
+
* reported; `getTuple` unless the caller says otherwise.
|
|
38
|
+
*
|
|
39
|
+
* Returns: the row, or undefined when there is none — including when every row
|
|
40
|
+
* in the namespace has expired, or when the only rows there belong to another
|
|
41
|
+
* writer.
|
|
42
|
+
*
|
|
43
|
+
* Throws: `FORMAT_UNSUPPORTED` for a row of ours written by a newer version;
|
|
44
|
+
* whatever the read throws.
|
|
45
|
+
*
|
|
46
|
+
* Guarantees: strongly consistent, and expiry is judged here rather than waited
|
|
47
|
+
* for, so a checkpoint past its ttl is absent to every reader however long
|
|
48
|
+
* DynamoDB's sweep lags. The newest-first read returns the first live row of
|
|
49
|
+
* ours and stops there, stepping over expired and foreign rows
|
|
50
|
+
* {@link LATEST_META_PAGE_SIZE} at a time when the adapter has a `ttl`, and
|
|
51
|
+
* reading one row per page when it has none.
|
|
52
|
+
*/
|
|
53
|
+
export declare function fetchTargetMeta(context: CheckpointerContext, address: ThreadAddress, signal?: AbortSignal, reader?: MetaReader): Promise<CheckpointMetaRow | undefined>;
|
|
54
|
+
/**
|
|
55
|
+
* The PAYLOAD row of one checkpoint.
|
|
56
|
+
*
|
|
57
|
+
* Accepts: `at` — the checkpoint's location. `read.consistent` — defaults to
|
|
58
|
+
* true; `list` passes false and accepts replica lag, since a listing tolerates
|
|
59
|
+
* what a read-your-writes `getTuple` does not.
|
|
60
|
+
*
|
|
61
|
+
* Returns: the row, or undefined when it is not there — the two rows land in
|
|
62
|
+
* one transaction, so that is a thread being deleted row by row, or DynamoDB's
|
|
63
|
+
* expiry sweep reaching the PAYLOAD row before the META row — which the caller
|
|
64
|
+
* answers as "no checkpoint".
|
|
65
|
+
*
|
|
66
|
+
* Throws: `FORMAT_UNSUPPORTED` for a row a newer release wrote; whatever the
|
|
67
|
+
* read throws.
|
|
68
|
+
*/
|
|
69
|
+
export declare function fetchPayload(context: CheckpointerContext, at: CheckpointLocation, read?: ReadOptions): Promise<CheckpointPayloadRow | undefined>;
|
|
70
|
+
/**
|
|
71
|
+
* Every pending write stored for one checkpoint, decoded, in write order.
|
|
72
|
+
*
|
|
73
|
+
* Accepts: `at` — the checkpoint's location. `read.consistent` — omitted reads
|
|
74
|
+
* strongly consistently; `list` passes `false` explicitly and accepts replica
|
|
75
|
+
* lag, `getTuple` passes `true`.
|
|
76
|
+
*
|
|
77
|
+
* Returns: the writes after `dropSupersededWrites` has resolved
|
|
78
|
+
* first-write-wins; a checkpoint with none returns an empty array.
|
|
79
|
+
*
|
|
80
|
+
* Throws: `FORMAT_UNSUPPORTED` for a row a newer release wrote; whatever the
|
|
81
|
+
* query or the payload decode throws.
|
|
82
|
+
*
|
|
83
|
+
* Guarantees: the read is deliberately uncapped. It must be complete to be
|
|
84
|
+
* correct — a `Send` fan-out retried with a changed write order leaves
|
|
85
|
+
* superseded rows behind that would count toward any cap — so past
|
|
86
|
+
* {@link LIST_SCAN_WARN_THRESHOLD} rows the read still succeeds and an operator
|
|
87
|
+
* is told the checkpoint is unusually heavy.
|
|
88
|
+
*/
|
|
89
|
+
export declare function fetchPendingWrites(context: CheckpointerContext, at: CheckpointLocation, read?: ReadOptions): Promise<CheckpointPendingWrite[]>;
|
|
90
|
+
/** How a tuple is assembled: cancellation, read consistency, and metadata already decoded by the caller. */
|
|
91
|
+
export interface AssembleOptions {
|
|
92
|
+
signal?: AbortSignal;
|
|
93
|
+
/** `true` for `getTuple` (read-your-writes), `false` for the eventually-consistent `list` path. */
|
|
94
|
+
consistent: boolean;
|
|
95
|
+
/** Metadata the caller decoded to apply a filter, so it is not decoded (or downloaded) twice. */
|
|
96
|
+
metadata?: CheckpointMetadata;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A full {@link CheckpointTuple} built from a META row.
|
|
100
|
+
*
|
|
101
|
+
* Accepts: `thread` — the **caller's** location, never the row's: `thread.threadId`
|
|
102
|
+
* scopes which S3 object the row may point at, so it must come from the
|
|
103
|
+
* partition the caller asked for; `thread.checkpointNs` is its namespace.
|
|
104
|
+
* `options.metadata` — already decoded by a filtered `list`, so a filtered
|
|
105
|
+
* listing decodes and downloads each metadata blob once, not twice.
|
|
106
|
+
* `options.consistent` — true for `getTuple`, false for `list`.
|
|
107
|
+
*
|
|
108
|
+
* Returns: the tuple, with `parentConfig` set only when the row names a parent;
|
|
109
|
+
* `undefined` when the PAYLOAD row is absent — a thread mid-delete, or an
|
|
110
|
+
* expiry sweep that reached the PAYLOAD row first — the same answer a caller
|
|
111
|
+
* gets for a checkpoint that does not exist.
|
|
112
|
+
*
|
|
113
|
+
* Throws: whatever the reads and decodes throw.
|
|
114
|
+
*/
|
|
115
|
+
export declare function assembleTuple(context: CheckpointerContext, thread: ThreadLocation, meta: CheckpointMetaRow, options: AssembleOptions): Promise<CheckpointTuple | undefined>;
|
|
116
|
+
/**
|
|
117
|
+
* Pre-v4 checkpoints kept a task's `Send`s as `__pregel_tasks` pending writes
|
|
118
|
+
* on the parent rather than in the checkpoint itself. Reading such a
|
|
119
|
+
* checkpoint rebuilds `channel_values[TASKS]` from those writes and stamps
|
|
120
|
+
* the channel with the highest version the checkpoint already carries (or
|
|
121
|
+
* the first version when it carries none), exactly as the reference savers
|
|
122
|
+
* do, so a thread written before LangGraph 0.2 still resumes.
|
|
123
|
+
*
|
|
124
|
+
* Accepts: `checkpoint` — any version. `parent` — the checkpoint's own thread
|
|
125
|
+
* and namespace, plus `parent.parentCheckpointId`, the parent whose pending
|
|
126
|
+
* writes hold the sends; absent means there is nowhere to migrate from.
|
|
127
|
+
* `read` — cancellation and consistency for the pending-writes read.
|
|
128
|
+
*
|
|
129
|
+
* Returns: the checkpoint untouched when it is v4 or has no parent, and
|
|
130
|
+
* otherwise a copy with `channel_values[TASKS]` rebuilt. The input is never
|
|
131
|
+
* mutated.
|
|
132
|
+
*
|
|
133
|
+
* Throws: whatever reading the parent's pending writes throws.
|
|
134
|
+
*/
|
|
135
|
+
export declare function migratePendingSends(context: CheckpointerContext, checkpoint: Checkpoint, parent: PendingSendsSource, read: ReadOptions): Promise<Checkpoint>;
|