@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,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.S3Offloader = exports.S3_DELETE_BATCH_MAX = exports.DEFAULT_MAX_S3_DOWNLOAD_BYTES = exports.DEFAULT_S3_SSE = exports.DEFAULT_S3_THRESHOLD_BYTES = void 0;
|
|
4
|
+
exports.uploadObject = uploadObject;
|
|
5
|
+
exports.downloadObject = downloadObject;
|
|
6
|
+
exports.oversizedObjectError = oversizedObjectError;
|
|
7
|
+
exports.readBodyBounded = readBodyBounded;
|
|
8
|
+
exports.deleteObjects = deleteObjects;
|
|
9
|
+
exports.backlinkMetadata = backlinkMetadata;
|
|
10
|
+
exports.cleanUpS3Orphans = cleanUpS3Orphans;
|
|
11
|
+
const abort_js_1 = require("../../dynamodb/abort.js");
|
|
12
|
+
const retry_js_1 = require("../../dynamodb/retry.js");
|
|
13
|
+
const base_error_js_1 = require("../../errors/base-error.js");
|
|
14
|
+
const classify_js_1 = require("../../errors/classify.js");
|
|
15
|
+
const error_code_js_1 = require("../../errors/error-code.js");
|
|
16
|
+
const errors_js_1 = require("../../errors/errors.js");
|
|
17
|
+
const logger_js_1 = require("../../logging/logger.js");
|
|
18
|
+
const secret_patterns_js_1 = require("../../logging/secret-patterns.js");
|
|
19
|
+
const truncate_js_1 = require("../../logging/truncate.js");
|
|
20
|
+
const client_js_1 = require("./client.js");
|
|
21
|
+
const config_js_1 = require("./config.js");
|
|
22
|
+
const lifecycle_js_1 = require("./lifecycle.js");
|
|
23
|
+
exports.DEFAULT_S3_THRESHOLD_BYTES = 350 * 1024;
|
|
24
|
+
exports.DEFAULT_S3_SSE = 'AES256';
|
|
25
|
+
const S3_MAX_ATTEMPTS = 3;
|
|
26
|
+
exports.DEFAULT_MAX_S3_DOWNLOAD_BYTES = 50 * 1024 * 1024;
|
|
27
|
+
exports.S3_DELETE_BATCH_MAX = 1000;
|
|
28
|
+
class S3Offloader {
|
|
29
|
+
clientPromise;
|
|
30
|
+
resolvedClient;
|
|
31
|
+
destroyed = false;
|
|
32
|
+
bucketName;
|
|
33
|
+
keyPrefix;
|
|
34
|
+
thresholdBytes;
|
|
35
|
+
sse;
|
|
36
|
+
sseKmsKeyId;
|
|
37
|
+
maxDownloadBytes;
|
|
38
|
+
config;
|
|
39
|
+
logger;
|
|
40
|
+
constructor(config, logger = logger_js_1.SILENT_LOGGER) {
|
|
41
|
+
this.config = config;
|
|
42
|
+
this.logger = logger;
|
|
43
|
+
this.bucketName = config.bucketName;
|
|
44
|
+
this.keyPrefix = config.keyPrefix ?? config_js_1.DEFAULT_S3_KEY_PREFIX;
|
|
45
|
+
this.thresholdBytes = config.thresholdBytes ?? exports.DEFAULT_S3_THRESHOLD_BYTES;
|
|
46
|
+
this.sse = config.serverSideEncryption ?? exports.DEFAULT_S3_SSE;
|
|
47
|
+
this.sseKmsKeyId = config.sseKmsKeyId;
|
|
48
|
+
this.maxDownloadBytes = config.maxDownloadBytes ?? exports.DEFAULT_MAX_S3_DOWNLOAD_BYTES;
|
|
49
|
+
void (0, client_js_1.loadS3Sdk)().catch(() => undefined);
|
|
50
|
+
}
|
|
51
|
+
getClient() {
|
|
52
|
+
if (!this.clientPromise) {
|
|
53
|
+
const cfg = this.config.clientConfig ?? {};
|
|
54
|
+
this.clientPromise = (this.config.createS3Client
|
|
55
|
+
? Promise.resolve(this.config.createS3Client((0, client_js_1.withS3ClientDefaults)(cfg)))
|
|
56
|
+
: (0, client_js_1.createDefaultS3Client)(cfg)).then((client) => {
|
|
57
|
+
this.resolvedClient = client;
|
|
58
|
+
if (this.destroyed)
|
|
59
|
+
client.destroy();
|
|
60
|
+
return client;
|
|
61
|
+
}, (error) => {
|
|
62
|
+
this.clientPromise = undefined;
|
|
63
|
+
throw error;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return this.clientPromise.catch((error) => {
|
|
67
|
+
throw (0, base_error_js_1.copyForCaller)(error);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
shouldOffload(data) {
|
|
71
|
+
return data.length >= this.thresholdBytes;
|
|
72
|
+
}
|
|
73
|
+
buildKey(parts, objectId) {
|
|
74
|
+
return (0, config_js_1.buildS3Key)(this.keyPrefix, parts, objectId);
|
|
75
|
+
}
|
|
76
|
+
getKeyPrefix() {
|
|
77
|
+
return this.keyPrefix;
|
|
78
|
+
}
|
|
79
|
+
ownsKey(key, scope) {
|
|
80
|
+
return (0, config_js_1.isKeyInScope)(key, this.keyPrefix, scope);
|
|
81
|
+
}
|
|
82
|
+
assertOwnedKey(key, scope) {
|
|
83
|
+
(0, config_js_1.assertKeyInScope)(key, this.keyPrefix, scope);
|
|
84
|
+
}
|
|
85
|
+
retryReporter(operation) {
|
|
86
|
+
return ({ attempt, delayMs, error }) => (0, logger_js_1.absorbLoggerFailure)(() => this.logger.debug('retrying after a transient error', {
|
|
87
|
+
attempt,
|
|
88
|
+
delayMs,
|
|
89
|
+
operation,
|
|
90
|
+
error: (0, truncate_js_1.truncateForLog)((0, base_error_js_1.failureLabel)(error)),
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
async upload(key, data, row, signal) {
|
|
94
|
+
if (data.length > this.maxDownloadBytes) {
|
|
95
|
+
throw (0, errors_js_1.validationError)(`payload of ${data.length} bytes exceeds s3.maxDownloadBytes (${this.maxDownloadBytes}), ` +
|
|
96
|
+
'so no reader configured like this adapter could download it; raise ' +
|
|
97
|
+
's3.maxDownloadBytes or store a smaller value', 'payload');
|
|
98
|
+
}
|
|
99
|
+
await uploadObject(await this.getClient(), {
|
|
100
|
+
bucket: this.bucketName,
|
|
101
|
+
key,
|
|
102
|
+
data,
|
|
103
|
+
serverSideEncryption: this.sse,
|
|
104
|
+
sseKmsKeyId: this.sseKmsKeyId,
|
|
105
|
+
metadata: backlinkMetadata(row),
|
|
106
|
+
signal,
|
|
107
|
+
onRetry: this.retryReporter('upload'),
|
|
108
|
+
});
|
|
109
|
+
return key;
|
|
110
|
+
}
|
|
111
|
+
async download(key, signal) {
|
|
112
|
+
return downloadObject(await this.getClient(), { bucket: this.bucketName, key, maxBytes: this.maxDownloadBytes }, signal, this.retryReporter('download'));
|
|
113
|
+
}
|
|
114
|
+
async deleteBatch(keys) {
|
|
115
|
+
return deleteObjects(await this.getClient(), this.bucketName, keys);
|
|
116
|
+
}
|
|
117
|
+
async ensureLifecycleRule(ttlDays, logger) {
|
|
118
|
+
return (0, lifecycle_js_1.ensureLifecycleRule)(await this.getClient(), { bucket: this.bucketName, prefix: this.keyPrefix, days: ttlDays }, logger);
|
|
119
|
+
}
|
|
120
|
+
destroy() {
|
|
121
|
+
this.destroyed = true;
|
|
122
|
+
this.resolvedClient?.destroy();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.S3Offloader = S3Offloader;
|
|
126
|
+
function rethrowIfCancelled(error) {
|
|
127
|
+
if ((0, abort_js_1.isAbortError)(error))
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
function alreadyStored(error) {
|
|
131
|
+
return (0, classify_js_1.classifyAwsError)(error) === error_code_js_1.ErrorCode.CONDITION_CONFLICT;
|
|
132
|
+
}
|
|
133
|
+
async function uploadObject(client, params) {
|
|
134
|
+
const { PutObjectCommand } = await (0, client_js_1.loadS3Sdk)();
|
|
135
|
+
try {
|
|
136
|
+
await (0, retry_js_1.withRetry)((request) => client.send(new PutObjectCommand({
|
|
137
|
+
Bucket: params.bucket,
|
|
138
|
+
Key: params.key,
|
|
139
|
+
Body: params.data,
|
|
140
|
+
ContentType: 'application/octet-stream',
|
|
141
|
+
IfNoneMatch: '*',
|
|
142
|
+
ServerSideEncryption: params.serverSideEncryption,
|
|
143
|
+
...(params.sseKmsKeyId ? { SSEKMSKeyId: params.sseKmsKeyId } : {}),
|
|
144
|
+
...(params.metadata ? { Metadata: params.metadata } : {}),
|
|
145
|
+
}), request), {
|
|
146
|
+
maxAttempts: S3_MAX_ATTEMPTS,
|
|
147
|
+
isRetryable: retry_js_1.isTransientS3Error,
|
|
148
|
+
signal: params.signal,
|
|
149
|
+
onRetry: params.onRetry,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
if (alreadyStored(error))
|
|
154
|
+
return;
|
|
155
|
+
rethrowIfCancelled(error);
|
|
156
|
+
throw new base_error_js_1.DynamoDBLangGraphError((0, secret_patterns_js_1.redactedMessage)(error), error_code_js_1.ErrorCode.S3_OFFLOAD_FAILED, {
|
|
157
|
+
operation: 'upload',
|
|
158
|
+
key: params.key,
|
|
159
|
+
...(0, classify_js_1.awsDiagnostics)((0, classify_js_1.classifiableCause)(error)),
|
|
160
|
+
}, error);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async function downloadObject(client, object, signal, onRetry) {
|
|
164
|
+
const { GetObjectCommand } = await (0, client_js_1.loadS3Sdk)();
|
|
165
|
+
const { bucket, key, maxBytes } = object;
|
|
166
|
+
try {
|
|
167
|
+
return await (0, retry_js_1.withRetry)(async (request) => {
|
|
168
|
+
const response = await client.send(new GetObjectCommand({ Bucket: bucket, Key: key }), request);
|
|
169
|
+
if (typeof response.ContentLength === 'number' && response.ContentLength > maxBytes) {
|
|
170
|
+
response.Body?.destroy?.();
|
|
171
|
+
throw oversizedObjectError(key, response.ContentLength, maxBytes);
|
|
172
|
+
}
|
|
173
|
+
if (!response.Body) {
|
|
174
|
+
throw new Error(`S3 object body is empty for key: ${(0, truncate_js_1.truncateForLog)(key)}`);
|
|
175
|
+
}
|
|
176
|
+
return readBodyBounded(response.Body, key, maxBytes);
|
|
177
|
+
}, { maxAttempts: S3_MAX_ATTEMPTS, isRetryable: retry_js_1.isTransientS3Error, signal, onRetry });
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
rethrowIfCancelled(error);
|
|
181
|
+
throw new base_error_js_1.DynamoDBLangGraphError((0, secret_patterns_js_1.redactedMessage)(error), error_code_js_1.ErrorCode.S3_OFFLOAD_FAILED, { operation: 'download', key, ...(0, classify_js_1.awsDiagnostics)((0, classify_js_1.classifiableCause)(error)) }, error);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function oversizedObjectError(key, bytes, maxBytes) {
|
|
185
|
+
return new base_error_js_1.DynamoDBLangGraphError(`S3 object ${(0, truncate_js_1.truncateForLog)(key)} exceeds the ${maxBytes}-byte maxDownloadBytes cap ` +
|
|
186
|
+
`(${bytes} bytes declared or read)`, error_code_js_1.ErrorCode.S3_OFFLOAD_FAILED, { operation: 'download', key });
|
|
187
|
+
}
|
|
188
|
+
function concat(chunks, total) {
|
|
189
|
+
const out = new Uint8Array(total);
|
|
190
|
+
let offset = 0;
|
|
191
|
+
for (const chunk of chunks) {
|
|
192
|
+
out.set(chunk, offset);
|
|
193
|
+
offset += chunk.length;
|
|
194
|
+
}
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
async function readBodyBounded(body, key, maxBytes) {
|
|
198
|
+
const streaming = body;
|
|
199
|
+
const iterate = streaming[Symbol.asyncIterator];
|
|
200
|
+
if (typeof iterate !== 'function') {
|
|
201
|
+
const whole = new Uint8Array(await body.transformToByteArray());
|
|
202
|
+
if (whole.length > maxBytes)
|
|
203
|
+
throw oversizedObjectError(key, whole.length, maxBytes);
|
|
204
|
+
return whole;
|
|
205
|
+
}
|
|
206
|
+
const chunks = [];
|
|
207
|
+
let total = 0;
|
|
208
|
+
for await (const chunk of { [Symbol.asyncIterator]: iterate.bind(streaming) }) {
|
|
209
|
+
total += chunk.length;
|
|
210
|
+
if (total > maxBytes) {
|
|
211
|
+
streaming.destroy?.();
|
|
212
|
+
throw oversizedObjectError(key, total, maxBytes);
|
|
213
|
+
}
|
|
214
|
+
chunks.push(chunk);
|
|
215
|
+
}
|
|
216
|
+
return concat(chunks, total);
|
|
217
|
+
}
|
|
218
|
+
async function deleteObjects(client, bucket, keys) {
|
|
219
|
+
if (keys.length === 0)
|
|
220
|
+
return [];
|
|
221
|
+
const { DeleteObjectsCommand } = await (0, client_js_1.loadS3Sdk)();
|
|
222
|
+
const failed = [];
|
|
223
|
+
for (let offset = 0; offset < keys.length; offset += exports.S3_DELETE_BATCH_MAX) {
|
|
224
|
+
const chunk = keys.slice(offset, offset + exports.S3_DELETE_BATCH_MAX);
|
|
225
|
+
const response = await client.send(new DeleteObjectsCommand({
|
|
226
|
+
Bucket: bucket,
|
|
227
|
+
Delete: { Objects: chunk.map((key) => ({ Key: key })), Quiet: true },
|
|
228
|
+
}));
|
|
229
|
+
for (const error of response.Errors ?? []) {
|
|
230
|
+
if (error.Key)
|
|
231
|
+
failed.push(error.Key);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return failed;
|
|
235
|
+
}
|
|
236
|
+
const PK_FIELD = 'dynamodb-pk-b64';
|
|
237
|
+
const SK_FIELD = 'dynamodb-sk-b64';
|
|
238
|
+
function backlinkMetadata(row) {
|
|
239
|
+
return { [PK_FIELD]: (0, config_js_1.encodeKeyPart)(row.pk), [SK_FIELD]: (0, config_js_1.encodeKeyPart)(row.sk) };
|
|
240
|
+
}
|
|
241
|
+
async function backoffSleep(delayMs, release) {
|
|
242
|
+
try {
|
|
243
|
+
await (0, retry_js_1.sleep)((0, retry_js_1.fullJitter)(delayMs, release.rng), release.signal);
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function ownedOnly(offloader, keys, release, scope) {
|
|
251
|
+
return keys.filter((key) => {
|
|
252
|
+
if (offloader.ownsKey(key, scope))
|
|
253
|
+
return true;
|
|
254
|
+
(0, logger_js_1.absorbLoggerFailure)(() => release.logger.warn(`${release.operation}: refusing to delete an S3 object outside this row's scope`, {
|
|
255
|
+
key: (0, truncate_js_1.truncateForLog)(key),
|
|
256
|
+
}));
|
|
257
|
+
return false;
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
function selectOrphans(offloader, release) {
|
|
261
|
+
const present = release.keys.filter((key) => typeof key === 'string' && key.length > 0);
|
|
262
|
+
return release.scope ? ownedOnly(offloader, present, release, release.scope) : present;
|
|
263
|
+
}
|
|
264
|
+
async function cleanUpS3Orphans(offloader, release) {
|
|
265
|
+
const orphans = selectOrphans(offloader, release);
|
|
266
|
+
if (orphans.length === 0)
|
|
267
|
+
return;
|
|
268
|
+
const maxAttempts = release.maxAttempts ?? S3_MAX_ATTEMPTS;
|
|
269
|
+
let delay = retry_js_1.INITIAL_BACKOFF_DELAY_MS;
|
|
270
|
+
let lastError = new Error('S3 orphan cleanup did not run');
|
|
271
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
272
|
+
try {
|
|
273
|
+
const failed = await offloader.deleteBatch(orphans);
|
|
274
|
+
if (failed.length === 0)
|
|
275
|
+
return;
|
|
276
|
+
(0, logger_js_1.absorbLoggerFailure)(() => release.logger.warn(`Some orphaned S3 objects could not be deleted after ${release.operation}; a lifecycle rule from ensureS3LifecycleRule() would sweep them, otherwise clean up manually`, { failedCount: failed.length }));
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
lastError = error;
|
|
281
|
+
if (attempt >= maxAttempts || !(0, retry_js_1.isTransientS3Error)(lastError))
|
|
282
|
+
break;
|
|
283
|
+
if (await backoffSleep(delay, release))
|
|
284
|
+
break;
|
|
285
|
+
delay = (0, retry_js_1.nextBackoffDelay)(delay);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
(0, logger_js_1.absorbLoggerFailure)(() => release.logger.warn(`Failed to clean up orphaned S3 objects after ${release.operation}; a lifecycle rule from ensureS3LifecycleRule() would sweep them, otherwise clean up manually`, { reason: (0, truncate_js_1.truncateForLog)((0, base_error_js_1.failureLabel)(lastError)) }));
|
|
289
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_READ_CONCURRENCY = void 0;
|
|
4
|
+
exports.mapWithConcurrency = mapWithConcurrency;
|
|
5
|
+
exports.DEFAULT_READ_CONCURRENCY = 8;
|
|
6
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
7
|
+
const results = [];
|
|
8
|
+
let next = 0;
|
|
9
|
+
let failed = false;
|
|
10
|
+
let failure;
|
|
11
|
+
const worker = async () => {
|
|
12
|
+
while (!failed && next < items.length) {
|
|
13
|
+
const index = next;
|
|
14
|
+
next += 1;
|
|
15
|
+
try {
|
|
16
|
+
results[index] = await fn(items[index], index);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
if (!failed) {
|
|
20
|
+
failed = true;
|
|
21
|
+
failure = error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const workers = Math.min(limit >= 1 ? Math.floor(limit) : 1, Math.max(items.length, 1));
|
|
27
|
+
await Promise.all(Array.from({ length: workers }, worker));
|
|
28
|
+
if (failed)
|
|
29
|
+
throw failure;
|
|
30
|
+
return results;
|
|
31
|
+
}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* twice, and one test on the library's brand and that code is what tells a
|
|
8
8
|
* cancellation from a failure, so no call site inspects a reason's shape.
|
|
9
9
|
*/
|
|
10
|
-
import { DynamoDBLangGraphError } from '../errors/base-error';
|
|
11
|
-
import { ErrorCode } from '../errors/error-code';
|
|
10
|
+
import { DynamoDBLangGraphError } from '../errors/base-error.js';
|
|
11
|
+
import { ErrorCode } from '../errors/error-code.js';
|
|
12
12
|
/**
|
|
13
13
|
* Whether `error` is a cancellation rather than a failure.
|
|
14
14
|
*
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isAbortError = isAbortError;
|
|
4
|
+
exports.abortErrorFrom = abortErrorFrom;
|
|
5
|
+
const base_error_js_1 = require("../errors/base-error.js");
|
|
6
|
+
const error_code_js_1 = require("../errors/error-code.js");
|
|
7
|
+
const errors_js_1 = require("../errors/errors.js");
|
|
8
|
+
function isAbortError(error) {
|
|
9
|
+
return error !== undefined && (0, base_error_js_1.hasErrorCode)(error, error_code_js_1.ErrorCode.ABORTED);
|
|
10
|
+
}
|
|
11
|
+
function abortErrorFrom(signal) {
|
|
12
|
+
const reason = signal.reason;
|
|
13
|
+
if (isAbortError(reason))
|
|
14
|
+
return reason;
|
|
15
|
+
return (0, errors_js_1.abortError)('Operation aborted', reason === undefined ? undefined : (0, base_error_js_1.toError)(reason));
|
|
16
|
+
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* back unprocessed; they are re-sent with backoff until a bound, and a batch
|
|
6
6
|
* that still cannot finish is reported with how much of it did.
|
|
7
7
|
*/
|
|
8
|
-
import type { DynamoDBDocumentLike, WriteRequest } from './client';
|
|
9
|
-
import { type RetryOptions } from './retry';
|
|
8
|
+
import type { DynamoDBDocumentLike, WriteRequest } from './client.js';
|
|
9
|
+
import { type RetryOptions } from './retry.js';
|
|
10
10
|
/**
|
|
11
11
|
* DynamoDB BatchWriteItem maximum requests per call.
|
|
12
12
|
*
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MAX_UNPROCESSED_RETRIES = exports.BATCH_WRITE_MAX = void 0;
|
|
4
|
+
exports.batchWriteAll = batchWriteAll;
|
|
5
|
+
exports.drainUnprocessedWrites = drainUnprocessedWrites;
|
|
6
|
+
const base_error_js_1 = require("../errors/base-error.js");
|
|
7
|
+
const error_code_js_1 = require("../errors/error-code.js");
|
|
8
|
+
const errors_js_1 = require("../errors/errors.js");
|
|
9
|
+
const abort_js_1 = require("./abort.js");
|
|
10
|
+
const retry_js_1 = require("./retry.js");
|
|
11
|
+
exports.BATCH_WRITE_MAX = 25;
|
|
12
|
+
exports.MAX_UNPROCESSED_RETRIES = 10;
|
|
13
|
+
async function batchWriteAll(client, tableName, requests, options = {}) {
|
|
14
|
+
const totalChunks = Math.ceil(requests.length / exports.BATCH_WRITE_MAX);
|
|
15
|
+
let succeededChunks = 0;
|
|
16
|
+
let succeededCount = 0;
|
|
17
|
+
const failedChunks = [];
|
|
18
|
+
for (let offset = 0; offset < requests.length; offset += exports.BATCH_WRITE_MAX) {
|
|
19
|
+
const chunk = requests.slice(offset, offset + exports.BATCH_WRITE_MAX);
|
|
20
|
+
try {
|
|
21
|
+
await drainUnprocessedWrites(client, tableName, chunk, options);
|
|
22
|
+
succeededChunks += 1;
|
|
23
|
+
succeededCount += chunk.length;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
const failure = error;
|
|
27
|
+
if (!(0, base_error_js_1.hasErrorCode)(failure, error_code_js_1.ErrorCode.BATCH_WRITE_INCOMPLETE))
|
|
28
|
+
throw failure;
|
|
29
|
+
failedChunks.push(failure);
|
|
30
|
+
succeededCount += failure.details.succeededCount;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (failedChunks.length > 0) {
|
|
34
|
+
throw (0, errors_js_1.batchWriteAllIncompleteError)({
|
|
35
|
+
succeeded: succeededChunks,
|
|
36
|
+
total: totalChunks,
|
|
37
|
+
failures: failedChunks,
|
|
38
|
+
succeededCount,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function drainBackoff(retry) {
|
|
43
|
+
const base = retry?.baseDelayMs ?? retry_js_1.INITIAL_BACKOFF_DELAY_MS;
|
|
44
|
+
const max = (0, retry_js_1.backoffCapMs)(base, retry?.maxDelayMs);
|
|
45
|
+
return { base: Math.min(base, max), max };
|
|
46
|
+
}
|
|
47
|
+
function drainFailure(error, succeededCount, pending, retries) {
|
|
48
|
+
if ((0, abort_js_1.isAbortError)(error))
|
|
49
|
+
return error;
|
|
50
|
+
return (0, errors_js_1.batchWriteIncompleteError)(succeededCount, pending, retries, error);
|
|
51
|
+
}
|
|
52
|
+
async function drainUnprocessedWrites(client, tableName, requests, options = {}) {
|
|
53
|
+
if (requests.length === 0)
|
|
54
|
+
return;
|
|
55
|
+
const maxRetries = options.maxRetries ?? exports.MAX_UNPROCESSED_RETRIES;
|
|
56
|
+
const initialCount = requests.length;
|
|
57
|
+
const { base: baseDelay, max: maxDelay } = drainBackoff(options.retry);
|
|
58
|
+
let pending = requests;
|
|
59
|
+
let delay = baseDelay;
|
|
60
|
+
let retries = 0;
|
|
61
|
+
while (pending.length > 0) {
|
|
62
|
+
try {
|
|
63
|
+
const result = await (0, retry_js_1.withDynamoDBRetry)((request) => client.batchWrite({ RequestItems: { [tableName]: pending } }, request), { ...options.retry, signal: options.signal });
|
|
64
|
+
const leftover = result.UnprocessedItems?.[tableName] ?? [];
|
|
65
|
+
if (leftover.length === 0)
|
|
66
|
+
return;
|
|
67
|
+
pending = leftover;
|
|
68
|
+
retries += 1;
|
|
69
|
+
if (retries > maxRetries)
|
|
70
|
+
break;
|
|
71
|
+
await (0, retry_js_1.sleep)((0, retry_js_1.fullJitter)(delay, options.rng), options.signal);
|
|
72
|
+
delay = (0, retry_js_1.nextBackoffDelay)(delay, maxDelay);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
throw drainFailure(error, initialCount - pending.length, pending, retries);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
throw (0, errors_js_1.batchWriteIncompleteError)(initialCount - pending.length, pending, maxRetries);
|
|
79
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCancellationReasons = getCancellationReasons;
|
|
4
|
+
exports.conditionalCheckFailure = conditionalCheckFailure;
|
|
5
|
+
exports.transientCancellation = transientCancellation;
|
|
6
|
+
exports.throttledCancellation = throttledCancellation;
|
|
7
|
+
exports.conditionFailedAt = conditionFailedAt;
|
|
8
|
+
const NOT_THE_CAUSE = 'None';
|
|
9
|
+
const CONDITION_FAILED = 'ConditionalCheckFailed';
|
|
10
|
+
function getCancellationReasons(error) {
|
|
11
|
+
return error?.CancellationReasons;
|
|
12
|
+
}
|
|
13
|
+
function conditionalCheckFailure(error) {
|
|
14
|
+
const reasons = getCancellationReasons(error) ?? [];
|
|
15
|
+
const causes = reasons.filter((reason) => reason.Code !== NOT_THE_CAUSE);
|
|
16
|
+
return causes.length === 1 && causes[0].Code === CONDITION_FAILED ? causes[0] : undefined;
|
|
17
|
+
}
|
|
18
|
+
const TRANSIENT_CANCELLATION_REASONS = [
|
|
19
|
+
'None',
|
|
20
|
+
'TransactionConflict',
|
|
21
|
+
'ThrottlingError',
|
|
22
|
+
'ProvisionedThroughputExceeded',
|
|
23
|
+
];
|
|
24
|
+
function transientCancellation(error) {
|
|
25
|
+
const reasons = getCancellationReasons(error);
|
|
26
|
+
if (!reasons)
|
|
27
|
+
return undefined;
|
|
28
|
+
return (reasons.length > 0 &&
|
|
29
|
+
reasons.every((reason) => reason.Code === undefined || TRANSIENT_CANCELLATION_REASONS.includes(reason.Code)));
|
|
30
|
+
}
|
|
31
|
+
const THROTTLING_REASONS = ['ThrottlingError', 'ProvisionedThroughputExceeded'];
|
|
32
|
+
function throttledCancellation(error) {
|
|
33
|
+
return (getCancellationReasons(error) ?? []).some((reason) => reason.Code !== undefined && THROTTLING_REASONS.includes(reason.Code));
|
|
34
|
+
}
|
|
35
|
+
function conditionFailedAt(error, index) {
|
|
36
|
+
return getCancellationReasons(error)?.[index]?.Code === CONDITION_FAILED;
|
|
37
|
+
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { DynamoDBClient, type DynamoDBClientConfig } from '@aws-sdk/client-dynamodb';
|
|
13
13
|
import { DynamoDBDocument, type NativeAttributeValue, type TransactWriteCommandInput } from '@aws-sdk/lib-dynamodb';
|
|
14
|
-
import type { Logger } from '../logging/logger';
|
|
14
|
+
import type { Logger } from '../logging/logger.js';
|
|
15
15
|
/**
|
|
16
16
|
* How long one request attempt may take on a client this library builds
|
|
17
17
|
* (10 seconds) before the SDK's request handler destroys it and rejects with a
|
|
@@ -22,14 +22,15 @@ import type { Logger } from '../logging/logger';
|
|
|
22
22
|
* of them defaults to 0 — a hung socket holds that attempt open forever and
|
|
23
23
|
* the write lifetime bounds nothing.
|
|
24
24
|
*
|
|
25
|
-
* Measured, not picked.
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
25
|
+
* Measured, not picked. At a thousand concurrent writes of 20 KB values —
|
|
26
|
+
* wider than one call's own fan-out now runs, but within reach of several
|
|
27
|
+
* calls sharing one client — the worst interval the handler itself saw —
|
|
28
|
+
* socket acquisition including the wait behind the agent's fifty sockets,
|
|
29
|
+
* connect, request write and time-to-first-response-header — was 0.92 s, and
|
|
30
|
+
* ten seconds is roughly eleven times that. The asymmetry settles the close
|
|
31
|
+
* call: too large leaves one attempt hanging for at most ten seconds, which
|
|
32
|
+
* the write lifetime's own headroom absorbs, while too small turns a healthy
|
|
33
|
+
* wide fan-out into a retry storm.
|
|
33
34
|
*/
|
|
34
35
|
export declare const DEFAULT_REQUEST_TIMEOUT_MS = 10000;
|
|
35
36
|
/**
|
|
@@ -89,8 +90,9 @@ export interface ResolveClientOptions {
|
|
|
89
90
|
* bounds how long one attempt may run, which `maxAttempts` alone does not. A
|
|
90
91
|
* `requestHandler` in `clientConfig` replaces that default whole rather than
|
|
91
92
|
* merging with it — the documented escape hatch, and equally the documented
|
|
92
|
-
* way to give up the bound.
|
|
93
|
-
*
|
|
93
|
+
* way to give up the bound. Either key named with `undefined` overrides
|
|
94
|
+
* nothing and keeps its default. An injected client keeps whatever it was
|
|
95
|
+
* built with — see {@link warnOnStackedRetries}.
|
|
94
96
|
*/
|
|
95
97
|
export declare function resolveDynamoDBClient(options: ResolveClientOptions): ResolvedDynamoDBClient;
|
|
96
98
|
/**
|
|
@@ -135,20 +137,21 @@ export declare function warnOnStackedRetries(client: DynamoDBDocumentLike, logge
|
|
|
135
137
|
* turns one into that feature's row type.
|
|
136
138
|
*/
|
|
137
139
|
export type AttributeMap = Record<string, NativeAttributeValue>;
|
|
138
|
-
/**
|
|
139
|
-
|
|
140
|
+
/**
|
|
141
|
+
* A single `BatchWriteItem` write request, as the document client takes it —
|
|
142
|
+
* a `PutRequest` carrying the item, or a `DeleteRequest` carrying the key:
|
|
143
|
+
* the shape of each entry a `BATCH_WRITE_INCOMPLETE` error's
|
|
144
|
+
* `details.unprocessed` carries, verbatim, so a caller can re-submit it.
|
|
145
|
+
*/
|
|
146
|
+
export type WriteRequest = {
|
|
140
147
|
PutRequest: {
|
|
141
|
-
Item:
|
|
148
|
+
Item: Record<string, NativeAttributeValue>;
|
|
142
149
|
};
|
|
143
|
-
}
|
|
144
|
-
/** A BatchWriteItem DeleteRequest. */
|
|
145
|
-
interface DeleteWriteRequest {
|
|
150
|
+
} | {
|
|
146
151
|
DeleteRequest: {
|
|
147
|
-
Key:
|
|
152
|
+
Key: Record<string, NativeAttributeValue>;
|
|
148
153
|
};
|
|
149
|
-
}
|
|
150
|
-
/** A single BatchWriteItem write request. */
|
|
151
|
-
export type WriteRequest = PutWriteRequest | DeleteWriteRequest;
|
|
154
|
+
};
|
|
152
155
|
/** One action of a `TransactWriteItems` request, as the document client takes it. */
|
|
153
156
|
export type TransactAction = NonNullable<TransactWriteCommandInput['TransactItems']>[number];
|
|
154
157
|
/**
|
|
@@ -172,4 +175,3 @@ export type TransactAction = NonNullable<TransactWriteCommandInput['TransactItem
|
|
|
172
175
|
* signatures cannot drift from the SDK this package installs.
|
|
173
176
|
*/
|
|
174
177
|
export type DynamoDBDocumentLike = Pick<DynamoDBDocument, 'batchWrite' | 'delete' | 'get' | 'put' | 'query' | 'scan' | 'transactWrite' | 'update'>;
|
|
175
|
-
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_SOCKET_TIMEOUT_MS = exports.DEFAULT_REQUEST_TIMEOUT_MS = void 0;
|
|
4
|
+
exports.resolveDynamoDBClient = resolveDynamoDBClient;
|
|
5
|
+
exports.warnOnStackedRetries = warnOnStackedRetries;
|
|
6
|
+
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
7
|
+
const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
|
|
8
|
+
exports.DEFAULT_REQUEST_TIMEOUT_MS = 10_000;
|
|
9
|
+
exports.DEFAULT_SOCKET_TIMEOUT_MS = 5_000;
|
|
10
|
+
function resolveDynamoDBClient(options) {
|
|
11
|
+
if (options.client) {
|
|
12
|
+
return { ddbClient: undefined, client: options.client, ownsClient: false };
|
|
13
|
+
}
|
|
14
|
+
const createClient = options.createClient ?? ((config) => new client_dynamodb_1.DynamoDBClient(config));
|
|
15
|
+
const ddbClient = createClient({
|
|
16
|
+
...options.clientConfig,
|
|
17
|
+
maxAttempts: options.clientConfig?.maxAttempts ?? 1,
|
|
18
|
+
requestHandler: options.clientConfig?.requestHandler ?? {
|
|
19
|
+
requestTimeout: exports.DEFAULT_REQUEST_TIMEOUT_MS,
|
|
20
|
+
socketTimeout: exports.DEFAULT_SOCKET_TIMEOUT_MS,
|
|
21
|
+
throwOnRequestTimeout: true,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
return { ddbClient, client: lib_dynamodb_1.DynamoDBDocument.from(ddbClient), ownsClient: true };
|
|
25
|
+
}
|
|
26
|
+
async function warnOnStackedRetries(client, logger) {
|
|
27
|
+
const report = client.config
|
|
28
|
+
?.maxAttempts;
|
|
29
|
+
if (typeof report !== 'function')
|
|
30
|
+
return;
|
|
31
|
+
try {
|
|
32
|
+
const maxAttempts = await report();
|
|
33
|
+
if (maxAttempts > 1) {
|
|
34
|
+
logger.warn("injected DynamoDB client keeps the SDK's own retries; they stack inside this library's " +
|
|
35
|
+
'retry budget — construct it with maxAttempts: 1 unless that is intended', { maxAttempts });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
}
|
|
40
|
+
}
|