@farukada/aws-langgraph-dynamodb-ts 1.0.0-rc.2 → 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 +390 -193
- package/dist/{backfill → cjs/backfill}/backfill.d.ts +15 -12
- package/dist/cjs/backfill/backfill.js +177 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/delete-thread.d.ts +1 -1
- package/dist/cjs/checkpointer/actions/delete-thread.js +26 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/get-tuple.d.ts +4 -3
- package/dist/cjs/checkpointer/actions/get-tuple.js +22 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/list.d.ts +7 -4
- package/dist/cjs/checkpointer/actions/list.js +70 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/put-writes.d.ts +8 -6
- package/dist/cjs/checkpointer/actions/put-writes.js +21 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/put.d.ts +21 -15
- package/dist/cjs/checkpointer/actions/put.js +79 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/delta-history.d.ts +38 -26
- package/dist/cjs/checkpointer/internal/delta-history.js +131 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/listing.d.ts +4 -4
- package/dist/cjs/checkpointer/internal/listing.js +104 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/parse.d.ts +51 -15
- package/dist/cjs/checkpointer/internal/parse.js +184 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/pending-writes.d.ts +64 -25
- package/dist/cjs/checkpointer/internal/pending-writes.js +241 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/read.d.ts +15 -10
- package/dist/cjs/checkpointer/internal/read.js +132 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/rows.d.ts +94 -21
- package/dist/cjs/checkpointer/internal/rows.js +356 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/setup.d.ts +13 -20
- package/dist/cjs/checkpointer/internal/setup.js +25 -0
- package/dist/{checkpointer → cjs/checkpointer}/saver.d.ts +72 -36
- package/dist/cjs/checkpointer/saver.js +56 -0
- package/dist/{checkpointer → cjs/checkpointer}/types.d.ts +1 -1
- package/dist/cjs/checkpointer/types.js +2 -0
- package/dist/{factory → cjs/factory}/factory.d.ts +25 -20
- package/dist/cjs/factory/factory.js +137 -0
- package/dist/{factory → cjs/factory}/types.d.ts +12 -12
- package/dist/cjs/factory/types.js +2 -0
- package/dist/{history → cjs/history}/actions/add-messages.d.ts +18 -10
- package/dist/cjs/history/actions/add-messages.js +17 -0
- package/dist/{history → cjs/history}/actions/clear.d.ts +1 -1
- package/dist/cjs/history/actions/clear.js +29 -0
- package/dist/{history → cjs/history}/actions/get-messages.d.ts +11 -9
- package/dist/cjs/history/actions/get-messages.js +58 -0
- package/dist/{history → cjs/history}/actions/list-sessions.d.ts +3 -3
- package/dist/cjs/history/actions/list-sessions.js +67 -0
- package/dist/{history → cjs/history}/actions/reconcile-count.d.ts +13 -9
- package/dist/cjs/history/actions/reconcile-count.js +8 -0
- package/dist/{history → cjs/history}/chat-message-history.d.ts +62 -30
- package/dist/cjs/history/chat-message-history.js +61 -0
- package/dist/{history → cjs/history}/internal/append.d.ts +64 -32
- package/dist/cjs/history/internal/append.js +267 -0
- package/dist/{history → cjs/history}/internal/message-read.d.ts +3 -3
- package/dist/cjs/history/internal/message-read.js +93 -0
- package/dist/{history → cjs/history}/internal/parse.d.ts +2 -2
- package/dist/cjs/history/internal/parse.js +113 -0
- package/dist/{history → cjs/history}/internal/rows.d.ts +11 -10
- package/dist/cjs/history/internal/rows.js +96 -0
- package/dist/{history → cjs/history}/internal/session.d.ts +41 -22
- package/dist/cjs/history/internal/session.js +296 -0
- package/dist/{history → cjs/history}/internal/setup.d.ts +2 -2
- package/dist/cjs/history/internal/setup.js +60 -0
- package/dist/{history → cjs/history}/session-adapter.d.ts +0 -6
- package/dist/cjs/history/session-adapter.js +38 -0
- package/dist/{history → cjs/history}/types.d.ts +18 -15
- package/dist/cjs/history/types.js +2 -0
- package/dist/{index.d.ts → cjs/index.d.ts} +27 -27
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/package.json +1 -0
- package/dist/{shared → cjs/shared}/adapter.d.ts +27 -16
- package/dist/cjs/shared/adapter.js +70 -0
- package/dist/cjs/shared/clock.js +14 -0
- package/dist/{shared → cjs/shared}/codec/codec.d.ts +37 -20
- package/dist/cjs/shared/codec/codec.js +162 -0
- package/dist/{shared → cjs/shared}/codec/compression.d.ts +9 -4
- package/dist/cjs/shared/codec/compression.js +45 -0
- package/dist/cjs/shared/codec/json-serde.js +58 -0
- package/dist/{shared → cjs/shared}/codec/s3/client-types.d.ts +2 -1
- package/dist/cjs/shared/codec/s3/client-types.js +6 -0
- package/dist/{shared → cjs/shared}/codec/s3/client.d.ts +25 -7
- package/dist/cjs/shared/codec/s3/client.js +78 -0
- package/dist/{shared → cjs/shared}/codec/s3/config.d.ts +12 -7
- package/dist/cjs/shared/codec/s3/config.js +92 -0
- package/dist/{shared → cjs/shared}/codec/s3/lifecycle.d.ts +71 -17
- package/dist/cjs/shared/codec/s3/lifecycle.js +223 -0
- package/dist/{shared → cjs/shared}/codec/s3/offloader.d.ts +42 -29
- package/dist/cjs/shared/codec/s3/offloader.js +289 -0
- package/dist/cjs/shared/concurrency.js +31 -0
- package/dist/{shared → cjs/shared}/dynamodb/abort.d.ts +2 -2
- package/dist/cjs/shared/dynamodb/abort.js +16 -0
- package/dist/{shared → cjs/shared}/dynamodb/batch-write.d.ts +2 -2
- package/dist/cjs/shared/dynamodb/batch-write.js +79 -0
- package/dist/cjs/shared/dynamodb/cancellation.js +37 -0
- package/dist/{shared → cjs/shared}/dynamodb/client.d.ts +24 -22
- package/dist/cjs/shared/dynamodb/client.js +40 -0
- package/dist/{shared → cjs/shared}/dynamodb/idempotent-write.d.ts +64 -19
- package/dist/cjs/shared/dynamodb/idempotent-write.js +173 -0
- package/dist/{shared → cjs/shared}/dynamodb/paginate.d.ts +2 -2
- package/dist/cjs/shared/dynamodb/paginate.js +90 -0
- package/dist/{shared → cjs/shared}/dynamodb/partition-delete.d.ts +6 -6
- package/dist/cjs/shared/dynamodb/partition-delete.js +177 -0
- package/dist/{shared → cjs/shared}/dynamodb/recency-index.d.ts +27 -15
- package/dist/cjs/shared/dynamodb/recency-index.js +146 -0
- package/dist/{shared → cjs/shared}/dynamodb/retry.d.ts +37 -6
- 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/{shared → cjs/shared}/dynamodb/table-schema.d.ts +27 -18
- package/dist/cjs/shared/dynamodb/table-schema.js +52 -0
- package/dist/{shared → cjs/shared}/errors/base-error.d.ts +42 -7
- package/dist/cjs/shared/errors/base-error.js +73 -0
- package/dist/{shared → cjs/shared}/errors/boundary.d.ts +29 -14
- 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/{shared → cjs/shared}/errors/error-code.d.ts +17 -10
- package/dist/cjs/shared/errors/error-code.js +27 -0
- package/dist/{shared → cjs/shared}/errors/errors.d.ts +75 -9
- package/dist/cjs/shared/errors/errors.js +123 -0
- package/dist/cjs/shared/logging/logger.js +30 -0
- package/dist/{shared → cjs/shared}/logging/redaction.d.ts +8 -4
- package/dist/cjs/shared/logging/redaction.js +145 -0
- package/dist/{shared → cjs/shared}/logging/secret-patterns.d.ts +30 -7
- package/dist/cjs/shared/logging/secret-patterns.js +93 -0
- package/dist/cjs/shared/logging/truncate.js +31 -0
- package/dist/{shared → cjs/shared}/options.d.ts +27 -11
- package/dist/cjs/shared/options.js +2 -0
- package/dist/cjs/shared/ulid.js +83 -0
- package/dist/{shared → cjs/shared}/validation/collaborators.d.ts +21 -2
- package/dist/cjs/shared/validation/collaborators.js +79 -0
- package/dist/{shared → cjs/shared}/validation/option-shape.d.ts +7 -5
- package/dist/cjs/shared/validation/option-shape.js +31 -0
- package/dist/{shared → cjs/shared}/validation/options.d.ts +4 -4
- package/dist/cjs/shared/validation/options.js +166 -0
- package/dist/cjs/shared/validation/primitives.js +114 -0
- package/dist/{shared → cjs/shared}/validation/ttl.d.ts +26 -9
- package/dist/cjs/shared/validation/ttl.js +52 -0
- package/dist/{store → cjs/store}/actions/list-namespaces.d.ts +5 -5
- package/dist/cjs/store/actions/list-namespaces.js +92 -0
- package/dist/{store → cjs/store}/actions/put.d.ts +11 -4
- package/dist/cjs/store/actions/put.js +49 -0
- package/dist/{store → cjs/store}/actions/reconcile-vector-index.d.ts +5 -5
- package/dist/cjs/store/actions/reconcile-vector-index.js +13 -0
- package/dist/{store → cjs/store}/actions/search.d.ts +2 -2
- 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/{store → cjs/store}/internal/filter.d.ts +3 -3
- 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/{store → cjs/store}/internal/item-write.d.ts +72 -32
- package/dist/cjs/store/internal/item-write.js +181 -0
- package/dist/{store → cjs/store}/internal/parse.d.ts +15 -10
- package/dist/cjs/store/internal/parse.js +180 -0
- package/dist/{store → cjs/store}/internal/rows.d.ts +38 -34
- package/dist/cjs/store/internal/rows.js +166 -0
- package/dist/{store → cjs/store}/internal/semantic-search.d.ts +2 -2
- package/dist/cjs/store/internal/semantic-search.js +211 -0
- package/dist/{store → cjs/store}/internal/setup.d.ts +10 -15
- package/dist/cjs/store/internal/setup.js +103 -0
- package/dist/{store → cjs/store}/internal/table-search.d.ts +5 -5
- package/dist/cjs/store/internal/table-search.js +123 -0
- package/dist/{store → cjs/store}/internal/vector-index.d.ts +26 -15
- package/dist/cjs/store/internal/vector-index.js +269 -0
- package/dist/{store → cjs/store}/store.d.ts +82 -39
- package/dist/cjs/store/store.js +97 -0
- package/dist/{store → cjs/store}/types.d.ts +25 -10
- package/dist/cjs/store/types.js +2 -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/{checkpointer/actions/delete-thread.js → esm/checkpointer/actions/delete-thread.d.ts} +4 -26
- package/dist/esm/checkpointer/actions/delete-thread.js +23 -0
- package/dist/{checkpointer/actions/get-tuple.js → esm/checkpointer/actions/get-tuple.d.ts} +7 -24
- 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/{checkpointer/actions/put-writes.js → esm/checkpointer/actions/put-writes.d.ts} +10 -37
- 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/{checkpointer/internal/listing.js → esm/checkpointer/internal/listing.d.ts} +22 -118
- 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/{checkpointer/saver.js → esm/checkpointer/saver.d.ts} +84 -87
- 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/{history/actions/add-messages.js → esm/history/actions/add-messages.d.ts} +20 -26
- package/dist/esm/history/actions/add-messages.js +14 -0
- package/dist/{history/actions/clear.js → esm/history/actions/clear.d.ts} +4 -35
- 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/{history/actions/reconcile-count.js → esm/history/actions/reconcile-count.d.ts} +14 -16
- package/dist/esm/history/actions/reconcile-count.js +5 -0
- package/dist/{history/chat-message-history.js → esm/history/chat-message-history.d.ts} +76 -87
- 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/{history/internal/rows.js → esm/history/internal/rows.d.ts} +58 -112
- 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/{history/session-adapter.js → esm/history/session-adapter.d.ts} +25 -39
- 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/{shared/clock.js → esm/shared/clock.d.ts} +3 -14
- 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/{shared/codec/s3/config.js → esm/shared/codec/s3/config.d.ts} +45 -93
- 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/{shared/concurrency.js → esm/shared/concurrency.d.ts} +2 -37
- package/dist/esm/shared/concurrency.js +27 -0
- package/dist/{shared/dynamodb/abort.js → esm/shared/dynamodb/abort.d.ts} +4 -16
- 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/{shared/dynamodb/cancellation.js → esm/shared/dynamodb/cancellation.d.ts} +25 -53
- package/dist/esm/shared/dynamodb/cancellation.js +30 -0
- package/dist/{shared/dynamodb/client.js → esm/shared/dynamodb/client.d.ts} +74 -64
- package/dist/esm/shared/dynamodb/client.js +35 -0
- package/dist/{shared/dynamodb/idempotent-write.js → esm/shared/dynamodb/idempotent-write.d.ts} +172 -169
- 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/{shared/dynamodb/table-schema.js → esm/shared/dynamodb/table-schema.d.ts} +57 -67
- 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/{shared/errors/error-code.js → esm/shared/errors/error-code.d.ts} +39 -43
- package/dist/esm/shared/errors/error-code.js +24 -0
- package/dist/{shared/errors/errors.js → esm/shared/errors/errors.d.ts} +92 -98
- package/dist/esm/shared/errors/errors.js +110 -0
- package/dist/{shared/logging/logger.js → esm/shared/logging/logger.d.ts} +22 -52
- 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/{shared/logging/secret-patterns.js → esm/shared/logging/secret-patterns.d.ts} +46 -87
- package/dist/esm/shared/logging/secret-patterns.js +83 -0
- package/dist/{shared/logging/truncate.js → esm/shared/logging/truncate.d.ts} +6 -40
- 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/{shared/ulid.js → esm/shared/ulid.d.ts} +4 -84
- package/dist/esm/shared/ulid.js +77 -0
- package/dist/{shared/validation/collaborators.js → esm/shared/validation/collaborators.d.ts} +37 -65
- package/dist/esm/shared/validation/collaborators.js +70 -0
- package/dist/{shared/validation/option-shape.js → esm/shared/validation/option-shape.d.ts} +14 -36
- 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/{shared/validation/primitives.js → esm/shared/validation/primitives.d.ts} +30 -125
- 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/{store/actions/reconcile-vector-index.js → esm/store/actions/reconcile-vector-index.d.ts} +8 -16
- 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/{store/internal/rows.js → esm/store/internal/rows.d.ts} +111 -199
- 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/{store/store.js → esm/store/store.d.ts} +99 -133
- 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 +50 -44
- package/dist/backfill/backfill.js +0 -393
- package/dist/checkpointer/actions/list.js +0 -142
- package/dist/checkpointer/actions/put.js +0 -195
- package/dist/checkpointer/internal/delta-history.js +0 -252
- package/dist/checkpointer/internal/parse.js +0 -372
- package/dist/checkpointer/internal/pending-writes.js +0 -588
- package/dist/checkpointer/internal/read.js +0 -264
- package/dist/checkpointer/internal/rows.js +0 -834
- package/dist/checkpointer/internal/setup.js +0 -72
- package/dist/checkpointer/types.js +0 -12
- package/dist/factory/factory.js +0 -266
- package/dist/factory/types.js +0 -10
- package/dist/history/actions/get-messages.js +0 -141
- package/dist/history/actions/list-sessions.js +0 -156
- package/dist/history/internal/append.js +0 -500
- package/dist/history/internal/message-read.js +0 -204
- package/dist/history/internal/parse.js +0 -252
- package/dist/history/internal/session.js +0 -628
- package/dist/history/internal/setup.js +0 -106
- package/dist/history/types.js +0 -12
- package/dist/index.js +0 -51
- package/dist/shared/adapter.js +0 -143
- package/dist/shared/codec/codec.js +0 -441
- package/dist/shared/codec/compression.js +0 -89
- package/dist/shared/codec/json-serde.js +0 -191
- package/dist/shared/codec/s3/client-types.js +0 -26
- package/dist/shared/codec/s3/client.js +0 -97
- package/dist/shared/codec/s3/lifecycle.js +0 -355
- package/dist/shared/codec/s3/offloader.js +0 -658
- package/dist/shared/dynamodb/batch-write.js +0 -173
- package/dist/shared/dynamodb/paginate.js +0 -188
- package/dist/shared/dynamodb/partition-delete.js +0 -340
- package/dist/shared/dynamodb/recency-index.js +0 -377
- package/dist/shared/dynamodb/retry.js +0 -463
- package/dist/shared/errors/base-error.js +0 -174
- package/dist/shared/errors/boundary.js +0 -143
- package/dist/shared/errors/classify.d.ts +0 -97
- package/dist/shared/errors/classify.js +0 -257
- package/dist/shared/logging/redaction.js +0 -316
- package/dist/shared/options.js +0 -11
- package/dist/shared/validation/options.js +0 -328
- package/dist/shared/validation/ttl.js +0 -132
- package/dist/store/actions/list-namespaces.js +0 -197
- package/dist/store/actions/put.js +0 -78
- package/dist/store/actions/search.js +0 -66
- package/dist/store/internal/batch-plan.d.ts +0 -26
- package/dist/store/internal/batch-plan.js +0 -109
- package/dist/store/internal/filter.js +0 -137
- package/dist/store/internal/get-item.d.ts +0 -45
- package/dist/store/internal/get-item.js +0 -115
- package/dist/store/internal/item-write.js +0 -463
- package/dist/store/internal/parse.js +0 -350
- package/dist/store/internal/semantic-search.js +0 -389
- package/dist/store/internal/setup.js +0 -223
- package/dist/store/internal/table-search.js +0 -213
- package/dist/store/internal/vector-index.js +0 -546
- package/dist/store/types.js +0 -15
- package/dist/store/vector-backend.js +0 -17
- /package/dist/{shared → cjs/shared}/clock.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/codec/json-serde.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/concurrency.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/dynamodb/cancellation.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/logging/logger.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/logging/truncate.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/ulid.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/validation/primitives.d.ts +0 -0
- /package/dist/{store → cjs/store}/vector-backend.d.ts +0 -0
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
* whose outcome was lost into one of three verdicts. Whether a write needs the
|
|
12
12
|
* token is the payload descriptor's question, answered here once.
|
|
13
13
|
*/
|
|
14
|
-
import { type PayloadDescriptor, type DescriptorRef } from '../codec/codec';
|
|
15
|
-
import type { DynamoDBDocumentLike, AttributeMap, TransactAction } from './client';
|
|
16
|
-
import type { RetryOptions } from './retry';
|
|
17
|
-
import { type RowKey } from './table-schema';
|
|
14
|
+
import { type PayloadDescriptor, type DescriptorRef } from '../codec/codec.js';
|
|
15
|
+
import type { DynamoDBDocumentLike, AttributeMap, TransactAction } from './client.js';
|
|
16
|
+
import type { RetryOptions } from './retry.js';
|
|
17
|
+
import { type RowKey } from './table-schema.js';
|
|
18
18
|
/**
|
|
19
19
|
* What a row write needs of its adapter: the document client, the table, and
|
|
20
20
|
* the retry policy. Every context that writes or reads back a row already
|
|
@@ -102,13 +102,14 @@ export declare function referencesS3Object(descriptor: DescriptorRef): boolean;
|
|
|
102
102
|
* token, which is required rather than merely tidy: the re-pinned request
|
|
103
103
|
* carries a different `ConditionExpression`, and the same token presented with
|
|
104
104
|
* changed parameters inside the window is refused with
|
|
105
|
-
* `IdempotentParameterMismatchException` —
|
|
106
|
-
*
|
|
107
|
-
*
|
|
105
|
+
* `IdempotentParameterMismatchException` — classified as `AWS_REJECTED` and
|
|
106
|
+
* never retried, so reusing a token would fail the caller's write with that
|
|
107
|
+
* error instead of applying the re-pin. That refusal is only observable against real
|
|
108
108
|
* DynamoDB: the local image does not reserve a cancelled token's parameters
|
|
109
|
-
* and simply re-evaluates the changed body, so the
|
|
110
|
-
* can assert only that two re-pins carry different tokens
|
|
111
|
-
*
|
|
109
|
+
* and simply re-evaluates the changed body, so the integration tier, on
|
|
110
|
+
* DynamoDB Local, can assert only that two re-pins carry different tokens —
|
|
111
|
+
* the unit tier mocks the client — and the refusal itself belongs to the
|
|
112
|
+
* tier that runs against AWS.
|
|
112
113
|
*
|
|
113
114
|
* **At most one guarded action, and only ever as many actions as must land
|
|
114
115
|
* together.** A cancellation is read as a guard rejection only while exactly
|
|
@@ -165,7 +166,7 @@ export declare function transactIdempotently(deps: RowWriteDeps, actions: Transa
|
|
|
165
166
|
* Commit one row under a request token; see {@link transactIdempotently} for
|
|
166
167
|
* why the write takes a transaction's shape and what the token buys.
|
|
167
168
|
*
|
|
168
|
-
* Accepts: `deps` — the adapter's client, table and retry policy. `
|
|
169
|
+
* Accepts: `deps` — the adapter's client, table and retry policy. `row` — the
|
|
169
170
|
* row to commit. It is captured by reference and re-sent unchanged on every
|
|
170
171
|
* attempt of the budget, so a caller must not mutate it while this call is in
|
|
171
172
|
* flight: the re-send would carry the same token with different parameters,
|
|
@@ -184,7 +185,7 @@ export declare function transactIdempotently(deps: RowWriteDeps, actions: Transa
|
|
|
184
185
|
* `rejectedRow`, so a caller reads them the same way. A spent budget
|
|
185
186
|
* throws `RETRY_EXHAUSTED` as any other call does.
|
|
186
187
|
*/
|
|
187
|
-
export declare function putIdempotently(deps: RowWriteDeps,
|
|
188
|
+
export declare function putIdempotently(deps: RowWriteDeps, row: AttributeMap, guard?: RevisionGuard, signal?: AbortSignal): Promise<void>;
|
|
188
189
|
/**
|
|
189
190
|
* Remove one row under a request token; see {@link transactIdempotently} for
|
|
190
191
|
* why the delete takes a transaction's shape and what the token buys.
|
|
@@ -241,7 +242,8 @@ export declare function commitRow(deps: RowWriteDeps, row: AttributeMap, payload
|
|
|
241
242
|
* unconditionally. Kept small on purpose: DynamoDB charges write capacity for a
|
|
242
243
|
* *failed* conditional write too, sized on the existing item, so an aggressive
|
|
243
244
|
* loop turns contention into cost. Three attempts settle every realistic race,
|
|
244
|
-
* and the fallback is
|
|
245
|
+
* and the fallback is an unconditional write — one possible orphaned object,
|
|
246
|
+
* reclaimed by the lifecycle rule — rather than an error.
|
|
245
247
|
*/
|
|
246
248
|
export declare const OVERWRITE_CAS_MAX_ATTEMPTS = 3;
|
|
247
249
|
/** What a caller saw at the row before it tried to overwrite it. */
|
|
@@ -272,8 +274,9 @@ export interface RevisionGuard {
|
|
|
272
274
|
* because neither writer can learn of an object it never saw; only refusing the
|
|
273
275
|
* second write until it re-reads can.
|
|
274
276
|
*
|
|
275
|
-
* A row with no revision attribute was written before
|
|
276
|
-
*
|
|
277
|
+
* A row with no revision attribute was written before the attribute existed
|
|
278
|
+
* — 0.9.0 for a store row's `rev`, 0.8.0 for a write row's `writeGroup`.
|
|
279
|
+
* Pinning its *absence* is what makes the swap correct across an upgrade: the first writer
|
|
277
280
|
* to touch such a row stamps one, and any racer still holding the pre-upgrade
|
|
278
281
|
* observation is turned away.
|
|
279
282
|
*
|
|
@@ -417,10 +420,7 @@ export declare function rejectedRow(error: Error): AttributeMap | undefined;
|
|
|
417
420
|
export type WriteVerdict = 'landed' | 'not-landed' | 'unverified';
|
|
418
421
|
/** Which row to read, and which attributes of it to project. */
|
|
419
422
|
export interface RowRead {
|
|
420
|
-
key:
|
|
421
|
-
PK: string;
|
|
422
|
-
SK: string;
|
|
423
|
-
};
|
|
423
|
+
key: RowKey;
|
|
424
424
|
/** The attribute carrying the row's identity; always projected. */
|
|
425
425
|
attribute: string;
|
|
426
426
|
/** Further attributes to project, when the caller needs the row itself back. */
|
|
@@ -492,6 +492,51 @@ export declare function identityOf(probe: RowProbe, row: AttributeMap | undefine
|
|
|
492
492
|
* Throws: nothing.
|
|
493
493
|
*/
|
|
494
494
|
export declare function verdictFor(probe: RowProbe, row: AttributeMap | undefined): WriteVerdict;
|
|
495
|
+
/**
|
|
496
|
+
* Whether a write that failed may still commit after its failure was reported.
|
|
497
|
+
*
|
|
498
|
+
* A write the service answered with a definite refusal or a throttle is
|
|
499
|
+
* finished: a strongly consistent read after that answer sees whatever it
|
|
500
|
+
* did. A write is not finished while *any* attempt of it left DynamoDB free to
|
|
501
|
+
* apply it later — not only its last attempt: `TransactWriteItems` is sent
|
|
502
|
+
* under one `ClientRequestToken` for the whole retry budget, and DynamoDB
|
|
503
|
+
* answers a re-send that arrives while an earlier attempt under that same
|
|
504
|
+
* token is still being processed with `TransactionInProgressException` —
|
|
505
|
+
* itself proof that the earlier attempt reached the service and may still
|
|
506
|
+
* land — while the very next attempt can be answered normally. A cancel is
|
|
507
|
+
* the same story from the caller's own side: it stops the client waiting, not
|
|
508
|
+
* the service applying a request it had already received.
|
|
509
|
+
*
|
|
510
|
+
* Accepts: `failure` — what the write threw.
|
|
511
|
+
*
|
|
512
|
+
* Returns: true for `ABORTED`, and for any failure carrying the record
|
|
513
|
+
* `withRetry` kept across every attempt of its budget
|
|
514
|
+
* (`retryBudgetMayStillLand`) — a spent budget, or a refusal that ended one
|
|
515
|
+
* after an attempt that got no answer. Without that record, a spent budget is
|
|
516
|
+
* judged by its last attempt's own failure (`mayStillBeInFlight`), which is
|
|
517
|
+
* what a `RETRY_EXHAUSTED` error built outside `withRetry` falls back to; any
|
|
518
|
+
* other failure is judged by itself the same way.
|
|
519
|
+
*
|
|
520
|
+
* Throws: nothing, for any value.
|
|
521
|
+
*/
|
|
522
|
+
export declare function mayStillLand(failure: Error): boolean;
|
|
523
|
+
/**
|
|
524
|
+
* The verdict a read-back licenses once the write it judges may still be in flight.
|
|
525
|
+
*
|
|
526
|
+
* Accepts: `verdict` — what the read found. `failure` — what the write threw.
|
|
527
|
+
*
|
|
528
|
+
* Returns: `'unverified'` in place of `'not-landed'` when the write may still
|
|
529
|
+
* commit ({@link mayStillLand}): an absent row is exactly what an attempt still
|
|
530
|
+
* on its way can fill, so the upload it names is not yet dead. Every other
|
|
531
|
+
* verdict is returned unchanged. A caller whose write is pinned to a state the
|
|
532
|
+
* row has already left may skip this, since such a write can no longer apply
|
|
533
|
+
* (the pending-writes verification does); `persistRow` asks it unconditionally,
|
|
534
|
+
* so its upload is kept whether the read found the row absent or holding
|
|
535
|
+
* another revision.
|
|
536
|
+
*
|
|
537
|
+
* Throws: nothing.
|
|
538
|
+
*/
|
|
539
|
+
export declare function settledVerdict(verdict: WriteVerdict, failure: Error): WriteVerdict;
|
|
495
540
|
/**
|
|
496
541
|
* Read the row a probe names, strongly consistently.
|
|
497
542
|
*
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WRITE_ID_ATTRIBUTE = exports.OVERWRITE_CAS_MAX_ATTEMPTS = void 0;
|
|
4
|
+
exports.referencesS3Object = referencesS3Object;
|
|
5
|
+
exports.transactIdempotently = transactIdempotently;
|
|
6
|
+
exports.putIdempotently = putIdempotently;
|
|
7
|
+
exports.deleteIdempotently = deleteIdempotently;
|
|
8
|
+
exports.commitRow = commitRow;
|
|
9
|
+
exports.revisionGuard = revisionGuard;
|
|
10
|
+
exports.writeIdGuard = writeIdGuard;
|
|
11
|
+
exports.isConditionalCheckFailed = isConditionalCheckFailed;
|
|
12
|
+
exports.rejectedRow = rejectedRow;
|
|
13
|
+
exports.offloadedKey = offloadedKey;
|
|
14
|
+
exports.identityOf = identityOf;
|
|
15
|
+
exports.verdictFor = verdictFor;
|
|
16
|
+
exports.mayStillLand = mayStillLand;
|
|
17
|
+
exports.settledVerdict = settledVerdict;
|
|
18
|
+
exports.readRow = readRow;
|
|
19
|
+
exports.verifyRow = verifyRow;
|
|
20
|
+
exports.isRowAbsent = isRowAbsent;
|
|
21
|
+
const node_crypto_1 = require("node:crypto");
|
|
22
|
+
const util_dynamodb_1 = require("@aws-sdk/util-dynamodb");
|
|
23
|
+
const clock_js_1 = require("../clock.js");
|
|
24
|
+
const codec_js_1 = require("../codec/codec.js");
|
|
25
|
+
const base_error_js_1 = require("../errors/base-error.js");
|
|
26
|
+
const classify_js_1 = require("../errors/classify.js");
|
|
27
|
+
const error_code_js_1 = require("../errors/error-code.js");
|
|
28
|
+
const errors_js_1 = require("../errors/errors.js");
|
|
29
|
+
const abort_js_1 = require("./abort.js");
|
|
30
|
+
const cancellation_js_1 = require("./cancellation.js");
|
|
31
|
+
const retry_js_1 = require("./retry.js");
|
|
32
|
+
const table_schema_js_1 = require("./table-schema.js");
|
|
33
|
+
function referencesS3Object(descriptor) {
|
|
34
|
+
return descriptor.location === codec_js_1.PayloadLocation.S3;
|
|
35
|
+
}
|
|
36
|
+
async function transactIdempotently(deps, actions, options = {}) {
|
|
37
|
+
const input = { TransactItems: actions, ClientRequestToken: (0, node_crypto_1.randomUUID)() };
|
|
38
|
+
const deadlineAt = (0, clock_js_1.nowMs)() + retry_js_1.MAX_WRITE_LIFETIME_MS;
|
|
39
|
+
await (0, retry_js_1.withDynamoDBRetry)((request) => deps.client.transactWrite(input, request), {
|
|
40
|
+
...(0, retry_js_1.retryFor)(deps, options.signal),
|
|
41
|
+
...(options.minAttempts === undefined
|
|
42
|
+
? {}
|
|
43
|
+
: { maxAttempts: Math.max(options.minAttempts, deps.retry?.maxAttempts ?? 0) }),
|
|
44
|
+
...(options.rng === undefined ? {} : { rng: options.rng }),
|
|
45
|
+
deadlineAt,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async function putIdempotently(deps, row, guard, signal) {
|
|
49
|
+
await transactIdempotently(deps, [{ Put: { TableName: deps.tableName, Item: row, ...guard } }], {
|
|
50
|
+
signal,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async function deleteIdempotently(deps, key, guard, signal) {
|
|
54
|
+
await transactIdempotently(deps, [{ Delete: { TableName: deps.tableName, Key: key, ...guard } }], { signal });
|
|
55
|
+
}
|
|
56
|
+
async function commitRow(deps, row, payload, options = {}) {
|
|
57
|
+
if (referencesS3Object(payload)) {
|
|
58
|
+
await putIdempotently(deps, row, options.guard, options.signal);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
await (0, retry_js_1.withDynamoDBRetry)((request) => deps.client.put({ TableName: deps.tableName, Item: row, ...options.guard }, request), (0, retry_js_1.retryFor)(deps, options.signal));
|
|
62
|
+
}
|
|
63
|
+
exports.OVERWRITE_CAS_MAX_ATTEMPTS = 3;
|
|
64
|
+
const RETURN_REJECTED_ROW = { ReturnValuesOnConditionCheckFailure: 'ALL_OLD' };
|
|
65
|
+
function revisionGuard(attribute, observed) {
|
|
66
|
+
if (!observed.exists)
|
|
67
|
+
return {
|
|
68
|
+
...RETURN_REJECTED_ROW,
|
|
69
|
+
ConditionExpression: `attribute_not_exists(${table_schema_js_1.PARTITION_KEY_ATTRIBUTE})`,
|
|
70
|
+
};
|
|
71
|
+
if (observed.revision === undefined) {
|
|
72
|
+
return {
|
|
73
|
+
...RETURN_REJECTED_ROW,
|
|
74
|
+
ConditionExpression: 'attribute_not_exists(#rev)',
|
|
75
|
+
ExpressionAttributeNames: { '#rev': attribute },
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
...RETURN_REJECTED_ROW,
|
|
80
|
+
ConditionExpression: '#rev = :rev',
|
|
81
|
+
ExpressionAttributeNames: { '#rev': attribute },
|
|
82
|
+
ExpressionAttributeValues: { ':rev': observed.revision },
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
exports.WRITE_ID_ATTRIBUTE = 'writeId';
|
|
86
|
+
function writeIdGuard(attribute, id, field) {
|
|
87
|
+
const names = { '#pin': attribute };
|
|
88
|
+
if (field !== undefined)
|
|
89
|
+
names['#field'] = field;
|
|
90
|
+
return {
|
|
91
|
+
...RETURN_REJECTED_ROW,
|
|
92
|
+
ConditionExpression: field === undefined ? '#pin = :pin' : '#pin.#field = :pin',
|
|
93
|
+
ExpressionAttributeNames: names,
|
|
94
|
+
ExpressionAttributeValues: { ':pin': id },
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function isConditionalCheckFailed(error) {
|
|
98
|
+
return (0, classify_js_1.classifyAwsError)(error) === error_code_js_1.ErrorCode.CONDITION_CONFLICT;
|
|
99
|
+
}
|
|
100
|
+
function rejectedRow(error) {
|
|
101
|
+
const attached = error.Item;
|
|
102
|
+
const raw = attached ?? (0, cancellation_js_1.conditionalCheckFailure)(error)?.Item;
|
|
103
|
+
return raw === undefined ? undefined : (0, util_dynamodb_1.unmarshall)(raw);
|
|
104
|
+
}
|
|
105
|
+
function offloadedKey(descriptor) {
|
|
106
|
+
return descriptor?.location === codec_js_1.PayloadLocation.S3 ? descriptor.s3Key : undefined;
|
|
107
|
+
}
|
|
108
|
+
function identityOf(probe, row) {
|
|
109
|
+
if (probe.kind === 'attribute')
|
|
110
|
+
return row?.[probe.attribute];
|
|
111
|
+
return offloadedKey(row?.[probe.attribute]);
|
|
112
|
+
}
|
|
113
|
+
function verdictFor(probe, row) {
|
|
114
|
+
return identityOf(probe, row) === probe.expected ? 'landed' : 'not-landed';
|
|
115
|
+
}
|
|
116
|
+
function mayStillLand(failure) {
|
|
117
|
+
if ((0, abort_js_1.isAbortError)(failure) || (0, errors_js_1.retryBudgetMayStillLand)(failure))
|
|
118
|
+
return true;
|
|
119
|
+
if ((0, base_error_js_1.hasErrorCode)(failure, error_code_js_1.ErrorCode.RETRY_EXHAUSTED)) {
|
|
120
|
+
return (0, classify_js_1.mayStillBeInFlight)(failure.cause);
|
|
121
|
+
}
|
|
122
|
+
return (0, classify_js_1.mayStillBeInFlight)(failure);
|
|
123
|
+
}
|
|
124
|
+
function settledVerdict(verdict, failure) {
|
|
125
|
+
return verdict === 'not-landed' && mayStillLand(failure) ? 'unverified' : verdict;
|
|
126
|
+
}
|
|
127
|
+
function projectionOf(read) {
|
|
128
|
+
const nested = read.descriptors ?? [];
|
|
129
|
+
const whole = [read.attribute, ...(read.also ?? [])].filter((name) => !nested.includes(name));
|
|
130
|
+
const names = {};
|
|
131
|
+
const paths = [];
|
|
132
|
+
whole.forEach((name, index) => {
|
|
133
|
+
names[`#a${index}`] = name;
|
|
134
|
+
paths.push(`#a${index}`);
|
|
135
|
+
});
|
|
136
|
+
nested.forEach((name, index) => {
|
|
137
|
+
names[`#d${index}`] = name;
|
|
138
|
+
paths.push(`#d${index}.#loc`, `#d${index}.#s3k`);
|
|
139
|
+
});
|
|
140
|
+
if (nested.length > 0)
|
|
141
|
+
Object.assign(names, { '#loc': 'location', '#s3k': 's3Key' });
|
|
142
|
+
return { expression: paths.join(', '), names };
|
|
143
|
+
}
|
|
144
|
+
async function readRow(deps, read) {
|
|
145
|
+
const { expression, names } = projectionOf(read);
|
|
146
|
+
const result = await (0, retry_js_1.withDynamoDBRetry)((request) => deps.client.get({
|
|
147
|
+
TableName: deps.tableName,
|
|
148
|
+
Key: read.key,
|
|
149
|
+
ConsistentRead: true,
|
|
150
|
+
ProjectionExpression: expression,
|
|
151
|
+
ExpressionAttributeNames: names,
|
|
152
|
+
}, request), deps.retry);
|
|
153
|
+
return result.Item;
|
|
154
|
+
}
|
|
155
|
+
async function verifyRow(deps, probe) {
|
|
156
|
+
if (probe.expected === undefined)
|
|
157
|
+
return { verdict: 'not-landed' };
|
|
158
|
+
try {
|
|
159
|
+
const row = await readRow(deps, probe);
|
|
160
|
+
return { verdict: verdictFor(probe, row), row };
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return { verdict: 'unverified' };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async function isRowAbsent(deps, key) {
|
|
167
|
+
try {
|
|
168
|
+
return (await readRow(deps, { key, attribute: table_schema_js_1.PARTITION_KEY_ATTRIBUTE })) === undefined;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* between pages are decided here, the same way for a Query and a Scan.
|
|
9
9
|
*/
|
|
10
10
|
import type { QueryCommandInput, ScanCommandInput } from '@aws-sdk/lib-dynamodb';
|
|
11
|
-
import type { DynamoDBDocumentLike, AttributeMap } from './client';
|
|
12
|
-
import { type RetryOptions } from './retry';
|
|
11
|
+
import type { DynamoDBDocumentLike, AttributeMap } from './client.js';
|
|
12
|
+
import { type RetryOptions } from './retry.js';
|
|
13
13
|
/** Hard cap on query-pagination loop iterations (runaway-loop guard). */
|
|
14
14
|
export declare const MAX_LOOP_ITERATIONS = 1000;
|
|
15
15
|
/** Hard cap on rows collected into memory across a paginated query. */
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LIST_SCAN_WARN_THRESHOLD = exports.MAX_TOTAL_ROWS_IN_MEMORY = exports.MAX_LOOP_ITERATIONS = void 0;
|
|
4
|
+
exports.paginateQuery = paginateQuery;
|
|
5
|
+
exports.paginatePages = paginatePages;
|
|
6
|
+
exports.paginateScan = paginateScan;
|
|
7
|
+
const errors_js_1 = require("../errors/errors.js");
|
|
8
|
+
const abort_js_1 = require("./abort.js");
|
|
9
|
+
const retry_js_1 = require("./retry.js");
|
|
10
|
+
exports.MAX_LOOP_ITERATIONS = 1000;
|
|
11
|
+
exports.MAX_TOTAL_ROWS_IN_MEMORY = 10000;
|
|
12
|
+
exports.LIST_SCAN_WARN_THRESHOLD = 10000;
|
|
13
|
+
function paginateQuery(options) {
|
|
14
|
+
return paginatePages(async (startKey) => {
|
|
15
|
+
const page = await (0, retry_js_1.withDynamoDBRetry)((request) => options.client.query({ ...options.params, ExclusiveStartKey: startKey }, request), { ...options.retry, signal: options.signal });
|
|
16
|
+
return {
|
|
17
|
+
items: page.Items ?? [],
|
|
18
|
+
lastKey: page.LastEvaluatedKey,
|
|
19
|
+
};
|
|
20
|
+
}, options);
|
|
21
|
+
}
|
|
22
|
+
async function readPage(reader, startKey) {
|
|
23
|
+
if (reader.iterations >= reader.maxIterations) {
|
|
24
|
+
throw (0, errors_js_1.resultTruncatedError)('maxIterations', reader.maxIterations);
|
|
25
|
+
}
|
|
26
|
+
if (reader.signal?.aborted)
|
|
27
|
+
throw (0, abort_js_1.abortErrorFrom)(reader.signal);
|
|
28
|
+
reader.iterations += 1;
|
|
29
|
+
return reader.fetchPage(startKey);
|
|
30
|
+
}
|
|
31
|
+
function* yieldPageRows(page, state, maxItems) {
|
|
32
|
+
for (let index = 0; index < page.items.length; index++) {
|
|
33
|
+
yield page.items[index];
|
|
34
|
+
state.yielded += 1;
|
|
35
|
+
if (state.yielded >= maxItems) {
|
|
36
|
+
if (index < page.items.length - 1)
|
|
37
|
+
throw (0, errors_js_1.resultTruncatedError)('maxItems', maxItems);
|
|
38
|
+
return 'capped';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return 'exhausted';
|
|
42
|
+
}
|
|
43
|
+
async function dataRemains(reader, startKey) {
|
|
44
|
+
let key = startKey;
|
|
45
|
+
while (key !== undefined) {
|
|
46
|
+
const page = await readPage(reader, key);
|
|
47
|
+
if (page.items.length > 0)
|
|
48
|
+
return true;
|
|
49
|
+
key = page.lastKey;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
function assertPositiveCap(value, field) {
|
|
54
|
+
if (!(value >= 1)) {
|
|
55
|
+
throw (0, errors_js_1.validationError)(`${field} must be at least 1 (pass Infinity to read to completion)`, field);
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
async function* paginatePages(fetchPage, options = {}) {
|
|
60
|
+
const maxItems = assertPositiveCap(options.maxItems ?? exports.MAX_TOTAL_ROWS_IN_MEMORY, 'maxItems');
|
|
61
|
+
const reader = {
|
|
62
|
+
fetchPage,
|
|
63
|
+
maxIterations: assertPositiveCap(options.maxIterations ?? exports.MAX_LOOP_ITERATIONS, 'maxIterations'),
|
|
64
|
+
iterations: 0,
|
|
65
|
+
signal: options.signal,
|
|
66
|
+
};
|
|
67
|
+
const state = { yielded: 0 };
|
|
68
|
+
let startKey;
|
|
69
|
+
for (;;) {
|
|
70
|
+
const page = await readPage(reader, startKey);
|
|
71
|
+
const outcome = yield* yieldPageRows(page, state, maxItems);
|
|
72
|
+
if (outcome === 'capped') {
|
|
73
|
+
if (await dataRemains(reader, page.lastKey))
|
|
74
|
+
throw (0, errors_js_1.resultTruncatedError)('maxItems', maxItems);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
startKey = page.lastKey;
|
|
78
|
+
if (startKey === undefined)
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function paginateScan(options) {
|
|
83
|
+
return paginatePages(async (startKey) => {
|
|
84
|
+
const page = await (0, retry_js_1.withDynamoDBRetry)((request) => options.client.scan({ ...options.params, ExclusiveStartKey: startKey }, request), { ...options.retry, signal: options.signal });
|
|
85
|
+
return {
|
|
86
|
+
items: page.Items ?? [],
|
|
87
|
+
lastKey: page.LastEvaluatedKey,
|
|
88
|
+
};
|
|
89
|
+
}, options);
|
|
90
|
+
}
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
* object is released only once the row naming it is confirmed gone.
|
|
9
9
|
*/
|
|
10
10
|
import type { QueryCommandInput } from '@aws-sdk/lib-dynamodb';
|
|
11
|
-
import { type PayloadDescriptor, type DescriptorRef } from '../codec/codec';
|
|
12
|
-
import { type S3Offloader } from '../codec/s3/offloader';
|
|
13
|
-
import type { Logger } from '../logging/logger';
|
|
14
|
-
import type { DynamoDBDocumentLike, AttributeMap } from './client';
|
|
15
|
-
import { type RevisionGuard } from './idempotent-write';
|
|
16
|
-
import { type RetryOptions } from './retry';
|
|
11
|
+
import { type PayloadDescriptor, type DescriptorRef } from '../codec/codec.js';
|
|
12
|
+
import { type S3Offloader } from '../codec/s3/offloader.js';
|
|
13
|
+
import type { Logger } from '../logging/logger.js';
|
|
14
|
+
import type { DynamoDBDocumentLike, AttributeMap } from './client.js';
|
|
15
|
+
import { type RevisionGuard } from './idempotent-write.js';
|
|
16
|
+
import { type RetryOptions } from './retry.js';
|
|
17
17
|
/**
|
|
18
18
|
* Conditional row deletes a partition-wide delete keeps in flight. Pinning a
|
|
19
19
|
* row on the write that produced it costs one request per row where a batch
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DELETE_CONCURRENCY = void 0;
|
|
4
|
+
exports.namedDescriptor = namedDescriptor;
|
|
5
|
+
exports.deletePartitionRows = deletePartitionRows;
|
|
6
|
+
exports.flushPendingDeletes = flushPendingDeletes;
|
|
7
|
+
const codec_js_1 = require("../codec/codec.js");
|
|
8
|
+
const offloader_js_1 = require("../codec/s3/offloader.js");
|
|
9
|
+
const concurrency_js_1 = require("../concurrency.js");
|
|
10
|
+
const errors_js_1 = require("../errors/errors.js");
|
|
11
|
+
const truncate_js_1 = require("../logging/truncate.js");
|
|
12
|
+
const abort_js_1 = require("./abort.js");
|
|
13
|
+
const batch_write_js_1 = require("./batch-write.js");
|
|
14
|
+
const idempotent_write_js_1 = require("./idempotent-write.js");
|
|
15
|
+
const paginate_js_1 = require("./paginate.js");
|
|
16
|
+
const retry_js_1 = require("./retry.js");
|
|
17
|
+
const table_schema_js_1 = require("./table-schema.js");
|
|
18
|
+
exports.DELETE_CONCURRENCY = 8;
|
|
19
|
+
function namedDescriptor(row, attribute) {
|
|
20
|
+
const descriptor = row[attribute];
|
|
21
|
+
if (descriptor === null || descriptor === undefined)
|
|
22
|
+
return undefined;
|
|
23
|
+
return { attribute, descriptor };
|
|
24
|
+
}
|
|
25
|
+
function pinFor(idAttribute, row, named) {
|
|
26
|
+
if (idAttribute !== undefined) {
|
|
27
|
+
const observed = row[idAttribute];
|
|
28
|
+
if (typeof observed === 'string')
|
|
29
|
+
return (0, idempotent_write_js_1.writeIdGuard)(idAttribute, observed);
|
|
30
|
+
}
|
|
31
|
+
for (const entry of named) {
|
|
32
|
+
const { writeId } = entry.descriptor;
|
|
33
|
+
if (writeId !== undefined)
|
|
34
|
+
return (0, idempotent_write_js_1.writeIdGuard)(entry.attribute, writeId, idempotent_write_js_1.WRITE_ID_ATTRIBUTE);
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
function pendingDelete(options, row) {
|
|
39
|
+
const named = options.descriptorsOf(row);
|
|
40
|
+
return {
|
|
41
|
+
key: (0, table_schema_js_1.rowKeyOf)(row),
|
|
42
|
+
guard: pinFor(options.idAttribute, row, named),
|
|
43
|
+
descriptors: named.map((entry) => entry.descriptor),
|
|
44
|
+
unit: options.unitOf?.(row),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function unitRefused(options, row, state) {
|
|
48
|
+
const unit = options.unitOf?.(row);
|
|
49
|
+
return unit !== undefined && state.units.has(unit);
|
|
50
|
+
}
|
|
51
|
+
function cancelAmong(failures) {
|
|
52
|
+
return failures.find(abort_js_1.isAbortError);
|
|
53
|
+
}
|
|
54
|
+
async function flushBuffer(options, state) {
|
|
55
|
+
if (state.buffer.length === 0)
|
|
56
|
+
return;
|
|
57
|
+
const tally = await flushPendingDeletes(options, state.buffer.splice(0));
|
|
58
|
+
state.deleted += tally.deleted;
|
|
59
|
+
state.skipped += tally.refused;
|
|
60
|
+
state.attempted += tally.deleted + tally.failures.length;
|
|
61
|
+
for (const unit of tally.refusedUnits)
|
|
62
|
+
state.units.add(unit);
|
|
63
|
+
if (tally.failures.length === 0)
|
|
64
|
+
return;
|
|
65
|
+
const cancelled = cancelAmong(tally.failures);
|
|
66
|
+
if (cancelled !== undefined)
|
|
67
|
+
throw cancelled;
|
|
68
|
+
const { deleted, attempted } = state;
|
|
69
|
+
throw (0, errors_js_1.batchWriteAllIncompleteError)({
|
|
70
|
+
succeeded: deleted,
|
|
71
|
+
total: attempted,
|
|
72
|
+
failures: tally.failures,
|
|
73
|
+
succeededCount: deleted,
|
|
74
|
+
unit: 'row',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
async function deletePartitionRows(options) {
|
|
78
|
+
const state = { buffer: [], deleted: 0, attempted: 0, skipped: 0, units: new Set() };
|
|
79
|
+
let kind;
|
|
80
|
+
const pages = (0, paginate_js_1.paginateQuery)({
|
|
81
|
+
client: options.client,
|
|
82
|
+
params: options.params,
|
|
83
|
+
retry: options.retry,
|
|
84
|
+
signal: options.signal,
|
|
85
|
+
maxItems: Number.POSITIVE_INFINITY,
|
|
86
|
+
maxIterations: Number.POSITIVE_INFINITY,
|
|
87
|
+
});
|
|
88
|
+
for await (const row of pages) {
|
|
89
|
+
const sortKey = row.SK;
|
|
90
|
+
if (!options.ownsSortKey(sortKey)) {
|
|
91
|
+
state.skipped += 1;
|
|
92
|
+
options.logger.warn(`${options.operation}: left a foreign row in place`, {
|
|
93
|
+
sortKey: (0, truncate_js_1.truncateForLog)(sortKey),
|
|
94
|
+
});
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const rowKind = options.kindOf?.(row);
|
|
98
|
+
if (rowKind !== kind) {
|
|
99
|
+
await flushBuffer(options, state);
|
|
100
|
+
kind = rowKind;
|
|
101
|
+
}
|
|
102
|
+
if (unitRefused(options, row, state)) {
|
|
103
|
+
state.skipped += 1;
|
|
104
|
+
options.logger.warn(`${options.operation}: skipped a row whose unit was refused`, {
|
|
105
|
+
sortKey: (0, truncate_js_1.truncateForLog)(sortKey),
|
|
106
|
+
});
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
state.buffer.push(pendingDelete(options, row));
|
|
110
|
+
if (state.buffer.length >= batch_write_js_1.BATCH_WRITE_MAX)
|
|
111
|
+
await flushBuffer(options, state);
|
|
112
|
+
}
|
|
113
|
+
await flushBuffer(options, state);
|
|
114
|
+
const { deleted, skipped } = state;
|
|
115
|
+
options.logger.info(`${options.operation}: deleted rows`, { deleted, skipped });
|
|
116
|
+
return deleted;
|
|
117
|
+
}
|
|
118
|
+
function recordRefusal(deps, row, tally) {
|
|
119
|
+
deps.logger.warn(`${deps.operation}: left a row rewritten since the read`, {
|
|
120
|
+
sortKey: (0, truncate_js_1.truncateForLog)(row.key.SK),
|
|
121
|
+
});
|
|
122
|
+
tally.refused += 1;
|
|
123
|
+
if (row.unit !== undefined)
|
|
124
|
+
tally.refusedUnits.push(row.unit);
|
|
125
|
+
}
|
|
126
|
+
async function settleRow(deps, row, tally) {
|
|
127
|
+
try {
|
|
128
|
+
await (0, retry_js_1.withDynamoDBRetry)((request) => deps.client.delete({
|
|
129
|
+
TableName: deps.tableName,
|
|
130
|
+
Key: row.key,
|
|
131
|
+
...row.guard,
|
|
132
|
+
}, request), deps.retry);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
const rejection = error;
|
|
136
|
+
if (!(0, idempotent_write_js_1.isConditionalCheckFailed)(rejection))
|
|
137
|
+
throw rejection;
|
|
138
|
+
if ((0, idempotent_write_js_1.rejectedRow)(rejection) !== undefined) {
|
|
139
|
+
recordRefusal(deps, row, tally);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
tally.deleted += 1;
|
|
144
|
+
tally.released.push(...row.descriptors);
|
|
145
|
+
}
|
|
146
|
+
async function deleteRow(deps, row, tally) {
|
|
147
|
+
try {
|
|
148
|
+
await settleRow(deps, row, tally);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
tally.failures.push(error);
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function flushPendingDeletes(deps, rows) {
|
|
156
|
+
const tally = {
|
|
157
|
+
deleted: 0,
|
|
158
|
+
refused: 0,
|
|
159
|
+
refusedUnits: [],
|
|
160
|
+
failures: [],
|
|
161
|
+
released: [],
|
|
162
|
+
};
|
|
163
|
+
try {
|
|
164
|
+
await (0, concurrency_js_1.mapWithConcurrency)(rows, exports.DELETE_CONCURRENCY, (row) => deleteRow(deps, row, tally));
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
}
|
|
168
|
+
if (deps.offloader) {
|
|
169
|
+
await (0, offloader_js_1.cleanUpS3Orphans)(deps.offloader, {
|
|
170
|
+
keys: (0, codec_js_1.collectS3Keys)(tally.released),
|
|
171
|
+
operation: deps.operation,
|
|
172
|
+
logger: deps.logger,
|
|
173
|
+
scope: deps.scope,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return tally;
|
|
177
|
+
}
|