@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
package/dist/{history/actions/reconcile-count.js → esm/history/actions/reconcile-count.d.ts}
RENAMED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Hides that repairing `messageCount` is the session row's own job.
|
|
4
3
|
*
|
|
@@ -8,10 +7,7 @@
|
|
|
8
7
|
* there, beside the append that keeps the count in step, so the repair and
|
|
9
8
|
* the append cannot come to disagree about what the count means.
|
|
10
9
|
*/
|
|
11
|
-
|
|
12
|
-
exports.reconcileMessageCount = reconcileMessageCount;
|
|
13
|
-
const parse_1 = require("../internal/parse");
|
|
14
|
-
const session_1 = require("../internal/session");
|
|
10
|
+
import type { HistoryContext } from '../internal/setup.js';
|
|
15
11
|
/**
|
|
16
12
|
* Recompute `messageCount` from the number of stored message items and write it
|
|
17
13
|
* back, repairing drift. The append path keeps the count consistent
|
|
@@ -20,15 +16,17 @@ const session_1 = require("../internal/session");
|
|
|
20
16
|
* **Safe to run on a live session.** The count is written under a condition on
|
|
21
17
|
* the value the row held when the count was computed, so an append landing in
|
|
22
18
|
* between makes the write fail rather than clobber the increment; the tool then
|
|
23
|
-
* recounts and tries again.
|
|
24
|
-
*
|
|
25
|
-
*
|
|
19
|
+
* recounts and tries again. Written unconditionally, it would silently discard
|
|
20
|
+
* concurrent appends on exactly the sessions an operator reaches for this tool
|
|
21
|
+
* to fix. The count itself is a consistent read, because the pin can only
|
|
22
|
+
* catch a counter that moved, not a count taken off a stale replica.
|
|
26
23
|
*
|
|
27
24
|
* Accepts: `sessionId` — validated, and an existing session: repairing one that
|
|
28
25
|
* does not exist would mean creating it. `signal` — aborts the reads.
|
|
29
26
|
*
|
|
30
|
-
* Returns: the count now stored
|
|
31
|
-
*
|
|
27
|
+
* Returns: the count now stored: the session's live message rows, which is
|
|
28
|
+
* what `getMessages` returns, except for a row it drops as corrupt under
|
|
29
|
+
* `onCorruptMessage: 'skip'`, which is counted here all the same.
|
|
32
30
|
*
|
|
33
31
|
* Throws: `VALIDATION` naming `sessionId`; `CONDITION_CONFLICT` when the
|
|
34
32
|
* session does not exist — rather than creating a permanent, TTL-less
|
|
@@ -42,10 +40,10 @@ const session_1 = require("../internal/session");
|
|
|
42
40
|
*
|
|
43
41
|
* Guarantees: safe on a live session. The write is pinned to the value the row
|
|
44
42
|
* held when the count was computed, so an append landing in between fails the
|
|
45
|
-
* write rather than clobbering its increment, and the tool recounts
|
|
46
|
-
*
|
|
47
|
-
*
|
|
43
|
+
* write rather than clobbering its increment, and the tool recounts; the rows
|
|
44
|
+
* are counted with a consistent read, so a chunk that just committed or was
|
|
45
|
+
* just rolled back is counted as it stands. Expired messages are not counted,
|
|
46
|
+
* so the repaired number agrees with what `getMessages` returns rather than
|
|
47
|
+
* with what the table still holds.
|
|
48
48
|
*/
|
|
49
|
-
|
|
50
|
-
return (0, session_1.repairMessageCount)(context, (0, parse_1.parseSessionId)(sessionId), signal);
|
|
51
|
-
}
|
|
49
|
+
export declare function reconcileMessageCount(context: HistoryContext, sessionId: string, signal?: AbortSignal): Promise<number>;
|
|
@@ -1,27 +1,20 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Hides that chat history is a set of actions behind one error boundary.
|
|
4
3
|
*
|
|
5
4
|
* The public class holds only what it resolved from its options and routes
|
|
6
5
|
* each read and write to the action that implements it, through
|
|
7
|
-
* `guardPublic`.
|
|
8
|
-
*
|
|
9
|
-
* `destroy` and `forSession`
|
|
10
|
-
* one route from it to
|
|
11
|
-
*
|
|
12
|
-
* change without touching
|
|
6
|
+
* `guardPublic`. Every method is the error boundary, so no error but the
|
|
7
|
+
* library's own reaches a caller (record 13) — an asynchronous one through
|
|
8
|
+
* `guardPublic`, and the synchronous `destroy` and `forSession` through
|
|
9
|
+
* `guardPublicSync`; `forSession` is also the one route from it to
|
|
10
|
+
* LangChain's single-session history. Where an action lives, how it reads or
|
|
11
|
+
* writes, and which client or offloader it uses can change without touching
|
|
12
|
+
* this surface.
|
|
13
13
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const add_messages_1 = require("./actions/add-messages");
|
|
19
|
-
const clear_1 = require("./actions/clear");
|
|
20
|
-
const get_messages_1 = require("./actions/get-messages");
|
|
21
|
-
const list_sessions_1 = require("./actions/list-sessions");
|
|
22
|
-
const reconcile_count_1 = require("./actions/reconcile-count");
|
|
23
|
-
const setup_1 = require("./internal/setup");
|
|
24
|
-
const session_adapter_1 = require("./session-adapter");
|
|
14
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
|
15
|
+
import type { CancelOptions } from '../shared/options.js';
|
|
16
|
+
import { type AdapterWindow, DynamoDBSessionChatMessageHistory } from './session-adapter.js';
|
|
17
|
+
import type { DynamoDBChatMessageHistoryOptions, GetMessagesOptions, ListSessionsOptions, SessionPage } from './types.js';
|
|
25
18
|
/**
|
|
26
19
|
* DynamoDB-backed multi-session chat history. Each message is its own row,
|
|
27
20
|
* ordered by when it was appended, beside one metadata row per session, and
|
|
@@ -30,9 +23,9 @@ const session_adapter_1 = require("./session-adapter");
|
|
|
30
23
|
* single-session LangChain adapter. Every public method rejects only with this
|
|
31
24
|
* library's error.
|
|
32
25
|
*/
|
|
33
|
-
class DynamoDBChatMessageHistory {
|
|
34
|
-
context;
|
|
35
|
-
shell;
|
|
26
|
+
export declare class DynamoDBChatMessageHistory {
|
|
27
|
+
private readonly context;
|
|
28
|
+
private readonly shell;
|
|
36
29
|
/**
|
|
37
30
|
* Accepts: `options` — validated here, so a misconfiguration surfaces at
|
|
38
31
|
* construction rather than on the first request.
|
|
@@ -44,16 +37,12 @@ class DynamoDBChatMessageHistory {
|
|
|
44
37
|
*
|
|
45
38
|
* Guarantees: no I/O. Constructing the adapter issues no request.
|
|
46
39
|
*/
|
|
47
|
-
constructor(options)
|
|
48
|
-
const setup = (0, setup_1.setUpHistory)(options);
|
|
49
|
-
this.context = setup.context;
|
|
50
|
-
this.shell = setup.shell;
|
|
51
|
-
}
|
|
40
|
+
constructor(options: DynamoDBChatMessageHistoryOptions);
|
|
52
41
|
/**
|
|
53
42
|
* Get a session's messages in chronological order.
|
|
54
43
|
*
|
|
55
44
|
* Accepts: `sessionId` — validated. `options.limit` — an integer from 1 to
|
|
56
|
-
*
|
|
45
|
+
* 10,000; only the newest that many messages. `0` is
|
|
57
46
|
* refused rather than answered with an empty conversation, which is the one
|
|
58
47
|
* place this package refuses a `limit` of zero. `options.before` — a valid
|
|
59
48
|
* `Date`; only messages appended before that instant. Neither given reads
|
|
@@ -68,6 +57,8 @@ class DynamoDBChatMessageHistory {
|
|
|
68
57
|
* session's own path, and naming `message` for a row in this session's
|
|
69
58
|
* message key space that this adapter did not write, both whatever the
|
|
70
59
|
* corruption policy;
|
|
60
|
+
* `COMPRESSION_LIMIT` for a payload larger than this reader's
|
|
61
|
+
* `compression.maxDecompressedBytes`, whatever the corruption policy too;
|
|
71
62
|
* `FORMAT_UNSUPPORTED` for a row, or a payload, a newer release wrote;
|
|
72
63
|
* a classified AWS failure;
|
|
73
64
|
* `ABORTED`; and, under `onCorruptMessage: 'throw'`, the decode error of a
|
|
@@ -77,37 +68,41 @@ class DynamoDBChatMessageHistory {
|
|
|
77
68
|
* Expired messages are filtered on read, so the history is never stale.
|
|
78
69
|
* @remarks One query page plus one S3 download per offloaded message.
|
|
79
70
|
*/
|
|
80
|
-
getMessages(sessionId, options)
|
|
81
|
-
return (0, boundary_1.guardPublic)('history.getMessages', () => (0, get_messages_1.getMessages)(this.context, sessionId, options));
|
|
82
|
-
}
|
|
71
|
+
getMessages(sessionId: string, options?: GetMessagesOptions): Promise<BaseMessage[]>;
|
|
83
72
|
/**
|
|
84
73
|
* Append messages to a session.
|
|
85
74
|
*
|
|
86
75
|
* Accepts: `sessionId` — validated. `messages` — LangChain messages; an empty
|
|
87
|
-
* list writes nothing and is not an error. `options.signal` —
|
|
88
|
-
*
|
|
76
|
+
* list writes nothing and is not an error. `options.signal` — ends the
|
|
77
|
+
* upload or chunk transaction in flight and any wait between them; a chunk
|
|
78
|
+
* that landed before the cancel is rolled back like any other committed
|
|
79
|
+
* chunk of a failed append.
|
|
89
80
|
*
|
|
90
81
|
* Returns: nothing, and only once every message has landed.
|
|
91
82
|
*
|
|
92
83
|
* Throws: `VALIDATION` naming `messages`, for a value that is not itself
|
|
93
84
|
* an array, or, with the offending index, for an element that is not a
|
|
94
|
-
* message or one that could never be read back;
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
85
|
+
* message or one that could never be read back; naming `payload` for a
|
|
86
|
+
* message too large to store inline without `s3`, or, once offloaded,
|
|
87
|
+
* larger than `s3.maxDownloadBytes`; naming `s3Key` for an offloaded
|
|
88
|
+
* object's key over S3's cap; or naming `signal` or `options.<key>` for a
|
|
89
|
+
* key this package does not read; `S3_OFFLOAD_FAILED` when an offloaded
|
|
90
|
+
* message cannot be uploaded;
|
|
91
|
+
* `COMPENSATION_FAILED` when a chunk fails and either the rollback fails
|
|
92
|
+
* too or that chunk's own outcome could not be established;
|
|
93
|
+
* `RETRY_EXHAUSTED` after 18 contended attempts; a classified AWS failure;
|
|
98
94
|
* `ABORTED`.
|
|
99
95
|
*
|
|
100
|
-
* Guarantees: a caller observes all messages or none
|
|
101
|
-
* chunk
|
|
102
|
-
*
|
|
103
|
-
*
|
|
96
|
+
* Guarantees: a caller observes all messages or none — except the one
|
|
97
|
+
* chunk a failed call could not settle: an `ABORTED` append whose in-flight
|
|
98
|
+
* chunk commits after the call returns, or a `COMPENSATION_FAILED` append
|
|
99
|
+
* whose failing chunk's own outcome could not be established. Read the
|
|
100
|
+
* session back before deciding whether to resend those messages. One
|
|
101
|
+
* transaction per chunk of up to 99 keeps `messageCount` exact. Lock-free
|
|
102
|
+
* and safe under concurrent appends to one session; every message shares
|
|
103
|
+
* the session's TTL when one is configured.
|
|
104
104
|
*/
|
|
105
|
-
addMessages(sessionId, messages, options)
|
|
106
|
-
return (0, boundary_1.guardPublic)('history.addMessages', () => {
|
|
107
|
-
(0, collaborators_1.assertCancelOptions)(options);
|
|
108
|
-
return (0, add_messages_1.addMessages)(this.context, sessionId, messages, options?.signal);
|
|
109
|
-
});
|
|
110
|
-
}
|
|
105
|
+
addMessages(sessionId: string, messages: BaseMessage[], options?: CancelOptions): Promise<void>;
|
|
111
106
|
/**
|
|
112
107
|
* Append one message.
|
|
113
108
|
*
|
|
@@ -117,16 +112,13 @@ class DynamoDBChatMessageHistory {
|
|
|
117
112
|
*
|
|
118
113
|
* Throws: as {@link addMessages}.
|
|
119
114
|
*/
|
|
120
|
-
addMessage(sessionId, message, options)
|
|
121
|
-
return (0, boundary_1.guardPublic)('history.addMessage', () => {
|
|
122
|
-
(0, collaborators_1.assertCancelOptions)(options);
|
|
123
|
-
return (0, add_messages_1.addMessages)(this.context, sessionId, [message], options?.signal);
|
|
124
|
-
});
|
|
125
|
-
}
|
|
115
|
+
addMessage(sessionId: string, message: BaseMessage, options?: CancelOptions): Promise<void>;
|
|
126
116
|
/**
|
|
127
117
|
* Delete a session's messages, metadata and offloaded objects.
|
|
128
118
|
*
|
|
129
|
-
* Accepts: `sessionId` — validated. `options.signal` —
|
|
119
|
+
* Accepts: `sessionId` — validated. `options.signal` — ends the read or
|
|
120
|
+
* delete in flight and any wait between them; rows already deleted stay
|
|
121
|
+
* deleted.
|
|
130
122
|
*
|
|
131
123
|
* Returns: nothing. Clearing a session that does not exist is not an error.
|
|
132
124
|
*
|
|
@@ -147,12 +139,7 @@ class DynamoDBChatMessageHistory {
|
|
|
147
139
|
* message appended while it runs may survive it, and the surviving session
|
|
148
140
|
* row then over-counts until `reconcileMessageCount` repairs it.
|
|
149
141
|
*/
|
|
150
|
-
clear(sessionId, options)
|
|
151
|
-
return (0, boundary_1.guardPublic)('history.clear', () => {
|
|
152
|
-
(0, collaborators_1.assertCancelOptions)(options);
|
|
153
|
-
return (0, clear_1.clearSession)(this.context, sessionId, options);
|
|
154
|
-
});
|
|
155
|
-
}
|
|
142
|
+
clear(sessionId: string, options?: CancelOptions): Promise<void>;
|
|
156
143
|
/**
|
|
157
144
|
* List every session as a metadata summary, most recently updated first.
|
|
158
145
|
* With a configured `indexName` this reads each index shard newest-first,
|
|
@@ -161,7 +148,7 @@ class DynamoDBChatMessageHistory {
|
|
|
161
148
|
* bounded by `maxItems` / `maxIterations`, and returning the newest `limit`
|
|
162
149
|
* sessions, or every session when no limit is given, with no cursor.
|
|
163
150
|
*
|
|
164
|
-
* Accepts: `options.limit` — an integer from 0 to
|
|
151
|
+
* Accepts: `options.limit` — an integer from 0 to 10,000;
|
|
165
152
|
* the page size with the index, the newest N without it, and `0` an empty
|
|
166
153
|
* page read from neither. `options.cursor` — from a previous page,
|
|
167
154
|
* and only with a configured `indexName`. `options.maxItems` /
|
|
@@ -186,12 +173,10 @@ class DynamoDBChatMessageHistory {
|
|
|
186
173
|
* page still needs one, so a shard can cost a query whose rows the page never
|
|
187
174
|
* takes; at most `readConcurrency` shards are queried at once. Memory is the
|
|
188
175
|
* page being built, up to `limit` rows and so bounded by
|
|
189
|
-
*
|
|
176
|
+
* 10,000, plus at most one DynamoDB page per shard,
|
|
190
177
|
* whatever the table holds.
|
|
191
178
|
*/
|
|
192
|
-
listSessions(options)
|
|
193
|
-
return (0, boundary_1.guardPublic)('history.listSessions', () => (0, list_sessions_1.listSessions)(this.context, options));
|
|
194
|
-
}
|
|
179
|
+
listSessions(options?: ListSessionsOptions): Promise<SessionPage>;
|
|
195
180
|
/**
|
|
196
181
|
* Recompute and repair a session's `messageCount` from the stored messages.
|
|
197
182
|
* A maintenance tool for external corruption; run it when the session is idle.
|
|
@@ -199,8 +184,9 @@ class DynamoDBChatMessageHistory {
|
|
|
199
184
|
* Accepts: `sessionId` — validated, and an existing session.
|
|
200
185
|
* `options.signal` — aborts the reads.
|
|
201
186
|
*
|
|
202
|
-
* Returns: the count now stored
|
|
203
|
-
*
|
|
187
|
+
* Returns: the count now stored: the session's live message rows, which is
|
|
188
|
+
* what `getMessages` returns, except for a row it drops as corrupt under
|
|
189
|
+
* `onCorruptMessage: 'skip'`, which is counted here all the same.
|
|
204
190
|
*
|
|
205
191
|
* Throws: `VALIDATION` for a malformed session id, an invalid `signal`,
|
|
206
192
|
* or an `options.<key>` this package does not read; `CONDITION_CONFLICT` when the
|
|
@@ -215,12 +201,7 @@ class DynamoDBChatMessageHistory {
|
|
|
215
201
|
* row held when the count was computed, so a concurrent append makes it
|
|
216
202
|
* recount instead of clobbering the increment.
|
|
217
203
|
*/
|
|
218
|
-
reconcileMessageCount(sessionId, options)
|
|
219
|
-
return (0, boundary_1.guardPublic)('history.reconcileMessageCount', () => {
|
|
220
|
-
(0, collaborators_1.assertCancelOptions)(options);
|
|
221
|
-
return (0, reconcile_count_1.reconcileMessageCount)(this.context, sessionId, options?.signal);
|
|
222
|
-
});
|
|
223
|
-
}
|
|
204
|
+
reconcileMessageCount(sessionId: string, options?: CancelOptions): Promise<number>;
|
|
224
205
|
/**
|
|
225
206
|
* Get a single-session LangChain adapter for `sessionId`.
|
|
226
207
|
*
|
|
@@ -237,9 +218,7 @@ class DynamoDBChatMessageHistory {
|
|
|
237
218
|
* `limit` — raised by the constructed adapter, so a bad id or window fails
|
|
238
219
|
* here rather than on first use.
|
|
239
220
|
*/
|
|
240
|
-
forSession(sessionId, window)
|
|
241
|
-
return new session_adapter_1.DynamoDBSessionChatMessageHistory(this, sessionId, window);
|
|
242
|
-
}
|
|
221
|
+
forSession(sessionId: string, window?: AdapterWindow): DynamoDBSessionChatMessageHistory;
|
|
243
222
|
/**
|
|
244
223
|
* Release owned resources.
|
|
245
224
|
*
|
|
@@ -248,13 +227,12 @@ class DynamoDBChatMessageHistory {
|
|
|
248
227
|
* Returns: nothing. Idempotent, and a no-op for a client the caller injected
|
|
249
228
|
* — that one is theirs to close.
|
|
250
229
|
*
|
|
251
|
-
* Throws:
|
|
252
|
-
*
|
|
253
|
-
*
|
|
230
|
+
* Throws: the first failure a resource's own `destroy` raised, as a
|
|
231
|
+
* `DynamoDBLangGraphError` (`UNEXPECTED_ERROR` unless the failure was AWS's)
|
|
232
|
+
* with it as `cause` — raised only after every other resource has been
|
|
233
|
+
* released, and only by the first call: `destroy()` is idempotent.
|
|
254
234
|
*/
|
|
255
|
-
destroy()
|
|
256
|
-
this.shell.release();
|
|
257
|
-
}
|
|
235
|
+
destroy(): void;
|
|
258
236
|
/**
|
|
259
237
|
* Provision an S3 lifecycle expiration rule matching the configured TTL, so
|
|
260
238
|
* offloaded objects don't outlive their DynamoDB item forever.
|
|
@@ -263,16 +241,27 @@ class DynamoDBChatMessageHistory {
|
|
|
263
241
|
* without both.
|
|
264
242
|
*
|
|
265
243
|
* Returns: nothing. Installing a rule that is already there is a no-op too.
|
|
244
|
+
* When it writes the rules but cannot confirm within its polling window
|
|
245
|
+
* that a re-read shows them — S3 documents that a lifecycle configuration
|
|
246
|
+
* can take minutes to propagate — it logs a `warn` and returns rather than
|
|
247
|
+
* throwing: the rules were written, and a later call can confirm them.
|
|
266
248
|
*
|
|
267
249
|
* Throws: `VALIDATION` naming `s3.keyPrefix` on a rule-id collision;
|
|
268
|
-
* a classified AWS failure when the bucket's lifecycle cannot be read or
|
|
250
|
+
* a classified AWS failure when the bucket's lifecycle cannot be read or
|
|
251
|
+
* written; `CONTENTION` when every one of the five rounds this call polls
|
|
252
|
+
* needs a write — a competing writer replacing the configuration on every
|
|
253
|
+
* single re-read.
|
|
269
254
|
* @remarks Requires the bucket-level `s3:GetLifecycleConfiguration` /
|
|
270
255
|
* `s3:PutLifecycleConfiguration` permissions, broader than the object-level
|
|
271
256
|
* CRUD the rest of S3 offload needs — call it once during provisioning, not
|
|
272
|
-
* per request.
|
|
257
|
+
* per request. When several adapters or processes provision the same
|
|
258
|
+
* bucket, call them one at a time and run each again after a few minutes
|
|
259
|
+
* once every one of them has run.
|
|
260
|
+
*
|
|
261
|
+
* Lowering the `ttl` is safe for new rows at once; the rule is not. Lower
|
|
262
|
+
* `ttl` now, and call this again only once the old `ttl` has elapsed since,
|
|
263
|
+
* because until then rows written under the old value still name objects
|
|
264
|
+
* the shorter rule would expire. Raising the `ttl` is safe at once.
|
|
273
265
|
*/
|
|
274
|
-
|
|
275
|
-
return (0, boundary_1.guardPublic)('history.ensureS3LifecycleRule', () => this.shell.ensureLifecycleRule());
|
|
276
|
-
}
|
|
266
|
+
ensureS3LifecycleRule(): Promise<void>;
|
|
277
267
|
}
|
|
278
|
-
exports.DynamoDBChatMessageHistory = DynamoDBChatMessageHistory;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { guardPublic, guardPublicSync } from '../shared/errors/boundary.js';
|
|
2
|
+
import { assertCancelOptions } from '../shared/validation/collaborators.js';
|
|
3
|
+
import { addMessages as addMessagesAction } from './actions/add-messages.js';
|
|
4
|
+
import { clearSession } from './actions/clear.js';
|
|
5
|
+
import { getMessages as getMessagesAction } from './actions/get-messages.js';
|
|
6
|
+
import { listSessions as listSessionsAction } from './actions/list-sessions.js';
|
|
7
|
+
import { reconcileMessageCount as reconcileMessageCountAction } from './actions/reconcile-count.js';
|
|
8
|
+
import { setUpHistory } from './internal/setup.js';
|
|
9
|
+
import { DynamoDBSessionChatMessageHistory } from './session-adapter.js';
|
|
10
|
+
export class DynamoDBChatMessageHistory {
|
|
11
|
+
context;
|
|
12
|
+
shell;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
const setup = setUpHistory(options);
|
|
15
|
+
this.context = setup.context;
|
|
16
|
+
this.shell = setup.shell;
|
|
17
|
+
}
|
|
18
|
+
getMessages(sessionId, options) {
|
|
19
|
+
return guardPublic('history.getMessages', () => getMessagesAction(this.context, sessionId, options), this.context.tableName);
|
|
20
|
+
}
|
|
21
|
+
addMessages(sessionId, messages, options) {
|
|
22
|
+
return guardPublic('history.addMessages', () => {
|
|
23
|
+
assertCancelOptions(options);
|
|
24
|
+
return addMessagesAction(this.context, sessionId, messages, options?.signal);
|
|
25
|
+
}, this.context.tableName);
|
|
26
|
+
}
|
|
27
|
+
addMessage(sessionId, message, options) {
|
|
28
|
+
return guardPublic('history.addMessage', () => {
|
|
29
|
+
assertCancelOptions(options);
|
|
30
|
+
return addMessagesAction(this.context, sessionId, [message], options?.signal);
|
|
31
|
+
}, this.context.tableName);
|
|
32
|
+
}
|
|
33
|
+
clear(sessionId, options) {
|
|
34
|
+
return guardPublic('history.clear', () => {
|
|
35
|
+
assertCancelOptions(options);
|
|
36
|
+
return clearSession(this.context, sessionId, options);
|
|
37
|
+
}, this.context.tableName);
|
|
38
|
+
}
|
|
39
|
+
listSessions(options) {
|
|
40
|
+
return guardPublic('history.listSessions', () => listSessionsAction(this.context, options), this.context.tableName);
|
|
41
|
+
}
|
|
42
|
+
reconcileMessageCount(sessionId, options) {
|
|
43
|
+
return guardPublic('history.reconcileMessageCount', () => {
|
|
44
|
+
assertCancelOptions(options);
|
|
45
|
+
return reconcileMessageCountAction(this.context, sessionId, options?.signal);
|
|
46
|
+
}, this.context.tableName);
|
|
47
|
+
}
|
|
48
|
+
forSession(sessionId, window) {
|
|
49
|
+
return guardPublicSync('history.forSession', () => new DynamoDBSessionChatMessageHistory(this, sessionId, window), this.context.tableName);
|
|
50
|
+
}
|
|
51
|
+
destroy() {
|
|
52
|
+
guardPublicSync('history.destroy', () => this.shell.release(), this.context.tableName);
|
|
53
|
+
}
|
|
54
|
+
async ensureS3LifecycleRule() {
|
|
55
|
+
return guardPublic('history.ensureS3LifecycleRule', () => this.shell.ensureLifecycleRule(), this.context.tableName);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides how an append of any size commits all-or-nothing, as its caller sees it.
|
|
3
|
+
*
|
|
4
|
+
* One `TransactWriteItems` carries at most a hundred items and four megabytes,
|
|
5
|
+
* so a large append is several transactions, each writing its messages and the
|
|
6
|
+
* SESSION row's update together. When one of them fails the append is rolled
|
|
7
|
+
* back: committed chunks are deleted and their effect on the SESSION row
|
|
8
|
+
* reverted, and each S3 object is released only once no row can name it.
|
|
9
|
+
* Every failure but a refusal is read back before anything is undone, and a
|
|
10
|
+
* chunk that may still commit keeps its objects. This is also the
|
|
11
|
+
* one module that writes a message row, which is what lets a delete pin a
|
|
12
|
+
* message row to the SESSION row's `writeId`.
|
|
13
|
+
*/
|
|
14
|
+
import { type RowKey } from '../../shared/dynamodb/table-schema.js';
|
|
15
|
+
import type { SessionId, StorableMessages } from './parse.js';
|
|
16
|
+
import { type MessageRow } from './rows.js';
|
|
17
|
+
import { type SessionUpdateFields, type TtlAnchorResult } from './session.js';
|
|
18
|
+
import { type HistoryContext } from './setup.js';
|
|
19
|
+
/** One append, parsed: the session, its messages in stored form, and the session's ttl anchor. */
|
|
20
|
+
export interface AppendRequest {
|
|
21
|
+
readonly sessionId: SessionId;
|
|
22
|
+
readonly messages: StorableMessages;
|
|
23
|
+
/** The session's creation-anchored ttl, when the adapter has a ttl. */
|
|
24
|
+
readonly anchor: TtlAnchorResult | undefined;
|
|
25
|
+
readonly signal?: AbortSignal;
|
|
26
|
+
}
|
|
27
|
+
/** Shared per-append metadata applied to every chunk's session update. */
|
|
28
|
+
interface AppendFields {
|
|
29
|
+
now: string;
|
|
30
|
+
title?: string;
|
|
31
|
+
ttlTimestamp?: number;
|
|
32
|
+
forceTtlRefresh?: boolean;
|
|
33
|
+
/** The expired anchor the session row carries, which the first chunk starts the session over from. */
|
|
34
|
+
restart?: number;
|
|
35
|
+
}
|
|
36
|
+
/** An append cut into chunks, with the fields every chunk's SESSION update stamps. */
|
|
37
|
+
export interface ChunkedAppend {
|
|
38
|
+
readonly sessionId: SessionId;
|
|
39
|
+
readonly chunks: MessageRow[][];
|
|
40
|
+
readonly fields: AppendFields;
|
|
41
|
+
readonly signal?: AbortSignal;
|
|
42
|
+
}
|
|
43
|
+
/** A chunk that committed, retained so it can be rolled back on a later failure. */
|
|
44
|
+
interface CommittedChunk {
|
|
45
|
+
keys: RowKey[];
|
|
46
|
+
count: number;
|
|
47
|
+
}
|
|
48
|
+
/** How far a failed append got, which decides what its rollback undoes. */
|
|
49
|
+
export interface FailedAppend {
|
|
50
|
+
readonly committed: CommittedChunk[];
|
|
51
|
+
readonly trigger: Error;
|
|
52
|
+
/** True when the failing chunk's own outcome could not be read back. */
|
|
53
|
+
readonly uncertain: boolean;
|
|
54
|
+
/** Why the failing chunk's outcome is unknown: the read-back's own failure, or the write's failure when some attempt of it may still be applied. */
|
|
55
|
+
readonly unsettledBecause?: Error;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Append messages to a session: encode them, cut them into transactions, and
|
|
59
|
+
* commit them all or undo what committed.
|
|
60
|
+
*
|
|
61
|
+
* Accepts: `request` — the parsed session and messages, the ttl anchor, and
|
|
62
|
+
* the caller's signal.
|
|
63
|
+
*
|
|
64
|
+
* Returns: nothing, once every chunk has committed.
|
|
65
|
+
*
|
|
66
|
+
* Throws: the first chunk's failure after the append is rolled back;
|
|
67
|
+
* `COMPENSATION_FAILED` when the rollback itself fails, or when a failing
|
|
68
|
+
* chunk's own outcome could not be established; `ABORTED` when the signal
|
|
69
|
+
* fires, after the same rollback; whatever encoding a message throws, after
|
|
70
|
+
* this call's own uploads are released.
|
|
71
|
+
*/
|
|
72
|
+
export declare function appendMessages(context: HistoryContext, request: AppendRequest): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Undo a failed batch. Always throws. S3 cleanup is split by commit status so
|
|
75
|
+
* no live row is ever left pointing at a deleted object: the never-committed
|
|
76
|
+
* suffix is cleaned immediately, the committed prefix only after its rows are
|
|
77
|
+
* confirmed deleted. If the rollback itself fails, the committed chunks' S3
|
|
78
|
+
* objects are deliberately left in place (their rows may survive) and it
|
|
79
|
+
* raises `COMPENSATION_FAILED` carrying both the trigger and the rollback
|
|
80
|
+
* error. Once the rollback has succeeded, it rethrows the trigger unchanged —
|
|
81
|
+
* unless the failing chunk itself is unsettled and the trigger is not a
|
|
82
|
+
* cancel, in which case it raises `COMPENSATION_FAILED` again, this time
|
|
83
|
+
* carrying `failure.unsettledBecause`: the rollback did not fail, but the
|
|
84
|
+
* session still cannot be called restored while that one chunk's own fate is
|
|
85
|
+
* unknown. A cancel is always reported as the cancel it is.
|
|
86
|
+
*
|
|
87
|
+
* `failure.uncertain` marks the failed chunk
|
|
88
|
+
* (`append.chunks[failure.committed.length]`) as one whose outcome could not be
|
|
89
|
+
* verified: its rows may be live, so its objects are leaked rather than
|
|
90
|
+
* deleted, while the never-attempted chunks after it are still cleaned.
|
|
91
|
+
*
|
|
92
|
+
* Accepts: `append` — the append that failed: its `sessionId`, its `chunks` in
|
|
93
|
+
* order, and the `fields.now` and `fields.title` its first chunk stamped on
|
|
94
|
+
* the session row. `failure.committed` — the chunks known to have landed, in
|
|
95
|
+
* order; empty means the very first chunk failed, and then the only thing to
|
|
96
|
+
* undo is the session row this call may have created. `failure.trigger` — the
|
|
97
|
+
* failure that started this. `failure.uncertain` — see above.
|
|
98
|
+
* `failure.unsettledBecause` — why the failing chunk is unsettled, when it
|
|
99
|
+
* is: the read-back's own failure, or the write's own failure when some
|
|
100
|
+
* attempt of it may still be applied.
|
|
101
|
+
*
|
|
102
|
+
* Returns: never; the declared `Promise<never>` is the contract.
|
|
103
|
+
*
|
|
104
|
+
* Throws: `failure.trigger` when the rollback succeeded and the failing chunk
|
|
105
|
+
* is settled, or is a cancel; `COMPENSATION_FAILED` when the rollback itself
|
|
106
|
+
* failed, carrying both the trigger and the rollback error as
|
|
107
|
+
* `details.rollbackError`; or when the rollback succeeded but the failing
|
|
108
|
+
* chunk is unsettled and the trigger is not a cancel, carrying the trigger
|
|
109
|
+
* and `failure.unsettledBecause` as `details.rollbackError`.
|
|
110
|
+
*
|
|
111
|
+
* Guarantees: an object is deleted only once no row can reference it — the
|
|
112
|
+
* never-committed suffix immediately, the committed prefix only after its rows
|
|
113
|
+
* are confirmed gone, and an unverified chunk never. Storage is leaked in
|
|
114
|
+
* preference to leaving a live row pointing at a deleted object.
|
|
115
|
+
*
|
|
116
|
+
* None of its three log lines can stop it: all three go through
|
|
117
|
+
* {@link reportStep}. Otherwise a throw from the first would skip the S3
|
|
118
|
+
* cleanup, the rollback, the count revert and the rethrow all at once, leaving
|
|
119
|
+
* every committed chunk in the table with `messageCount` still counting it,
|
|
120
|
+
* and handing the caller the logger's own error in place of the failure that
|
|
121
|
+
* started this. Announcing the rollback is not the rollback.
|
|
122
|
+
*/
|
|
123
|
+
export declare function compensate(context: HistoryContext, append: ChunkedAppend, failure: FailedAppend): Promise<never>;
|
|
124
|
+
/**
|
|
125
|
+
* Append message chunks with caller-observed atomicity. Each chunk commits its
|
|
126
|
+
* messages and count in one transaction; if a later chunk fails, every
|
|
127
|
+
* already-committed chunk is deleted and its count reverted, and the batch's
|
|
128
|
+
* S3 objects are cleaned once their rows are gone, restoring the pre-call
|
|
129
|
+
* state before the error is rethrown. Except on a failed rollback, or a chunk
|
|
130
|
+
* whose outcome cannot be established (below), which surface as
|
|
131
|
+
* `COMPENSATION_FAILED`; a failed rollback deliberately leaves the committed
|
|
132
|
+
* chunks' S3 objects behind, since their rows may survive.
|
|
133
|
+
*
|
|
134
|
+
* A failure that is not a refusal is ambiguous — the transaction may have
|
|
135
|
+
* committed and lost its response — so the chunk is read back first. Present
|
|
136
|
+
* means it committed. Absent means it did not, unless some attempt of it may
|
|
137
|
+
* still be applied by DynamoDB — one that got no answer, or one DynamoDB
|
|
138
|
+
* answered as still in progress (`TransactionInProgressException`) or with a
|
|
139
|
+
* server error (5xx). A failed read, and that last case, leave the chunk
|
|
140
|
+
* unsettled: its objects are leaked, the rest is rolled back, and the call
|
|
141
|
+
* fails with `COMPENSATION_FAILED`, or with `ABORTED` when the caller
|
|
142
|
+
* cancelled. A chunk that landed although the cancel cut its answer short is
|
|
143
|
+
* rolled back with the rest, and no chunk is sent once the signal has fired.
|
|
144
|
+
*
|
|
145
|
+
* Accepts: `append.sessionId` — the session every chunk writes to.
|
|
146
|
+
* `append.chunks` — in order, each already within the transaction's limits;
|
|
147
|
+
* no chunks is no work and no write. `append.fields` — the session update every
|
|
148
|
+
* chunk carries. `append.signal` — aborts between chunks.
|
|
149
|
+
*
|
|
150
|
+
* Returns: nothing, and only when every chunk is known to have committed.
|
|
151
|
+
*
|
|
152
|
+
* Throws: the first chunk's failure, after the rollback has restored the
|
|
153
|
+
* pre-call state; `COMPENSATION_FAILED` carrying both that failure and the
|
|
154
|
+
* rollback's own, when the rollback could not finish; `COMPENSATION_FAILED`
|
|
155
|
+
* too, carrying the failing chunk's own unsettled reason as
|
|
156
|
+
* `details.rollbackError`, when the rollback succeeded but that chunk's own
|
|
157
|
+
* outcome could not be established; `ABORTED` when the signal fires, after
|
|
158
|
+
* the same rollback.
|
|
159
|
+
*
|
|
160
|
+
* Guarantees: each message's S3 key carries its own ULID, so no two rows of any
|
|
161
|
+
* call can address the same object and the rollback's cleanup can never delete
|
|
162
|
+
* an object a surviving row still points at. What a caller observes is
|
|
163
|
+
* all-or-nothing; what the table holds is all-or-nothing only until a
|
|
164
|
+
* rollback fails, or a failing chunk's own outcome cannot be established,
|
|
165
|
+
* which is why either case is a distinct error and not a rethrow.
|
|
166
|
+
*/
|
|
167
|
+
export declare function appendChunks(context: HistoryContext, append: ChunkedAppend): Promise<void>;
|
|
168
|
+
/** Per-call retry seams (injected in tests to keep backoff instant). */
|
|
169
|
+
export interface ChunkRetryOptions {
|
|
170
|
+
rng?: () => number;
|
|
171
|
+
signal?: AbortSignal;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Atomically write a chunk of message items together with the session-metadata
|
|
175
|
+
* count update in one {@link https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html | TransactWriteItems}
|
|
176
|
+
* call, so `messageCount` can never disagree with the messages that landed. A
|
|
177
|
+
* single `ClientRequestToken` is used per attempt so a re-sent commit (e.g.
|
|
178
|
+
* after a lost response) is idempotent and never double-applies the count
|
|
179
|
+
* `ADD`. When `fields.forceTtlRefresh` is set, the session update carries a
|
|
180
|
+
* monotonic ConditionExpression (see session.ts), and when `fields.restart`
|
|
181
|
+
* names an expired anchor it is pinned to that anchor; if — and only if —
|
|
182
|
+
* that condition loses a race against a concurrent caller who just healed or
|
|
183
|
+
* restarted the same session, this retries the identical chunk once with
|
|
184
|
+
* `forceTtlRefresh: false` and no `restart` (safe: `if_not_exists` and `ADD`
|
|
185
|
+
* then converge on whatever already won) rather than losing the message
|
|
186
|
+
* writes to a benign ttl race. A
|
|
187
|
+
* cancellation caused by any other item (a genuine message-row conflict) is
|
|
188
|
+
* not retried here — it propagates for the normal transient-conflict retry
|
|
189
|
+
* budget inside `withDynamoDBRetry` to handle, or to the caller otherwise.
|
|
190
|
+
*
|
|
191
|
+
* Accepts: `items` — one chunk, already within the transaction's limits.
|
|
192
|
+
* `fields` — the session-metadata update accompanying it; its `indexShards` and
|
|
193
|
+
* its `writeId` are taken from the adapter's context, never from the caller.
|
|
194
|
+
* `retry.signal` — aborts between attempts.
|
|
195
|
+
*
|
|
196
|
+
* Returns: nothing. The chunk and the count are committed together or not at
|
|
197
|
+
* all.
|
|
198
|
+
*
|
|
199
|
+
* Throws: whatever the transaction throws — including a
|
|
200
|
+
* `TransactionCanceledException` for a genuine conflict, after the retry budget
|
|
201
|
+
* is spent. The caller compensates; this function never partially succeeds.
|
|
202
|
+
*
|
|
203
|
+
* Guarantees: `messageCount` can never disagree with the messages that landed,
|
|
204
|
+
* because they land in one transaction. At most one extra attempt is spent on
|
|
205
|
+
* the benign ttl race, and it carries its own request token, so a retry can
|
|
206
|
+
* never double-apply the count — and its own deadline of
|
|
207
|
+
* `MAX_WRITE_LIFETIME_MS`, so the retrying stops while that token is
|
|
208
|
+
* still deduplicating rather than after it has expired. The SESSION row's
|
|
209
|
+
* `writeId` moves if and only if a message row was added: the update travels in
|
|
210
|
+
* the same transaction as the rows, and nothing else writes it.
|
|
211
|
+
*/
|
|
212
|
+
export declare function writeMessageChunk(context: HistoryContext, items: MessageRow[], fields: Omit<SessionUpdateFields, 'writeId'>, retry?: ChunkRetryOptions): Promise<void>;
|
|
213
|
+
/**
|
|
214
|
+
* Conservatively estimate a message row's stored size.
|
|
215
|
+
*
|
|
216
|
+
* Accepts: any message row, inline or offloaded — an offloaded one measures
|
|
217
|
+
* its S3 key, since that is what the row actually carries.
|
|
218
|
+
*
|
|
219
|
+
* Returns: an estimate at or above the real marshalled size. Erring high is the
|
|
220
|
+
* whole point: an underestimate builds a transaction DynamoDB refuses, and the
|
|
221
|
+
* cost of erring high is one extra transaction.
|
|
222
|
+
*
|
|
223
|
+
* Throws: nothing.
|
|
224
|
+
*/
|
|
225
|
+
export declare function estimateRowBytes(item: MessageRow): number;
|
|
226
|
+
/**
|
|
227
|
+
* Split message items into transaction-sized chunks.
|
|
228
|
+
*
|
|
229
|
+
* Accepts: `items` — in order; empty yields no chunks, so an append of nothing
|
|
230
|
+
* issues no write. `maxItems` and `maxBytes` — the transaction's two limits,
|
|
231
|
+
* both binding.
|
|
232
|
+
*
|
|
233
|
+
* Returns: the chunks, in order, each within both limits — except that a single
|
|
234
|
+
* item larger than `maxBytes` is placed alone rather than dropped: refusing it
|
|
235
|
+
* here would lose a message that DynamoDB might still accept, and if it does
|
|
236
|
+
* not, the transaction says so.
|
|
237
|
+
*
|
|
238
|
+
* Throws: nothing.
|
|
239
|
+
*
|
|
240
|
+
* Guarantees: order is preserved across chunks, so messages keep the order the
|
|
241
|
+
* caller wrote them in, which is the order their ULIDs already encode.
|
|
242
|
+
*/
|
|
243
|
+
export declare function chunkBySize(items: MessageRow[], maxItems: number, maxBytes: number): MessageRow[][];
|
|
244
|
+
export {};
|