@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
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.searchItems = searchItems;
|
|
4
|
+
const truncate_js_1 = require("../../shared/logging/truncate.js");
|
|
5
|
+
const semantic_search_js_1 = require("../internal/semantic-search.js");
|
|
6
|
+
const table_search_js_1 = require("../internal/table-search.js");
|
|
7
|
+
const vector_index_js_1 = require("../internal/vector-index.js");
|
|
8
|
+
async function searchItems(context, search, signal) {
|
|
9
|
+
const { offset, limit } = search;
|
|
10
|
+
if (limit === 0)
|
|
11
|
+
return [];
|
|
12
|
+
if (search.query && (0, vector_index_js_1.hasVectorBackend)(context)) {
|
|
13
|
+
const ranked = await (0, vector_index_js_1.searchViaBackend)(context, search, signal);
|
|
14
|
+
return ranked.slice(offset, offset + limit);
|
|
15
|
+
}
|
|
16
|
+
if (!search.query || !context.index) {
|
|
17
|
+
const page = await (0, table_search_js_1.collectCandidates)(context, search, { kind: 'page', need: offset + limit }, signal);
|
|
18
|
+
return page.map(({ item }) => ({ ...item, score: undefined })).slice(offset, offset + limit);
|
|
19
|
+
}
|
|
20
|
+
const candidates = await (0, table_search_js_1.collectCandidates)(context, search, { kind: 'semantic', cap: context.maxSearchCandidates }, signal);
|
|
21
|
+
const queryVector = await context.index.embeddings.embedQuery(search.query);
|
|
22
|
+
(0, semantic_search_js_1.assertVectorDims)(context.index, queryVector, 'query');
|
|
23
|
+
const ranked = (0, table_search_js_1.rankInMemory)(candidates, queryVector, context.maxSearchCandidates, (count) => context.logger.warn('search: some candidates carry an embedding of a different dimension than the query and ' +
|
|
24
|
+
'were ranked unscored; re-embed them with reconcileVectorIndex or a re-put', { namespacePrefix: (0, truncate_js_1.truncateLabelsForLog)(search.namespacePrefix), count }));
|
|
25
|
+
return ranked.slice(offset, offset + limit);
|
|
26
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides how a batch runs: every read first, against the state the batch found,
|
|
3
|
+
* then one write per item, concurrently within each phase.
|
|
4
|
+
*
|
|
5
|
+
* That is how the reference store evaluates a batch — a get, a search or a
|
|
6
|
+
* listing is answered as the batch found things, and the puts are applied
|
|
7
|
+
* afterwards, the last one per item winning — so a graph developed against it
|
|
8
|
+
* gets the same answers here, and two tasks of one superstep that touch the
|
|
9
|
+
* same item get answers that do not depend on which of them was enqueued
|
|
10
|
+
* first. The operations of one phase share the call's one decode budget,
|
|
11
|
+
* divided between them, so a batch of concurrent searches costs no more memory
|
|
12
|
+
* than a single one.
|
|
13
|
+
*/
|
|
14
|
+
import type { ParsedOperation } from './parse.js';
|
|
15
|
+
/** The two phases of a batch: the indices of its reads, and of the one write kept per item. */
|
|
16
|
+
export interface BatchPlan {
|
|
17
|
+
readonly reads: number[];
|
|
18
|
+
readonly writes: number[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Split a batch into the reads it answers first and the writes it applies
|
|
22
|
+
* afterwards.
|
|
23
|
+
*
|
|
24
|
+
* Accepts: `operations` — in caller order.
|
|
25
|
+
*
|
|
26
|
+
* Returns: the indices of every get, search and listing, in caller order, and
|
|
27
|
+
* the index of the last put or delete addressing each item, in caller order.
|
|
28
|
+
* An earlier write to the same item is superseded before it is sent: the
|
|
29
|
+
* reference applies only the last put per key, and sending both would race
|
|
30
|
+
* two compare-and-swaps for an outcome the batch has already decided.
|
|
31
|
+
*
|
|
32
|
+
* Throws: nothing.
|
|
33
|
+
*/
|
|
34
|
+
export declare function planBatch(operations: readonly ParsedOperation[]): BatchPlan;
|
|
35
|
+
/**
|
|
36
|
+
* Run a batch: its reads concurrently, at most `limit` in flight, then its
|
|
37
|
+
* writes the same way. Results come back in operation order.
|
|
38
|
+
*
|
|
39
|
+
* Accepts: `operations` — in caller order. `dispatch` — handed each operation
|
|
40
|
+
* and its share of the budget: `limit` divided by the operations its phase
|
|
41
|
+
* keeps in flight, and never less than one. `limit` — operations in flight
|
|
42
|
+
* within one phase.
|
|
43
|
+
*
|
|
44
|
+
* Returns: the results in operation order, not completion order; a write
|
|
45
|
+
* superseded by a later one to the same item answers `null`, as the write
|
|
46
|
+
* that was sent does, without having been sent.
|
|
47
|
+
*
|
|
48
|
+
* Throws: the first failure. Any failure rejects the whole batch: no operation
|
|
49
|
+
* in a later phase starts, the ones already in flight settle, and that first
|
|
50
|
+
* error is the one thrown.
|
|
51
|
+
*
|
|
52
|
+
* Guarantees: every read sees the state before any of the batch's writes, and
|
|
53
|
+
* the operations of one call decode at most `limit` payloads at once between
|
|
54
|
+
* them, which is what `readConcurrency`'s documented memory ceiling assumes.
|
|
55
|
+
*/
|
|
56
|
+
export declare function runBatch<R>(operations: readonly ParsedOperation[], dispatch: (operation: ParsedOperation, readConcurrency: number) => Promise<R>, limit?: number): Promise<(R | null)[]>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.planBatch = planBatch;
|
|
4
|
+
exports.runBatch = runBatch;
|
|
5
|
+
const concurrency_js_1 = require("../../shared/concurrency.js");
|
|
6
|
+
function itemOf(address) {
|
|
7
|
+
return JSON.stringify([address.namespace, address.key]);
|
|
8
|
+
}
|
|
9
|
+
function planBatch(operations) {
|
|
10
|
+
const reads = [];
|
|
11
|
+
const lastWrite = new Map();
|
|
12
|
+
operations.forEach((op, index) => {
|
|
13
|
+
if (op.kind === 'put' || op.kind === 'delete')
|
|
14
|
+
lastWrite.set(itemOf(op.address), index);
|
|
15
|
+
else
|
|
16
|
+
reads.push(index);
|
|
17
|
+
});
|
|
18
|
+
return { reads, writes: [...lastWrite.values()].sort((a, b) => a - b) };
|
|
19
|
+
}
|
|
20
|
+
async function runBatch(operations, dispatch, limit = concurrency_js_1.DEFAULT_READ_CONCURRENCY) {
|
|
21
|
+
const results = operations.map(() => null);
|
|
22
|
+
const { reads, writes } = planBatch(operations);
|
|
23
|
+
for (const phase of [reads, writes]) {
|
|
24
|
+
if (phase.length === 0)
|
|
25
|
+
continue;
|
|
26
|
+
const share = Math.max(1, Math.floor(limit / Math.min(limit, phase.length)));
|
|
27
|
+
await (0, concurrency_js_1.mapWithConcurrency)(phase, limit, async (index) => {
|
|
28
|
+
results[index] = await dispatch(operations[index], share);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return results;
|
|
32
|
+
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Hides the store's filter grammar.
|
|
3
3
|
*
|
|
4
4
|
* Which operators a search filter accepts, how each compares a stored field —
|
|
5
|
-
* ordered comparisons only between like-typed values, an absent field
|
|
6
|
-
*
|
|
7
|
-
* here, the same way whichever search path runs.
|
|
5
|
+
* ordered comparisons only between like-typed values, an absent field
|
|
6
|
+
* satisfying only `$ne` and `$nin` — and whether an item passes a search's
|
|
7
|
+
* optional filter are decided here, the same way whichever search path runs.
|
|
8
8
|
*/
|
|
9
9
|
import type { Item } from '@langchain/langgraph-checkpoint';
|
|
10
10
|
/** A JSON value stored in an item or supplied in a filter. */
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.matchesStoreFilter = matchesStoreFilter;
|
|
4
|
+
exports.passesFilter = passesFilter;
|
|
5
|
+
const node_util_1 = require("node:util");
|
|
6
|
+
function orderOf(actual, expected) {
|
|
7
|
+
if (actual < expected)
|
|
8
|
+
return -1;
|
|
9
|
+
if (actual > expected)
|
|
10
|
+
return 1;
|
|
11
|
+
return actual === expected ? 0 : undefined;
|
|
12
|
+
}
|
|
13
|
+
function testOrder(order, test) {
|
|
14
|
+
return order !== undefined && test(order);
|
|
15
|
+
}
|
|
16
|
+
function compareOrdered(actual, expected, test) {
|
|
17
|
+
if (typeof actual === 'number' && typeof expected === 'number') {
|
|
18
|
+
return testOrder(orderOf(actual, expected), test);
|
|
19
|
+
}
|
|
20
|
+
if (typeof actual === 'string' && typeof expected === 'string') {
|
|
21
|
+
return testOrder(orderOf(actual, expected), test);
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
function equalValues(actual, expected) {
|
|
26
|
+
if (typeof actual === 'number' && typeof expected === 'number') {
|
|
27
|
+
return actual === expected || (Number.isNaN(actual) && Number.isNaN(expected));
|
|
28
|
+
}
|
|
29
|
+
return (0, node_util_1.isDeepStrictEqual)(actual, expected);
|
|
30
|
+
}
|
|
31
|
+
const COMPARATORS = {
|
|
32
|
+
$eq: (actual, expected) => equalValues(actual, expected),
|
|
33
|
+
$ne: (actual, expected) => !equalValues(actual, expected),
|
|
34
|
+
$gt: (actual, expected) => compareOrdered(actual, expected, (order) => order > 0),
|
|
35
|
+
$gte: (actual, expected) => compareOrdered(actual, expected, (order) => order >= 0),
|
|
36
|
+
$lt: (actual, expected) => compareOrdered(actual, expected, (order) => order < 0),
|
|
37
|
+
$lte: (actual, expected) => compareOrdered(actual, expected, (order) => order <= 0),
|
|
38
|
+
$in: (actual, expected) => Array.isArray(expected) ? expected.some((candidate) => equalValues(actual, candidate)) : false,
|
|
39
|
+
$nin: (actual, expected) => Array.isArray(expected) ? !expected.some((candidate) => equalValues(actual, candidate)) : true,
|
|
40
|
+
};
|
|
41
|
+
function isOperatorObject(condition) {
|
|
42
|
+
return (typeof condition === 'object' &&
|
|
43
|
+
condition !== null &&
|
|
44
|
+
!Array.isArray(condition) &&
|
|
45
|
+
Object.keys(condition).every((key) => Object.prototype.hasOwnProperty.call(COMPARATORS, key)));
|
|
46
|
+
}
|
|
47
|
+
function matchesCondition(actual, condition) {
|
|
48
|
+
if (!isOperatorObject(condition))
|
|
49
|
+
return equalValues(actual, condition);
|
|
50
|
+
return Object.entries(condition).every(([operator, expected]) => COMPARATORS[operator](actual, expected));
|
|
51
|
+
}
|
|
52
|
+
function ownField(item, field) {
|
|
53
|
+
if (item === null || typeof item !== 'object')
|
|
54
|
+
return undefined;
|
|
55
|
+
return Object.hasOwn(item, field) ? item[field] : undefined;
|
|
56
|
+
}
|
|
57
|
+
function matchesStoreFilter(value, filter) {
|
|
58
|
+
return Object.entries(filter).every(([field, condition]) => matchesCondition(ownField(value, field), condition));
|
|
59
|
+
}
|
|
60
|
+
function passesFilter(item, filter) {
|
|
61
|
+
if (!filter)
|
|
62
|
+
return true;
|
|
63
|
+
return matchesStoreFilter(item.value, filter);
|
|
64
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides what a single read counts as absent, and how it outlives an overwrite.
|
|
3
|
+
*
|
|
4
|
+
* A get reads its row strongly consistently and answers `null` alike for a
|
|
5
|
+
* missing row, an expired one and a row this adapter does not own. When the
|
|
6
|
+
* object an offloaded row names is deleted between the row read and the
|
|
7
|
+
* download, one re-read settles whether the item was replaced, removed or
|
|
8
|
+
* truly lost. A caller gets an item or `null` and never sees the race.
|
|
9
|
+
*/
|
|
10
|
+
import type { Item } from '@langchain/langgraph-checkpoint';
|
|
11
|
+
import type { StoreAddress } from './parse.js';
|
|
12
|
+
import { type StoreItemRow } from './rows.js';
|
|
13
|
+
import type { StoreContext } from './setup.js';
|
|
14
|
+
/** A row and the item it decodes to, read together so a caller can use the row's own fields. */
|
|
15
|
+
export interface ReadCandidate {
|
|
16
|
+
readonly row: StoreItemRow;
|
|
17
|
+
readonly item: Item;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The item a row denotes, recovering from a concurrent overwrite of that row.
|
|
21
|
+
*
|
|
22
|
+
* An offloaded item can lose a race with a concurrent overwrite: between the
|
|
23
|
+
* row read and the S3 download the writer commits a new descriptor and deletes
|
|
24
|
+
* the object this read was about to fetch. That surfaces as `NoSuchKey` — or
|
|
25
|
+
* as a 403 `AccessDenied` for a role without `s3:ListBucket`, which S3 answers
|
|
26
|
+
* for a missing key instead — and one strongly-consistent re-read settles it —
|
|
27
|
+
* the row now points at the new object (that is the answer), is gone, or
|
|
28
|
+
* still points at the same missing object (a genuine loss, rethrown) — and a
|
|
29
|
+
* refused download on an unchanged row is rethrown the same way, since it is
|
|
30
|
+
* then a real permission failure. A row the overwrite left with no descriptor
|
|
31
|
+
* at all is a replacement like any other: it is decoded, and refused by its
|
|
32
|
+
* own coded error. Any other download failure propagates.
|
|
33
|
+
*
|
|
34
|
+
* Every reader that downloads a row it read earlier takes this route: `get`,
|
|
35
|
+
* whose window is one read; a search, which reads a whole page before it
|
|
36
|
+
* downloads anything; and a reconcile, which reads a whole namespace. A
|
|
37
|
+
* search that failed on it failed for an item that is live and readable a
|
|
38
|
+
* moment later.
|
|
39
|
+
*
|
|
40
|
+
* Accepts: `record` — a row read moments ago, whose object may since have been
|
|
41
|
+
* released. `signal` — aborts the download and the re-read.
|
|
42
|
+
*
|
|
43
|
+
* Returns: the row that was finally decoded and its item — the one given, or
|
|
44
|
+
* the one the overwrite left — or `undefined` when the re-read finds the row
|
|
45
|
+
* gone or expired.
|
|
46
|
+
*
|
|
47
|
+
* Throws: as {@link readStoreItem}, for the row finally decoded; the
|
|
48
|
+
* download's own failure when the re-read finds the same row.
|
|
49
|
+
*/
|
|
50
|
+
export declare function readCandidate(context: StoreContext, record: StoreItemRow, signal?: AbortSignal): Promise<ReadCandidate | undefined>;
|
|
51
|
+
/**
|
|
52
|
+
* Retrieve a single item by namespace and key (strongly consistent), or null.
|
|
53
|
+
*
|
|
54
|
+
* A download that finds its object released by a concurrent overwrite is
|
|
55
|
+
* settled by {@link readCandidate}.
|
|
56
|
+
*
|
|
57
|
+
* Accepts: `address` — parsed; no check is repeated here. `signal` — aborts
|
|
58
|
+
* the reads.
|
|
59
|
+
*
|
|
60
|
+
* Returns: the item, or `null` for one that does not exist, has expired, or
|
|
61
|
+
* whose key holds a row this adapter does not own — which includes a row whose
|
|
62
|
+
* `createdAt` or `updatedAt` is not the string this package writes there, since
|
|
63
|
+
* an item is reported with both. The answers are one on purpose: a caller
|
|
64
|
+
* cannot act on the difference, and reporting a foreign row would leak that a
|
|
65
|
+
* shared table holds one.
|
|
66
|
+
*
|
|
67
|
+
* Throws: `VALIDATION` naming — for a row whose descriptor is not one —
|
|
68
|
+
* `descriptor`; `FORMAT_UNSUPPORTED` for
|
|
69
|
+
* a row, or a payload, written by a newer version, which is *not* reported as
|
|
70
|
+
* absent — hiding an item that exists is worse than failing; `PAYLOAD_CORRUPT`
|
|
71
|
+
* or the download's own error for a payload that cannot be read; `ABORTED`
|
|
72
|
+
* when the signal fires.
|
|
73
|
+
*
|
|
74
|
+
* Guarantees: strongly consistent — an item just written is always seen, and
|
|
75
|
+
* the ttl is honoured here rather than waited for.
|
|
76
|
+
*/
|
|
77
|
+
export declare function getItem(context: StoreContext, address: StoreAddress, signal?: AbortSignal): Promise<Item | null>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readCandidate = readCandidate;
|
|
4
|
+
exports.getItem = getItem;
|
|
5
|
+
const clock_js_1 = require("../../shared/clock.js");
|
|
6
|
+
const codec_js_1 = require("../../shared/codec/codec.js");
|
|
7
|
+
const retry_js_1 = require("../../shared/dynamodb/retry.js");
|
|
8
|
+
const table_schema_js_1 = require("../../shared/dynamodb/table-schema.js");
|
|
9
|
+
const rows_js_1 = require("./rows.js");
|
|
10
|
+
async function readRow(context, namespace, key, signal) {
|
|
11
|
+
const result = await (0, retry_js_1.withDynamoDBRetry)((request) => context.client.get({
|
|
12
|
+
TableName: context.tableName,
|
|
13
|
+
Key: (0, rows_js_1.itemRowKey)({ namespace, key }),
|
|
14
|
+
ConsistentRead: true,
|
|
15
|
+
}, request), (0, retry_js_1.retryFor)(context, signal));
|
|
16
|
+
if (!result.Item)
|
|
17
|
+
return undefined;
|
|
18
|
+
const record = (0, rows_js_1.parseWholeStoreRow)(result.Item);
|
|
19
|
+
if (!record) {
|
|
20
|
+
context.logger.warn('store.get: ignored a row that is not a store item', {
|
|
21
|
+
partitionKey: (0, rows_js_1.partitionKey)(namespace),
|
|
22
|
+
sortKey: (0, rows_js_1.sortKey)(namespace, key),
|
|
23
|
+
});
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
return (0, table_schema_js_1.isExpiredRow)(record, (0, clock_js_1.nowSeconds)()) ? undefined : record;
|
|
27
|
+
}
|
|
28
|
+
function sameObject(read, reread) {
|
|
29
|
+
const fresh = reread.value;
|
|
30
|
+
if (!fresh)
|
|
31
|
+
return false;
|
|
32
|
+
return (read.value.location === codec_js_1.PayloadLocation.S3 &&
|
|
33
|
+
fresh.location === codec_js_1.PayloadLocation.S3 &&
|
|
34
|
+
read.value.s3Key === fresh.s3Key);
|
|
35
|
+
}
|
|
36
|
+
async function readCandidate(context, record, signal) {
|
|
37
|
+
try {
|
|
38
|
+
return { row: record, item: await (0, rows_js_1.readStoreItem)(context, record, signal) };
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (!(0, codec_js_1.isMissingObjectError)(error) && !(0, codec_js_1.isRefusedObjectError)(error))
|
|
42
|
+
throw error;
|
|
43
|
+
const fresh = await readRow(context, record.namespace, record.key, signal);
|
|
44
|
+
if (!fresh)
|
|
45
|
+
return undefined;
|
|
46
|
+
if (sameObject(record, fresh))
|
|
47
|
+
throw error;
|
|
48
|
+
return { row: fresh, item: await (0, rows_js_1.readStoreItem)(context, fresh, signal) };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function getItem(context, address, signal) {
|
|
52
|
+
const { namespace, key } = address;
|
|
53
|
+
const record = await readRow(context, namespace, key, signal);
|
|
54
|
+
if (!record)
|
|
55
|
+
return null;
|
|
56
|
+
const read = await readCandidate(context, record, signal);
|
|
57
|
+
return read === undefined ? null : read.item;
|
|
58
|
+
}
|
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
* anything is released. Without an offloader there is no object to protect,
|
|
11
11
|
* and a put is a plain write.
|
|
12
12
|
*/
|
|
13
|
-
import { type WriteVerdict } from '../../shared/dynamodb/idempotent-write';
|
|
14
|
-
import type
|
|
15
|
-
import
|
|
16
|
-
import type
|
|
13
|
+
import { type WriteVerdict } from '../../shared/dynamodb/idempotent-write.js';
|
|
14
|
+
import { type RowKey } from '../../shared/dynamodb/table-schema.js';
|
|
15
|
+
import type { StoreAddress } from './parse.js';
|
|
16
|
+
import { type ExistingRowMeta, type StoreItemRow } from './rows.js';
|
|
17
|
+
import type { StoreContext } from './setup.js';
|
|
17
18
|
/**
|
|
18
19
|
* Delete the item and, when a vector backend is configured, drop its vector.
|
|
19
20
|
*
|
|
@@ -99,6 +100,20 @@ import type { StoreContext } from './setup';
|
|
|
99
100
|
* comes back unnoticed.
|
|
100
101
|
*/
|
|
101
102
|
export declare function deleteStoreItem(context: StoreContext, address: StoreAddress): Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* Refuse a row DynamoDB would refuse for its size.
|
|
105
|
+
*
|
|
106
|
+
* Accepts: `record` — the fully built row, its payload encoded and its inline
|
|
107
|
+
* vectors attached.
|
|
108
|
+
*
|
|
109
|
+
* Returns: nothing: the row is kept under its declared type, and this checks it.
|
|
110
|
+
*
|
|
111
|
+
* Throws: `VALIDATION` when the row would pass DynamoDB's 400 KB item limit —
|
|
112
|
+
* naming `index` when the row fits without its vectors, since the vectors are
|
|
113
|
+
* what pushed it over (index fewer fields, embed with fewer dimensions, or
|
|
114
|
+
* configure a `vectorBackend`), and `value` otherwise.
|
|
115
|
+
*/
|
|
116
|
+
export declare function assertRowFits(record: StoreItemRow): void;
|
|
102
117
|
/**
|
|
103
118
|
* Put the record and clean up whichever side is now dead.
|
|
104
119
|
*
|
|
@@ -109,19 +124,25 @@ export declare function deleteStoreItem(context: StoreContext, address: StoreAdd
|
|
|
109
124
|
* delete exactly the payload it superseded rather than a descriptor a racer may
|
|
110
125
|
* already have replaced.
|
|
111
126
|
*
|
|
112
|
-
* Every
|
|
113
|
-
* `putWithRevisionSwap` only re-reads
|
|
114
|
-
*
|
|
115
|
-
*
|
|
127
|
+
* Every failed put arrives after at least one write was issued —
|
|
128
|
+
* `putWithRevisionSwap` only re-reads after a rejection — so none of them
|
|
129
|
+
* proves a non-commit on its own: a put can commit server-side and lose its
|
|
130
|
+
* response, and a `ConditionalCheckFailedException` is as consistent with
|
|
116
131
|
* hitting the row this call just wrote as with a competitor's win. The row is
|
|
117
|
-
* therefore read back (
|
|
118
|
-
* confirmed `'not-landed'` deletes this record's own object; a confirmed
|
|
119
|
-
* `'landed'` cleans up the
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
132
|
+
* therefore read back ({@link settleFailedPut}) before anything is deleted.
|
|
133
|
+
* Only a confirmed `'not-landed'` deletes this record's own object; a confirmed
|
|
134
|
+
* `'landed'` cleans up what the landed write replaced — the observation the
|
|
135
|
+
* attempt in flight was pinned to, which after a re-pin is a competitor's, not
|
|
136
|
+
* what this call first read — and swallows the error; an `'unverified'` read
|
|
137
|
+
* deletes nothing and rethrows, leaking one object at worst rather than
|
|
138
|
+
* stranding a live row pointing at a deleted one. So does a read that finds
|
|
139
|
+
* nothing, or finds another revision, after a write that DynamoDB may still
|
|
140
|
+
* apply: any attempt of the budget that got no answer, that DynamoDB answered
|
|
141
|
+
* as still in progress (`TransactionInProgressException`) or that failed with a
|
|
142
|
+
* server error (5xx). The verification compares the per-call `rev`, so an
|
|
143
|
+
* inline record is verified too: otherwise a lost acknowledgement of an inline
|
|
144
|
+
* overwrite would be reported as a failure while the previous offloaded object
|
|
145
|
+
* was never cleaned.
|
|
125
146
|
*
|
|
126
147
|
* Neither release reads the row again first. The record's object is uploaded
|
|
127
148
|
* under the record's own `rev`, which no other put uses, so no row another put
|
|
@@ -134,9 +155,11 @@ export declare function deleteStoreItem(context: StoreContext, address: StoreAdd
|
|
|
134
155
|
* Returns: nothing. The row is committed and exactly one side's object, at
|
|
135
156
|
* most, has been released.
|
|
136
157
|
*
|
|
137
|
-
* Throws:
|
|
138
|
-
*
|
|
139
|
-
*
|
|
158
|
+
* Throws: `VALIDATION` naming `index` or `value` for a row over DynamoDB's
|
|
159
|
+
* item limit, before any write and after releasing this put's own upload;
|
|
160
|
+
* whatever the write, or the swap's re-read after a rejection, throws, unless
|
|
161
|
+
* the verification proves the write landed after all — in which case the error
|
|
162
|
+
* is swallowed and the cleanup runs as on the success path.
|
|
140
163
|
*
|
|
141
164
|
* Guarantees: this record's own object is released only after a read proves
|
|
142
165
|
* the write did not land, and a superseded object only after this record is
|
|
@@ -146,9 +169,22 @@ export declare function deleteStoreItem(context: StoreContext, address: StoreAdd
|
|
|
146
169
|
* deletes.
|
|
147
170
|
*/
|
|
148
171
|
export declare function persistRow(context: StoreContext, record: StoreItemRow, existing: ExistingRowMeta): Promise<void>;
|
|
172
|
+
/**
|
|
173
|
+
* How a revision swap ended, settled rather than thrown: what its committed
|
|
174
|
+
* write superseded, or the failure together with the observation the attempt in
|
|
175
|
+
* flight was pinned to — what that write replaced, if it landed after all.
|
|
176
|
+
*/
|
|
177
|
+
type SwapOutcome = {
|
|
178
|
+
ok: true;
|
|
179
|
+
superseded: ExistingRowMeta;
|
|
180
|
+
} | {
|
|
181
|
+
ok: false;
|
|
182
|
+
reason: Error;
|
|
183
|
+
pinned: ExistingRowMeta;
|
|
184
|
+
};
|
|
149
185
|
/**
|
|
150
186
|
* Commit `record`, re-reading and retrying while another writer holds the row,
|
|
151
|
-
* and
|
|
187
|
+
* and report the state this write actually superseded — the only descriptor
|
|
152
188
|
* safe to delete afterwards.
|
|
153
189
|
*
|
|
154
190
|
* Without the swap both racers read the same previous descriptor, both commit,
|
|
@@ -169,27 +205,32 @@ export declare function persistRow(context: StoreContext, record: StoreItemRow,
|
|
|
169
205
|
* and claim a race it never entered.
|
|
170
206
|
*
|
|
171
207
|
* On exhaustion the write proceeds unconditionally and warns. That is
|
|
172
|
-
* deliberate: the fallback
|
|
173
|
-
*
|
|
174
|
-
*
|
|
208
|
+
* deliberate: the fallback costs at most one orphaned object, reclaimed by a
|
|
209
|
+
* lifecycle rule, so pathological contention degrades instead of turning a
|
|
210
|
+
* working put into an error. `createdAt` is refreshed from
|
|
175
211
|
* each re-read so a row created by whoever won keeps its true creation time.
|
|
176
212
|
*
|
|
177
213
|
* Accepts: `record` — the row to commit, carrying this call's own `rev`.
|
|
178
214
|
* `existing` — what the caller read before encoding, used as the first pin; an
|
|
179
215
|
* `exists: false` observation pins "no row", so a creation races correctly too.
|
|
180
216
|
*
|
|
181
|
-
* Returns: the state this write actually superseded — the
|
|
182
|
-
* delete — which is the last observation the winning put
|
|
183
|
-
* this record's own value.
|
|
217
|
+
* Returns: on success, the state this write actually superseded — the
|
|
218
|
+
* descriptor safe to delete — which is the last observation the winning put
|
|
219
|
+
* was pinned to, never this record's own value. On failure — a put failing
|
|
220
|
+
* other than on its guard, or a re-read failing after a rejection — the error,
|
|
221
|
+
* with the observation the failed attempt was pinned to. After a re-pin that is
|
|
222
|
+
* a competitor's row, not `existing`: the competitor already replaced and
|
|
223
|
+
* released `existing`, so a write that landed without an answer superseded the
|
|
224
|
+
* competitor's object, and only this observation names it.
|
|
184
225
|
*
|
|
185
|
-
* Throws:
|
|
186
|
-
*
|
|
226
|
+
* Throws: nothing; a failure is reported in the outcome, because only the
|
|
227
|
+
* swap knows which observation the failed attempt was pinned to.
|
|
187
228
|
*
|
|
188
229
|
* Guarantees: at most {@link OVERWRITE_CAS_MAX_ATTEMPTS} conditional puts, and
|
|
189
230
|
* a re-read only when the rejection did not already carry the row that caused
|
|
190
231
|
* it.
|
|
191
232
|
*/
|
|
192
|
-
export declare function putWithRevisionSwap(context: StoreContext, record: StoreItemRow, existing: ExistingRowMeta): Promise<
|
|
233
|
+
export declare function putWithRevisionSwap(context: StoreContext, record: StoreItemRow, existing: ExistingRowMeta): Promise<SwapOutcome>;
|
|
193
234
|
/**
|
|
194
235
|
* Whether `error` is a spent retry budget.
|
|
195
236
|
*
|
|
@@ -223,8 +264,7 @@ export declare function isRetryExhausted(error: Error): boolean;
|
|
|
223
264
|
* Throws: nothing — a failed verification is `'unverified'`, which is an
|
|
224
265
|
* answer, not an error.
|
|
225
266
|
*/
|
|
226
|
-
export declare function verifyWriteLanded(context: StoreContext, record: {
|
|
227
|
-
PK: string;
|
|
228
|
-
SK: string;
|
|
267
|
+
export declare function verifyWriteLanded(context: StoreContext, record: RowKey & {
|
|
229
268
|
rev?: string;
|
|
230
269
|
}): Promise<WriteVerdict>;
|
|
270
|
+
export {};
|