@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,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides the JSON form: writing it, reading it, and recognising it.
|
|
3
|
+
*
|
|
4
|
+
* The default serde writes a value as JSON under the `json` type and reads
|
|
5
|
+
* back only that type; the codec also asks, when a serde refuses stored bytes,
|
|
6
|
+
* whether those bytes are still JSON at all, which tells a corrupt payload from
|
|
7
|
+
* a serde that would not reconstruct it.
|
|
8
|
+
*/
|
|
9
|
+
import type { SerializerProtocol } from '@langchain/langgraph-checkpoint';
|
|
10
|
+
/**
|
|
11
|
+
* A plain JSON serializer implementing LangGraph's `SerializerProtocol`:
|
|
12
|
+
* the default `serde` of `DynamoDBStore` and `DynamoDBChatMessageHistory`, and
|
|
13
|
+
* the alternative a `DynamoDBSaver` can be given in place of LangGraph's
|
|
14
|
+
* `JsonPlusSerializer`.
|
|
15
|
+
*
|
|
16
|
+
* It is exported so that choice is available. The checkpointer's default
|
|
17
|
+
* revives a stored `{"lc": …}` record by instantiating the class the record
|
|
18
|
+
* names, so the row selects which constructor runs on read; this serializer
|
|
19
|
+
* runs `JSON.parse` and nothing else, and reconstructs no class at all.
|
|
20
|
+
* Reading with it is the narrower trust boundary, and the price is stated
|
|
21
|
+
* below: it stores the JSON projection of a value, not the value.
|
|
22
|
+
*
|
|
23
|
+
* `dumpsTyped` accepts any value `JSON.stringify` can represent and refuses the
|
|
24
|
+
* rest. A value it cannot represent — `undefined`, a function, a symbol —
|
|
25
|
+
* stringifies to `undefined` and would be stored as **zero bytes**, which reads
|
|
26
|
+
* back as a parse error; a circular structure or a `BigInt` makes it throw. Both
|
|
27
|
+
* are reported as `VALIDATION` naming `value`, at the write, rather than
|
|
28
|
+
* as an unreadable row later — with the refusal attached as `cause` and never
|
|
29
|
+
* quoted into the message, which for a circular structure names the caller's
|
|
30
|
+
* own properties and classes.
|
|
31
|
+
*
|
|
32
|
+
* What it represents, it represents as JSON, which is lossy in ways nothing
|
|
33
|
+
* records: a `Map` or `Set` stores as `{}`, an object key whose value is
|
|
34
|
+
* `undefined` is dropped and an array element is stored as `null`, `NaN` and
|
|
35
|
+
* `Infinity` store as `null`, `-0` as `0`, a `Uint8Array` as an index-keyed
|
|
36
|
+
* object and a `Date` as an ISO string. The README's *Table schema* section
|
|
37
|
+
* holds the whole table, against the checkpointer default column by column.
|
|
38
|
+
*
|
|
39
|
+
* `loadsTyped` reads only the `json` form it writes, and says
|
|
40
|
+
* so before it looks at a byte. Any other declared form is a `VALIDATION` error
|
|
41
|
+
* naming `serde`, because it says what *this* reader may rebuild and not that
|
|
42
|
+
* the payload is damaged. Bytes of that form which do not parse are
|
|
43
|
+
* `PAYLOAD_CORRUPT`, because they can never be read and the caller should
|
|
44
|
+
* report rather than retry; a `data` that is not bytes at all is a
|
|
45
|
+
* `VALIDATION` naming `data`, because that is the caller's mistake and
|
|
46
|
+
* not a row's.
|
|
47
|
+
*
|
|
48
|
+
* Frozen for the reason {@link ErrorCode} is: one object, shared by every
|
|
49
|
+
* adapter in the process that did not pass a `serde` of its own, and
|
|
50
|
+
* reachable from the package root. An assignment to `dumpsTyped` by any one
|
|
51
|
+
* consumer would silently change how every other one writes.
|
|
52
|
+
*/
|
|
53
|
+
export declare const JSON_SERDE: SerializerProtocol;
|
|
54
|
+
/**
|
|
55
|
+
* Whether stored bytes are still the form the row that holds them declares.
|
|
56
|
+
*
|
|
57
|
+
* This is the structural question behind the two ways a decode fails —
|
|
58
|
+
* `PAYLOAD_CORRUPT` for bytes no reader can decode, and the `serde` refusal for
|
|
59
|
+
* bytes *this* reader will not rebuild a value from — and it is the only one
|
|
60
|
+
* this package can answer on its own. `SerializerProtocol` offers no way to ask
|
|
61
|
+
* a serde whether it parsed the bytes before deciding not to reconstruct what
|
|
62
|
+
* they name, and the refusal it throws is a caller's object: its class, its
|
|
63
|
+
* fields and its prose are all whatever that caller chose. Classifying a
|
|
64
|
+
* payload by any of those would make the code mean "a third party said so",
|
|
65
|
+
* which is exactly what neither code may mean.
|
|
66
|
+
*
|
|
67
|
+
* Accepts: `serdeType` — the type stamped on the row, as the descriptor carries
|
|
68
|
+
* it. `bytes` — what the row stored, already decompressed.
|
|
69
|
+
*
|
|
70
|
+
* Returns: whether the bytes still parse as the declared form. A type this
|
|
71
|
+
* package has no grammar for is taken at its word and answers `true`, so its
|
|
72
|
+
* serde's refusal is reported rather than written off: dropping a payload this
|
|
73
|
+
* reader merely cannot check would lose data on nothing but its own ignorance.
|
|
74
|
+
*
|
|
75
|
+
* Throws: **nothing**, for any bytes. It is called from inside the `catch` that
|
|
76
|
+
* is classifying a decode failure, where a throw would replace the failure
|
|
77
|
+
* being reported — and the value it is handed came off a row, so it may be
|
|
78
|
+
* anything that row's writer stored.
|
|
79
|
+
*/
|
|
80
|
+
export declare function bytesHoldDeclaredForm(serdeType: string, bytes: Uint8Array): boolean;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { DynamoDBLangGraphError, toError } from '../errors/base-error.js';
|
|
2
|
+
import { ErrorCode } from '../errors/error-code.js';
|
|
3
|
+
import { validationError } from '../errors/errors.js';
|
|
4
|
+
import { truncateForLog } from '../logging/truncate.js';
|
|
5
|
+
export const JSON_SERDE = {
|
|
6
|
+
async dumpsTyped(value) {
|
|
7
|
+
let text;
|
|
8
|
+
try {
|
|
9
|
+
text = JSON.stringify(value);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
throw validationError('value cannot be serialized as JSON — a circular structure, or a value JSON has no ' +
|
|
13
|
+
'encoding for such as a BigInt; the refusal itself is attached as `cause`', 'value', toError(error));
|
|
14
|
+
}
|
|
15
|
+
if (text === undefined) {
|
|
16
|
+
throw validationError('value has no JSON representation (undefined, a function or a symbol), so it cannot be ' +
|
|
17
|
+
'stored; store null instead to record an absent value', 'value');
|
|
18
|
+
}
|
|
19
|
+
return Promise.resolve([JSON_SERDE_TYPE, new TextEncoder().encode(text)]);
|
|
20
|
+
},
|
|
21
|
+
async loadsTyped(type, data) {
|
|
22
|
+
if (type !== JSON_SERDE_TYPE) {
|
|
23
|
+
throw validationError(`this serializer reads only the \`${JSON_SERDE_TYPE}\` form it writes, and this payload ` +
|
|
24
|
+
`declares ${truncateForLog(String(JSON.stringify(type)))}; read the row with the ` +
|
|
25
|
+
'serializer that wrote it, or rewrite the row', 'serde');
|
|
26
|
+
}
|
|
27
|
+
let text;
|
|
28
|
+
try {
|
|
29
|
+
text = typeof data === 'string' ? data : new TextDecoder().decode(data);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
throw validationError('data must be the bytes or text this serializer wrote, as a Uint8Array or a string', 'data', error);
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
return Promise.resolve(JSON.parse(text));
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
throw new DynamoDBLangGraphError('the stored payload is not the JSON this serializer wrote, so it cannot be decoded', ErrorCode.PAYLOAD_CORRUPT, {}, error);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
Object.freeze(JSON_SERDE);
|
|
43
|
+
const JSON_SERDE_TYPE = 'json';
|
|
44
|
+
export function bytesHoldDeclaredForm(serdeType, bytes) {
|
|
45
|
+
if (serdeType !== JSON_SERDE_TYPE)
|
|
46
|
+
return true;
|
|
47
|
+
try {
|
|
48
|
+
JSON.parse(new TextDecoder().decode(bytes));
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides the S3 SDK's own types from this package's declarations.
|
|
3
|
+
*
|
|
4
|
+
* The S3 client, its config and a command are described by the members this
|
|
5
|
+
* package touches, so no shipped declaration imports the optional
|
|
6
|
+
* `@aws-sdk/client-s3` peer and a caller without it installed still compiles
|
|
7
|
+
* (record 1). A real `S3Client` or `S3ClientConfig` satisfies these shapes as
|
|
8
|
+
* it is, so a caller who has the SDK passes its own values unchanged.
|
|
9
|
+
*/
|
|
10
|
+
/** A region as the SDK accepts it: a string or a provider resolving to one. */
|
|
11
|
+
export type S3RegionLike = string | (() => Promise<string>);
|
|
12
|
+
/** A value an S3 client option can hold. */
|
|
13
|
+
export type S3ClientOption = string | number | boolean | object | null | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* The S3 client options this library reads (`region`) or sets (`maxAttempts`),
|
|
16
|
+
* open to every other `S3ClientConfig` key.
|
|
17
|
+
*/
|
|
18
|
+
export interface S3ClientOptions {
|
|
19
|
+
region?: S3RegionLike;
|
|
20
|
+
maxAttempts?: number;
|
|
21
|
+
[option: string]: S3ClientOption;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Structural stand-in for `S3ClientConfig`, so the shipped declarations compile
|
|
25
|
+
* without the optional `@aws-sdk/client-s3` peer installed. A literal gets
|
|
26
|
+
* completion for the options the library uses; a typed `S3ClientConfig`
|
|
27
|
+
* variable is accepted as it is.
|
|
28
|
+
*/
|
|
29
|
+
export type S3ClientConfigLike = S3ClientOptions | object;
|
|
30
|
+
/**
|
|
31
|
+
* The options of a config, read through the structural type.
|
|
32
|
+
*
|
|
33
|
+
* Accepts: a config as the caller gave it, or nothing.
|
|
34
|
+
*
|
|
35
|
+
* Returns: the same object seen as {@link S3ClientOptions} so `region` and
|
|
36
|
+
* `maxAttempts` can be read; an absent config reads as empty rather than
|
|
37
|
+
* needing a guard at every call site.
|
|
38
|
+
*
|
|
39
|
+
* Throws: nothing.
|
|
40
|
+
*/
|
|
41
|
+
export declare function s3ClientOptions(config: S3ClientConfigLike | undefined): S3ClientOptions;
|
|
42
|
+
/** What every SDK command object carries: its `input`. */
|
|
43
|
+
interface S3CommandLike {
|
|
44
|
+
input: object;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The S3 client surface this library calls, typed structurally for the same
|
|
48
|
+
* reason. `S3Client` from `@aws-sdk/client-s3` satisfies it.
|
|
49
|
+
*/
|
|
50
|
+
export interface S3ClientLike {
|
|
51
|
+
send(command: S3CommandLike, options?: object): Promise<object>;
|
|
52
|
+
destroy(): void;
|
|
53
|
+
}
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides that the S3 SDK is loaded on first use, and how its client is set up.
|
|
3
|
+
*
|
|
4
|
+
* An adapter without offload never imports the optional peer; the first
|
|
5
|
+
* offload does, once, and a missing install surfaces as `VALIDATION` naming
|
|
6
|
+
* the remedy (record 1). The client built here defaults to no retries of its
|
|
7
|
+
* own — `maxAttempts: 1` — so this package's retry is the only layer unless a
|
|
8
|
+
* caller's own `maxAttempts` overrides it (record 14), and its idle timer
|
|
9
|
+
* bounds a stalled transfer without bounding a slow one.
|
|
10
|
+
*/
|
|
11
|
+
import type { S3Client } from '@aws-sdk/client-s3';
|
|
12
|
+
import { type S3ClientConfigLike, type S3ClientOptions } from './client-types.js';
|
|
13
|
+
type S3Sdk = typeof import('@aws-sdk/client-s3');
|
|
14
|
+
/**
|
|
15
|
+
* The optional `@aws-sdk/client-s3` peer, imported on first use.
|
|
16
|
+
*
|
|
17
|
+
* Accepts: nothing. Concurrent callers share one import.
|
|
18
|
+
*
|
|
19
|
+
* Returns: the module, cached for every later call.
|
|
20
|
+
*
|
|
21
|
+
* Throws: `VALIDATION` naming `s3` when the package is not installed,
|
|
22
|
+
* carrying the install command; any other import failure — a broken build, a
|
|
23
|
+
* syntax error inside the package — passes through unchanged. A failure is not
|
|
24
|
+
* cached, so an install or a fixed bundle succeeds on a later call. Each
|
|
25
|
+
* concurrent caller of a failed import gets its own error instance
|
|
26
|
+
* (`copyForCaller`), so the public boundary stamping one's `context.operation`
|
|
27
|
+
* cannot leave it sitting in another caller's error too.
|
|
28
|
+
*/
|
|
29
|
+
export declare function loadS3Sdk(): Promise<S3Sdk>;
|
|
30
|
+
/**
|
|
31
|
+
* `config` with the two defaults every S3 client of this library is built
|
|
32
|
+
* with, whichever constructor builds it.
|
|
33
|
+
*
|
|
34
|
+
* Accepts: `config` — the caller's `s3.clientConfig`, or an empty object.
|
|
35
|
+
*
|
|
36
|
+
* Returns: a copy whose `maxAttempts` and `requestHandler` are the caller's
|
|
37
|
+
* own where it gave one and the default where it did not. A key named with
|
|
38
|
+
* `undefined` — a config assembled from settings that were not all set — gave
|
|
39
|
+
* none, and keeps the default.
|
|
40
|
+
*
|
|
41
|
+
* Throws: nothing.
|
|
42
|
+
*
|
|
43
|
+
* Guarantees: `maxAttempts` defaults to 1, so the SDK performs no retries of
|
|
44
|
+
* its own and this library's retry, backoff and classification are the only
|
|
45
|
+
* retry layer — the same default `resolveDynamoDBClient` applies on the
|
|
46
|
+
* DynamoDB side. A default request handler bounds a transfer that has
|
|
47
|
+
* stalled, which `maxAttempts` alone does not; a `requestHandler` in `config`
|
|
48
|
+
* replaces it whole rather than merging with it.
|
|
49
|
+
*/
|
|
50
|
+
export declare function withS3ClientDefaults(config: S3ClientConfigLike): S3ClientOptions;
|
|
51
|
+
/**
|
|
52
|
+
* An `S3Client` built from `config` with the lazily-loaded SDK.
|
|
53
|
+
*
|
|
54
|
+
* Accepts: `config` — any `S3ClientConfig`; an explicit `maxAttempts` or
|
|
55
|
+
* `requestHandler` wins over the defaults {@link withS3ClientDefaults} fills
|
|
56
|
+
* in.
|
|
57
|
+
*
|
|
58
|
+
* Returns: the client. The caller owns it and destroys it.
|
|
59
|
+
*
|
|
60
|
+
* Throws: whatever {@link loadS3Sdk} throws.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createDefaultS3Client(config: S3ClientConfigLike): Promise<S3Client>;
|
|
63
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DEFAULT_SOCKET_TIMEOUT_MS } from '../../dynamodb/client.js';
|
|
2
|
+
import { copyForCaller } from '../../errors/base-error.js';
|
|
3
|
+
import { validationError } from '../../errors/errors.js';
|
|
4
|
+
import { s3ClientOptions } from './client-types.js';
|
|
5
|
+
const MISSING_MODULE_CODES = ['ERR_MODULE_NOT_FOUND', 'MODULE_NOT_FOUND'];
|
|
6
|
+
let sdkPromise;
|
|
7
|
+
function wrapMissingPeer(error) {
|
|
8
|
+
const code = error.code;
|
|
9
|
+
if (code !== undefined && MISSING_MODULE_CODES.includes(code)) {
|
|
10
|
+
throw validationError('S3 offload requires the optional peer @aws-sdk/client-s3 (npm install @aws-sdk/client-s3); ' +
|
|
11
|
+
'bundlers must keep it installed or external', 's3', error);
|
|
12
|
+
}
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
export async function loadS3Sdk() {
|
|
16
|
+
if (!sdkPromise) {
|
|
17
|
+
sdkPromise = import('@aws-sdk/client-s3').catch((error) => {
|
|
18
|
+
sdkPromise = undefined;
|
|
19
|
+
return wrapMissingPeer(error);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
return await sdkPromise;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
throw copyForCaller(error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function withS3ClientDefaults(config) {
|
|
30
|
+
const options = s3ClientOptions(config);
|
|
31
|
+
return {
|
|
32
|
+
...options,
|
|
33
|
+
maxAttempts: options.maxAttempts ?? 1,
|
|
34
|
+
requestHandler: options.requestHandler ?? { socketTimeout: DEFAULT_SOCKET_TIMEOUT_MS },
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export async function createDefaultS3Client(config) {
|
|
38
|
+
const { S3Client: S3ClientCtor } = await loadS3Sdk();
|
|
39
|
+
return new S3ClientCtor(withS3ClientDefaults(config));
|
|
40
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Hides the S3 key layout: where a row's object lives, and which keys a row may touch.
|
|
4
3
|
*
|
|
@@ -9,26 +8,41 @@
|
|
|
9
8
|
* caller passes, its checks, the default prefix per adapter and the lifecycle
|
|
10
9
|
* rule ids derived from a prefix are part of the same layout.
|
|
11
10
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
exports.encodeKeyPart = encodeKeyPart;
|
|
15
|
-
exports.buildS3Key = buildS3Key;
|
|
16
|
-
exports.assertScopedKeyPrefix = assertScopedKeyPrefix;
|
|
17
|
-
exports.buildLifecycleRuleId = buildLifecycleRuleId;
|
|
18
|
-
exports.buildMarkerRuleId = buildMarkerRuleId;
|
|
19
|
-
exports.defaultAdapterKeyPrefix = defaultAdapterKeyPrefix;
|
|
20
|
-
exports.s3KeyScope = s3KeyScope;
|
|
21
|
-
exports.isKeyInScope = isKeyInScope;
|
|
22
|
-
exports.assertKeyInScope = assertKeyInScope;
|
|
23
|
-
exports.offloaderConfigFor = offloaderConfigFor;
|
|
24
|
-
const errors_1 = require("../../errors/errors");
|
|
25
|
-
const truncate_1 = require("../../logging/truncate");
|
|
26
|
-
const primitives_1 = require("../../validation/primitives");
|
|
27
|
-
const client_types_1 = require("./client-types");
|
|
11
|
+
import type { DynamoDBClientConfig } from '@aws-sdk/client-dynamodb';
|
|
12
|
+
import { type S3ClientConfigLike } from './client-types.js';
|
|
28
13
|
/** Default S3 key prefix for offloaded payloads. */
|
|
29
|
-
|
|
14
|
+
export declare const DEFAULT_S3_KEY_PREFIX = "langgraph-checkpoints/";
|
|
30
15
|
/** S3 cap on an object key, applied to the produced offload key. */
|
|
31
|
-
|
|
16
|
+
export declare const MAX_S3_KEY_BYTES = 1024;
|
|
17
|
+
/** Configuration for offloading large payloads to S3. */
|
|
18
|
+
export interface S3OffloadConfig {
|
|
19
|
+
bucketName: string;
|
|
20
|
+
keyPrefix?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Serialized payloads at or above this size are offloaded (default 350 KB).
|
|
23
|
+
* Only the payload counts: the store's inline vectors live on the same item
|
|
24
|
+
* and are not part of it. The store embeds one vector per text its
|
|
25
|
+
* `index.fields` extract — a wildcard path yields one per element — each up
|
|
26
|
+
* to about 10 bytes per dimension, so three texts at 1024 dims cost roughly
|
|
27
|
+
* 30 KB. A row that payload and those vectors would take past DynamoDB's
|
|
28
|
+
* 400 KB item limit is refused with `VALIDATION` naming `index`.
|
|
29
|
+
*/
|
|
30
|
+
thresholdBytes?: number;
|
|
31
|
+
serverSideEncryption?: string;
|
|
32
|
+
sseKmsKeyId?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Largest object this adapter will buffer from S3 (default 50 MiB). An
|
|
35
|
+
* offloaded payload larger than it is refused at the write, and a value
|
|
36
|
+
* below `thresholdBytes` is refused at construction, so an adapter never
|
|
37
|
+
* stores an object it could not read back.
|
|
38
|
+
*/
|
|
39
|
+
maxDownloadBytes?: number;
|
|
40
|
+
/**
|
|
41
|
+
* S3 client configuration (an `S3ClientConfig`). `region` defaults to the
|
|
42
|
+
* adapter's DynamoDB region.
|
|
43
|
+
*/
|
|
44
|
+
clientConfig?: S3ClientConfigLike;
|
|
45
|
+
}
|
|
32
46
|
/**
|
|
33
47
|
* One key part, base64url-encoded.
|
|
34
48
|
*
|
|
@@ -40,9 +54,7 @@ exports.MAX_S3_KEY_BYTES = 1024;
|
|
|
40
54
|
*
|
|
41
55
|
* Throws: nothing.
|
|
42
56
|
*/
|
|
43
|
-
function encodeKeyPart(part)
|
|
44
|
-
return Buffer.from(part, 'utf8').toString('base64url');
|
|
45
|
-
}
|
|
57
|
+
export declare function encodeKeyPart(part: string): string;
|
|
46
58
|
/**
|
|
47
59
|
* Build a fully-qualified S3 key: `${prefix}${parts, each base64url-encoded,
|
|
48
60
|
* joined with '/'}/${objectId}.bin`.
|
|
@@ -72,21 +84,7 @@ function encodeKeyPart(part) {
|
|
|
72
84
|
* third, so identifiers that each pass their own length rule can still compose
|
|
73
85
|
* a key S3 would reject with a raw error.
|
|
74
86
|
*/
|
|
75
|
-
function buildS3Key(prefix, parts, objectId)
|
|
76
|
-
if (parts.length === 0) {
|
|
77
|
-
throw (0, errors_1.validationError)('an offloaded object needs the identity of the row that points at it; parts was empty', 's3Key');
|
|
78
|
-
}
|
|
79
|
-
const encoded = [...parts.map(encodeKeyPart), objectId];
|
|
80
|
-
const key = `${prefix}${encoded.join('/')}.bin`;
|
|
81
|
-
const bytes = Buffer.byteLength(key, 'utf8');
|
|
82
|
-
if (bytes > exports.MAX_S3_KEY_BYTES) {
|
|
83
|
-
throw (0, errors_1.validationError)(`the offloaded S3 object key would be ${bytes} bytes; S3 caps keys at ` +
|
|
84
|
-
`${exports.MAX_S3_KEY_BYTES} — shorten the identifiers or the keyPrefix`, 's3Key');
|
|
85
|
-
}
|
|
86
|
-
return key;
|
|
87
|
-
}
|
|
88
|
-
/** A path segment that names something other than itself, or nothing at all. */
|
|
89
|
-
const UNSCOPED_SEGMENTS = new Set(['', '.', '..']);
|
|
87
|
+
export declare function buildS3Key(prefix: string, parts: readonly string[], objectId: string): string;
|
|
90
88
|
/**
|
|
91
89
|
* Refuse a key prefix that does not scope what it is used for.
|
|
92
90
|
*
|
|
@@ -118,25 +116,7 @@ const UNSCOPED_SEGMENTS = new Set(['', '.', '..']);
|
|
|
118
116
|
* outside the path the lifecycle rule sweeps, which is the whole job of a
|
|
119
117
|
* prefix.
|
|
120
118
|
*/
|
|
121
|
-
function assertScopedKeyPrefix(keyPrefix)
|
|
122
|
-
if (typeof keyPrefix !== 'string' ||
|
|
123
|
-
keyPrefix === '' ||
|
|
124
|
-
keyPrefix === '/' ||
|
|
125
|
-
!keyPrefix.endsWith('/')) {
|
|
126
|
-
throw (0, errors_1.validationError)('s3.keyPrefix must be a non-empty path that ends with "/" (for example "langgraph/"): ' +
|
|
127
|
-
'it scopes both the offloaded objects and the S3 lifecycle rule', 's3.keyPrefix');
|
|
128
|
-
}
|
|
129
|
-
(0, primitives_1.assertNoControlChars)(keyPrefix, 's3.keyPrefix');
|
|
130
|
-
(0, primitives_1.assertWellFormed)(keyPrefix, 's3.keyPrefix');
|
|
131
|
-
if (keyPrefix
|
|
132
|
-
.slice(0, -1)
|
|
133
|
-
.split('/')
|
|
134
|
-
.some((segment) => UNSCOPED_SEGMENTS.has(segment))) {
|
|
135
|
-
throw (0, errors_1.validationError)('s3.keyPrefix must name a real path: no empty, "." or ".." segment (for example ' +
|
|
136
|
-
'"langgraph/", not "../langgraph/" or "/langgraph/"). Such a prefix addresses object ' +
|
|
137
|
-
'keys outside the path the IAM policy grants and the lifecycle rule sweeps', 's3.keyPrefix');
|
|
138
|
-
}
|
|
139
|
-
}
|
|
119
|
+
export declare function assertScopedKeyPrefix(keyPrefix: string): void;
|
|
140
120
|
/**
|
|
141
121
|
* The lifecycle rule id for `prefix`: `langgraph-ttl-` plus its slug.
|
|
142
122
|
*
|
|
@@ -153,13 +133,7 @@ function assertScopedKeyPrefix(keyPrefix) {
|
|
|
153
133
|
* and `ensureLifecycleRule` refuses rather than take over a rule that a
|
|
154
134
|
* different prefix already holds.
|
|
155
135
|
*/
|
|
156
|
-
function buildLifecycleRuleId(prefix)
|
|
157
|
-
let trimmed = prefix;
|
|
158
|
-
while (trimmed.endsWith('/'))
|
|
159
|
-
trimmed = trimmed.slice(0, -1);
|
|
160
|
-
const slug = trimmed.replace(/[^a-zA-Z0-9-]/g, '-') || 'default';
|
|
161
|
-
return `langgraph-ttl-${slug}`;
|
|
162
|
-
}
|
|
136
|
+
export declare function buildLifecycleRuleId(prefix: string): string;
|
|
163
137
|
/**
|
|
164
138
|
* The id of the rule that reclaims this prefix's expired delete markers:
|
|
165
139
|
* {@link buildLifecycleRuleId}'s id with a suffix of its own.
|
|
@@ -181,9 +155,7 @@ function buildLifecycleRuleId(prefix) {
|
|
|
181
155
|
* over either id when a different prefix already holds it, and its refusal
|
|
182
156
|
* names the suffix so the remedy fits the case.
|
|
183
157
|
*/
|
|
184
|
-
function buildMarkerRuleId(prefix)
|
|
185
|
-
return `${buildLifecycleRuleId(prefix)}-markers`;
|
|
186
|
-
}
|
|
158
|
+
export declare function buildMarkerRuleId(prefix: string): string;
|
|
187
159
|
/**
|
|
188
160
|
* An adapter's default S3 key prefix.
|
|
189
161
|
*
|
|
@@ -196,9 +168,7 @@ function buildMarkerRuleId(prefix) {
|
|
|
196
168
|
*
|
|
197
169
|
* Throws: nothing.
|
|
198
170
|
*/
|
|
199
|
-
function defaultAdapterKeyPrefix(base, adapter)
|
|
200
|
-
return `${base}${adapter}/`;
|
|
201
|
-
}
|
|
171
|
+
export declare function defaultAdapterKeyPrefix(base: string, adapter: string): string;
|
|
202
172
|
/**
|
|
203
173
|
* The path every key built from `parts` shares.
|
|
204
174
|
*
|
|
@@ -210,9 +180,7 @@ function defaultAdapterKeyPrefix(base, adapter) {
|
|
|
210
180
|
*
|
|
211
181
|
* Throws: nothing.
|
|
212
182
|
*/
|
|
213
|
-
function s3KeyScope(prefix, parts)
|
|
214
|
-
return `${prefix}${parts.map(encodeKeyPart).join('/')}`;
|
|
215
|
-
}
|
|
183
|
+
export declare function s3KeyScope(prefix: string, parts: readonly string[]): string;
|
|
216
184
|
/**
|
|
217
185
|
* Whether `key` lies inside the path `parts` produce.
|
|
218
186
|
*
|
|
@@ -231,12 +199,7 @@ function s3KeyScope(prefix, parts) {
|
|
|
231
199
|
* `t1`) never matches its scope — the parts are base64url-encoded and joined
|
|
232
200
|
* by `/`, so the comparison is segment-wise, not textual.
|
|
233
201
|
*/
|
|
234
|
-
function isKeyInScope(key, prefix, parts)
|
|
235
|
-
const scope = s3KeyScope(prefix, parts);
|
|
236
|
-
if (parts.length === 0)
|
|
237
|
-
return key.startsWith(scope);
|
|
238
|
-
return key === `${scope}.bin` || key.startsWith(`${scope}/`);
|
|
239
|
-
}
|
|
202
|
+
export declare function isKeyInScope(key: string, prefix: string, parts: readonly string[]): boolean;
|
|
240
203
|
/**
|
|
241
204
|
* Refuse a row-sourced `s3Key` outside the path the row's own identifiers
|
|
242
205
|
* produce.
|
|
@@ -271,13 +234,9 @@ function isKeyInScope(key, prefix, parts) {
|
|
|
271
234
|
* at. A writer able to place one row in a partition cannot make this library
|
|
272
235
|
* download or delete another tenant's object, nor make it quietly return less.
|
|
273
236
|
*/
|
|
274
|
-
function assertKeyInScope(key, prefix, parts)
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
throw (0, errors_1.validationError)(`s3Key "${(0, truncate_1.truncateForLog)(key)}" lies outside the S3 path this row may reference ` +
|
|
278
|
-
`("${(0, truncate_1.truncateForLog)(s3KeyScope(prefix, parts))}"); refusing to touch an object the row ` +
|
|
279
|
-
'does not own', 's3Key');
|
|
280
|
-
}
|
|
237
|
+
export declare function assertKeyInScope(key: string, prefix: string, parts: readonly string[]): void;
|
|
238
|
+
/** The adapters that share one bucket, each under its own default key prefix. */
|
|
239
|
+
export type AdapterName = 'checkpointer' | 'store' | 'history';
|
|
281
240
|
/**
|
|
282
241
|
* An adapter's `s3` option resolved into the offloader's configuration.
|
|
283
242
|
*
|
|
@@ -298,11 +257,4 @@ function assertKeyInScope(key, prefix, parts) {
|
|
|
298
257
|
* region redirects, so such a bucket otherwise failed with an opaque
|
|
299
258
|
* `PermanentRedirect` on the first offload.
|
|
300
259
|
*/
|
|
301
|
-
function offloaderConfigFor(s3, adapter, clientConfig)
|
|
302
|
-
const region = (0, client_types_1.s3ClientOptions)(s3.clientConfig).region ?? clientConfig?.region;
|
|
303
|
-
return {
|
|
304
|
-
...s3,
|
|
305
|
-
keyPrefix: s3.keyPrefix ?? defaultAdapterKeyPrefix(exports.DEFAULT_S3_KEY_PREFIX, adapter),
|
|
306
|
-
...(region === undefined ? {} : { clientConfig: { ...s3.clientConfig, region } }),
|
|
307
|
-
};
|
|
308
|
-
}
|
|
260
|
+
export declare function offloaderConfigFor(s3: S3OffloadConfig, adapter: AdapterName, clientConfig?: DynamoDBClientConfig): S3OffloadConfig;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { validationError } from '../../errors/errors.js';
|
|
2
|
+
import { truncateForLog } from '../../logging/truncate.js';
|
|
3
|
+
import { assertNoControlChars, assertWellFormed } from '../../validation/primitives.js';
|
|
4
|
+
import { s3ClientOptions } from './client-types.js';
|
|
5
|
+
export const DEFAULT_S3_KEY_PREFIX = 'langgraph-checkpoints/';
|
|
6
|
+
export const MAX_S3_KEY_BYTES = 1024;
|
|
7
|
+
export function encodeKeyPart(part) {
|
|
8
|
+
return Buffer.from(part, 'utf8').toString('base64url');
|
|
9
|
+
}
|
|
10
|
+
export function buildS3Key(prefix, parts, objectId) {
|
|
11
|
+
if (parts.length === 0) {
|
|
12
|
+
throw validationError('an offloaded object needs the identity of the row that points at it; parts was empty', 's3Key');
|
|
13
|
+
}
|
|
14
|
+
const encoded = [...parts.map(encodeKeyPart), objectId];
|
|
15
|
+
const key = `${prefix}${encoded.join('/')}.bin`;
|
|
16
|
+
const bytes = Buffer.byteLength(key, 'utf8');
|
|
17
|
+
if (bytes > MAX_S3_KEY_BYTES) {
|
|
18
|
+
throw validationError(`the offloaded S3 object key would be ${bytes} bytes; S3 caps keys at ` +
|
|
19
|
+
`${MAX_S3_KEY_BYTES} — shorten the identifiers or the keyPrefix`, 's3Key');
|
|
20
|
+
}
|
|
21
|
+
return key;
|
|
22
|
+
}
|
|
23
|
+
const UNSCOPED_SEGMENTS = new Set(['', '.', '..']);
|
|
24
|
+
export function assertScopedKeyPrefix(keyPrefix) {
|
|
25
|
+
if (typeof keyPrefix !== 'string' ||
|
|
26
|
+
keyPrefix === '' ||
|
|
27
|
+
keyPrefix === '/' ||
|
|
28
|
+
!keyPrefix.endsWith('/')) {
|
|
29
|
+
throw validationError('s3.keyPrefix must be a non-empty path that ends with "/" (for example "langgraph/"): ' +
|
|
30
|
+
'it scopes both the offloaded objects and the S3 lifecycle rule', 's3.keyPrefix');
|
|
31
|
+
}
|
|
32
|
+
assertNoControlChars(keyPrefix, 's3.keyPrefix');
|
|
33
|
+
assertWellFormed(keyPrefix, 's3.keyPrefix');
|
|
34
|
+
if (keyPrefix
|
|
35
|
+
.slice(0, -1)
|
|
36
|
+
.split('/')
|
|
37
|
+
.some((segment) => UNSCOPED_SEGMENTS.has(segment))) {
|
|
38
|
+
throw validationError('s3.keyPrefix must name a real path: no empty, "." or ".." segment (for example ' +
|
|
39
|
+
'"langgraph/", not "../langgraph/" or "/langgraph/"). Such a prefix addresses object ' +
|
|
40
|
+
'keys outside the path the IAM policy grants and the lifecycle rule sweeps', 's3.keyPrefix');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export function buildLifecycleRuleId(prefix) {
|
|
44
|
+
let trimmed = prefix;
|
|
45
|
+
while (trimmed.endsWith('/'))
|
|
46
|
+
trimmed = trimmed.slice(0, -1);
|
|
47
|
+
const slug = trimmed.replace(/[^a-zA-Z0-9-]/g, '-') || 'default';
|
|
48
|
+
return `langgraph-ttl-${slug}`;
|
|
49
|
+
}
|
|
50
|
+
export function buildMarkerRuleId(prefix) {
|
|
51
|
+
return `${buildLifecycleRuleId(prefix)}-markers`;
|
|
52
|
+
}
|
|
53
|
+
export function defaultAdapterKeyPrefix(base, adapter) {
|
|
54
|
+
return `${base}${adapter}/`;
|
|
55
|
+
}
|
|
56
|
+
export function s3KeyScope(prefix, parts) {
|
|
57
|
+
return `${prefix}${parts.map(encodeKeyPart).join('/')}`;
|
|
58
|
+
}
|
|
59
|
+
export function isKeyInScope(key, prefix, parts) {
|
|
60
|
+
const scope = s3KeyScope(prefix, parts);
|
|
61
|
+
if (parts.length === 0)
|
|
62
|
+
return key.startsWith(scope);
|
|
63
|
+
return key === `${scope}.bin` || key.startsWith(`${scope}/`);
|
|
64
|
+
}
|
|
65
|
+
export function assertKeyInScope(key, prefix, parts) {
|
|
66
|
+
if (isKeyInScope(key, prefix, parts))
|
|
67
|
+
return;
|
|
68
|
+
throw validationError(`s3Key "${truncateForLog(key)}" lies outside the S3 path this row may reference ` +
|
|
69
|
+
`("${truncateForLog(s3KeyScope(prefix, parts))}"); refusing to touch an object the row ` +
|
|
70
|
+
'does not own', 's3Key');
|
|
71
|
+
}
|
|
72
|
+
export function offloaderConfigFor(s3, adapter, clientConfig) {
|
|
73
|
+
const region = s3ClientOptions(s3.clientConfig).region ?? clientConfig?.region;
|
|
74
|
+
return {
|
|
75
|
+
...s3,
|
|
76
|
+
keyPrefix: s3.keyPrefix ?? defaultAdapterKeyPrefix(DEFAULT_S3_KEY_PREFIX, adapter),
|
|
77
|
+
...(region === undefined ? {} : { clientConfig: { ...s3.clientConfig, region } }),
|
|
78
|
+
};
|
|
79
|
+
}
|