@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.
Files changed (409) hide show
  1. package/README.md +390 -193
  2. package/dist/{backfill → cjs/backfill}/backfill.d.ts +15 -12
  3. package/dist/cjs/backfill/backfill.js +177 -0
  4. package/dist/{checkpointer → cjs/checkpointer}/actions/delete-thread.d.ts +1 -1
  5. package/dist/cjs/checkpointer/actions/delete-thread.js +26 -0
  6. package/dist/{checkpointer → cjs/checkpointer}/actions/get-tuple.d.ts +4 -3
  7. package/dist/cjs/checkpointer/actions/get-tuple.js +22 -0
  8. package/dist/{checkpointer → cjs/checkpointer}/actions/list.d.ts +7 -4
  9. package/dist/cjs/checkpointer/actions/list.js +70 -0
  10. package/dist/{checkpointer → cjs/checkpointer}/actions/put-writes.d.ts +8 -6
  11. package/dist/cjs/checkpointer/actions/put-writes.js +21 -0
  12. package/dist/{checkpointer → cjs/checkpointer}/actions/put.d.ts +21 -15
  13. package/dist/cjs/checkpointer/actions/put.js +79 -0
  14. package/dist/{checkpointer → cjs/checkpointer}/internal/delta-history.d.ts +38 -26
  15. package/dist/cjs/checkpointer/internal/delta-history.js +131 -0
  16. package/dist/{checkpointer → cjs/checkpointer}/internal/listing.d.ts +4 -4
  17. package/dist/cjs/checkpointer/internal/listing.js +104 -0
  18. package/dist/{checkpointer → cjs/checkpointer}/internal/parse.d.ts +51 -15
  19. package/dist/cjs/checkpointer/internal/parse.js +184 -0
  20. package/dist/{checkpointer → cjs/checkpointer}/internal/pending-writes.d.ts +64 -25
  21. package/dist/cjs/checkpointer/internal/pending-writes.js +241 -0
  22. package/dist/{checkpointer → cjs/checkpointer}/internal/read.d.ts +15 -10
  23. package/dist/cjs/checkpointer/internal/read.js +132 -0
  24. package/dist/{checkpointer → cjs/checkpointer}/internal/rows.d.ts +94 -21
  25. package/dist/cjs/checkpointer/internal/rows.js +356 -0
  26. package/dist/{checkpointer → cjs/checkpointer}/internal/setup.d.ts +13 -20
  27. package/dist/cjs/checkpointer/internal/setup.js +25 -0
  28. package/dist/{checkpointer → cjs/checkpointer}/saver.d.ts +72 -36
  29. package/dist/cjs/checkpointer/saver.js +56 -0
  30. package/dist/{checkpointer → cjs/checkpointer}/types.d.ts +1 -1
  31. package/dist/cjs/checkpointer/types.js +2 -0
  32. package/dist/{factory → cjs/factory}/factory.d.ts +25 -20
  33. package/dist/cjs/factory/factory.js +137 -0
  34. package/dist/{factory → cjs/factory}/types.d.ts +12 -12
  35. package/dist/cjs/factory/types.js +2 -0
  36. package/dist/{history → cjs/history}/actions/add-messages.d.ts +18 -10
  37. package/dist/cjs/history/actions/add-messages.js +17 -0
  38. package/dist/{history → cjs/history}/actions/clear.d.ts +1 -1
  39. package/dist/cjs/history/actions/clear.js +29 -0
  40. package/dist/{history → cjs/history}/actions/get-messages.d.ts +11 -9
  41. package/dist/cjs/history/actions/get-messages.js +58 -0
  42. package/dist/{history → cjs/history}/actions/list-sessions.d.ts +3 -3
  43. package/dist/cjs/history/actions/list-sessions.js +67 -0
  44. package/dist/{history → cjs/history}/actions/reconcile-count.d.ts +13 -9
  45. package/dist/cjs/history/actions/reconcile-count.js +8 -0
  46. package/dist/{history → cjs/history}/chat-message-history.d.ts +62 -30
  47. package/dist/cjs/history/chat-message-history.js +61 -0
  48. package/dist/{history → cjs/history}/internal/append.d.ts +64 -32
  49. package/dist/cjs/history/internal/append.js +267 -0
  50. package/dist/{history → cjs/history}/internal/message-read.d.ts +3 -3
  51. package/dist/cjs/history/internal/message-read.js +93 -0
  52. package/dist/{history → cjs/history}/internal/parse.d.ts +2 -2
  53. package/dist/cjs/history/internal/parse.js +113 -0
  54. package/dist/{history → cjs/history}/internal/rows.d.ts +11 -10
  55. package/dist/cjs/history/internal/rows.js +96 -0
  56. package/dist/{history → cjs/history}/internal/session.d.ts +41 -22
  57. package/dist/cjs/history/internal/session.js +296 -0
  58. package/dist/{history → cjs/history}/internal/setup.d.ts +2 -2
  59. package/dist/cjs/history/internal/setup.js +60 -0
  60. package/dist/{history → cjs/history}/session-adapter.d.ts +0 -6
  61. package/dist/cjs/history/session-adapter.js +38 -0
  62. package/dist/{history → cjs/history}/types.d.ts +18 -15
  63. package/dist/cjs/history/types.js +2 -0
  64. package/dist/{index.d.ts → cjs/index.d.ts} +27 -27
  65. package/dist/cjs/index.js +25 -0
  66. package/dist/cjs/package.json +1 -0
  67. package/dist/{shared → cjs/shared}/adapter.d.ts +27 -16
  68. package/dist/cjs/shared/adapter.js +70 -0
  69. package/dist/cjs/shared/clock.js +14 -0
  70. package/dist/{shared → cjs/shared}/codec/codec.d.ts +37 -20
  71. package/dist/cjs/shared/codec/codec.js +162 -0
  72. package/dist/{shared → cjs/shared}/codec/compression.d.ts +9 -4
  73. package/dist/cjs/shared/codec/compression.js +45 -0
  74. package/dist/cjs/shared/codec/json-serde.js +58 -0
  75. package/dist/{shared → cjs/shared}/codec/s3/client-types.d.ts +2 -1
  76. package/dist/cjs/shared/codec/s3/client-types.js +6 -0
  77. package/dist/{shared → cjs/shared}/codec/s3/client.d.ts +25 -7
  78. package/dist/cjs/shared/codec/s3/client.js +78 -0
  79. package/dist/{shared → cjs/shared}/codec/s3/config.d.ts +12 -7
  80. package/dist/cjs/shared/codec/s3/config.js +92 -0
  81. package/dist/{shared → cjs/shared}/codec/s3/lifecycle.d.ts +71 -17
  82. package/dist/cjs/shared/codec/s3/lifecycle.js +223 -0
  83. package/dist/{shared → cjs/shared}/codec/s3/offloader.d.ts +42 -29
  84. package/dist/cjs/shared/codec/s3/offloader.js +289 -0
  85. package/dist/cjs/shared/concurrency.js +31 -0
  86. package/dist/{shared → cjs/shared}/dynamodb/abort.d.ts +2 -2
  87. package/dist/cjs/shared/dynamodb/abort.js +16 -0
  88. package/dist/{shared → cjs/shared}/dynamodb/batch-write.d.ts +2 -2
  89. package/dist/cjs/shared/dynamodb/batch-write.js +79 -0
  90. package/dist/cjs/shared/dynamodb/cancellation.js +37 -0
  91. package/dist/{shared → cjs/shared}/dynamodb/client.d.ts +24 -22
  92. package/dist/cjs/shared/dynamodb/client.js +40 -0
  93. package/dist/{shared → cjs/shared}/dynamodb/idempotent-write.d.ts +64 -19
  94. package/dist/cjs/shared/dynamodb/idempotent-write.js +173 -0
  95. package/dist/{shared → cjs/shared}/dynamodb/paginate.d.ts +2 -2
  96. package/dist/cjs/shared/dynamodb/paginate.js +90 -0
  97. package/dist/{shared → cjs/shared}/dynamodb/partition-delete.d.ts +6 -6
  98. package/dist/cjs/shared/dynamodb/partition-delete.js +177 -0
  99. package/dist/{shared → cjs/shared}/dynamodb/recency-index.d.ts +27 -15
  100. package/dist/cjs/shared/dynamodb/recency-index.js +146 -0
  101. package/dist/{shared → cjs/shared}/dynamodb/retry.d.ts +37 -6
  102. package/dist/cjs/shared/dynamodb/retry.js +193 -0
  103. package/dist/cjs/shared/dynamodb/row-size.d.ts +33 -0
  104. package/dist/cjs/shared/dynamodb/row-size.js +30 -0
  105. package/dist/{shared → cjs/shared}/dynamodb/table-schema.d.ts +27 -18
  106. package/dist/cjs/shared/dynamodb/table-schema.js +52 -0
  107. package/dist/{shared → cjs/shared}/errors/base-error.d.ts +42 -7
  108. package/dist/cjs/shared/errors/base-error.js +73 -0
  109. package/dist/{shared → cjs/shared}/errors/boundary.d.ts +29 -14
  110. package/dist/cjs/shared/errors/boundary.js +61 -0
  111. package/dist/cjs/shared/errors/classify.d.ts +206 -0
  112. package/dist/cjs/shared/errors/classify.js +232 -0
  113. package/dist/{shared → cjs/shared}/errors/error-code.d.ts +17 -10
  114. package/dist/cjs/shared/errors/error-code.js +27 -0
  115. package/dist/{shared → cjs/shared}/errors/errors.d.ts +75 -9
  116. package/dist/cjs/shared/errors/errors.js +123 -0
  117. package/dist/cjs/shared/logging/logger.js +30 -0
  118. package/dist/{shared → cjs/shared}/logging/redaction.d.ts +8 -4
  119. package/dist/cjs/shared/logging/redaction.js +145 -0
  120. package/dist/{shared → cjs/shared}/logging/secret-patterns.d.ts +30 -7
  121. package/dist/cjs/shared/logging/secret-patterns.js +93 -0
  122. package/dist/cjs/shared/logging/truncate.js +31 -0
  123. package/dist/{shared → cjs/shared}/options.d.ts +27 -11
  124. package/dist/cjs/shared/options.js +2 -0
  125. package/dist/cjs/shared/ulid.js +83 -0
  126. package/dist/{shared → cjs/shared}/validation/collaborators.d.ts +21 -2
  127. package/dist/cjs/shared/validation/collaborators.js +79 -0
  128. package/dist/{shared → cjs/shared}/validation/option-shape.d.ts +7 -5
  129. package/dist/cjs/shared/validation/option-shape.js +31 -0
  130. package/dist/{shared → cjs/shared}/validation/options.d.ts +4 -4
  131. package/dist/cjs/shared/validation/options.js +166 -0
  132. package/dist/cjs/shared/validation/primitives.js +114 -0
  133. package/dist/{shared → cjs/shared}/validation/ttl.d.ts +26 -9
  134. package/dist/cjs/shared/validation/ttl.js +52 -0
  135. package/dist/{store → cjs/store}/actions/list-namespaces.d.ts +5 -5
  136. package/dist/cjs/store/actions/list-namespaces.js +92 -0
  137. package/dist/{store → cjs/store}/actions/put.d.ts +11 -4
  138. package/dist/cjs/store/actions/put.js +49 -0
  139. package/dist/{store → cjs/store}/actions/reconcile-vector-index.d.ts +5 -5
  140. package/dist/cjs/store/actions/reconcile-vector-index.js +13 -0
  141. package/dist/{store → cjs/store}/actions/search.d.ts +2 -2
  142. package/dist/cjs/store/actions/search.js +26 -0
  143. package/dist/cjs/store/internal/batch-plan.d.ts +56 -0
  144. package/dist/cjs/store/internal/batch-plan.js +32 -0
  145. package/dist/{store → cjs/store}/internal/filter.d.ts +3 -3
  146. package/dist/cjs/store/internal/filter.js +64 -0
  147. package/dist/cjs/store/internal/get-item.d.ts +77 -0
  148. package/dist/cjs/store/internal/get-item.js +58 -0
  149. package/dist/{store → cjs/store}/internal/item-write.d.ts +72 -32
  150. package/dist/cjs/store/internal/item-write.js +181 -0
  151. package/dist/{store → cjs/store}/internal/parse.d.ts +15 -10
  152. package/dist/cjs/store/internal/parse.js +180 -0
  153. package/dist/{store → cjs/store}/internal/rows.d.ts +38 -34
  154. package/dist/cjs/store/internal/rows.js +166 -0
  155. package/dist/{store → cjs/store}/internal/semantic-search.d.ts +2 -2
  156. package/dist/cjs/store/internal/semantic-search.js +211 -0
  157. package/dist/{store → cjs/store}/internal/setup.d.ts +10 -15
  158. package/dist/cjs/store/internal/setup.js +103 -0
  159. package/dist/{store → cjs/store}/internal/table-search.d.ts +5 -5
  160. package/dist/cjs/store/internal/table-search.js +123 -0
  161. package/dist/{store → cjs/store}/internal/vector-index.d.ts +26 -15
  162. package/dist/cjs/store/internal/vector-index.js +269 -0
  163. package/dist/{store → cjs/store}/store.d.ts +82 -39
  164. package/dist/cjs/store/store.js +97 -0
  165. package/dist/{store → cjs/store}/types.d.ts +25 -10
  166. package/dist/cjs/store/types.js +2 -0
  167. package/dist/cjs/store/vector-backend.js +4 -0
  168. package/dist/esm/backfill/backfill.d.ts +171 -0
  169. package/dist/esm/backfill/backfill.js +170 -0
  170. package/dist/{checkpointer/actions/delete-thread.js → esm/checkpointer/actions/delete-thread.d.ts} +4 -26
  171. package/dist/esm/checkpointer/actions/delete-thread.js +23 -0
  172. package/dist/{checkpointer/actions/get-tuple.js → esm/checkpointer/actions/get-tuple.d.ts} +7 -24
  173. package/dist/esm/checkpointer/actions/get-tuple.js +19 -0
  174. package/dist/esm/checkpointer/actions/list.d.ts +55 -0
  175. package/dist/esm/checkpointer/actions/list.js +67 -0
  176. package/dist/{checkpointer/actions/put-writes.js → esm/checkpointer/actions/put-writes.d.ts} +10 -37
  177. package/dist/esm/checkpointer/actions/put-writes.js +18 -0
  178. package/dist/esm/checkpointer/actions/put.d.ts +95 -0
  179. package/dist/esm/checkpointer/actions/put.js +75 -0
  180. package/dist/esm/checkpointer/internal/delta-history.d.ts +124 -0
  181. package/dist/esm/checkpointer/internal/delta-history.js +126 -0
  182. package/dist/{checkpointer/internal/listing.js → esm/checkpointer/internal/listing.d.ts} +22 -118
  183. package/dist/esm/checkpointer/internal/listing.js +95 -0
  184. package/dist/esm/checkpointer/internal/parse.d.ts +298 -0
  185. package/dist/esm/checkpointer/internal/parse.js +169 -0
  186. package/dist/esm/checkpointer/internal/pending-writes.d.ts +314 -0
  187. package/dist/esm/checkpointer/internal/pending-writes.js +229 -0
  188. package/dist/esm/checkpointer/internal/read.d.ts +135 -0
  189. package/dist/esm/checkpointer/internal/read.js +125 -0
  190. package/dist/esm/checkpointer/internal/rows.d.ts +644 -0
  191. package/dist/esm/checkpointer/internal/rows.js +323 -0
  192. package/dist/esm/checkpointer/internal/setup.d.ts +47 -0
  193. package/dist/esm/checkpointer/internal/setup.js +21 -0
  194. package/dist/{checkpointer/saver.js → esm/checkpointer/saver.d.ts} +84 -87
  195. package/dist/esm/checkpointer/saver.js +52 -0
  196. package/dist/esm/checkpointer/types.d.ts +51 -0
  197. package/dist/esm/checkpointer/types.js +1 -0
  198. package/dist/esm/factory/factory.d.ts +154 -0
  199. package/dist/esm/factory/factory.js +133 -0
  200. package/dist/esm/factory/types.d.ts +76 -0
  201. package/dist/esm/factory/types.js +1 -0
  202. package/dist/{history/actions/add-messages.js → esm/history/actions/add-messages.d.ts} +20 -26
  203. package/dist/esm/history/actions/add-messages.js +14 -0
  204. package/dist/{history/actions/clear.js → esm/history/actions/clear.d.ts} +4 -35
  205. package/dist/esm/history/actions/clear.js +26 -0
  206. package/dist/esm/history/actions/get-messages.d.ts +60 -0
  207. package/dist/esm/history/actions/get-messages.js +55 -0
  208. package/dist/esm/history/actions/list-sessions.d.ts +55 -0
  209. package/dist/esm/history/actions/list-sessions.js +64 -0
  210. package/dist/{history/actions/reconcile-count.js → esm/history/actions/reconcile-count.d.ts} +14 -16
  211. package/dist/esm/history/actions/reconcile-count.js +5 -0
  212. package/dist/{history/chat-message-history.js → esm/history/chat-message-history.d.ts} +76 -87
  213. package/dist/esm/history/chat-message-history.js +57 -0
  214. package/dist/esm/history/internal/append.d.ts +244 -0
  215. package/dist/esm/history/internal/append.js +259 -0
  216. package/dist/esm/history/internal/message-read.d.ts +84 -0
  217. package/dist/esm/history/internal/message-read.js +89 -0
  218. package/dist/esm/history/internal/parse.d.ts +153 -0
  219. package/dist/esm/history/internal/parse.js +105 -0
  220. package/dist/{history/internal/rows.js → esm/history/internal/rows.d.ts} +58 -112
  221. package/dist/esm/history/internal/rows.js +83 -0
  222. package/dist/esm/history/internal/session.d.ts +350 -0
  223. package/dist/esm/history/internal/session.js +285 -0
  224. package/dist/esm/history/internal/setup.d.ts +64 -0
  225. package/dist/esm/history/internal/setup.js +56 -0
  226. package/dist/{history/session-adapter.js → esm/history/session-adapter.d.ts} +25 -39
  227. package/dist/esm/history/session-adapter.js +34 -0
  228. package/dist/esm/history/types.d.ts +102 -0
  229. package/dist/esm/history/types.js +1 -0
  230. package/dist/esm/index.d.ts +53 -0
  231. package/dist/esm/index.js +10 -0
  232. package/dist/esm/shared/adapter.d.ts +146 -0
  233. package/dist/esm/shared/adapter.js +65 -0
  234. package/dist/{shared/clock.js → esm/shared/clock.d.ts} +3 -14
  235. package/dist/esm/shared/clock.js +9 -0
  236. package/dist/esm/shared/codec/codec.d.ts +336 -0
  237. package/dist/esm/shared/codec/codec.js +150 -0
  238. package/dist/esm/shared/codec/compression.d.ts +66 -0
  239. package/dist/esm/shared/codec/compression.js +40 -0
  240. package/dist/esm/shared/codec/json-serde.d.ts +80 -0
  241. package/dist/esm/shared/codec/json-serde.js +54 -0
  242. package/dist/esm/shared/codec/s3/client-types.d.ts +54 -0
  243. package/dist/esm/shared/codec/s3/client-types.js +3 -0
  244. package/dist/esm/shared/codec/s3/client.d.ts +63 -0
  245. package/dist/esm/shared/codec/s3/client.js +40 -0
  246. package/dist/{shared/codec/s3/config.js → esm/shared/codec/s3/config.d.ts} +45 -93
  247. package/dist/esm/shared/codec/s3/config.js +79 -0
  248. package/dist/esm/shared/codec/s3/lifecycle.d.ts +220 -0
  249. package/dist/esm/shared/codec/s3/lifecycle.js +214 -0
  250. package/dist/esm/shared/codec/s3/offloader.d.ts +428 -0
  251. package/dist/esm/shared/codec/s3/offloader.js +278 -0
  252. package/dist/{shared/concurrency.js → esm/shared/concurrency.d.ts} +2 -37
  253. package/dist/esm/shared/concurrency.js +27 -0
  254. package/dist/{shared/dynamodb/abort.js → esm/shared/dynamodb/abort.d.ts} +4 -16
  255. package/dist/esm/shared/dynamodb/abort.js +12 -0
  256. package/dist/esm/shared/dynamodb/batch-write.d.ts +86 -0
  257. package/dist/esm/shared/dynamodb/batch-write.js +74 -0
  258. package/dist/{shared/dynamodb/cancellation.js → esm/shared/dynamodb/cancellation.d.ts} +25 -53
  259. package/dist/esm/shared/dynamodb/cancellation.js +30 -0
  260. package/dist/{shared/dynamodb/client.js → esm/shared/dynamodb/client.d.ts} +74 -64
  261. package/dist/esm/shared/dynamodb/client.js +35 -0
  262. package/dist/{shared/dynamodb/idempotent-write.js → esm/shared/dynamodb/idempotent-write.d.ts} +172 -169
  263. package/dist/esm/shared/dynamodb/idempotent-write.js +153 -0
  264. package/dist/esm/shared/dynamodb/paginate.d.ts +111 -0
  265. package/dist/esm/shared/dynamodb/paginate.js +84 -0
  266. package/dist/esm/shared/dynamodb/partition-delete.d.ts +204 -0
  267. package/dist/esm/shared/dynamodb/partition-delete.js +171 -0
  268. package/dist/esm/shared/dynamodb/recency-index.d.ts +243 -0
  269. package/dist/esm/shared/dynamodb/recency-index.js +136 -0
  270. package/dist/esm/shared/dynamodb/retry.d.ts +317 -0
  271. package/dist/esm/shared/dynamodb/retry.js +180 -0
  272. package/dist/esm/shared/dynamodb/row-size.d.ts +33 -0
  273. package/dist/esm/shared/dynamodb/row-size.js +26 -0
  274. package/dist/{shared/dynamodb/table-schema.js → esm/shared/dynamodb/table-schema.d.ts} +57 -67
  275. package/dist/esm/shared/dynamodb/table-schema.js +43 -0
  276. package/dist/esm/shared/errors/base-error.d.ts +231 -0
  277. package/dist/esm/shared/errors/base-error.js +64 -0
  278. package/dist/esm/shared/errors/boundary.d.ts +86 -0
  279. package/dist/esm/shared/errors/boundary.js +54 -0
  280. package/dist/esm/shared/errors/classify.d.ts +206 -0
  281. package/dist/esm/shared/errors/classify.js +220 -0
  282. package/dist/{shared/errors/error-code.js → esm/shared/errors/error-code.d.ts} +39 -43
  283. package/dist/esm/shared/errors/error-code.js +24 -0
  284. package/dist/{shared/errors/errors.js → esm/shared/errors/errors.d.ts} +92 -98
  285. package/dist/esm/shared/errors/errors.js +110 -0
  286. package/dist/{shared/logging/logger.js → esm/shared/logging/logger.d.ts} +22 -52
  287. package/dist/esm/shared/logging/logger.js +25 -0
  288. package/dist/esm/shared/logging/redaction.d.ts +123 -0
  289. package/dist/esm/shared/logging/redaction.js +140 -0
  290. package/dist/{shared/logging/secret-patterns.js → esm/shared/logging/secret-patterns.d.ts} +46 -87
  291. package/dist/esm/shared/logging/secret-patterns.js +83 -0
  292. package/dist/{shared/logging/truncate.js → esm/shared/logging/truncate.d.ts} +6 -40
  293. package/dist/esm/shared/logging/truncate.js +25 -0
  294. package/dist/esm/shared/options.d.ts +100 -0
  295. package/dist/esm/shared/options.js +1 -0
  296. package/dist/{shared/ulid.js → esm/shared/ulid.d.ts} +4 -84
  297. package/dist/esm/shared/ulid.js +77 -0
  298. package/dist/{shared/validation/collaborators.js → esm/shared/validation/collaborators.d.ts} +37 -65
  299. package/dist/esm/shared/validation/collaborators.js +70 -0
  300. package/dist/{shared/validation/option-shape.js → esm/shared/validation/option-shape.d.ts} +14 -36
  301. package/dist/esm/shared/validation/option-shape.js +24 -0
  302. package/dist/esm/shared/validation/options.d.ts +145 -0
  303. package/dist/esm/shared/validation/options.js +156 -0
  304. package/dist/{shared/validation/primitives.js → esm/shared/validation/primitives.d.ts} +30 -125
  305. package/dist/esm/shared/validation/primitives.js +100 -0
  306. package/dist/esm/shared/validation/ttl.d.ts +94 -0
  307. package/dist/esm/shared/validation/ttl.js +46 -0
  308. package/dist/esm/store/actions/list-namespaces.d.ts +79 -0
  309. package/dist/esm/store/actions/list-namespaces.js +86 -0
  310. package/dist/esm/store/actions/put.d.ts +43 -0
  311. package/dist/esm/store/actions/put.js +46 -0
  312. package/dist/{store/actions/reconcile-vector-index.js → esm/store/actions/reconcile-vector-index.d.ts} +8 -16
  313. package/dist/esm/store/actions/reconcile-vector-index.js +10 -0
  314. package/dist/esm/store/actions/search.d.ts +38 -0
  315. package/dist/esm/store/actions/search.js +23 -0
  316. package/dist/esm/store/internal/batch-plan.d.ts +56 -0
  317. package/dist/esm/store/internal/batch-plan.js +28 -0
  318. package/dist/esm/store/internal/filter.d.ts +43 -0
  319. package/dist/esm/store/internal/filter.js +60 -0
  320. package/dist/esm/store/internal/get-item.d.ts +77 -0
  321. package/dist/esm/store/internal/get-item.js +54 -0
  322. package/dist/esm/store/internal/item-write.d.ts +270 -0
  323. package/dist/esm/store/internal/item-write.js +173 -0
  324. package/dist/esm/store/internal/parse.d.ts +230 -0
  325. package/dist/esm/store/internal/parse.js +169 -0
  326. package/dist/{store/internal/rows.js → esm/store/internal/rows.d.ts} +111 -199
  327. package/dist/esm/store/internal/rows.js +147 -0
  328. package/dist/esm/store/internal/semantic-search.d.ts +168 -0
  329. package/dist/esm/store/internal/semantic-search.js +200 -0
  330. package/dist/esm/store/internal/setup.d.ts +96 -0
  331. package/dist/esm/store/internal/setup.js +98 -0
  332. package/dist/esm/store/internal/table-search.d.ts +100 -0
  333. package/dist/esm/store/internal/table-search.js +119 -0
  334. package/dist/esm/store/internal/vector-index.d.ts +258 -0
  335. package/dist/esm/store/internal/vector-index.js +256 -0
  336. package/dist/{store/store.js → esm/store/store.d.ts} +99 -133
  337. package/dist/esm/store/store.js +93 -0
  338. package/dist/esm/store/types.d.ts +111 -0
  339. package/dist/esm/store/types.js +1 -0
  340. package/dist/esm/store/vector-backend.d.ts +104 -0
  341. package/dist/esm/store/vector-backend.js +1 -0
  342. package/package.json +50 -44
  343. package/dist/backfill/backfill.js +0 -393
  344. package/dist/checkpointer/actions/list.js +0 -142
  345. package/dist/checkpointer/actions/put.js +0 -195
  346. package/dist/checkpointer/internal/delta-history.js +0 -252
  347. package/dist/checkpointer/internal/parse.js +0 -372
  348. package/dist/checkpointer/internal/pending-writes.js +0 -588
  349. package/dist/checkpointer/internal/read.js +0 -264
  350. package/dist/checkpointer/internal/rows.js +0 -834
  351. package/dist/checkpointer/internal/setup.js +0 -72
  352. package/dist/checkpointer/types.js +0 -12
  353. package/dist/factory/factory.js +0 -266
  354. package/dist/factory/types.js +0 -10
  355. package/dist/history/actions/get-messages.js +0 -141
  356. package/dist/history/actions/list-sessions.js +0 -156
  357. package/dist/history/internal/append.js +0 -500
  358. package/dist/history/internal/message-read.js +0 -204
  359. package/dist/history/internal/parse.js +0 -252
  360. package/dist/history/internal/session.js +0 -628
  361. package/dist/history/internal/setup.js +0 -106
  362. package/dist/history/types.js +0 -12
  363. package/dist/index.js +0 -51
  364. package/dist/shared/adapter.js +0 -143
  365. package/dist/shared/codec/codec.js +0 -441
  366. package/dist/shared/codec/compression.js +0 -89
  367. package/dist/shared/codec/json-serde.js +0 -191
  368. package/dist/shared/codec/s3/client-types.js +0 -26
  369. package/dist/shared/codec/s3/client.js +0 -97
  370. package/dist/shared/codec/s3/lifecycle.js +0 -355
  371. package/dist/shared/codec/s3/offloader.js +0 -658
  372. package/dist/shared/dynamodb/batch-write.js +0 -173
  373. package/dist/shared/dynamodb/paginate.js +0 -188
  374. package/dist/shared/dynamodb/partition-delete.js +0 -340
  375. package/dist/shared/dynamodb/recency-index.js +0 -377
  376. package/dist/shared/dynamodb/retry.js +0 -463
  377. package/dist/shared/errors/base-error.js +0 -174
  378. package/dist/shared/errors/boundary.js +0 -143
  379. package/dist/shared/errors/classify.d.ts +0 -97
  380. package/dist/shared/errors/classify.js +0 -257
  381. package/dist/shared/logging/redaction.js +0 -316
  382. package/dist/shared/options.js +0 -11
  383. package/dist/shared/validation/options.js +0 -328
  384. package/dist/shared/validation/ttl.js +0 -132
  385. package/dist/store/actions/list-namespaces.js +0 -197
  386. package/dist/store/actions/put.js +0 -78
  387. package/dist/store/actions/search.js +0 -66
  388. package/dist/store/internal/batch-plan.d.ts +0 -26
  389. package/dist/store/internal/batch-plan.js +0 -109
  390. package/dist/store/internal/filter.js +0 -137
  391. package/dist/store/internal/get-item.d.ts +0 -45
  392. package/dist/store/internal/get-item.js +0 -115
  393. package/dist/store/internal/item-write.js +0 -463
  394. package/dist/store/internal/parse.js +0 -350
  395. package/dist/store/internal/semantic-search.js +0 -389
  396. package/dist/store/internal/setup.js +0 -223
  397. package/dist/store/internal/table-search.js +0 -213
  398. package/dist/store/internal/vector-index.js +0 -546
  399. package/dist/store/types.js +0 -15
  400. package/dist/store/vector-backend.js +0 -17
  401. /package/dist/{shared → cjs/shared}/clock.d.ts +0 -0
  402. /package/dist/{shared → cjs/shared}/codec/json-serde.d.ts +0 -0
  403. /package/dist/{shared → cjs/shared}/concurrency.d.ts +0 -0
  404. /package/dist/{shared → cjs/shared}/dynamodb/cancellation.d.ts +0 -0
  405. /package/dist/{shared → cjs/shared}/logging/logger.d.ts +0 -0
  406. /package/dist/{shared → cjs/shared}/logging/truncate.d.ts +0 -0
  407. /package/dist/{shared → cjs/shared}/ulid.d.ts +0 -0
  408. /package/dist/{shared → cjs/shared}/validation/primitives.d.ts +0 -0
  409. /package/dist/{store → cjs/store}/vector-backend.d.ts +0 -0
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Hides how a `ttl` option becomes an expiry.
3
+ *
4
+ * A caller gives days or seconds. The one-unit rule, the five-year cap, the
5
+ * epoch second DynamoDB's TTL attribute takes, and the S3 lifecycle days that
6
+ * keep an offloaded object from expiring before its row are all derived
7
+ * here, so the two spellings of the `ttl` option are accepted or rejected
8
+ * alike and no reader re-derives one unit from the other itself. A stored
9
+ * row's own epoch-second `ttl` is converted to milliseconds for `Date` where
10
+ * that row is read, not here.
11
+ */
12
+ /** Maximum TTL expressed in days (5 years). */
13
+ export declare const MAX_TTL_DAYS: number;
14
+ /** Maximum TTL expressed in seconds: the same five years as {@link MAX_TTL_DAYS}. */
15
+ export declare const MAX_TTL_SECONDS: number;
16
+ /**
17
+ * Extra days an S3 lifecycle rule adds over the TTL it backs, so the offloaded
18
+ * object is never removed before the row that names it expires, never the
19
+ * other way round. The rule expires an object by age, at or after creation +
20
+ * ceil(ttl) + this margin, which is at or after the `ttl` of any row naming
21
+ * it, so DynamoDB's physical-deletion lag (typically within a few days of the
22
+ * `ttl`, with no fixed bound:
23
+ * https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html)
24
+ * does not matter. The margin is headroom, not a bound on that lag.
25
+ */
26
+ export declare const S3_LIFECYCLE_SWEEP_MARGIN_DAYS = 2;
27
+ /** Time-to-live expressed in whole days or whole seconds. */
28
+ export type TtlOption = {
29
+ days: number;
30
+ } | {
31
+ seconds: number;
32
+ };
33
+ /**
34
+ * A {@link TtlOption} resolved to a positive number of seconds.
35
+ *
36
+ * Accepts: `ttl` — declared as the two-shape union; a JavaScript caller, or a
37
+ * config built from JSON, can also reach `undefined`, a non-object, `{}`, an
38
+ * object carrying both keys and one carrying any other key, and each is
39
+ * rejected. Within a shape the value must be an integer of at least 1.
40
+ *
41
+ * Returns: whole seconds, `days × 86400` for the days form.
42
+ *
43
+ * Throws: `VALIDATION`, in this order, naming `ttl` for a value that is not
44
+ * an object, `ttl.<key>` for a key other than `days` or `seconds`, `ttl` for
45
+ * an object naming neither unit or both, and `ttl.days` or `ttl.seconds` for a
46
+ * value outside 1..five years. Both forms share that cap, so the two spellings
47
+ * of one duration are accepted or rejected alike.
48
+ */
49
+ export declare function resolveTtlSeconds(ttl: TtlOption): number;
50
+ /**
51
+ * The value DynamoDB's TTL attribute takes for an item written now: the Unix
52
+ * epoch second at which it expires.
53
+ *
54
+ * Accepts: `ttl` — as {@link resolveTtlSeconds}. `now` — a clock returning
55
+ * epoch **milliseconds**, defaulting to `Date.now`; supplied by tests and by
56
+ * the adapters' clock seam.
57
+ *
58
+ * Returns: `floor(now() / 1000) + resolveTtlSeconds(ttl)`. Whole seconds,
59
+ * because DynamoDB reads the attribute as an epoch-second Number
60
+ * (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/time-to-live-ttl-before-you-start.html).
61
+ *
62
+ * Throws: whatever {@link resolveTtlSeconds} throws.
63
+ */
64
+ export declare function calculateTtlTimestamp(ttl: TtlOption, now?: () => number): number;
65
+ /**
66
+ * The `Days` of the S3 lifecycle expiration rule that backs a TTL.
67
+ *
68
+ * Accepts: `ttl` — as {@link resolveTtlSeconds}.
69
+ *
70
+ * Returns: the TTL rounded **up** to whole days plus
71
+ * {@link S3_LIFECYCLE_SWEEP_MARGIN_DAYS}, so always at least
72
+ * `1 + margin`.
73
+ *
74
+ * Throws: whatever {@link resolveTtlSeconds} throws.
75
+ *
76
+ * Guarantees: the object outlives the row that points at it, for every row
77
+ * written under the `ttl` this rule was computed from. S3 expires an object at
78
+ * the first midnight UTC at least `Days` after creation, while DynamoDB
79
+ * deletes an expired item typically within a few days of its `ttl`, with no
80
+ * fixed bound
81
+ * (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html).
82
+ * Every row naming the object carries a `ttl` no later than its creation plus
83
+ * `ttl`, so the object, expiring at or after that, is not removed before its
84
+ * row expires; readers hide a metadata, store or history row by its own `ttl`,
85
+ * and serve a checkpoint's payload and pending-write rows only while its
86
+ * metadata row is live. The margin is headroom, not a bound on the lag.
87
+ *
88
+ * The rule expires by age every object under its prefix, including objects
89
+ * named by rows written under an earlier `ttl`. After a rule is rewritten for
90
+ * a smaller `ttl`, the guarantee therefore holds only once every row written
91
+ * under the old, longer value has expired; until then such a row can outlive
92
+ * its object. Rewriting it for a larger `ttl` keeps the guarantee.
93
+ */
94
+ export declare function lifecycleExpirationDays(ttl: TtlOption): number;
@@ -0,0 +1,46 @@
1
+ import { validationError } from '../errors/errors.js';
2
+ import { allKeysOf, assertShape } from './option-shape.js';
3
+ import { assertInteger } from './primitives.js';
4
+ const SECONDS_PER_DAY = 24 * 60 * 60;
5
+ export const MAX_TTL_DAYS = 365 * 5;
6
+ export const MAX_TTL_SECONDS = MAX_TTL_DAYS * 24 * 60 * 60;
7
+ export const S3_LIFECYCLE_SWEEP_MARGIN_DAYS = 2;
8
+ const TTL_KEYS = allKeysOf({
9
+ days: 'days',
10
+ seconds: 'seconds',
11
+ });
12
+ function assertWithinCap(value, field, max) {
13
+ assertInteger(value, field, { min: 1 });
14
+ if (value > max) {
15
+ throw validationError(`${field} must be <= ${max} (five years)`, field);
16
+ }
17
+ }
18
+ function assertOneUnit(ttl) {
19
+ if (typeof ttl !== 'object' || ttl === null) {
20
+ throw validationError('ttl must be an object: { days } or { seconds }', 'ttl');
21
+ }
22
+ assertShape(ttl, TTL_KEYS, 'ttl');
23
+ const days = 'days' in ttl;
24
+ const seconds = 'seconds' in ttl;
25
+ if (days && seconds) {
26
+ throw validationError('ttl must specify either ttl.days or ttl.seconds, not both', 'ttl');
27
+ }
28
+ if (!days && !seconds) {
29
+ throw validationError('ttl must specify either ttl.days or ttl.seconds', 'ttl');
30
+ }
31
+ }
32
+ export function resolveTtlSeconds(ttl) {
33
+ assertOneUnit(ttl);
34
+ if ('days' in ttl) {
35
+ assertWithinCap(ttl.days, 'ttl.days', MAX_TTL_DAYS);
36
+ return ttl.days * SECONDS_PER_DAY;
37
+ }
38
+ assertWithinCap(ttl.seconds, 'ttl.seconds', MAX_TTL_SECONDS);
39
+ return ttl.seconds;
40
+ }
41
+ export function calculateTtlTimestamp(ttl, now = Date.now) {
42
+ return Math.floor(now() / 1000) + resolveTtlSeconds(ttl);
43
+ }
44
+ export function lifecycleExpirationDays(ttl) {
45
+ return Math.ceil(resolveTtlSeconds(ttl) / SECONDS_PER_DAY) + S3_LIFECYCLE_SWEEP_MARGIN_DAYS;
46
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Hides how the distinct namespaces are found and held in one order.
3
+ *
4
+ * A listing reads every live row it can reach — one partition when its first
5
+ * prefix condition opens with concrete labels, the whole table otherwise —
6
+ * keeps the namespaces every condition matches, truncates and deduplicates
7
+ * them, and sorts them by one pinned collation with its ties settled. A caller
8
+ * paging by `offset` gets the same order on every call and every host.
9
+ */
10
+ import type { MatchCondition } from '@langchain/langgraph-checkpoint';
11
+ import type { ParsedList } from '../internal/parse.js';
12
+ import type { StoreContext } from '../internal/setup.js';
13
+ /**
14
+ * Whether `namespace` satisfies one match condition. `condition.matchType` is
15
+ * `'prefix'` or `'suffix'`, already refused otherwise by the parser that built
16
+ * `condition` (`parseMatchCondition` in `parse.ts`).
17
+ *
18
+ * Accepts: `condition.path` — elements, where `'*'` matches any one element;
19
+ * longer than the namespace never matches, and empty matches every namespace.
20
+ *
21
+ * Returns: whether the condition holds.
22
+ *
23
+ * Throws: nothing.
24
+ */
25
+ export declare function matchNamespace(namespace: string[], condition: MatchCondition): boolean;
26
+ /**
27
+ * Cap a namespace to at most `maxDepth` elements.
28
+ *
29
+ * Accepts: `maxDepth` — absent returns the namespace unchanged; otherwise a
30
+ * parsed positive integer (see `parseListOperation` for what a negative or
31
+ * zero value did here).
32
+ *
33
+ * Returns: the namespace, truncated from the end; shorter than `maxDepth` is
34
+ * returned whole.
35
+ *
36
+ * Throws: nothing.
37
+ */
38
+ export declare function truncateDepth(namespace: string[], maxDepth?: number): string[];
39
+ /**
40
+ * Leading concrete (non-wildcard) elements of the first prefix condition.
41
+ *
42
+ * Accepts: `conditions` — absent, empty, suffix-only, or a prefix condition
43
+ * starting with `'*'` all yield nothing to scope by.
44
+ *
45
+ * Returns: the concrete leading elements, which name a partition and a sort-key
46
+ * prefix the listing can be read from. An empty result means the listing cannot
47
+ * be scoped to one partition and falls back to a Scan.
48
+ *
49
+ * Throws: nothing.
50
+ *
51
+ * Guarantees: the root is only ever a *superset* of what the conditions select
52
+ * — every condition is still applied to each namespace read — so scoping can
53
+ * never drop a namespace that belongs in the answer.
54
+ */
55
+ export declare function prefixRoot(conditions?: MatchCondition[]): string[];
56
+ /**
57
+ * The distinct namespaces satisfying every match condition.
58
+ *
59
+ * Accepts: `op` — parsed; every match condition must hold, absent or empty
60
+ * matches every namespace. A concrete prefix root scopes the read to one
61
+ * partition's Query, and anything else — a suffix condition, a leading `*`, no
62
+ * conditions — spans the table and is one of the four reads allowed to Scan
63
+ * (`test/static/guards/scan-sites.ts`).
64
+ * `op.maxDepth` — namespaces are truncated to it and then
65
+ * deduplicated, so `['a','b']` and `['a','c']` list once as `['a']`.
66
+ * `op.offset` and `op.limit` — a `limit` of 0 returns an empty listing without reading.
67
+ *
68
+ * Returns: the namespaces, sorted, then `limit` of them from `offset`.
69
+ *
70
+ * Throws: `RESULT_TRUNCATED` when `maxScanItems` or `maxIterations` is
71
+ * reached while rows remain, so a partial listing is never returned as a
72
+ * complete one; `FORMAT_UNSUPPORTED` for a store item a newer release wrote.
73
+ *
74
+ * Guarantees: every live row is read — the answer is about which namespaces
75
+ * exist, and paging over it must not depend on which rows were read first. That
76
+ * is also why the sort is total (see {@link compareNamespaces}), and why a
77
+ * `limit` of 0 is answered ahead of the read rather than by slicing one.
78
+ */
79
+ export declare function listNamespaces(context: StoreContext, op: ParsedList): Promise<string[][]>;
@@ -0,0 +1,86 @@
1
+ import { nowSeconds } from '../../shared/clock.js';
2
+ import { paginateQuery, paginateScan } from '../../shared/dynamodb/paginate.js';
3
+ import { isExpiredRow, KEY_SEPARATOR, withoutExpired } from '../../shared/dynamodb/table-schema.js';
4
+ import { parseStoreRow, projectKeys, scopedQuery, storeScan } from '../internal/rows.js';
5
+ const WILDCARD = '*';
6
+ function segmentMatches(actual, path) {
7
+ return path.every((element, index) => element === WILDCARD || element === actual[index]);
8
+ }
9
+ export function matchNamespace(namespace, condition) {
10
+ const { matchType, path } = condition;
11
+ if (path.length > namespace.length)
12
+ return false;
13
+ const slice = matchType === 'prefix'
14
+ ? namespace.slice(0, path.length)
15
+ : namespace.slice(namespace.length - path.length);
16
+ return segmentMatches(slice, path);
17
+ }
18
+ export function truncateDepth(namespace, maxDepth) {
19
+ return maxDepth === undefined ? namespace : namespace.slice(0, maxDepth);
20
+ }
21
+ export function prefixRoot(conditions) {
22
+ const prefixCondition = conditions?.find((condition) => condition.matchType === 'prefix');
23
+ if (!prefixCondition)
24
+ return [];
25
+ const root = [];
26
+ for (const element of prefixCondition.path) {
27
+ if (element === WILDCARD)
28
+ break;
29
+ root.push(element);
30
+ }
31
+ return root;
32
+ }
33
+ function namespaceSource(context, op, now) {
34
+ const root = prefixRoot(op.matchConditions);
35
+ if (root.length > 0) {
36
+ return paginateQuery({
37
+ retry: context.retry,
38
+ client: context.client,
39
+ params: withoutExpired(projectKeys(scopedQuery(context.tableName, root)), now),
40
+ maxItems: context.maxScanItems,
41
+ maxIterations: context.maxIterations,
42
+ });
43
+ }
44
+ return paginateScan({
45
+ retry: context.retry,
46
+ client: context.client,
47
+ params: withoutExpired(projectKeys(storeScan(context.tableName)), now),
48
+ maxItems: context.maxScanItems,
49
+ maxIterations: context.maxIterations,
50
+ });
51
+ }
52
+ const NAMESPACE_COLLATOR = new Intl.Collator('en');
53
+ const REFERENCE_JOIN = ':';
54
+ function compareNamespaces(a, b) {
55
+ const collated = NAMESPACE_COLLATOR.compare(a.join(REFERENCE_JOIN), b.join(REFERENCE_JOIN));
56
+ if (collated !== 0)
57
+ return collated;
58
+ const left = a.join(KEY_SEPARATOR);
59
+ const right = b.join(KEY_SEPARATOR);
60
+ return left < right ? -1 : Number(left > right);
61
+ }
62
+ export async function listNamespaces(context, op) {
63
+ if (op.limit === 0)
64
+ return [];
65
+ const now = nowSeconds();
66
+ const seen = new Set();
67
+ const namespaces = [];
68
+ for await (const raw of namespaceSource(context, op, now)) {
69
+ const record = parseStoreRow(raw);
70
+ if (!record || isExpiredRow(record, now))
71
+ continue;
72
+ const namespace = record.namespace;
73
+ if (op.matchConditions &&
74
+ !op.matchConditions.every((condition) => matchNamespace(namespace, condition))) {
75
+ continue;
76
+ }
77
+ const truncated = truncateDepth(namespace, op.maxDepth);
78
+ const dedupeKey = truncated.join(KEY_SEPARATOR);
79
+ if (seen.has(dedupeKey))
80
+ continue;
81
+ seen.add(dedupeKey);
82
+ namespaces.push(truncated);
83
+ }
84
+ namespaces.sort(compareNamespaces);
85
+ return namespaces.slice(op.offset, op.offset + op.limit);
86
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Hides the order a put happens in.
3
+ *
4
+ * A put reads the row it replaces for its `createdAt`, embeds once — a vector
5
+ * per extracted path onto the row, or one vector for the `vectorBackend`,
6
+ * never both — writes the row, and only then syncs the backend, best-effort.
7
+ * A `null` value takes the delete path instead. A caller hands over an item;
8
+ * that the table commits first and the vector copy follows is decided here.
9
+ */
10
+ import type { ParsedDelete, ParsedPut } from '../internal/parse.js';
11
+ import type { StoreContext } from '../internal/setup.js';
12
+ /**
13
+ * Store, update or delete an item.
14
+ *
15
+ * Accepts: `op` — parsed; a `ParsedDelete` removes the item, a `ParsedPut` is
16
+ * stored, its value encoded with optional compression and S3 offload under
17
+ * this row's own path, in an object named by this put's own id. `op.index` —
18
+ * `false` stores the item without indexing it and clears any vector it had, an
19
+ * array overrides the configured fields for this put, and absent uses the
20
+ * store's configuration.
21
+ *
22
+ * Returns: nothing. Deleting an item that is not there is not an error.
23
+ *
24
+ * Throws: `VALIDATION` naming `value` for a value that JSON cannot represent —
25
+ * refused at the write rather than stored as a row that can never be read
26
+ * back — or naming `payload` for one too large to store inline without `s3`,
27
+ * or, once offloaded, larger than `s3.maxDownloadBytes`; `VALIDATION` again,
28
+ * naming `index` or `value`, for the built row — payload plus its inline
29
+ * vectors — over DynamoDB's 400 KB item limit, naming `index` when the
30
+ * vectors are what pushed it over, checked before anything is written;
31
+ * `S3_OFFLOAD_FAILED`; whatever the write throws.
32
+ *
33
+ * Guarantees: DynamoDB holds the canonical item — the vector index is synced
34
+ * afterwards and best-effort, so a backend outage never fails a put or leaves a
35
+ * half-written item. `createdAt` survives every update of a live item; a put
36
+ * over a row that has expired but not yet been swept is a creation, since no
37
+ * reader could still see that item. The superseded payload
38
+ * is deleted only once the new row is committed, and this put's own upload
39
+ * only once a read proves its write did not land. Neither release reads the
40
+ * row first: each put uploads under a key ending in an id of its own, so the
41
+ * object a put uploads is named only by that put's own rows.
42
+ */
43
+ export declare function putItem(context: StoreContext, op: ParsedPut | ParsedDelete): Promise<void>;
@@ -0,0 +1,46 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { nowIso } from '../../shared/clock.js';
3
+ import { calculateTtlTimestamp } from '../../shared/validation/ttl.js';
4
+ import { deleteStoreItem, persistRow, verifyWriteLanded } from '../internal/item-write.js';
5
+ import { buildStoreRow, isLiveRow, itemRowKey, readExisting, } from '../internal/rows.js';
6
+ import { embedPassages } from '../internal/semantic-search.js';
7
+ import { itemVector, syncItemVector } from '../internal/vector-index.js';
8
+ async function resolvePassages(context, op, value) {
9
+ if (op.index === false)
10
+ return undefined;
11
+ return embedPassages(context, value, op.index);
12
+ }
13
+ export async function putItem(context, op) {
14
+ if (op.kind === 'delete') {
15
+ await deleteStoreItem(context, op.address);
16
+ return;
17
+ }
18
+ const { namespace, key } = op.address;
19
+ const value = op.value;
20
+ const timestamp = nowIso();
21
+ const existing = await readExisting(context, itemRowKey(op.address));
22
+ const embedding = await itemVector(context, op);
23
+ const embeddings = context.vectorBackend ? undefined : await resolvePassages(context, op, value);
24
+ const ttlTimestamp = context.ttl ? calculateTtlTimestamp(context.ttl) : undefined;
25
+ const record = await buildStoreRow(context, { namespace, key }, value, {
26
+ createdAt: isLiveRow(existing) ? (existing.createdAt ?? timestamp) : timestamp,
27
+ updatedAt: timestamp,
28
+ embeddings,
29
+ ttlTimestamp,
30
+ rev: randomUUID(),
31
+ });
32
+ await persistRow(context, record, existing);
33
+ await syncVectorWhileCurrent(context, op.address, record, embedding);
34
+ }
35
+ async function syncVectorWhileCurrent(context, address, record, embedding) {
36
+ if (context.vectorBackend === undefined)
37
+ return;
38
+ if ((await verifyWriteLanded(context, record)) !== 'landed') {
39
+ context.logger.info('store.put: left the vector index to the write that superseded this put', {
40
+ namespace: address.namespace,
41
+ key: address.key,
42
+ });
43
+ return;
44
+ }
45
+ await syncItemVector(context, address, embedding);
46
+ }
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * Hides what a reconcile refuses before it touches the backend.
4
3
  *
@@ -8,11 +7,8 @@
8
7
  * is then made to agree with the table belongs to the vector index, so the
9
8
  * store's method knows neither half.
10
9
  */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.reconcileVectorIndex = reconcileVectorIndex;
13
- const errors_1 = require("../../shared/errors/errors");
14
- const parse_1 = require("../internal/parse");
15
- const vector_index_1 = require("../internal/vector-index");
10
+ import type { StoreContext } from '../internal/setup.js';
11
+ import type { VectorReconcileResult } from '../types.js';
16
12
  /**
17
13
  * Repair the vector backend against the canonical DynamoDB items under
18
14
  * `namespacePrefix`: re-push every live embedding, and — when the backend
@@ -28,19 +24,15 @@ const vector_index_1 = require("../internal/vector-index");
28
24
  * Throws: `VALIDATION` naming `namespacePrefix` or `namespacePrefix element`
29
25
  * for an empty or malformed prefix, as `search` names it, and `vectorBackend`
30
26
  * when the store has no index or backend to reconcile;
31
- * `RESULT_TRUNCATED` past `maxScanItems`, since repairing from a
32
- * partial view would prune live vectors; whatever the reads, the embeddings
33
- * model and the backend throw.
27
+ * `RESULT_TRUNCATED` past `maxScanItems` or `maxIterations`, since repairing
28
+ * from a partial view would prune live vectors; whatever the reads, the
29
+ * embeddings model and the backend throw.
34
30
  *
35
31
  * Guarantees: re-embeds with the store's configured fields, so a per-put
36
32
  * `index` field override is not reproduced — a reconcile makes the backend
37
33
  * agree with the store's configuration, not with each item's write-time one.
38
34
  * DynamoDB is never written: only the backend is repaired.
39
35
  */
40
- async function reconcileVectorIndex(context, namespacePrefix, options = {}) {
41
- const prefix = (0, parse_1.parseNamespace)(namespacePrefix, 'namespacePrefix');
42
- if (!(0, vector_index_1.hasVectorBackend)(context)) {
43
- throw (0, errors_1.validationError)('reconcileVectorIndex requires a configured index and vectorBackend', 'vectorBackend');
44
- }
45
- return (0, vector_index_1.reconcileVectors)(context, prefix, options.signal);
46
- }
36
+ export declare function reconcileVectorIndex(context: StoreContext, namespacePrefix: string[], options?: {
37
+ signal?: AbortSignal;
38
+ }): Promise<VectorReconcileResult>;
@@ -0,0 +1,10 @@
1
+ import { validationError } from '../../shared/errors/errors.js';
2
+ import { parseNamespace } from '../internal/parse.js';
3
+ import { hasVectorBackend, reconcileVectors } from '../internal/vector-index.js';
4
+ export async function reconcileVectorIndex(context, namespacePrefix, options = {}) {
5
+ const prefix = parseNamespace(namespacePrefix, 'namespacePrefix');
6
+ if (!hasVectorBackend(context)) {
7
+ throw validationError('reconcileVectorIndex requires a configured index and vectorBackend', 'vectorBackend');
8
+ }
9
+ return reconcileVectors(context, prefix, options.signal);
10
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Hides which of three paths serves a search.
3
+ *
4
+ * A query with a `vectorBackend` is answered by the backend; no query, or no
5
+ * `index` to embed one with, is a page read from the table that stops once
6
+ * full; anything else is ranked in memory over at most `maxSearchCandidates`.
7
+ * A page of zero is answered before any of them. A caller gets the same shape
8
+ * of page whichever path ran, scored exactly when a query could be ranked.
9
+ */
10
+ import type { SearchItem } from '@langchain/langgraph-checkpoint';
11
+ import type { ParsedSearch } from '../internal/parse.js';
12
+ import type { StoreContext } from '../internal/setup.js';
13
+ /**
14
+ * Search items under a namespace prefix: metadata filtering plus optional
15
+ * semantic ranking.
16
+ *
17
+ * Accepts: `search` — already parsed, so `namespacePrefix`, `offset` and
18
+ * `limit` are resolved; `search.query` absent or empty
19
+ * (which is absent: there is no query to embed) ranks nothing and returns the
20
+ * page as read, which is what the reference store does
21
+ * (`@langchain/langgraph-checkpoint@1.1.5` `dist/store/memory.js:70-80`, where a
22
+ * falsy query takes the unscored path). A query without a configured `index`
23
+ * does the same, since there is nothing to embed it with.
24
+ *
25
+ * Returns: at most `limit` items from `offset`. With a query and an index every
26
+ * item carries a `score`; without one none does. Scores rank best-first; an item
27
+ * that cannot be scored ranks last rather than being dropped.
28
+ *
29
+ * Throws: `VALIDATION` naming `maxSearchCandidates` or `index.dims`; whatever
30
+ * the reads, decodes and the embeddings model throw.
31
+ *
32
+ * Guarantees: a page of zero costs no request at all, and otherwise only the
33
+ * page's own items are decoded on the unranked path — the
34
+ * read stops as soon as it is full. A semantic search must read every candidate
35
+ * to rank it, which is why it is capped and why a large corpus belongs in a
36
+ * `vectorBackend`.
37
+ */
38
+ export declare function searchItems(context: StoreContext, search: ParsedSearch, signal?: AbortSignal): Promise<SearchItem[]>;
@@ -0,0 +1,23 @@
1
+ import { truncateLabelsForLog } from '../../shared/logging/truncate.js';
2
+ import { assertVectorDims } from '../internal/semantic-search.js';
3
+ import { collectCandidates, rankInMemory } from '../internal/table-search.js';
4
+ import { hasVectorBackend, searchViaBackend } from '../internal/vector-index.js';
5
+ export async function searchItems(context, search, signal) {
6
+ const { offset, limit } = search;
7
+ if (limit === 0)
8
+ return [];
9
+ if (search.query && hasVectorBackend(context)) {
10
+ const ranked = await searchViaBackend(context, search, signal);
11
+ return ranked.slice(offset, offset + limit);
12
+ }
13
+ if (!search.query || !context.index) {
14
+ const page = await collectCandidates(context, search, { kind: 'page', need: offset + limit }, signal);
15
+ return page.map(({ item }) => ({ ...item, score: undefined })).slice(offset, offset + limit);
16
+ }
17
+ const candidates = await collectCandidates(context, search, { kind: 'semantic', cap: context.maxSearchCandidates }, signal);
18
+ const queryVector = await context.index.embeddings.embedQuery(search.query);
19
+ assertVectorDims(context.index, queryVector, 'query');
20
+ const ranked = rankInMemory(candidates, queryVector, context.maxSearchCandidates, (count) => context.logger.warn('search: some candidates carry an embedding of a different dimension than the query and ' +
21
+ 'were ranked unscored; re-embed them with reconcileVectorIndex or a re-put', { namespacePrefix: truncateLabelsForLog(search.namespacePrefix), count }));
22
+ return ranked.slice(offset, offset + limit);
23
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Hides how a batch runs: every read first, against the state the batch found,
3
+ * then one write per item, concurrently within each phase.
4
+ *
5
+ * That is how the reference store evaluates a batch — a get, a search or a
6
+ * listing is answered as the batch found things, and the puts are applied
7
+ * afterwards, the last one per item winning — so a graph developed against it
8
+ * gets the same answers here, and two tasks of one superstep that touch the
9
+ * same item get answers that do not depend on which of them was enqueued
10
+ * first. The operations of one phase share the call's one decode budget,
11
+ * divided between them, so a batch of concurrent searches costs no more memory
12
+ * than a single one.
13
+ */
14
+ import type { ParsedOperation } from './parse.js';
15
+ /** The two phases of a batch: the indices of its reads, and of the one write kept per item. */
16
+ export interface BatchPlan {
17
+ readonly reads: number[];
18
+ readonly writes: number[];
19
+ }
20
+ /**
21
+ * Split a batch into the reads it answers first and the writes it applies
22
+ * afterwards.
23
+ *
24
+ * Accepts: `operations` — in caller order.
25
+ *
26
+ * Returns: the indices of every get, search and listing, in caller order, and
27
+ * the index of the last put or delete addressing each item, in caller order.
28
+ * An earlier write to the same item is superseded before it is sent: the
29
+ * reference applies only the last put per key, and sending both would race
30
+ * two compare-and-swaps for an outcome the batch has already decided.
31
+ *
32
+ * Throws: nothing.
33
+ */
34
+ export declare function planBatch(operations: readonly ParsedOperation[]): BatchPlan;
35
+ /**
36
+ * Run a batch: its reads concurrently, at most `limit` in flight, then its
37
+ * writes the same way. Results come back in operation order.
38
+ *
39
+ * Accepts: `operations` — in caller order. `dispatch` — handed each operation
40
+ * and its share of the budget: `limit` divided by the operations its phase
41
+ * keeps in flight, and never less than one. `limit` — operations in flight
42
+ * within one phase.
43
+ *
44
+ * Returns: the results in operation order, not completion order; a write
45
+ * superseded by a later one to the same item answers `null`, as the write
46
+ * that was sent does, without having been sent.
47
+ *
48
+ * Throws: the first failure. Any failure rejects the whole batch: no operation
49
+ * in a later phase starts, the ones already in flight settle, and that first
50
+ * error is the one thrown.
51
+ *
52
+ * Guarantees: every read sees the state before any of the batch's writes, and
53
+ * the operations of one call decode at most `limit` payloads at once between
54
+ * them, which is what `readConcurrency`'s documented memory ceiling assumes.
55
+ */
56
+ export declare function runBatch<R>(operations: readonly ParsedOperation[], dispatch: (operation: ParsedOperation, readConcurrency: number) => Promise<R>, limit?: number): Promise<(R | null)[]>;
@@ -0,0 +1,28 @@
1
+ import { DEFAULT_READ_CONCURRENCY, mapWithConcurrency } from '../../shared/concurrency.js';
2
+ function itemOf(address) {
3
+ return JSON.stringify([address.namespace, address.key]);
4
+ }
5
+ export function planBatch(operations) {
6
+ const reads = [];
7
+ const lastWrite = new Map();
8
+ operations.forEach((op, index) => {
9
+ if (op.kind === 'put' || op.kind === 'delete')
10
+ lastWrite.set(itemOf(op.address), index);
11
+ else
12
+ reads.push(index);
13
+ });
14
+ return { reads, writes: [...lastWrite.values()].sort((a, b) => a - b) };
15
+ }
16
+ export async function runBatch(operations, dispatch, limit = DEFAULT_READ_CONCURRENCY) {
17
+ const results = operations.map(() => null);
18
+ const { reads, writes } = planBatch(operations);
19
+ for (const phase of [reads, writes]) {
20
+ if (phase.length === 0)
21
+ continue;
22
+ const share = Math.max(1, Math.floor(limit / Math.min(limit, phase.length)));
23
+ await mapWithConcurrency(phase, limit, async (index) => {
24
+ results[index] = await dispatch(operations[index], share);
25
+ });
26
+ }
27
+ return results;
28
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Hides the store's filter grammar.
3
+ *
4
+ * Which operators a search filter accepts, how each compares a stored field —
5
+ * ordered comparisons only between like-typed values, an absent field
6
+ * satisfying only `$ne` and `$nin` — and whether an item passes a search's
7
+ * optional filter are decided here, the same way whichever search path runs.
8
+ */
9
+ import type { Item } from '@langchain/langgraph-checkpoint';
10
+ /** A JSON value stored in an item or supplied in a filter. */
11
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
12
+ [key: string]: JsonValue;
13
+ };
14
+ /**
15
+ * Whether `value` satisfies every field condition in `filter`.
16
+ *
17
+ * Accepts: `value` — a stored item's decoded value. Declared as a record, but a
18
+ * row holds whatever its writer stored, including `null` and a scalar; such a
19
+ * value has no own properties and so satisfies no condition. `filter` — a plain
20
+ * value per field is exact match, an operator object (`{ $gt: 4 }`) applies
21
+ * comparisons, and `{}` constrains nothing.
22
+ *
23
+ * Returns: whether every condition holds.
24
+ *
25
+ * Throws: nothing. `search` walks every candidate row, so one row whose value
26
+ * is not an object must not fail the search.
27
+ *
28
+ * Guarantees: own properties only — `value['toString']` would otherwise resolve
29
+ * up the prototype chain and be compared as if it were stored data.
30
+ */
31
+ export declare function matchesStoreFilter(value: Record<string, JsonValue>, filter: Record<string, JsonValue>): boolean;
32
+ /**
33
+ * Whether `item` satisfies a search's optional metadata filter.
34
+ *
35
+ * Accepts: `filter` — a parsed search's filter; absent passes every item.
36
+ * `item.value` — whatever the item's writer stored; a value that is not
37
+ * an object satisfies no condition (see `matchesStoreFilter`).
38
+ *
39
+ * Returns: whether the item belongs in the result.
40
+ *
41
+ * Throws: nothing, so one unusual row cannot fail a search over many.
42
+ */
43
+ export declare function passesFilter(item: Item, filter: Record<string, JsonValue> | undefined): boolean;