@farukada/aws-langgraph-dynamodb-ts 0.9.0 → 1.0.0-rc.2
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 +1720 -154
- package/dist/backfill/backfill.d.ts +168 -0
- package/dist/backfill/backfill.js +393 -0
- package/dist/checkpointer/actions/delete-thread.d.ts +47 -6
- package/dist/checkpointer/actions/delete-thread.js +58 -21
- package/dist/checkpointer/actions/get-tuple.d.ts +29 -4
- package/dist/checkpointer/actions/get-tuple.js +44 -10
- package/dist/checkpointer/actions/list.d.ts +46 -4
- package/dist/checkpointer/actions/list.js +121 -66
- package/dist/checkpointer/actions/put-writes.d.ts +41 -9
- package/dist/checkpointer/actions/put-writes.js +62 -77
- package/dist/checkpointer/actions/put.d.ts +83 -4
- package/dist/checkpointer/actions/put.js +177 -25
- package/dist/checkpointer/internal/delta-history.d.ts +112 -0
- package/dist/checkpointer/internal/delta-history.js +252 -0
- package/dist/checkpointer/internal/listing.d.ts +149 -0
- package/dist/checkpointer/internal/listing.js +245 -0
- package/dist/checkpointer/internal/parse.d.ts +262 -0
- package/dist/checkpointer/internal/parse.js +372 -0
- package/dist/checkpointer/internal/pending-writes.d.ts +275 -0
- package/dist/checkpointer/internal/pending-writes.js +588 -0
- package/dist/checkpointer/internal/read.d.ts +130 -0
- package/dist/checkpointer/internal/read.js +264 -0
- package/dist/checkpointer/internal/rows.d.ts +571 -0
- package/dist/checkpointer/internal/rows.js +834 -0
- package/dist/checkpointer/internal/setup.d.ts +42 -19
- package/dist/checkpointer/internal/setup.js +65 -29
- package/dist/checkpointer/saver.d.ts +256 -16
- package/dist/checkpointer/saver.js +275 -29
- package/dist/checkpointer/types.d.ts +39 -39
- package/dist/checkpointer/types.js +10 -1
- package/dist/factory/factory.d.ts +134 -28
- package/dist/factory/factory.js +240 -21
- package/dist/factory/types.d.ts +76 -0
- package/dist/factory/types.js +10 -0
- package/dist/history/actions/add-messages.d.ts +31 -4
- package/dist/history/actions/add-messages.js +38 -58
- package/dist/history/actions/clear.d.ts +49 -6
- package/dist/history/actions/clear.js +66 -14
- package/dist/history/actions/get-messages.d.ts +54 -6
- package/dist/history/actions/get-messages.js +126 -43
- package/dist/history/actions/list-sessions.d.ts +52 -10
- package/dist/history/actions/list-sessions.js +139 -40
- package/dist/history/actions/reconcile-count.d.ts +42 -10
- package/dist/history/actions/reconcile-count.js +45 -45
- package/dist/history/chat-message-history.d.ts +220 -33
- package/dist/history/chat-message-history.js +240 -43
- package/dist/history/internal/append.d.ts +212 -0
- package/dist/history/internal/append.js +500 -0
- package/dist/history/internal/message-read.d.ts +84 -0
- package/dist/history/internal/message-read.js +204 -0
- package/dist/history/internal/parse.d.ts +153 -0
- package/dist/history/internal/parse.js +252 -0
- package/dist/history/internal/rows.d.ts +195 -0
- package/dist/history/internal/rows.js +250 -0
- package/dist/history/internal/session.d.ts +331 -0
- package/dist/history/internal/session.js +628 -0
- package/dist/history/internal/setup.d.ts +52 -17
- package/dist/history/internal/setup.js +92 -21
- package/dist/history/session-adapter.d.ts +102 -7
- package/dist/history/session-adapter.js +103 -9
- package/dist/history/types.d.ts +80 -29
- package/dist/history/types.js +10 -1
- package/dist/index.d.ts +42 -11
- package/dist/index.js +33 -12
- package/dist/shared/adapter.d.ts +135 -0
- package/dist/shared/adapter.js +143 -0
- package/dist/shared/clock.d.ts +51 -2
- package/dist/shared/clock.js +57 -2
- package/dist/shared/codec/codec.d.ts +288 -13
- package/dist/shared/codec/codec.js +416 -19
- package/dist/shared/codec/compression.d.ts +43 -7
- package/dist/shared/codec/compression.js +53 -13
- package/dist/shared/codec/json-serde.d.ts +76 -4
- package/dist/shared/codec/json-serde.js +181 -8
- package/dist/shared/codec/s3/client-types.d.ts +53 -0
- package/dist/shared/codec/s3/client-types.js +26 -0
- package/dist/shared/codec/s3/client.d.ts +43 -10
- package/dist/shared/codec/s3/client.js +82 -9
- package/dist/shared/codec/s3/config.d.ts +242 -11
- package/dist/shared/codec/s3/config.js +293 -11
- package/dist/shared/codec/s3/lifecycle.d.ts +164 -6
- package/dist/shared/codec/s3/lifecycle.js +335 -27
- package/dist/shared/codec/s3/offloader.d.ts +393 -18
- package/dist/shared/codec/s3/offloader.js +595 -37
- package/dist/shared/concurrency.d.ts +43 -0
- package/dist/shared/concurrency.js +78 -0
- package/dist/shared/dynamodb/abort.d.ts +47 -0
- package/dist/shared/dynamodb/abort.js +59 -0
- package/dist/shared/dynamodb/batch-write.d.ts +77 -14
- package/dist/shared/dynamodb/batch-write.js +146 -27
- package/dist/shared/dynamodb/cancellation.d.ts +121 -4
- package/dist/shared/dynamodb/cancellation.js +147 -3
- package/dist/shared/dynamodb/client.d.ts +162 -8
- package/dist/shared/dynamodb/client.js +153 -5
- package/dist/shared/dynamodb/idempotent-write.d.ts +551 -0
- package/dist/shared/dynamodb/idempotent-write.js +593 -0
- package/dist/shared/dynamodb/paginate.d.ts +105 -9
- package/dist/shared/dynamodb/paginate.js +175 -7
- package/dist/shared/dynamodb/partition-delete.d.ts +185 -14
- package/dist/shared/dynamodb/partition-delete.js +314 -44
- package/dist/shared/dynamodb/recency-index.d.ts +231 -0
- package/dist/shared/dynamodb/recency-index.js +377 -0
- package/dist/shared/dynamodb/retry.d.ts +276 -8
- package/dist/shared/dynamodb/retry.js +433 -23
- package/dist/shared/dynamodb/table-schema.d.ts +190 -0
- package/dist/shared/dynamodb/table-schema.js +209 -0
- package/dist/shared/errors/base-error.d.ts +184 -10
- package/dist/shared/errors/base-error.js +160 -14
- package/dist/shared/errors/boundary.d.ts +71 -0
- package/dist/shared/errors/boundary.js +143 -0
- package/dist/shared/errors/classify.d.ts +97 -0
- package/dist/shared/errors/classify.js +257 -0
- package/dist/shared/errors/error-code.d.ts +77 -2
- package/dist/shared/errors/error-code.js +83 -1
- package/dist/shared/errors/errors.d.ts +158 -59
- package/dist/shared/errors/errors.js +219 -92
- package/dist/shared/logging/logger.d.ts +69 -3
- package/dist/shared/logging/logger.js +97 -3
- package/dist/shared/logging/redaction.d.ts +92 -8
- package/dist/shared/logging/redaction.js +273 -17
- package/dist/shared/logging/secret-patterns.d.ts +149 -19
- package/dist/shared/logging/secret-patterns.js +188 -27
- package/dist/shared/logging/truncate.d.ts +197 -0
- package/dist/shared/logging/truncate.js +231 -0
- package/dist/shared/options.d.ts +59 -7
- package/dist/shared/options.js +9 -1
- package/dist/shared/ulid.d.ts +77 -7
- package/dist/shared/ulid.js +103 -8
- package/dist/shared/validation/collaborators.d.ts +141 -0
- package/dist/shared/validation/collaborators.js +188 -0
- package/dist/shared/validation/option-shape.d.ts +89 -0
- package/dist/shared/validation/option-shape.js +113 -0
- package/dist/shared/validation/options.d.ts +145 -0
- package/dist/shared/validation/options.js +328 -0
- package/dist/shared/validation/primitives.d.ts +288 -21
- package/dist/shared/validation/primitives.js +353 -50
- package/dist/shared/validation/ttl.d.ts +66 -10
- package/dist/shared/validation/ttl.js +113 -15
- package/dist/store/actions/list-namespaces.d.ts +76 -6
- package/dist/store/actions/list-namespaces.js +166 -24
- package/dist/store/actions/put.d.ts +33 -8
- package/dist/store/actions/put.js +53 -60
- package/dist/store/actions/reconcile-vector-index.d.ts +31 -10
- package/dist/store/actions/reconcile-vector-index.js +34 -15
- package/dist/store/actions/search.d.ts +34 -6
- package/dist/store/actions/search.js +56 -51
- package/dist/store/internal/batch-plan.d.ts +26 -0
- package/dist/store/internal/batch-plan.js +109 -0
- package/dist/store/internal/filter.d.ts +36 -3
- package/dist/store/internal/filter.js +66 -15
- package/dist/store/internal/get-item.d.ts +45 -0
- package/dist/store/internal/get-item.js +115 -0
- package/dist/store/internal/item-write.d.ts +230 -0
- package/dist/store/internal/item-write.js +463 -0
- package/dist/store/internal/parse.d.ts +225 -0
- package/dist/store/internal/parse.js +350 -0
- package/dist/store/internal/rows.d.ts +355 -0
- package/dist/store/internal/rows.js +447 -0
- package/dist/store/internal/semantic-search.d.ts +161 -6
- package/dist/store/internal/semantic-search.js +360 -18
- package/dist/store/internal/setup.d.ts +77 -20
- package/dist/store/internal/setup.js +178 -47
- package/dist/store/internal/table-search.d.ts +100 -0
- package/dist/store/internal/table-search.js +213 -0
- package/dist/store/internal/vector-index.d.ts +247 -0
- package/dist/store/internal/vector-index.js +546 -0
- package/dist/store/store.d.ts +270 -17
- package/dist/store/store.js +329 -38
- package/dist/store/types.d.ts +76 -26
- package/dist/store/types.js +13 -1
- package/dist/store/vector-backend.d.ts +64 -4
- package/dist/store/vector-backend.js +15 -1
- package/package.json +58 -36
- package/dist/checkpointer/actions/delete-thread.d.ts.map +0 -1
- package/dist/checkpointer/actions/delete-thread.js.map +0 -1
- package/dist/checkpointer/actions/get-tuple.d.ts.map +0 -1
- package/dist/checkpointer/actions/get-tuple.js.map +0 -1
- package/dist/checkpointer/actions/list.d.ts.map +0 -1
- package/dist/checkpointer/actions/list.js.map +0 -1
- package/dist/checkpointer/actions/put-writes.d.ts.map +0 -1
- package/dist/checkpointer/actions/put-writes.js.map +0 -1
- package/dist/checkpointer/actions/put.d.ts.map +0 -1
- package/dist/checkpointer/actions/put.js.map +0 -1
- package/dist/checkpointer/internal/assemble.d.ts +0 -10
- package/dist/checkpointer/internal/assemble.d.ts.map +0 -1
- package/dist/checkpointer/internal/assemble.js +0 -37
- package/dist/checkpointer/internal/assemble.js.map +0 -1
- package/dist/checkpointer/internal/configurable.d.ts +0 -13
- package/dist/checkpointer/internal/configurable.d.ts.map +0 -1
- package/dist/checkpointer/internal/configurable.js +0 -23
- package/dist/checkpointer/internal/configurable.js.map +0 -1
- package/dist/checkpointer/internal/fetch.d.ts +0 -10
- package/dist/checkpointer/internal/fetch.d.ts.map +0 -1
- package/dist/checkpointer/internal/fetch.js +0 -46
- package/dist/checkpointer/internal/fetch.js.map +0 -1
- package/dist/checkpointer/internal/filter-match.d.ts +0 -12
- package/dist/checkpointer/internal/filter-match.d.ts.map +0 -1
- package/dist/checkpointer/internal/filter-match.js +0 -14
- package/dist/checkpointer/internal/filter-match.js.map +0 -1
- package/dist/checkpointer/internal/item-reader.d.ts +0 -55
- package/dist/checkpointer/internal/item-reader.d.ts.map +0 -1
- package/dist/checkpointer/internal/item-reader.js +0 -88
- package/dist/checkpointer/internal/item-reader.js.map +0 -1
- package/dist/checkpointer/internal/item-writer.d.ts +0 -26
- package/dist/checkpointer/internal/item-writer.d.ts.map +0 -1
- package/dist/checkpointer/internal/item-writer.js +0 -92
- package/dist/checkpointer/internal/item-writer.js.map +0 -1
- package/dist/checkpointer/internal/keys.d.ts +0 -31
- package/dist/checkpointer/internal/keys.d.ts.map +0 -1
- package/dist/checkpointer/internal/keys.js +0 -87
- package/dist/checkpointer/internal/keys.js.map +0 -1
- package/dist/checkpointer/internal/query.d.ts +0 -20
- package/dist/checkpointer/internal/query.d.ts.map +0 -1
- package/dist/checkpointer/internal/query.js +0 -36
- package/dist/checkpointer/internal/query.js.map +0 -1
- package/dist/checkpointer/internal/setup.d.ts.map +0 -1
- package/dist/checkpointer/internal/setup.js.map +0 -1
- package/dist/checkpointer/internal/special-write-cas.d.ts +0 -30
- package/dist/checkpointer/internal/special-write-cas.d.ts.map +0 -1
- package/dist/checkpointer/internal/special-write-cas.js +0 -104
- package/dist/checkpointer/internal/special-write-cas.js.map +0 -1
- package/dist/checkpointer/internal/special-write-cleanup.d.ts +0 -24
- package/dist/checkpointer/internal/special-write-cleanup.d.ts.map +0 -1
- package/dist/checkpointer/internal/special-write-cleanup.js +0 -47
- package/dist/checkpointer/internal/special-write-cleanup.js.map +0 -1
- package/dist/checkpointer/internal/special-write-verify.d.ts +0 -54
- package/dist/checkpointer/internal/special-write-verify.d.ts.map +0 -1
- package/dist/checkpointer/internal/special-write-verify.js +0 -65
- package/dist/checkpointer/internal/special-write-verify.js.map +0 -1
- package/dist/checkpointer/internal/validation.d.ts +0 -13
- package/dist/checkpointer/internal/validation.d.ts.map +0 -1
- package/dist/checkpointer/internal/validation.js +0 -30
- package/dist/checkpointer/internal/validation.js.map +0 -1
- package/dist/checkpointer/internal/write-guard.d.ts +0 -13
- package/dist/checkpointer/internal/write-guard.d.ts.map +0 -1
- package/dist/checkpointer/internal/write-guard.js +0 -39
- package/dist/checkpointer/internal/write-guard.js.map +0 -1
- package/dist/checkpointer/internal/write-index.d.ts +0 -37
- package/dist/checkpointer/internal/write-index.d.ts.map +0 -1
- package/dist/checkpointer/internal/write-index.js +0 -42
- package/dist/checkpointer/internal/write-index.js.map +0 -1
- package/dist/checkpointer/saver.d.ts.map +0 -1
- package/dist/checkpointer/saver.js.map +0 -1
- package/dist/checkpointer/types.d.ts.map +0 -1
- package/dist/checkpointer/types.js.map +0 -1
- package/dist/factory/factory.d.ts.map +0 -1
- package/dist/factory/factory.js.map +0 -1
- package/dist/history/actions/add-messages.d.ts.map +0 -1
- package/dist/history/actions/add-messages.js.map +0 -1
- package/dist/history/actions/clear.d.ts.map +0 -1
- package/dist/history/actions/clear.js.map +0 -1
- package/dist/history/actions/get-messages.d.ts.map +0 -1
- package/dist/history/actions/get-messages.js.map +0 -1
- package/dist/history/actions/list-sessions.d.ts.map +0 -1
- package/dist/history/actions/list-sessions.js.map +0 -1
- package/dist/history/actions/reconcile-count.d.ts.map +0 -1
- package/dist/history/actions/reconcile-count.js.map +0 -1
- package/dist/history/chat-message-history.d.ts.map +0 -1
- package/dist/history/chat-message-history.js.map +0 -1
- package/dist/history/internal/append-saga.d.ts +0 -20
- package/dist/history/internal/append-saga.d.ts.map +0 -1
- package/dist/history/internal/append-saga.js +0 -35
- package/dist/history/internal/append-saga.js.map +0 -1
- package/dist/history/internal/compensation.d.ts +0 -21
- package/dist/history/internal/compensation.d.ts.map +0 -1
- package/dist/history/internal/compensation.js +0 -84
- package/dist/history/internal/compensation.js.map +0 -1
- package/dist/history/internal/item-mapper.d.ts +0 -12
- package/dist/history/internal/item-mapper.d.ts.map +0 -1
- package/dist/history/internal/item-mapper.js +0 -33
- package/dist/history/internal/item-mapper.js.map +0 -1
- package/dist/history/internal/keys.d.ts +0 -17
- package/dist/history/internal/keys.d.ts.map +0 -1
- package/dist/history/internal/keys.js +0 -49
- package/dist/history/internal/keys.js.map +0 -1
- package/dist/history/internal/message-chunker.d.ts +0 -14
- package/dist/history/internal/message-chunker.d.ts.map +0 -1
- package/dist/history/internal/message-chunker.js +0 -68
- package/dist/history/internal/message-chunker.js.map +0 -1
- package/dist/history/internal/message-transaction.d.ts +0 -26
- package/dist/history/internal/message-transaction.d.ts.map +0 -1
- package/dist/history/internal/message-transaction.js +0 -60
- package/dist/history/internal/message-transaction.js.map +0 -1
- package/dist/history/internal/query.d.ts +0 -10
- package/dist/history/internal/query.d.ts.map +0 -1
- package/dist/history/internal/query.js +0 -31
- package/dist/history/internal/query.js.map +0 -1
- package/dist/history/internal/session-count.d.ts +0 -41
- package/dist/history/internal/session-count.d.ts.map +0 -1
- package/dist/history/internal/session-count.js +0 -109
- package/dist/history/internal/session-count.js.map +0 -1
- package/dist/history/internal/session-title.d.ts +0 -20
- package/dist/history/internal/session-title.d.ts.map +0 -1
- package/dist/history/internal/session-title.js +0 -44
- package/dist/history/internal/session-title.js.map +0 -1
- package/dist/history/internal/session-update.d.ts +0 -28
- package/dist/history/internal/session-update.d.ts.map +0 -1
- package/dist/history/internal/session-update.js +0 -70
- package/dist/history/internal/session-update.js.map +0 -1
- package/dist/history/internal/setup.d.ts.map +0 -1
- package/dist/history/internal/setup.js.map +0 -1
- package/dist/history/internal/title-generator.d.ts +0 -13
- package/dist/history/internal/title-generator.d.ts.map +0 -1
- package/dist/history/internal/title-generator.js +0 -25
- package/dist/history/internal/title-generator.js.map +0 -1
- package/dist/history/internal/ttl-anchor.d.ts +0 -25
- package/dist/history/internal/ttl-anchor.d.ts.map +0 -1
- package/dist/history/internal/ttl-anchor.js +0 -38
- package/dist/history/internal/ttl-anchor.js.map +0 -1
- package/dist/history/internal/validation.d.ts +0 -9
- package/dist/history/internal/validation.d.ts.map +0 -1
- package/dist/history/internal/validation.js +0 -16
- package/dist/history/internal/validation.js.map +0 -1
- package/dist/history/session-adapter.d.ts.map +0 -1
- package/dist/history/session-adapter.js.map +0 -1
- package/dist/history/types.d.ts.map +0 -1
- package/dist/history/types.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/shared/clock.d.ts.map +0 -1
- package/dist/shared/clock.js.map +0 -1
- package/dist/shared/codec/codec.d.ts.map +0 -1
- package/dist/shared/codec/codec.js.map +0 -1
- package/dist/shared/codec/compression.d.ts.map +0 -1
- package/dist/shared/codec/compression.js.map +0 -1
- package/dist/shared/codec/descriptor-keys.d.ts +0 -4
- package/dist/shared/codec/descriptor-keys.d.ts.map +0 -1
- package/dist/shared/codec/descriptor-keys.js +0 -14
- package/dist/shared/codec/descriptor-keys.js.map +0 -1
- package/dist/shared/codec/json-serde.d.ts.map +0 -1
- package/dist/shared/codec/json-serde.js.map +0 -1
- package/dist/shared/codec/s3/client.d.ts.map +0 -1
- package/dist/shared/codec/s3/client.js.map +0 -1
- package/dist/shared/codec/s3/config.d.ts.map +0 -1
- package/dist/shared/codec/s3/config.js.map +0 -1
- package/dist/shared/codec/s3/delete.d.ts +0 -8
- package/dist/shared/codec/s3/delete.d.ts.map +0 -1
- package/dist/shared/codec/s3/delete.js +0 -29
- package/dist/shared/codec/s3/delete.js.map +0 -1
- package/dist/shared/codec/s3/lifecycle.d.ts.map +0 -1
- package/dist/shared/codec/s3/lifecycle.js.map +0 -1
- package/dist/shared/codec/s3/offloader.d.ts.map +0 -1
- package/dist/shared/codec/s3/offloader.js.map +0 -1
- package/dist/shared/codec/s3/orphans.d.ts +0 -18
- package/dist/shared/codec/s3/orphans.d.ts.map +0 -1
- package/dist/shared/codec/s3/orphans.js +0 -58
- package/dist/shared/codec/s3/orphans.js.map +0 -1
- package/dist/shared/codec/s3/read-write.d.ts +0 -14
- package/dist/shared/codec/s3/read-write.d.ts.map +0 -1
- package/dist/shared/codec/s3/read-write.js +0 -43
- package/dist/shared/codec/s3/read-write.js.map +0 -1
- package/dist/shared/codec/s3/retry.d.ts +0 -5
- package/dist/shared/codec/s3/retry.d.ts.map +0 -1
- package/dist/shared/codec/s3/retry.js +0 -25
- package/dist/shared/codec/s3/retry.js.map +0 -1
- package/dist/shared/constants.d.ts +0 -64
- package/dist/shared/constants.d.ts.map +0 -1
- package/dist/shared/constants.js +0 -67
- package/dist/shared/constants.js.map +0 -1
- package/dist/shared/dynamodb/backoff.d.ts +0 -15
- package/dist/shared/dynamodb/backoff.d.ts.map +0 -1
- package/dist/shared/dynamodb/backoff.js +0 -48
- package/dist/shared/dynamodb/backoff.js.map +0 -1
- package/dist/shared/dynamodb/batch-write.d.ts.map +0 -1
- package/dist/shared/dynamodb/batch-write.js.map +0 -1
- package/dist/shared/dynamodb/cancellation.d.ts.map +0 -1
- package/dist/shared/dynamodb/cancellation.js.map +0 -1
- package/dist/shared/dynamodb/client.d.ts.map +0 -1
- package/dist/shared/dynamodb/client.js.map +0 -1
- package/dist/shared/dynamodb/conditional-put.d.ts +0 -51
- package/dist/shared/dynamodb/conditional-put.d.ts.map +0 -1
- package/dist/shared/dynamodb/conditional-put.js +0 -59
- package/dist/shared/dynamodb/conditional-put.js.map +0 -1
- package/dist/shared/dynamodb/drain-unprocessed.d.ts +0 -19
- package/dist/shared/dynamodb/drain-unprocessed.d.ts.map +0 -1
- package/dist/shared/dynamodb/drain-unprocessed.js +0 -44
- package/dist/shared/dynamodb/drain-unprocessed.js.map +0 -1
- package/dist/shared/dynamodb/paginate-core.d.ts +0 -22
- package/dist/shared/dynamodb/paginate-core.d.ts.map +0 -1
- package/dist/shared/dynamodb/paginate-core.js +0 -52
- package/dist/shared/dynamodb/paginate-core.js.map +0 -1
- package/dist/shared/dynamodb/paginate.d.ts.map +0 -1
- package/dist/shared/dynamodb/paginate.js.map +0 -1
- package/dist/shared/dynamodb/partition-delete.d.ts.map +0 -1
- package/dist/shared/dynamodb/partition-delete.js.map +0 -1
- package/dist/shared/dynamodb/retry-classifier.d.ts +0 -9
- package/dist/shared/dynamodb/retry-classifier.d.ts.map +0 -1
- package/dist/shared/dynamodb/retry-classifier.js +0 -87
- package/dist/shared/dynamodb/retry-classifier.js.map +0 -1
- package/dist/shared/dynamodb/retry.d.ts.map +0 -1
- package/dist/shared/dynamodb/retry.js.map +0 -1
- package/dist/shared/dynamodb/scan.d.ts +0 -15
- package/dist/shared/dynamodb/scan.d.ts.map +0 -1
- package/dist/shared/dynamodb/scan.js +0 -20
- package/dist/shared/dynamodb/scan.js.map +0 -1
- package/dist/shared/dynamodb/types.d.ts +0 -24
- package/dist/shared/dynamodb/types.d.ts.map +0 -1
- package/dist/shared/dynamodb/types.js +0 -3
- package/dist/shared/dynamodb/types.js.map +0 -1
- package/dist/shared/errors/base-error.d.ts.map +0 -1
- package/dist/shared/errors/base-error.js.map +0 -1
- package/dist/shared/errors/error-code.d.ts.map +0 -1
- package/dist/shared/errors/error-code.js.map +0 -1
- package/dist/shared/errors/errors.d.ts.map +0 -1
- package/dist/shared/errors/errors.js.map +0 -1
- package/dist/shared/errors/wrap-error.d.ts +0 -16
- package/dist/shared/errors/wrap-error.d.ts.map +0 -1
- package/dist/shared/errors/wrap-error.js +0 -30
- package/dist/shared/errors/wrap-error.js.map +0 -1
- package/dist/shared/logging/logger.d.ts.map +0 -1
- package/dist/shared/logging/logger.js.map +0 -1
- package/dist/shared/logging/redaction-walk.d.ts +0 -23
- package/dist/shared/logging/redaction-walk.d.ts.map +0 -1
- package/dist/shared/logging/redaction-walk.js +0 -92
- package/dist/shared/logging/redaction-walk.js.map +0 -1
- package/dist/shared/logging/redaction.d.ts.map +0 -1
- package/dist/shared/logging/redaction.js.map +0 -1
- package/dist/shared/logging/secret-patterns.d.ts.map +0 -1
- package/dist/shared/logging/secret-patterns.js.map +0 -1
- package/dist/shared/options.d.ts.map +0 -1
- package/dist/shared/options.js.map +0 -1
- package/dist/shared/ulid.d.ts.map +0 -1
- package/dist/shared/ulid.js.map +0 -1
- package/dist/shared/validation/primitives.d.ts.map +0 -1
- package/dist/shared/validation/primitives.js.map +0 -1
- package/dist/shared/validation/ttl.d.ts.map +0 -1
- package/dist/shared/validation/ttl.js.map +0 -1
- package/dist/store/actions/get.d.ts +0 -5
- package/dist/store/actions/get.d.ts.map +0 -1
- package/dist/store/actions/get.js +0 -35
- package/dist/store/actions/get.js.map +0 -1
- package/dist/store/actions/list-namespaces.d.ts.map +0 -1
- package/dist/store/actions/list-namespaces.js.map +0 -1
- package/dist/store/actions/put.d.ts.map +0 -1
- package/dist/store/actions/put.js.map +0 -1
- package/dist/store/actions/reconcile-vector-index.d.ts.map +0 -1
- package/dist/store/actions/reconcile-vector-index.js.map +0 -1
- package/dist/store/actions/search.d.ts.map +0 -1
- package/dist/store/actions/search.js.map +0 -1
- package/dist/store/internal/backend-search.d.ts +0 -5
- package/dist/store/internal/backend-search.d.ts.map +0 -1
- package/dist/store/internal/backend-search.js +0 -68
- package/dist/store/internal/backend-search.js.map +0 -1
- package/dist/store/internal/filter.d.ts.map +0 -1
- package/dist/store/internal/filter.js.map +0 -1
- package/dist/store/internal/index-reconcile.d.ts +0 -22
- package/dist/store/internal/index-reconcile.d.ts.map +0 -1
- package/dist/store/internal/index-reconcile.js +0 -105
- package/dist/store/internal/index-reconcile.js.map +0 -1
- package/dist/store/internal/index-sync.d.ts +0 -11
- package/dist/store/internal/index-sync.d.ts.map +0 -1
- package/dist/store/internal/index-sync.js +0 -26
- package/dist/store/internal/index-sync.js.map +0 -1
- package/dist/store/internal/item-mapper.d.ts +0 -25
- package/dist/store/internal/item-mapper.d.ts.map +0 -1
- package/dist/store/internal/item-mapper.js +0 -53
- package/dist/store/internal/item-mapper.js.map +0 -1
- package/dist/store/internal/keys.d.ts +0 -18
- package/dist/store/internal/keys.d.ts.map +0 -1
- package/dist/store/internal/keys.js +0 -42
- package/dist/store/internal/keys.js.map +0 -1
- package/dist/store/internal/namespace-match.d.ts +0 -12
- package/dist/store/internal/namespace-match.d.ts.map +0 -1
- package/dist/store/internal/namespace-match.js +0 -41
- package/dist/store/internal/namespace-match.js.map +0 -1
- package/dist/store/internal/overwrite-swap.d.ts +0 -33
- package/dist/store/internal/overwrite-swap.d.ts.map +0 -1
- package/dist/store/internal/overwrite-swap.js +0 -62
- package/dist/store/internal/overwrite-swap.js.map +0 -1
- package/dist/store/internal/persist.d.ts +0 -27
- package/dist/store/internal/persist.d.ts.map +0 -1
- package/dist/store/internal/persist.js +0 -59
- package/dist/store/internal/persist.js.map +0 -1
- package/dist/store/internal/query.d.ts +0 -6
- package/dist/store/internal/query.d.ts.map +0 -1
- package/dist/store/internal/query.js +0 -32
- package/dist/store/internal/query.js.map +0 -1
- package/dist/store/internal/ranker.d.ts +0 -13
- package/dist/store/internal/ranker.d.ts.map +0 -1
- package/dist/store/internal/ranker.js +0 -31
- package/dist/store/internal/ranker.js.map +0 -1
- package/dist/store/internal/read-existing.d.ts +0 -19
- package/dist/store/internal/read-existing.d.ts.map +0 -1
- package/dist/store/internal/read-existing.js +0 -29
- package/dist/store/internal/read-existing.js.map +0 -1
- package/dist/store/internal/score-direction.d.ts +0 -32
- package/dist/store/internal/score-direction.d.ts.map +0 -1
- package/dist/store/internal/score-direction.js +0 -39
- package/dist/store/internal/score-direction.js.map +0 -1
- package/dist/store/internal/search-filter.d.ts +0 -4
- package/dist/store/internal/search-filter.d.ts.map +0 -1
- package/dist/store/internal/search-filter.js +0 -11
- package/dist/store/internal/search-filter.js.map +0 -1
- package/dist/store/internal/semantic-search.d.ts.map +0 -1
- package/dist/store/internal/semantic-search.js.map +0 -1
- package/dist/store/internal/setup.d.ts.map +0 -1
- package/dist/store/internal/setup.js.map +0 -1
- package/dist/store/internal/validation.d.ts +0 -13
- package/dist/store/internal/validation.d.ts.map +0 -1
- package/dist/store/internal/validation.js +0 -35
- package/dist/store/internal/validation.js.map +0 -1
- package/dist/store/internal/write-verify.d.ts +0 -37
- package/dist/store/internal/write-verify.d.ts.map +0 -1
- package/dist/store/internal/write-verify.js +0 -68
- package/dist/store/internal/write-verify.js.map +0 -1
- package/dist/store/store.d.ts.map +0 -1
- package/dist/store/store.js.map +0 -1
- package/dist/store/types.d.ts.map +0 -1
- package/dist/store/types.js.map +0 -1
- package/dist/store/vector-backend.d.ts.map +0 -1
- package/dist/store/vector-backend.js.map +0 -1
|
@@ -1,52 +1,195 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hides which options the store and its methods accept, and how the store is
|
|
4
|
+
* assembled from them.
|
|
5
|
+
*
|
|
6
|
+
* The exhaustive key list of every option bag — the constructor's, `search`'s,
|
|
7
|
+
* `listNamespaces`' — lives here, compiler-checked against its type. The
|
|
8
|
+
* store's own options are checked after the shared ones — the in-memory caps,
|
|
9
|
+
* that a vector backend comes with an index, that the index can embed, the
|
|
10
|
+
* score direction — and the context every operation receives is built with its
|
|
11
|
+
* defaults filled in.
|
|
12
|
+
*/
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.STORE_LIST_NAMESPACES_KEYS = exports.STORE_SEARCH_KEYS = exports.STORE_KEYS = exports.MAX_SCAN_ITEMS = exports.MAX_SEARCH_CANDIDATES = exports.DEFAULT_MAX_SEARCH_CANDIDATES = void 0;
|
|
3
15
|
exports.setUpStore = setUpStore;
|
|
16
|
+
exports.assertStoreOptions = assertStoreOptions;
|
|
17
|
+
const adapter_1 = require("../../shared/adapter");
|
|
4
18
|
const json_serde_1 = require("../../shared/codec/json-serde");
|
|
5
|
-
const
|
|
6
|
-
const offloader_1 = require("../../shared/codec/s3/offloader");
|
|
7
|
-
const constants_1 = require("../../shared/constants");
|
|
8
|
-
const client_1 = require("../../shared/dynamodb/client");
|
|
19
|
+
const paginate_1 = require("../../shared/dynamodb/paginate");
|
|
9
20
|
const errors_1 = require("../../shared/errors/errors");
|
|
10
|
-
const
|
|
11
|
-
const
|
|
21
|
+
const collaborators_1 = require("../../shared/validation/collaborators");
|
|
22
|
+
const option_shape_1 = require("../../shared/validation/option-shape");
|
|
23
|
+
const primitives_1 = require("../../shared/validation/primitives");
|
|
24
|
+
const vector_backend_1 = require("../vector-backend");
|
|
25
|
+
/** Default cap on candidates the in-DB semantic ranker will score. */
|
|
26
|
+
exports.DEFAULT_MAX_SEARCH_CANDIDATES = 1000;
|
|
27
|
+
/**
|
|
28
|
+
* Largest `maxSearchCandidates` an adapter accepts: this many decoded
|
|
29
|
+
* candidates are held and re-ranked in memory by one `search()` call, so an
|
|
30
|
+
* unbounded value lets a typo or hostile config hold an unbounded working set.
|
|
31
|
+
*/
|
|
32
|
+
exports.MAX_SEARCH_CANDIDATES = 100_000;
|
|
33
|
+
/**
|
|
34
|
+
* Largest `maxScanItems` an adapter accepts: this many raw rows are collected
|
|
35
|
+
* into memory across one paginated scan/query before it errors, so — like
|
|
36
|
+
* {@link MAX_SEARCH_CANDIDATES} — an unbounded value lets a typo or hostile
|
|
37
|
+
* config hold an unbounded working set.
|
|
38
|
+
*/
|
|
39
|
+
exports.MAX_SCAN_ITEMS = 1_000_000;
|
|
40
|
+
/**
|
|
41
|
+
* Validate the options, then resolve the client, offloader, serializer and index.
|
|
42
|
+
*
|
|
43
|
+
* Accepts: `options` — validated first, so no half-built store exists when one
|
|
44
|
+
* is wrong. Everything optional has a default here and nowhere else, which is
|
|
45
|
+
* what lets every action read `context.x` without re-deciding what absent means.
|
|
46
|
+
*
|
|
47
|
+
* Returns: the context every action shares, and the shell that releases what
|
|
48
|
+
* it holds — a client the caller passed in is never destroyed by `destroy()`.
|
|
49
|
+
*
|
|
50
|
+
* Throws: `VALIDATION` for any invalid option, naming the option.
|
|
51
|
+
*
|
|
52
|
+
* Guarantees: constructing a store performs no I/O. The stacked-retry check is
|
|
53
|
+
* deliberately not awaited: it is a warning about a caller-supplied client, not
|
|
54
|
+
* a precondition.
|
|
55
|
+
*/
|
|
56
|
+
function setUpStore(options) {
|
|
57
|
+
(0, option_shape_1.assertShape)(options, exports.STORE_KEYS, 'options');
|
|
58
|
+
const shell = (0, adapter_1.openAdapter)(options, 'store', {
|
|
59
|
+
options: () => assertStoreOptions(options),
|
|
60
|
+
collaborators: () => {
|
|
61
|
+
if (options.vectorBackend !== undefined) {
|
|
62
|
+
(0, collaborators_1.assertMembers)(options.vectorBackend, collaborators_1.VECTOR_BACKEND_MEMBERS, 'vectorBackend');
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
shell,
|
|
68
|
+
context: {
|
|
69
|
+
...shell.core,
|
|
70
|
+
serde: options.serde ?? json_serde_1.JSON_SERDE,
|
|
71
|
+
index: options.index,
|
|
72
|
+
vectorBackend: options.vectorBackend,
|
|
73
|
+
vectorScoreDirection: options.vectorScoreDirection ?? 'relevance',
|
|
74
|
+
maxSearchCandidates: options.maxSearchCandidates ?? exports.DEFAULT_MAX_SEARCH_CANDIDATES,
|
|
75
|
+
maxScanItems: options.maxScanItems ?? paginate_1.MAX_TOTAL_ROWS_IN_MEMORY,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The keys of each store option bag, exhaustive in both directions:
|
|
81
|
+
* `allKeysOf<T>` makes omitting or inventing one a compile error, so a list
|
|
82
|
+
* cannot rot away from the type it guards. They live with the feature because
|
|
83
|
+
* the types they are checked against do; `shared/` knows no feature.
|
|
84
|
+
*/
|
|
85
|
+
exports.STORE_KEYS = (0, option_shape_1.allKeysOf)({
|
|
86
|
+
tableName: 'tableName',
|
|
87
|
+
client: 'client',
|
|
88
|
+
clientConfig: 'clientConfig',
|
|
89
|
+
createClient: 'createClient',
|
|
90
|
+
ttl: 'ttl',
|
|
91
|
+
logger: 'logger',
|
|
92
|
+
retry: 'retry',
|
|
93
|
+
indexShards: 'indexShards',
|
|
94
|
+
indexName: 'indexName',
|
|
95
|
+
readConcurrency: 'readConcurrency',
|
|
96
|
+
compression: 'compression',
|
|
97
|
+
s3: 's3',
|
|
98
|
+
serde: 'serde',
|
|
99
|
+
index: 'index',
|
|
100
|
+
vectorBackend: 'vectorBackend',
|
|
101
|
+
maxSearchCandidates: 'maxSearchCandidates',
|
|
102
|
+
maxScanItems: 'maxScanItems',
|
|
103
|
+
vectorScoreDirection: 'vectorScoreDirection',
|
|
104
|
+
});
|
|
105
|
+
/** See {@link STORE_KEYS}. */
|
|
106
|
+
exports.STORE_SEARCH_KEYS = (0, option_shape_1.allKeysOf)({
|
|
107
|
+
filter: 'filter',
|
|
108
|
+
limit: 'limit',
|
|
109
|
+
offset: 'offset',
|
|
110
|
+
query: 'query',
|
|
111
|
+
signal: 'signal',
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* See {@link STORE_KEYS}. `ListNamespacesOptions` is pinned equal to
|
|
115
|
+
* `BaseStore.listNamespaces`' own parameter type, so this list is checked
|
|
116
|
+
* against upstream's options through it.
|
|
117
|
+
*/
|
|
118
|
+
exports.STORE_LIST_NAMESPACES_KEYS = (0, option_shape_1.allKeysOf)({
|
|
119
|
+
prefix: 'prefix',
|
|
120
|
+
suffix: 'suffix',
|
|
121
|
+
maxDepth: 'maxDepth',
|
|
122
|
+
limit: 'limit',
|
|
123
|
+
offset: 'offset',
|
|
124
|
+
});
|
|
125
|
+
/**
|
|
126
|
+
* The keys `IndexConfig` declares. The type is upstream's, but this package is
|
|
127
|
+
* what reads `index`, so a key missing from this list — a misspelling, or one
|
|
128
|
+
* a later upstream release adds — is one it would silently ignore; refusing it
|
|
129
|
+
* is what tells the caller their setting is not in effect.
|
|
130
|
+
*/
|
|
131
|
+
const INDEX_KEYS = (0, option_shape_1.allKeysOf)({
|
|
132
|
+
dims: 'dims',
|
|
133
|
+
embeddings: 'embeddings',
|
|
134
|
+
fields: 'fields',
|
|
135
|
+
});
|
|
12
136
|
/**
|
|
13
137
|
* Reject an `index` that cannot actually embed. `IndexConfig` mandates
|
|
14
138
|
* `embeddings`, but a JavaScript caller can omit it or pass the wrong shape,
|
|
15
139
|
* and the failure then surfaced as a raw `TypeError` deep inside the first
|
|
16
140
|
* `put()`/`search()` rather than this library's typed error at construction.
|
|
17
141
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
142
|
+
* Both methods are required: documents are embedded with `embedDocuments()`
|
|
143
|
+
* on `put()` and queries with `embedQuery()` on `search()`.
|
|
144
|
+
*
|
|
145
|
+
* The keys are checked first, so `{ dims, embed }` names the misspelt `embed`
|
|
146
|
+
* rather than the `embeddings` it displaced. `null` is refused like any other
|
|
147
|
+
* value that is not an object, rather than read as no index; only `undefined`
|
|
148
|
+
* means no index. `fields`, when given, must be an array of strings, the rule a
|
|
149
|
+
* put's own `index` argument follows: a string would otherwise reach the first
|
|
150
|
+
* put and fail there as an upstream error.
|
|
21
151
|
*/
|
|
22
152
|
function assertUsableIndex(index) {
|
|
23
|
-
if (
|
|
153
|
+
if (index === undefined)
|
|
24
154
|
return;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
155
|
+
(0, option_shape_1.assertShape)(index, INDEX_KEYS, 'index');
|
|
156
|
+
(0, collaborators_1.assertMembers)(index.embeddings, collaborators_1.EMBEDDINGS_MEMBERS, 'index.embeddings');
|
|
157
|
+
if (index.fields !== undefined)
|
|
158
|
+
(0, primitives_1.assertStringArray)(index.fields, 'index.fields');
|
|
30
159
|
}
|
|
31
160
|
/**
|
|
32
161
|
* Reject a `vectorScoreDirection` outside the declared union.
|
|
33
162
|
*
|
|
34
|
-
*
|
|
35
|
-
* the only safe default, since guessing would invert
|
|
163
|
+
* `toRelevanceScores` (store/internal/vector-index.ts) treats anything it does
|
|
164
|
+
* not recognise as a no-op — the only safe default, since guessing would invert
|
|
165
|
+
* a ranking — so a mistyped
|
|
36
166
|
* or config-file-sourced value would otherwise leave a distance backend ranked
|
|
37
167
|
* backwards with no error and no warning anywhere. Same premise as
|
|
38
168
|
* {@link assertUsableIndex}: a JavaScript caller can pass a string the type
|
|
39
169
|
* never admits.
|
|
40
170
|
*/
|
|
41
171
|
function assertScoreDirection(direction) {
|
|
42
|
-
if (direction === undefined ||
|
|
172
|
+
if (direction === undefined || vector_backend_1.VECTOR_SCORE_DIRECTIONS.includes(direction))
|
|
43
173
|
return;
|
|
44
|
-
throw
|
|
174
|
+
throw (0, errors_1.validationError)(`vectorScoreDirection must be one of ${vector_backend_1.VECTOR_SCORE_DIRECTIONS.join(' | ')}; received ` +
|
|
45
175
|
`${JSON.stringify(direction)}, which would be left in the backend's own direction and ` +
|
|
46
176
|
'could rank a distance backend backwards', 'vectorScoreDirection');
|
|
47
177
|
}
|
|
178
|
+
/** Both in-memory caps must be positive integers; 0 would silently return nothing. */
|
|
179
|
+
function assertLimits(options) {
|
|
180
|
+
if (options.maxScanItems !== undefined) {
|
|
181
|
+
(0, primitives_1.assertInteger)(options.maxScanItems, 'maxScanItems', { min: 1, max: exports.MAX_SCAN_ITEMS });
|
|
182
|
+
}
|
|
183
|
+
if (options.maxSearchCandidates !== undefined) {
|
|
184
|
+
(0, primitives_1.assertInteger)(options.maxSearchCandidates, 'maxSearchCandidates', {
|
|
185
|
+
min: 1,
|
|
186
|
+
max: exports.MAX_SEARCH_CANDIDATES,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
48
190
|
/**
|
|
49
|
-
*
|
|
191
|
+
* Validate the store's own options at construction; the shared ones are
|
|
192
|
+
* `openAdapter`'s, which checks them before these.
|
|
50
193
|
*
|
|
51
194
|
* A `vectorBackend` without an `index` is rejected outright rather than
|
|
52
195
|
* silently degrading: with no embeddings configured, every `put` would compute
|
|
@@ -55,38 +198,26 @@ function assertScoreDirection(direction) {
|
|
|
55
198
|
* listing with no `.score` field and no error — a semantic query returning a
|
|
56
199
|
* normal-looking but meaningless response. `reconcileVectorIndex` already
|
|
57
200
|
* refused this exact misconfiguration.
|
|
201
|
+
*
|
|
202
|
+
* Accepts: every option the store takes. The types describe the intended
|
|
203
|
+
* shapes; this runs for the JavaScript caller the types never see, and for the
|
|
204
|
+
* combinations no type can express — a backend without an index, an `index`
|
|
205
|
+
* key `IndexConfig` does not declare, an `embeddings` object missing a method,
|
|
206
|
+
* a direction outside its union.
|
|
207
|
+
*
|
|
208
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
209
|
+
* checks it.
|
|
210
|
+
*
|
|
211
|
+
* Throws: `VALIDATION` naming the offending option. Every failure is raised
|
|
212
|
+
* at construction, where the fix is, rather than at the first put or search.
|
|
58
213
|
*/
|
|
59
|
-
function
|
|
214
|
+
function assertStoreOptions(options) {
|
|
215
|
+
assertLimits(options);
|
|
60
216
|
if (options.vectorBackend && !options.index) {
|
|
61
|
-
throw
|
|
217
|
+
throw (0, errors_1.validationError)('vectorBackend requires a configured `index` (embeddings); without one no embedding ' +
|
|
62
218
|
'is computed, every put would clear the item vector, and search would silently return ' +
|
|
63
219
|
'unranked, score-less results', 'vectorBackend');
|
|
64
220
|
}
|
|
65
221
|
assertUsableIndex(options.index);
|
|
66
222
|
assertScoreDirection(options.vectorScoreDirection);
|
|
67
|
-
const resolved = (0, client_1.resolveDynamoDBClient)(options);
|
|
68
|
-
return {
|
|
69
|
-
context: {
|
|
70
|
-
client: resolved.client,
|
|
71
|
-
tableName: options.tableName,
|
|
72
|
-
serde: options.serde ?? json_serde_1.JSON_SERDE,
|
|
73
|
-
compression: options.compression,
|
|
74
|
-
offloader: options.s3
|
|
75
|
-
? new offloader_1.S3Offloader({
|
|
76
|
-
...options.s3,
|
|
77
|
-
keyPrefix: options.s3.keyPrefix ?? (0, config_1.defaultAdapterKeyPrefix)(constants_1.DEFAULT_S3_KEY_PREFIX, 'store'),
|
|
78
|
-
})
|
|
79
|
-
: undefined,
|
|
80
|
-
ttl: options.ttl,
|
|
81
|
-
logger: (0, logger_1.resolveLogger)(options.logger),
|
|
82
|
-
index: options.index,
|
|
83
|
-
vectorBackend: options.vectorBackend,
|
|
84
|
-
vectorScoreDirection: options.vectorScoreDirection ?? 'relevance',
|
|
85
|
-
maxSearchCandidates: options.maxSearchCandidates ?? constants_1.DEFAULT_MAX_SEARCH_CANDIDATES,
|
|
86
|
-
maxScanItems: options.maxScanItems ?? constants_1.MAX_TOTAL_ITEMS_IN_MEMORY,
|
|
87
|
-
},
|
|
88
|
-
ddbClient: resolved.ddbClient,
|
|
89
|
-
ownsClient: resolved.ownsClient,
|
|
90
|
-
};
|
|
91
223
|
}
|
|
92
|
-
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hides how a search is served from the table alone.
|
|
3
|
+
*
|
|
4
|
+
* Without a vector backend, a search reads the rows under its prefix within
|
|
5
|
+
* `maxScanItems`, decodes them a batch at a time, keeps the ones its filter
|
|
6
|
+
* passes, and — for a semantic query — ranks them in memory by cosine
|
|
7
|
+
* similarity within `maxSearchCandidates`, an item without an embedding sorting
|
|
8
|
+
* last. How far the read goes before it can stop is decided here.
|
|
9
|
+
*/
|
|
10
|
+
import type { Item, SearchItem } from '@langchain/langgraph-checkpoint';
|
|
11
|
+
import type { ParsedSearch } from './parse';
|
|
12
|
+
import type { StoreContext } from './setup';
|
|
13
|
+
/**
|
|
14
|
+
* How far a collection must go. A plain page is complete once `need`
|
|
15
|
+
* (`offset + limit`) matching items are in hand, so rows past it are never
|
|
16
|
+
* read or decoded; a semantic ranking needs every candidate but is refused as
|
|
17
|
+
* soon as more than `cap` rows exist, before a single decode or embedding.
|
|
18
|
+
*/
|
|
19
|
+
export type CollectBound = {
|
|
20
|
+
kind: 'page';
|
|
21
|
+
need: number;
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'semantic';
|
|
24
|
+
cap: number;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Collect the live rows under the prefix and decode them within `bound`.
|
|
28
|
+
*
|
|
29
|
+
* Accepts: `search.namespacePrefix` — a non-empty prefix is a Query on one
|
|
30
|
+
* partition; an empty one spans every partition and is the Scan this adapter
|
|
31
|
+
* reserves for exactly that (`test/static/guards/scan-sites.ts`). `bound` — a
|
|
32
|
+
* page stops as soon as
|
|
33
|
+
* `need` matching items are in hand; a semantic collection needs every
|
|
34
|
+
* candidate and is refused past `cap`. `search.filter` — applied after decoding,
|
|
35
|
+
* since the filter reads the value.
|
|
36
|
+
*
|
|
37
|
+
* Returns: the matching candidates with the vectors their rows carry, in the
|
|
38
|
+
* order read: sort-key order within a partition, unspecified across partitions.
|
|
39
|
+
* A page therefore pages stably within a namespace, and only there.
|
|
40
|
+
*
|
|
41
|
+
* Throws: `VALIDATION` naming `maxSearchCandidates` before any decode when a
|
|
42
|
+
* semantic collection exceeds `cap`; `RESULT_TRUNCATED` when
|
|
43
|
+
* `maxScanItems` is reached while rows remain — a search never silently answers
|
|
44
|
+
* from part of the table; `ABORTED` when the signal fires between pages;
|
|
45
|
+
* whatever a decode throws for a corrupt or unreadable row.
|
|
46
|
+
*
|
|
47
|
+
* Guarantees: a page closes the paginator as soon as it is full, so a namespace
|
|
48
|
+
* far larger than the page costs neither a full decode nor a truncation error.
|
|
49
|
+
* The bound is tested after a row is in hand, not before one is asked for, so
|
|
50
|
+
* a `need` of 0 would still cost one request; `searchItems` answers that case
|
|
51
|
+
* ahead of this call rather than letting it be paid here.
|
|
52
|
+
* Expired rows, rows of other adapters, rows carrying none of the timestamps a
|
|
53
|
+
* decoded item reports, and rows whose own `namespace` does not match the
|
|
54
|
+
* prefix are all skipped — the last matters because a Scan has no key condition
|
|
55
|
+
* at all, so the prefix is enforced here rather than by DynamoDB, and the one
|
|
56
|
+
* before it because a single such row must not cost a search its other results.
|
|
57
|
+
*/
|
|
58
|
+
export declare function collectCandidates(context: StoreContext, search: ParsedSearch, bound: CollectBound, signal?: AbortSignal): Promise<RankCandidate[]>;
|
|
59
|
+
/** A decoded item plus its stored vectors, awaiting ranking. */
|
|
60
|
+
export interface RankCandidate {
|
|
61
|
+
item: Item;
|
|
62
|
+
/**
|
|
63
|
+
* One vector per extracted path. A row written before the store embedded
|
|
64
|
+
* per path carries a single vector and arrives here as a one-element list,
|
|
65
|
+
* which scores identically to how it always did.
|
|
66
|
+
*/
|
|
67
|
+
embeddings?: number[][];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Rank candidates by cosine similarity to `queryVector`, descending. Throws a
|
|
71
|
+
* `VALIDATION` when the candidate count exceeds `maxCandidates`
|
|
72
|
+
* (steer large corpora to an external VectorBackend).
|
|
73
|
+
*
|
|
74
|
+
* An item is scored by its best-matching vector, as the reference store scores
|
|
75
|
+
* its per-path embeddings. A stored vector whose length differs from the query
|
|
76
|
+
* vector's cannot be scored — it was written by a different embeddings model —
|
|
77
|
+
* and an item with no comparable vector at all is ranked last with an
|
|
78
|
+
* undefined score. `onDimensionMismatch` is invoked once with how many
|
|
79
|
+
* candidates that affected, so the caller can say so instead of silently
|
|
80
|
+
* returning a ranking that quietly omits them.
|
|
81
|
+
*
|
|
82
|
+
* Accepts: `candidates` — in any order; empty ranks to empty. A candidate with
|
|
83
|
+
* no `embeddings` was never indexed (indexing off at write time, or no
|
|
84
|
+
* indexable text) and one with an empty list is the same thing. `queryVector` —
|
|
85
|
+
* the embedded query; one of a different length than everything stored means
|
|
86
|
+
* the query and the corpus were embedded by different models, and nothing
|
|
87
|
+
* scores.
|
|
88
|
+
*
|
|
89
|
+
* Returns: every candidate, scored and sorted best-first. Nothing is dropped:
|
|
90
|
+
* an unscorable item still belongs to the namespace the caller searched, and
|
|
91
|
+
* dropping it would turn a model mismatch into a silently empty result.
|
|
92
|
+
*
|
|
93
|
+
* Throws: `VALIDATION` naming `maxSearchCandidates` when more candidates
|
|
94
|
+
* arrive than may be ranked in memory — a bound on this process's memory, not
|
|
95
|
+
* on the corpus, which is what a `vectorBackend` is for.
|
|
96
|
+
*
|
|
97
|
+
* Guarantees: ranking reads the vectors only; no item is decoded or fetched
|
|
98
|
+
* again, and `onDimensionMismatch` fires at most once per call.
|
|
99
|
+
*/
|
|
100
|
+
export declare function rankInMemory(candidates: RankCandidate[], queryVector: number[], maxCandidates: number, onDimensionMismatch?: (count: number) => void): SearchItem[];
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hides how a search is served from the table alone.
|
|
4
|
+
*
|
|
5
|
+
* Without a vector backend, a search reads the rows under its prefix within
|
|
6
|
+
* `maxScanItems`, decodes them a batch at a time, keeps the ones its filter
|
|
7
|
+
* passes, and — for a semantic query — ranks them in memory by cosine
|
|
8
|
+
* similarity within `maxSearchCandidates`, an item without an embedding sorting
|
|
9
|
+
* last. How far the read goes before it can stop is decided here.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.collectCandidates = collectCandidates;
|
|
13
|
+
exports.rankInMemory = rankInMemory;
|
|
14
|
+
const clock_1 = require("../../shared/clock");
|
|
15
|
+
const concurrency_1 = require("../../shared/concurrency");
|
|
16
|
+
const paginate_1 = require("../../shared/dynamodb/paginate");
|
|
17
|
+
const retry_1 = require("../../shared/dynamodb/retry");
|
|
18
|
+
const table_schema_1 = require("../../shared/dynamodb/table-schema");
|
|
19
|
+
const errors_1 = require("../../shared/errors/errors");
|
|
20
|
+
const filter_1 = require("./filter");
|
|
21
|
+
const rows_1 = require("./rows");
|
|
22
|
+
const semantic_search_1 = require("./semantic-search");
|
|
23
|
+
/**
|
|
24
|
+
* The vectors a row carries, whichever shape it was written in: a list of
|
|
25
|
+
* per-path vectors, or the single joined vector of an earlier version read as
|
|
26
|
+
* a one-element list so it ranks as it always did.
|
|
27
|
+
*/
|
|
28
|
+
function storedVectors(record) {
|
|
29
|
+
if (record.embeddings)
|
|
30
|
+
return record.embeddings;
|
|
31
|
+
return record.embedding ? [record.embedding] : undefined;
|
|
32
|
+
}
|
|
33
|
+
function candidateSource(context, search, signal, now) {
|
|
34
|
+
return search.namespacePrefix.length > 0
|
|
35
|
+
? (0, paginate_1.paginateQuery)({
|
|
36
|
+
retry: (0, retry_1.retryFor)(context, signal),
|
|
37
|
+
signal,
|
|
38
|
+
client: context.client,
|
|
39
|
+
params: (0, table_schema_1.withoutExpired)((0, rows_1.scopedQuery)(context.tableName, search.namespacePrefix), now),
|
|
40
|
+
maxItems: context.maxScanItems,
|
|
41
|
+
})
|
|
42
|
+
: (0, paginate_1.paginateScan)({
|
|
43
|
+
retry: (0, retry_1.retryFor)(context, signal),
|
|
44
|
+
signal,
|
|
45
|
+
client: context.client,
|
|
46
|
+
params: (0, table_schema_1.withoutExpired)((0, rows_1.storeScan)(context.tableName), now),
|
|
47
|
+
maxItems: context.maxScanItems,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** The store record a raw row denotes, or undefined for a foreign, malformed, expired or out-of-prefix row. */
|
|
51
|
+
function liveRow(raw, search, now) {
|
|
52
|
+
const record = (0, rows_1.parseWholeStoreRow)(raw);
|
|
53
|
+
if (!record || (0, table_schema_1.isExpiredRow)(record, now))
|
|
54
|
+
return undefined;
|
|
55
|
+
return (0, rows_1.namespaceMatchesPrefix)(record.namespace, search.namespacePrefix) ? record : undefined;
|
|
56
|
+
}
|
|
57
|
+
/** Decode the pending rows concurrently (each offloaded row is one S3 GET) and keep the ones passing the filter. */
|
|
58
|
+
async function flush(context, search, state, signal) {
|
|
59
|
+
if (state.pending.length === 0)
|
|
60
|
+
return;
|
|
61
|
+
const batch = state.pending;
|
|
62
|
+
state.pending = [];
|
|
63
|
+
const items = await (0, concurrency_1.mapWithConcurrency)(batch, context.readConcurrency ?? concurrency_1.DEFAULT_READ_CONCURRENCY, (record) => (0, rows_1.readStoreItem)(context, record, signal));
|
|
64
|
+
batch.forEach((record, index) => {
|
|
65
|
+
if ((0, filter_1.passesFilter)(items[index], search.filter)) {
|
|
66
|
+
state.collected.push({ item: items[index], embeddings: storedVectors(record) });
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Rows to gather before the next decode. With a filter every batch is a full
|
|
72
|
+
* one, since any row may be dropped; without one every decoded row is a match,
|
|
73
|
+
* so the batch never exceeds what the page still needs.
|
|
74
|
+
*/
|
|
75
|
+
function batchSize(search, need, collected, limit) {
|
|
76
|
+
return search.filter === undefined ? Math.min(limit, need - collected) : limit;
|
|
77
|
+
}
|
|
78
|
+
function tooManyCandidates(count, cap) {
|
|
79
|
+
return (0, errors_1.validationError)(`Semantic search candidate set (${count}) exceeds maxSearchCandidates (${cap}); ` +
|
|
80
|
+
'use a dedicated VectorBackend for large corpora', 'maxSearchCandidates');
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Collect the live rows under the prefix and decode them within `bound`.
|
|
84
|
+
*
|
|
85
|
+
* Accepts: `search.namespacePrefix` — a non-empty prefix is a Query on one
|
|
86
|
+
* partition; an empty one spans every partition and is the Scan this adapter
|
|
87
|
+
* reserves for exactly that (`test/static/guards/scan-sites.ts`). `bound` — a
|
|
88
|
+
* page stops as soon as
|
|
89
|
+
* `need` matching items are in hand; a semantic collection needs every
|
|
90
|
+
* candidate and is refused past `cap`. `search.filter` — applied after decoding,
|
|
91
|
+
* since the filter reads the value.
|
|
92
|
+
*
|
|
93
|
+
* Returns: the matching candidates with the vectors their rows carry, in the
|
|
94
|
+
* order read: sort-key order within a partition, unspecified across partitions.
|
|
95
|
+
* A page therefore pages stably within a namespace, and only there.
|
|
96
|
+
*
|
|
97
|
+
* Throws: `VALIDATION` naming `maxSearchCandidates` before any decode when a
|
|
98
|
+
* semantic collection exceeds `cap`; `RESULT_TRUNCATED` when
|
|
99
|
+
* `maxScanItems` is reached while rows remain — a search never silently answers
|
|
100
|
+
* from part of the table; `ABORTED` when the signal fires between pages;
|
|
101
|
+
* whatever a decode throws for a corrupt or unreadable row.
|
|
102
|
+
*
|
|
103
|
+
* Guarantees: a page closes the paginator as soon as it is full, so a namespace
|
|
104
|
+
* far larger than the page costs neither a full decode nor a truncation error.
|
|
105
|
+
* The bound is tested after a row is in hand, not before one is asked for, so
|
|
106
|
+
* a `need` of 0 would still cost one request; `searchItems` answers that case
|
|
107
|
+
* ahead of this call rather than letting it be paid here.
|
|
108
|
+
* Expired rows, rows of other adapters, rows carrying none of the timestamps a
|
|
109
|
+
* decoded item reports, and rows whose own `namespace` does not match the
|
|
110
|
+
* prefix are all skipped — the last matters because a Scan has no key condition
|
|
111
|
+
* at all, so the prefix is enforced here rather than by DynamoDB, and the one
|
|
112
|
+
* before it because a single such row must not cost a search its other results.
|
|
113
|
+
*/
|
|
114
|
+
async function collectCandidates(context, search, bound, signal) {
|
|
115
|
+
const now = (0, clock_1.nowSeconds)();
|
|
116
|
+
const limit = context.readConcurrency ?? concurrency_1.DEFAULT_READ_CONCURRENCY;
|
|
117
|
+
const state = { pending: [], collected: [] };
|
|
118
|
+
for await (const raw of candidateSource(context, search, signal, now)) {
|
|
119
|
+
const record = liveRow(raw, search, now);
|
|
120
|
+
if (!record)
|
|
121
|
+
continue;
|
|
122
|
+
state.pending.push(record);
|
|
123
|
+
if (bound.kind === 'semantic') {
|
|
124
|
+
if (state.pending.length > bound.cap)
|
|
125
|
+
throw tooManyCandidates(state.pending.length, bound.cap);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (state.pending.length < batchSize(search, bound.need, state.collected.length, limit)) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
await flush(context, search, state, signal);
|
|
132
|
+
if (state.collected.length >= bound.need)
|
|
133
|
+
return state.collected;
|
|
134
|
+
}
|
|
135
|
+
await flush(context, search, state, signal);
|
|
136
|
+
return state.collected;
|
|
137
|
+
}
|
|
138
|
+
/** Sort weight for an item without an embedding; below the −1 cosine minimum. */
|
|
139
|
+
const UNSCORED_RANK = -2;
|
|
140
|
+
/**
|
|
141
|
+
* The best cosine similarity across an item's vectors, or undefined when none
|
|
142
|
+
* can be compared. Scoring by the *best* passage rather than by an average is
|
|
143
|
+
* what the reference store does, and it is why a long document with one
|
|
144
|
+
* strongly-matching section is found.
|
|
145
|
+
*/
|
|
146
|
+
function bestScore(vectors, queryVector) {
|
|
147
|
+
let best;
|
|
148
|
+
for (const vector of vectors) {
|
|
149
|
+
if (vector.length !== queryVector.length)
|
|
150
|
+
continue;
|
|
151
|
+
const score = (0, semantic_search_1.cosineSimilarity)(queryVector, vector);
|
|
152
|
+
if (best === undefined || score > best)
|
|
153
|
+
best = score;
|
|
154
|
+
}
|
|
155
|
+
return best;
|
|
156
|
+
}
|
|
157
|
+
/** True when the candidate has vectors but none of a comparable length. */
|
|
158
|
+
function isDimensionMismatch(candidate, queryVector) {
|
|
159
|
+
const vectors = candidate.embeddings;
|
|
160
|
+
return (vectors !== undefined &&
|
|
161
|
+
vectors.length > 0 &&
|
|
162
|
+
vectors.every((vector) => vector.length !== queryVector.length));
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Rank candidates by cosine similarity to `queryVector`, descending. Throws a
|
|
166
|
+
* `VALIDATION` when the candidate count exceeds `maxCandidates`
|
|
167
|
+
* (steer large corpora to an external VectorBackend).
|
|
168
|
+
*
|
|
169
|
+
* An item is scored by its best-matching vector, as the reference store scores
|
|
170
|
+
* its per-path embeddings. A stored vector whose length differs from the query
|
|
171
|
+
* vector's cannot be scored — it was written by a different embeddings model —
|
|
172
|
+
* and an item with no comparable vector at all is ranked last with an
|
|
173
|
+
* undefined score. `onDimensionMismatch` is invoked once with how many
|
|
174
|
+
* candidates that affected, so the caller can say so instead of silently
|
|
175
|
+
* returning a ranking that quietly omits them.
|
|
176
|
+
*
|
|
177
|
+
* Accepts: `candidates` — in any order; empty ranks to empty. A candidate with
|
|
178
|
+
* no `embeddings` was never indexed (indexing off at write time, or no
|
|
179
|
+
* indexable text) and one with an empty list is the same thing. `queryVector` —
|
|
180
|
+
* the embedded query; one of a different length than everything stored means
|
|
181
|
+
* the query and the corpus were embedded by different models, and nothing
|
|
182
|
+
* scores.
|
|
183
|
+
*
|
|
184
|
+
* Returns: every candidate, scored and sorted best-first. Nothing is dropped:
|
|
185
|
+
* an unscorable item still belongs to the namespace the caller searched, and
|
|
186
|
+
* dropping it would turn a model mismatch into a silently empty result.
|
|
187
|
+
*
|
|
188
|
+
* Throws: `VALIDATION` naming `maxSearchCandidates` when more candidates
|
|
189
|
+
* arrive than may be ranked in memory — a bound on this process's memory, not
|
|
190
|
+
* on the corpus, which is what a `vectorBackend` is for.
|
|
191
|
+
*
|
|
192
|
+
* Guarantees: ranking reads the vectors only; no item is decoded or fetched
|
|
193
|
+
* again, and `onDimensionMismatch` fires at most once per call.
|
|
194
|
+
*/
|
|
195
|
+
function rankInMemory(candidates, queryVector, maxCandidates, onDimensionMismatch) {
|
|
196
|
+
if (candidates.length > maxCandidates) {
|
|
197
|
+
throw (0, errors_1.validationError)(`Semantic search candidate set (${candidates.length}) exceeds maxSearchCandidates ` +
|
|
198
|
+
`(${maxCandidates}); use a dedicated VectorBackend for large corpora`, 'maxSearchCandidates');
|
|
199
|
+
}
|
|
200
|
+
const mismatched = candidates.filter((candidate) => isDimensionMismatch(candidate, queryVector)).length;
|
|
201
|
+
if (mismatched > 0)
|
|
202
|
+
onDimensionMismatch?.(mismatched);
|
|
203
|
+
return candidates
|
|
204
|
+
.map(({ item, embeddings }) => ({
|
|
205
|
+
...item,
|
|
206
|
+
score: embeddings ? bestScore(embeddings, queryVector) : undefined,
|
|
207
|
+
}))
|
|
208
|
+
.sort((a, b) => rankValue(b) - rankValue(a));
|
|
209
|
+
}
|
|
210
|
+
/** Sort weight: real cosine score, or a value below the cosine minimum for unscored items. */
|
|
211
|
+
function rankValue(item) {
|
|
212
|
+
return item.score ?? UNSCORED_RANK;
|
|
213
|
+
}
|