@farukada/aws-langgraph-dynamodb-ts 0.8.0 → 1.0.0-rc.1

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 (482) hide show
  1. package/README.md +282 -49
  2. package/dist/checkpointer/actions/delete-thread.d.ts +3 -2
  3. package/dist/checkpointer/actions/delete-thread.js +5 -2
  4. package/dist/checkpointer/actions/get-tuple.d.ts +3 -2
  5. package/dist/checkpointer/actions/get-tuple.js +10 -4
  6. package/dist/checkpointer/actions/list.d.ts +14 -4
  7. package/dist/checkpointer/actions/list.js +94 -61
  8. package/dist/checkpointer/actions/put-writes.d.ts +5 -5
  9. package/dist/checkpointer/actions/put-writes.js +12 -40
  10. package/dist/checkpointer/actions/put.d.ts +10 -3
  11. package/dist/checkpointer/actions/put.js +42 -12
  12. package/dist/checkpointer/internal/assemble.d.ts +10 -3
  13. package/dist/checkpointer/internal/assemble.js +7 -6
  14. package/dist/checkpointer/internal/checkpoint-write-verify.d.ts +24 -0
  15. package/dist/checkpointer/internal/checkpoint-write-verify.js +67 -0
  16. package/dist/checkpointer/internal/configurable.d.ts +0 -1
  17. package/dist/checkpointer/internal/configurable.js +10 -9
  18. package/dist/checkpointer/internal/fetch.d.ts +14 -5
  19. package/dist/checkpointer/internal/fetch.js +56 -14
  20. package/dist/checkpointer/internal/filter-match.d.ts +3 -2
  21. package/dist/checkpointer/internal/filter-match.js +4 -3
  22. package/dist/checkpointer/internal/item-reader.d.ts +31 -6
  23. package/dist/checkpointer/internal/item-reader.js +54 -15
  24. package/dist/checkpointer/internal/item-writer.d.ts +12 -3
  25. package/dist/checkpointer/internal/item-writer.js +26 -10
  26. package/dist/checkpointer/internal/keys.d.ts +11 -1
  27. package/dist/checkpointer/internal/keys.js +33 -3
  28. package/dist/checkpointer/internal/list-scope.d.ts +61 -0
  29. package/dist/checkpointer/internal/list-scope.js +108 -0
  30. package/dist/checkpointer/internal/pending-sends.d.ts +13 -0
  31. package/dist/checkpointer/internal/pending-sends.js +29 -0
  32. package/dist/checkpointer/internal/query.d.ts +2 -1
  33. package/dist/checkpointer/internal/query.js +9 -3
  34. package/dist/checkpointer/internal/regular-write.d.ts +28 -0
  35. package/dist/checkpointer/internal/regular-write.js +66 -0
  36. package/dist/checkpointer/internal/setup.d.ts +3 -1
  37. package/dist/checkpointer/internal/setup.js +10 -8
  38. package/dist/checkpointer/internal/special-write-cas.d.ts +29 -0
  39. package/dist/checkpointer/internal/special-write-cas.js +104 -0
  40. package/dist/checkpointer/internal/special-write-cleanup.d.ts +19 -14
  41. package/dist/checkpointer/internal/special-write-cleanup.js +35 -87
  42. package/dist/checkpointer/internal/special-write-verify.d.ts +53 -0
  43. package/dist/checkpointer/internal/special-write-verify.js +80 -0
  44. package/dist/checkpointer/internal/stored-channels.d.ts +31 -0
  45. package/dist/checkpointer/internal/stored-channels.js +70 -0
  46. package/dist/checkpointer/internal/validation.d.ts +11 -6
  47. package/dist/checkpointer/internal/validation.js +19 -9
  48. package/dist/checkpointer/internal/write-guard.d.ts +8 -9
  49. package/dist/checkpointer/internal/write-guard.js +16 -16
  50. package/dist/checkpointer/internal/write-index.d.ts +8 -1
  51. package/dist/checkpointer/internal/write-index.js +6 -3
  52. package/dist/checkpointer/saver.d.ts +50 -10
  53. package/dist/checkpointer/saver.js +59 -17
  54. package/dist/checkpointer/types.d.ts +14 -1
  55. package/dist/checkpointer/types.js +0 -1
  56. package/dist/factory/factory.d.ts +22 -25
  57. package/dist/factory/factory.js +58 -18
  58. package/dist/factory/types.d.ts +57 -0
  59. package/dist/factory/types.js +2 -0
  60. package/dist/history/actions/add-messages.d.ts +1 -2
  61. package/dist/history/actions/add-messages.js +4 -4
  62. package/dist/history/actions/clear.d.ts +3 -2
  63. package/dist/history/actions/clear.js +5 -2
  64. package/dist/history/actions/get-messages.d.ts +13 -6
  65. package/dist/history/actions/get-messages.js +63 -42
  66. package/dist/history/actions/list-sessions.d.ts +1 -1
  67. package/dist/history/actions/list-sessions.js +8 -12
  68. package/dist/history/actions/reconcile-count.d.ts +1 -2
  69. package/dist/history/actions/reconcile-count.js +20 -7
  70. package/dist/history/chat-message-history.d.ts +51 -26
  71. package/dist/history/chat-message-history.js +60 -30
  72. package/dist/history/internal/append-saga.d.ts +7 -2
  73. package/dist/history/internal/append-saga.js +58 -14
  74. package/dist/history/internal/compensation.d.ts +6 -2
  75. package/dist/history/internal/compensation.js +14 -6
  76. package/dist/history/internal/item-mapper.d.ts +0 -3
  77. package/dist/history/internal/item-mapper.js +2 -8
  78. package/dist/history/internal/keys.d.ts +0 -1
  79. package/dist/history/internal/keys.js +0 -1
  80. package/dist/history/internal/message-chunker.d.ts +0 -1
  81. package/dist/history/internal/message-chunker.js +0 -1
  82. package/dist/history/internal/message-transaction.d.ts +0 -1
  83. package/dist/history/internal/message-transaction.js +3 -2
  84. package/dist/history/internal/message-window.d.ts +17 -0
  85. package/dist/history/internal/message-window.js +49 -0
  86. package/dist/history/internal/query.d.ts +16 -3
  87. package/dist/history/internal/query.js +13 -5
  88. package/dist/history/internal/session-count.d.ts +8 -2
  89. package/dist/history/internal/session-count.js +14 -8
  90. package/dist/history/internal/session-title.d.ts +0 -1
  91. package/dist/history/internal/session-title.js +1 -2
  92. package/dist/history/internal/session-update.d.ts +0 -1
  93. package/dist/history/internal/session-update.js +0 -1
  94. package/dist/history/internal/setup.d.ts +3 -1
  95. package/dist/history/internal/setup.js +16 -8
  96. package/dist/history/internal/title-generator.d.ts +0 -1
  97. package/dist/history/internal/title-generator.js +19 -3
  98. package/dist/history/internal/ttl-anchor.d.ts +1 -2
  99. package/dist/history/internal/ttl-anchor.js +5 -5
  100. package/dist/history/internal/validation.d.ts +19 -3
  101. package/dist/history/internal/validation.js +41 -4
  102. package/dist/history/session-adapter.d.ts +9 -3
  103. package/dist/history/session-adapter.js +6 -3
  104. package/dist/history/types.d.ts +23 -2
  105. package/dist/history/types.js +0 -1
  106. package/dist/index.d.ts +12 -5
  107. package/dist/index.js +5 -3
  108. package/dist/shared/clock.d.ts +6 -1
  109. package/dist/shared/clock.js +9 -1
  110. package/dist/shared/codec/codec.d.ts +26 -17
  111. package/dist/shared/codec/codec.js +46 -24
  112. package/dist/shared/codec/compression.d.ts +1 -2
  113. package/dist/shared/codec/compression.js +2 -3
  114. package/dist/shared/codec/descriptor-keys.d.ts +11 -3
  115. package/dist/shared/codec/descriptor-keys.js +2 -2
  116. package/dist/shared/codec/encode.d.ts +13 -0
  117. package/dist/shared/codec/encode.js +43 -0
  118. package/dist/shared/codec/json-serde.d.ts +0 -1
  119. package/dist/shared/codec/json-serde.js +0 -1
  120. package/dist/shared/codec/payload-loss.d.ts +12 -0
  121. package/dist/shared/codec/payload-loss.js +38 -0
  122. package/dist/shared/codec/s3/adapter-config.d.ts +13 -0
  123. package/dist/shared/codec/s3/adapter-config.js +22 -0
  124. package/dist/shared/codec/s3/bounded-body.d.ts +14 -0
  125. package/dist/shared/codec/s3/bounded-body.js +47 -0
  126. package/dist/shared/codec/s3/client-types.d.ts +34 -0
  127. package/dist/shared/codec/s3/client-types.js +7 -0
  128. package/dist/shared/codec/s3/client.d.ts +11 -5
  129. package/dist/shared/codec/s3/client.js +25 -3
  130. package/dist/shared/codec/s3/config.d.ts +32 -5
  131. package/dist/shared/codec/s3/config.js +37 -5
  132. package/dist/shared/codec/s3/delete.d.ts +0 -1
  133. package/dist/shared/codec/s3/delete.js +0 -1
  134. package/dist/shared/codec/s3/key-scope.d.ts +23 -0
  135. package/dist/shared/codec/s3/key-scope.js +44 -0
  136. package/dist/shared/codec/s3/lifecycle.d.ts +11 -5
  137. package/dist/shared/codec/s3/lifecycle.js +32 -16
  138. package/dist/shared/codec/s3/offloader.d.ts +6 -2
  139. package/dist/shared/codec/s3/offloader.js +21 -3
  140. package/dist/shared/codec/s3/orphans.d.ts +6 -1
  141. package/dist/shared/codec/s3/orphans.js +15 -2
  142. package/dist/shared/codec/s3/read-write.d.ts +7 -3
  143. package/dist/shared/codec/s3/read-write.js +16 -8
  144. package/dist/shared/codec/s3/retry.d.ts +4 -4
  145. package/dist/shared/codec/s3/retry.js +13 -16
  146. package/dist/shared/concurrency.d.ts +6 -0
  147. package/dist/shared/concurrency.js +30 -0
  148. package/dist/shared/constants.d.ts +68 -5
  149. package/dist/shared/constants.js +70 -7
  150. package/dist/shared/dynamodb/abort.d.ts +9 -0
  151. package/dist/shared/dynamodb/abort.js +27 -0
  152. package/dist/shared/dynamodb/backoff.d.ts +4 -4
  153. package/dist/shared/dynamodb/backoff.js +7 -7
  154. package/dist/shared/dynamodb/batch-write.d.ts +0 -1
  155. package/dist/shared/dynamodb/batch-write.js +0 -1
  156. package/dist/shared/dynamodb/cancellation.d.ts +0 -1
  157. package/dist/shared/dynamodb/cancellation.js +0 -1
  158. package/dist/shared/dynamodb/client.d.ts +9 -2
  159. package/dist/shared/dynamodb/client.js +24 -1
  160. package/dist/shared/dynamodb/conditional-put.d.ts +67 -0
  161. package/dist/shared/dynamodb/conditional-put.js +76 -0
  162. package/dist/shared/dynamodb/drain-unprocessed.d.ts +3 -1
  163. package/dist/shared/dynamodb/drain-unprocessed.js +1 -2
  164. package/dist/shared/dynamodb/expiry.d.ts +16 -0
  165. package/dist/shared/dynamodb/expiry.js +29 -0
  166. package/dist/shared/dynamodb/paginate-core.d.ts +5 -3
  167. package/dist/shared/dynamodb/paginate-core.js +47 -17
  168. package/dist/shared/dynamodb/paginate.d.ts +0 -1
  169. package/dist/shared/dynamodb/paginate.js +1 -2
  170. package/dist/shared/dynamodb/partition-delete.d.ts +7 -1
  171. package/dist/shared/dynamodb/partition-delete.js +4 -3
  172. package/dist/shared/dynamodb/retry-classifier.d.ts +10 -2
  173. package/dist/shared/dynamodb/retry-classifier.js +42 -11
  174. package/dist/shared/dynamodb/retry-policy.d.ts +26 -0
  175. package/dist/shared/dynamodb/retry-policy.js +22 -0
  176. package/dist/shared/dynamodb/retry.d.ts +14 -1
  177. package/dist/shared/dynamodb/retry.js +11 -7
  178. package/dist/shared/dynamodb/scan.d.ts +0 -1
  179. package/dist/shared/dynamodb/scan.js +1 -2
  180. package/dist/shared/dynamodb/types.d.ts +1 -2
  181. package/dist/shared/dynamodb/types.js +0 -1
  182. package/dist/shared/errors/base-error.d.ts +14 -6
  183. package/dist/shared/errors/base-error.js +8 -9
  184. package/dist/shared/errors/boundary.d.ts +18 -0
  185. package/dist/shared/errors/boundary.js +46 -0
  186. package/dist/shared/errors/error-code.d.ts +2 -2
  187. package/dist/shared/errors/error-code.js +1 -1
  188. package/dist/shared/errors/errors.d.ts +13 -13
  189. package/dist/shared/errors/errors.js +18 -16
  190. package/dist/shared/errors/upstream-error.d.ts +16 -0
  191. package/dist/shared/errors/upstream-error.js +27 -0
  192. package/dist/shared/errors/wrap-error.d.ts +0 -9
  193. package/dist/shared/errors/wrap-error.js +0 -15
  194. package/dist/shared/logging/logger.d.ts +6 -2
  195. package/dist/shared/logging/logger.js +0 -1
  196. package/dist/shared/logging/redaction-walk.d.ts +2 -2
  197. package/dist/shared/logging/redaction-walk.js +38 -18
  198. package/dist/shared/logging/redaction.d.ts +14 -6
  199. package/dist/shared/logging/redaction.js +19 -4
  200. package/dist/shared/logging/secret-patterns.d.ts +54 -3
  201. package/dist/shared/logging/secret-patterns.js +67 -8
  202. package/dist/shared/options.d.ts +9 -4
  203. package/dist/shared/options.js +0 -1
  204. package/dist/shared/ulid.d.ts +15 -2
  205. package/dist/shared/ulid.js +35 -3
  206. package/dist/shared/validation/options.d.ts +8 -0
  207. package/dist/shared/validation/options.js +90 -0
  208. package/dist/shared/validation/primitives.d.ts +14 -10
  209. package/dist/shared/validation/primitives.js +23 -25
  210. package/dist/shared/validation/ttl.d.ts +14 -7
  211. package/dist/shared/validation/ttl.js +29 -11
  212. package/dist/store/actions/get.d.ts +11 -3
  213. package/dist/store/actions/get.js +52 -14
  214. package/dist/store/actions/list-namespaces.d.ts +0 -1
  215. package/dist/store/actions/list-namespaces.js +10 -6
  216. package/dist/store/actions/put.d.ts +0 -1
  217. package/dist/store/actions/put.js +27 -28
  218. package/dist/store/actions/reconcile-vector-index.d.ts +3 -2
  219. package/dist/store/actions/reconcile-vector-index.js +2 -3
  220. package/dist/store/actions/search.d.ts +1 -2
  221. package/dist/store/actions/search.js +11 -38
  222. package/dist/store/internal/backend-search.d.ts +1 -2
  223. package/dist/store/internal/backend-search.js +14 -7
  224. package/dist/store/internal/batch-plan.d.ts +11 -0
  225. package/dist/store/internal/batch-plan.js +52 -0
  226. package/dist/store/internal/candidates.d.ts +23 -0
  227. package/dist/store/internal/candidates.js +94 -0
  228. package/dist/store/internal/filter.d.ts +0 -1
  229. package/dist/store/internal/filter.js +25 -6
  230. package/dist/store/internal/index-reconcile.d.ts +5 -6
  231. package/dist/store/internal/index-reconcile.js +32 -13
  232. package/dist/store/internal/index-sync.d.ts +0 -1
  233. package/dist/store/internal/index-sync.js +0 -1
  234. package/dist/store/internal/item-mapper.d.ts +6 -3
  235. package/dist/store/internal/item-mapper.js +16 -6
  236. package/dist/store/internal/keys.d.ts +0 -1
  237. package/dist/store/internal/keys.js +0 -1
  238. package/dist/store/internal/namespace-match.d.ts +0 -1
  239. package/dist/store/internal/namespace-match.js +0 -1
  240. package/dist/store/internal/option-validation.d.ts +13 -0
  241. package/dist/store/internal/option-validation.js +77 -0
  242. package/dist/store/internal/overwrite-swap.d.ts +32 -0
  243. package/dist/store/internal/overwrite-swap.js +68 -0
  244. package/dist/store/internal/persist.d.ts +24 -7
  245. package/dist/store/internal/persist.js +49 -19
  246. package/dist/store/internal/query.d.ts +6 -1
  247. package/dist/store/internal/query.js +17 -1
  248. package/dist/store/internal/ranker.d.ts +7 -2
  249. package/dist/store/internal/ranker.js +10 -2
  250. package/dist/store/internal/read-existing.d.ts +23 -0
  251. package/dist/store/internal/read-existing.js +41 -0
  252. package/dist/store/internal/score-direction.d.ts +31 -0
  253. package/dist/store/internal/score-direction.js +38 -0
  254. package/dist/store/internal/search-filter.d.ts +0 -1
  255. package/dist/store/internal/search-filter.js +0 -1
  256. package/dist/store/internal/semantic-search.d.ts +26 -5
  257. package/dist/store/internal/semantic-search.js +59 -19
  258. package/dist/store/internal/setup.d.ts +6 -12
  259. package/dist/store/internal/setup.js +12 -24
  260. package/dist/store/internal/text-path.d.ts +17 -0
  261. package/dist/store/internal/text-path.js +147 -0
  262. package/dist/store/internal/validation.d.ts +8 -3
  263. package/dist/store/internal/validation.js +21 -5
  264. package/dist/store/internal/write-verify.d.ts +27 -9
  265. package/dist/store/internal/write-verify.js +35 -19
  266. package/dist/store/store.d.ts +37 -9
  267. package/dist/store/store.js +52 -17
  268. package/dist/store/types.d.ts +22 -2
  269. package/dist/store/types.js +0 -1
  270. package/dist/store/vector-backend.d.ts +6 -7
  271. package/dist/store/vector-backend.js +0 -1
  272. package/package.json +21 -15
  273. package/dist/checkpointer/actions/delete-thread.d.ts.map +0 -1
  274. package/dist/checkpointer/actions/delete-thread.js.map +0 -1
  275. package/dist/checkpointer/actions/get-tuple.d.ts.map +0 -1
  276. package/dist/checkpointer/actions/get-tuple.js.map +0 -1
  277. package/dist/checkpointer/actions/list.d.ts.map +0 -1
  278. package/dist/checkpointer/actions/list.js.map +0 -1
  279. package/dist/checkpointer/actions/put-writes.d.ts.map +0 -1
  280. package/dist/checkpointer/actions/put-writes.js.map +0 -1
  281. package/dist/checkpointer/actions/put.d.ts.map +0 -1
  282. package/dist/checkpointer/actions/put.js.map +0 -1
  283. package/dist/checkpointer/internal/assemble.d.ts.map +0 -1
  284. package/dist/checkpointer/internal/assemble.js.map +0 -1
  285. package/dist/checkpointer/internal/configurable.d.ts.map +0 -1
  286. package/dist/checkpointer/internal/configurable.js.map +0 -1
  287. package/dist/checkpointer/internal/fetch.d.ts.map +0 -1
  288. package/dist/checkpointer/internal/fetch.js.map +0 -1
  289. package/dist/checkpointer/internal/filter-match.d.ts.map +0 -1
  290. package/dist/checkpointer/internal/filter-match.js.map +0 -1
  291. package/dist/checkpointer/internal/item-reader.d.ts.map +0 -1
  292. package/dist/checkpointer/internal/item-reader.js.map +0 -1
  293. package/dist/checkpointer/internal/item-writer.d.ts.map +0 -1
  294. package/dist/checkpointer/internal/item-writer.js.map +0 -1
  295. package/dist/checkpointer/internal/keys.d.ts.map +0 -1
  296. package/dist/checkpointer/internal/keys.js.map +0 -1
  297. package/dist/checkpointer/internal/query.d.ts.map +0 -1
  298. package/dist/checkpointer/internal/query.js.map +0 -1
  299. package/dist/checkpointer/internal/setup.d.ts.map +0 -1
  300. package/dist/checkpointer/internal/setup.js.map +0 -1
  301. package/dist/checkpointer/internal/special-write-cleanup.d.ts.map +0 -1
  302. package/dist/checkpointer/internal/special-write-cleanup.js.map +0 -1
  303. package/dist/checkpointer/internal/validation.d.ts.map +0 -1
  304. package/dist/checkpointer/internal/validation.js.map +0 -1
  305. package/dist/checkpointer/internal/write-guard.d.ts.map +0 -1
  306. package/dist/checkpointer/internal/write-guard.js.map +0 -1
  307. package/dist/checkpointer/internal/write-index.d.ts.map +0 -1
  308. package/dist/checkpointer/internal/write-index.js.map +0 -1
  309. package/dist/checkpointer/saver.d.ts.map +0 -1
  310. package/dist/checkpointer/saver.js.map +0 -1
  311. package/dist/checkpointer/types.d.ts.map +0 -1
  312. package/dist/checkpointer/types.js.map +0 -1
  313. package/dist/factory/factory.d.ts.map +0 -1
  314. package/dist/factory/factory.js.map +0 -1
  315. package/dist/history/actions/add-messages.d.ts.map +0 -1
  316. package/dist/history/actions/add-messages.js.map +0 -1
  317. package/dist/history/actions/clear.d.ts.map +0 -1
  318. package/dist/history/actions/clear.js.map +0 -1
  319. package/dist/history/actions/get-messages.d.ts.map +0 -1
  320. package/dist/history/actions/get-messages.js.map +0 -1
  321. package/dist/history/actions/list-sessions.d.ts.map +0 -1
  322. package/dist/history/actions/list-sessions.js.map +0 -1
  323. package/dist/history/actions/reconcile-count.d.ts.map +0 -1
  324. package/dist/history/actions/reconcile-count.js.map +0 -1
  325. package/dist/history/chat-message-history.d.ts.map +0 -1
  326. package/dist/history/chat-message-history.js.map +0 -1
  327. package/dist/history/internal/append-saga.d.ts.map +0 -1
  328. package/dist/history/internal/append-saga.js.map +0 -1
  329. package/dist/history/internal/compensation.d.ts.map +0 -1
  330. package/dist/history/internal/compensation.js.map +0 -1
  331. package/dist/history/internal/item-mapper.d.ts.map +0 -1
  332. package/dist/history/internal/item-mapper.js.map +0 -1
  333. package/dist/history/internal/keys.d.ts.map +0 -1
  334. package/dist/history/internal/keys.js.map +0 -1
  335. package/dist/history/internal/message-chunker.d.ts.map +0 -1
  336. package/dist/history/internal/message-chunker.js.map +0 -1
  337. package/dist/history/internal/message-transaction.d.ts.map +0 -1
  338. package/dist/history/internal/message-transaction.js.map +0 -1
  339. package/dist/history/internal/query.d.ts.map +0 -1
  340. package/dist/history/internal/query.js.map +0 -1
  341. package/dist/history/internal/session-count.d.ts.map +0 -1
  342. package/dist/history/internal/session-count.js.map +0 -1
  343. package/dist/history/internal/session-title.d.ts.map +0 -1
  344. package/dist/history/internal/session-title.js.map +0 -1
  345. package/dist/history/internal/session-update.d.ts.map +0 -1
  346. package/dist/history/internal/session-update.js.map +0 -1
  347. package/dist/history/internal/setup.d.ts.map +0 -1
  348. package/dist/history/internal/setup.js.map +0 -1
  349. package/dist/history/internal/title-generator.d.ts.map +0 -1
  350. package/dist/history/internal/title-generator.js.map +0 -1
  351. package/dist/history/internal/ttl-anchor.d.ts.map +0 -1
  352. package/dist/history/internal/ttl-anchor.js.map +0 -1
  353. package/dist/history/internal/validation.d.ts.map +0 -1
  354. package/dist/history/internal/validation.js.map +0 -1
  355. package/dist/history/session-adapter.d.ts.map +0 -1
  356. package/dist/history/session-adapter.js.map +0 -1
  357. package/dist/history/types.d.ts.map +0 -1
  358. package/dist/history/types.js.map +0 -1
  359. package/dist/index.d.ts.map +0 -1
  360. package/dist/index.js.map +0 -1
  361. package/dist/shared/clock.d.ts.map +0 -1
  362. package/dist/shared/clock.js.map +0 -1
  363. package/dist/shared/codec/codec.d.ts.map +0 -1
  364. package/dist/shared/codec/codec.js.map +0 -1
  365. package/dist/shared/codec/compression.d.ts.map +0 -1
  366. package/dist/shared/codec/compression.js.map +0 -1
  367. package/dist/shared/codec/descriptor-keys.d.ts.map +0 -1
  368. package/dist/shared/codec/descriptor-keys.js.map +0 -1
  369. package/dist/shared/codec/json-serde.d.ts.map +0 -1
  370. package/dist/shared/codec/json-serde.js.map +0 -1
  371. package/dist/shared/codec/s3/client.d.ts.map +0 -1
  372. package/dist/shared/codec/s3/client.js.map +0 -1
  373. package/dist/shared/codec/s3/config.d.ts.map +0 -1
  374. package/dist/shared/codec/s3/config.js.map +0 -1
  375. package/dist/shared/codec/s3/delete.d.ts.map +0 -1
  376. package/dist/shared/codec/s3/delete.js.map +0 -1
  377. package/dist/shared/codec/s3/lifecycle.d.ts.map +0 -1
  378. package/dist/shared/codec/s3/lifecycle.js.map +0 -1
  379. package/dist/shared/codec/s3/offloader.d.ts.map +0 -1
  380. package/dist/shared/codec/s3/offloader.js.map +0 -1
  381. package/dist/shared/codec/s3/orphans.d.ts.map +0 -1
  382. package/dist/shared/codec/s3/orphans.js.map +0 -1
  383. package/dist/shared/codec/s3/read-write.d.ts.map +0 -1
  384. package/dist/shared/codec/s3/read-write.js.map +0 -1
  385. package/dist/shared/codec/s3/retry.d.ts.map +0 -1
  386. package/dist/shared/codec/s3/retry.js.map +0 -1
  387. package/dist/shared/constants.d.ts.map +0 -1
  388. package/dist/shared/constants.js.map +0 -1
  389. package/dist/shared/dynamodb/backoff.d.ts.map +0 -1
  390. package/dist/shared/dynamodb/backoff.js.map +0 -1
  391. package/dist/shared/dynamodb/batch-write.d.ts.map +0 -1
  392. package/dist/shared/dynamodb/batch-write.js.map +0 -1
  393. package/dist/shared/dynamodb/cancellation.d.ts.map +0 -1
  394. package/dist/shared/dynamodb/cancellation.js.map +0 -1
  395. package/dist/shared/dynamodb/client.d.ts.map +0 -1
  396. package/dist/shared/dynamodb/client.js.map +0 -1
  397. package/dist/shared/dynamodb/drain-unprocessed.d.ts.map +0 -1
  398. package/dist/shared/dynamodb/drain-unprocessed.js.map +0 -1
  399. package/dist/shared/dynamodb/paginate-core.d.ts.map +0 -1
  400. package/dist/shared/dynamodb/paginate-core.js.map +0 -1
  401. package/dist/shared/dynamodb/paginate.d.ts.map +0 -1
  402. package/dist/shared/dynamodb/paginate.js.map +0 -1
  403. package/dist/shared/dynamodb/partition-delete.d.ts.map +0 -1
  404. package/dist/shared/dynamodb/partition-delete.js.map +0 -1
  405. package/dist/shared/dynamodb/retry-classifier.d.ts.map +0 -1
  406. package/dist/shared/dynamodb/retry-classifier.js.map +0 -1
  407. package/dist/shared/dynamodb/retry.d.ts.map +0 -1
  408. package/dist/shared/dynamodb/retry.js.map +0 -1
  409. package/dist/shared/dynamodb/scan.d.ts.map +0 -1
  410. package/dist/shared/dynamodb/scan.js.map +0 -1
  411. package/dist/shared/dynamodb/types.d.ts.map +0 -1
  412. package/dist/shared/dynamodb/types.js.map +0 -1
  413. package/dist/shared/errors/base-error.d.ts.map +0 -1
  414. package/dist/shared/errors/base-error.js.map +0 -1
  415. package/dist/shared/errors/error-code.d.ts.map +0 -1
  416. package/dist/shared/errors/error-code.js.map +0 -1
  417. package/dist/shared/errors/errors.d.ts.map +0 -1
  418. package/dist/shared/errors/errors.js.map +0 -1
  419. package/dist/shared/errors/wrap-error.d.ts.map +0 -1
  420. package/dist/shared/errors/wrap-error.js.map +0 -1
  421. package/dist/shared/logging/logger.d.ts.map +0 -1
  422. package/dist/shared/logging/logger.js.map +0 -1
  423. package/dist/shared/logging/redaction-walk.d.ts.map +0 -1
  424. package/dist/shared/logging/redaction-walk.js.map +0 -1
  425. package/dist/shared/logging/redaction.d.ts.map +0 -1
  426. package/dist/shared/logging/redaction.js.map +0 -1
  427. package/dist/shared/logging/secret-patterns.d.ts.map +0 -1
  428. package/dist/shared/logging/secret-patterns.js.map +0 -1
  429. package/dist/shared/options.d.ts.map +0 -1
  430. package/dist/shared/options.js.map +0 -1
  431. package/dist/shared/ulid.d.ts.map +0 -1
  432. package/dist/shared/ulid.js.map +0 -1
  433. package/dist/shared/validation/primitives.d.ts.map +0 -1
  434. package/dist/shared/validation/primitives.js.map +0 -1
  435. package/dist/shared/validation/ttl.d.ts.map +0 -1
  436. package/dist/shared/validation/ttl.js.map +0 -1
  437. package/dist/store/actions/get.d.ts.map +0 -1
  438. package/dist/store/actions/get.js.map +0 -1
  439. package/dist/store/actions/list-namespaces.d.ts.map +0 -1
  440. package/dist/store/actions/list-namespaces.js.map +0 -1
  441. package/dist/store/actions/put.d.ts.map +0 -1
  442. package/dist/store/actions/put.js.map +0 -1
  443. package/dist/store/actions/reconcile-vector-index.d.ts.map +0 -1
  444. package/dist/store/actions/reconcile-vector-index.js.map +0 -1
  445. package/dist/store/actions/search.d.ts.map +0 -1
  446. package/dist/store/actions/search.js.map +0 -1
  447. package/dist/store/internal/backend-search.d.ts.map +0 -1
  448. package/dist/store/internal/backend-search.js.map +0 -1
  449. package/dist/store/internal/filter.d.ts.map +0 -1
  450. package/dist/store/internal/filter.js.map +0 -1
  451. package/dist/store/internal/index-reconcile.d.ts.map +0 -1
  452. package/dist/store/internal/index-reconcile.js.map +0 -1
  453. package/dist/store/internal/index-sync.d.ts.map +0 -1
  454. package/dist/store/internal/index-sync.js.map +0 -1
  455. package/dist/store/internal/item-mapper.d.ts.map +0 -1
  456. package/dist/store/internal/item-mapper.js.map +0 -1
  457. package/dist/store/internal/keys.d.ts.map +0 -1
  458. package/dist/store/internal/keys.js.map +0 -1
  459. package/dist/store/internal/namespace-match.d.ts.map +0 -1
  460. package/dist/store/internal/namespace-match.js.map +0 -1
  461. package/dist/store/internal/persist.d.ts.map +0 -1
  462. package/dist/store/internal/persist.js.map +0 -1
  463. package/dist/store/internal/query.d.ts.map +0 -1
  464. package/dist/store/internal/query.js.map +0 -1
  465. package/dist/store/internal/ranker.d.ts.map +0 -1
  466. package/dist/store/internal/ranker.js.map +0 -1
  467. package/dist/store/internal/search-filter.d.ts.map +0 -1
  468. package/dist/store/internal/search-filter.js.map +0 -1
  469. package/dist/store/internal/semantic-search.d.ts.map +0 -1
  470. package/dist/store/internal/semantic-search.js.map +0 -1
  471. package/dist/store/internal/setup.d.ts.map +0 -1
  472. package/dist/store/internal/setup.js.map +0 -1
  473. package/dist/store/internal/validation.d.ts.map +0 -1
  474. package/dist/store/internal/validation.js.map +0 -1
  475. package/dist/store/internal/write-verify.d.ts.map +0 -1
  476. package/dist/store/internal/write-verify.js.map +0 -1
  477. package/dist/store/store.d.ts.map +0 -1
  478. package/dist/store/store.js.map +0 -1
  479. package/dist/store/types.d.ts.map +0 -1
  480. package/dist/store/types.js.map +0 -1
  481. package/dist/store/vector-backend.d.ts.map +0 -1
  482. package/dist/store/vector-backend.js.map +0 -1
@@ -33,7 +33,7 @@ async function rollbackCommitted(context, sessionId, committed, now, title) {
33
33
  return;
34
34
  }
35
35
  try {
36
- await (0, batch_write_1.batchWriteAll)(context.client, context.tableName, keys.map((Key) => ({ DeleteRequest: { Key } })));
36
+ await (0, batch_write_1.batchWriteAll)(context.client, context.tableName, keys.map((Key) => ({ DeleteRequest: { Key } })), { retry: context.retry });
37
37
  }
38
38
  catch (error) {
39
39
  /**
@@ -43,7 +43,7 @@ async function rollbackCommitted(context, sessionId, committed, now, title) {
43
43
  * enforces 100% branch coverage with no exceptions.
44
44
  */
45
45
  const deleted = error.succeededCount;
46
- await (0, session_count_1.revertSessionCount)(context, sessionId, deleted);
46
+ await (0, session_count_1.revertSessionCount)(context, sessionId, deleted, now);
47
47
  throw error;
48
48
  }
49
49
  await (0, session_count_1.revertSessionCreation)(context, sessionId, total, now, title);
@@ -56,16 +56,25 @@ async function rollbackCommitted(context, sessionId, committed, now, title) {
56
56
  * objects are deliberately left in place (their rows may survive) and it
57
57
  * raises {@link CompensationFailedError} carrying both the trigger and the
58
58
  * rollback error; otherwise it rethrows the trigger.
59
+ *
60
+ * `uncertain` marks the failed chunk (`chunks[committed.length]`) as one whose
61
+ * outcome could not be verified: its rows may be live, so its objects are
62
+ * leaked rather than deleted, while the never-attempted chunks after it are
63
+ * still cleaned.
59
64
  */
60
- async function compensate(context, sessionId, chunks, committed, trigger, now, title) {
65
+ async function compensate(context, sessionId, chunks, committed, trigger, now, title, uncertain) {
61
66
  if (committed.length > 0) {
62
67
  context.logger.warn('history.addMessages compensating committed chunks after a chunk failed', {
63
68
  sessionId,
64
69
  committedChunks: committed.length,
65
70
  });
66
71
  }
67
- /** The failed/never-attempted suffix never had a DynamoDB row, so it's safe to clean now. */
68
- await cleanBatchS3(context, chunks.slice(committed.length));
72
+ /**
73
+ * The never-attempted suffix never had a DynamoDB row, so it is safe to
74
+ * clean now; an uncertain failed chunk is skipped because its rows may live.
75
+ */
76
+ const firstDead = committed.length + (uncertain ? 1 : 0);
77
+ await cleanBatchS3(context, chunks.slice(firstDead));
69
78
  try {
70
79
  await rollbackCommitted(context, sessionId, committed, now, title);
71
80
  }
@@ -81,4 +90,3 @@ async function compensate(context, sessionId, chunks, committed, trigger, now, t
81
90
  await cleanBatchS3(context, chunks.slice(0, committed.length));
82
91
  throw trigger;
83
92
  }
84
- //# sourceMappingURL=compensation.js.map
@@ -7,6 +7,3 @@ import type { HistoryContext } from './setup';
7
7
  * whole-conversation expiry shared by every message in the session.
8
8
  */
9
9
  export declare function buildMessageItem(context: HistoryContext, sessionId: string, ulid: string, message: StoredMessage, ttlTimestamp?: number): Promise<ChatMessageItem>;
10
- /** Decode a single message item back into its stored message. */
11
- export declare function decodeMessageItem(context: HistoryContext, item: ChatMessageItem): Promise<StoredMessage>;
12
- //# sourceMappingURL=item-mapper.d.ts.map
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildMessageItem = buildMessageItem;
4
- exports.decodeMessageItem = decodeMessageItem;
5
- const codec_1 = require("../../shared/codec/codec");
4
+ const encode_1 = require("../../shared/codec/encode");
6
5
  const keys_1 = require("./keys");
7
6
  function codecDeps(context) {
8
7
  return { serde: context.serde, compression: context.compression, offloader: context.offloader };
@@ -13,7 +12,7 @@ function codecDeps(context) {
13
12
  * whole-conversation expiry shared by every message in the session.
14
13
  */
15
14
  async function buildMessageItem(context, sessionId, ulid, message, ttlTimestamp) {
16
- const descriptor = await (0, codec_1.encodePayload)(message, codecDeps(context), {
15
+ const descriptor = await (0, encode_1.encodePayload)(message, codecDeps(context), {
17
16
  keyParts: [sessionId, ulid],
18
17
  });
19
18
  const item = {
@@ -26,8 +25,3 @@ async function buildMessageItem(context, sessionId, ulid, message, ttlTimestamp)
26
25
  item.ttl = ttlTimestamp;
27
26
  return item;
28
27
  }
29
- /** Decode a single message item back into its stored message. */
30
- async function decodeMessageItem(context, item) {
31
- return (0, codec_1.decodePayload)(item.message, codecDeps(context));
32
- }
33
- //# sourceMappingURL=item-mapper.js.map
@@ -14,4 +14,3 @@ export declare function messageSortKey(ulid: string): string;
14
14
  export declare function isHistorySortKey(sortKey: string): boolean;
15
15
  /** `begins_with` prefix selecting every message item in a session. */
16
16
  export declare function messageSortKeyPrefix(): string;
17
- //# sourceMappingURL=keys.d.ts.map
@@ -46,4 +46,3 @@ function isHistorySortKey(sortKey) {
46
46
  function messageSortKeyPrefix() {
47
47
  return MESSAGE_PREFIX;
48
48
  }
49
- //# sourceMappingURL=keys.js.map
@@ -11,4 +11,3 @@ export declare function estimateItemBytes(item: ChatMessageItem): number;
11
11
  * placed alone rather than dropped.
12
12
  */
13
13
  export declare function chunkBySize(items: ChatMessageItem[], maxItems: number, maxBytes: number): ChatMessageItem[][];
14
- //# sourceMappingURL=message-chunker.d.ts.map
@@ -65,4 +65,3 @@ function chunkBySize(items, maxItems, maxBytes) {
65
65
  chunks.push(current);
66
66
  return chunks;
67
67
  }
68
- //# sourceMappingURL=message-chunker.js.map
@@ -23,4 +23,3 @@ export interface ChunkRetryOptions {
23
23
  * budget inside `withDynamoDBRetry` to handle, or to the caller otherwise.
24
24
  */
25
25
  export declare function writeMessageChunk(context: HistoryContext, items: ChatMessageItem[], fields: SessionUpdateFields, retry?: ChunkRetryOptions): Promise<void>;
26
- //# sourceMappingURL=message-transaction.d.ts.map
@@ -24,7 +24,9 @@ function buildInput(context, items, fields) {
24
24
  async function attempt(context, items, fields, retry) {
25
25
  const input = buildInput(context, items, fields);
26
26
  await (0, retry_1.withDynamoDBRetry)(() => context.client.transactWrite(input), {
27
- maxAttempts: constants_1.MESSAGE_APPEND_RETRY_MAX_ATTEMPTS,
27
+ ...context.retry,
28
+ /** The contention floor: a caller policy may raise the budget, never lower it. */
29
+ maxAttempts: Math.max(constants_1.MESSAGE_APPEND_RETRY_MAX_ATTEMPTS, context.retry?.maxAttempts ?? 0),
28
30
  rng: retry.rng,
29
31
  signal: retry.signal,
30
32
  });
@@ -57,4 +59,3 @@ async function writeMessageChunk(context, items, fields, retry = {}) {
57
59
  throw error;
58
60
  }
59
61
  }
60
- //# sourceMappingURL=message-transaction.js.map
@@ -0,0 +1,17 @@
1
+ import type { CancelOptions } from '../../shared/options';
2
+ import type { ChatMessageItem, MessageWindow } from '../types';
3
+ import type { HistoryContext } from './setup';
4
+ /**
5
+ * Read the live message items a window selects, in chronological order.
6
+ *
7
+ * Without `limit` the query walks the session oldest-first. With it the query
8
+ * walks newest-first with a matching page cap and stops as soon as `limit`
9
+ * live items are in hand — rows past their TTL are skipped here, so a page can
10
+ * come back short and the walk simply continues — and the tail is then
11
+ * reversed back into chronological order. `before` becomes an exclusive upper
12
+ * sort-key bound: the message prefix plus the ULID time characters of that
13
+ * instant, which every message id from that millisecond onwards sorts after.
14
+ * Reads are strongly consistent so the turn just appended is visible to the
15
+ * very next read.
16
+ */
17
+ export declare function readWindow(context: HistoryContext, sessionId: string, options: MessageWindow & CancelOptions): Promise<ChatMessageItem[]>;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readWindow = readWindow;
4
+ const clock_1 = require("../../shared/clock");
5
+ const expiry_1 = require("../../shared/dynamodb/expiry");
6
+ const paginate_1 = require("../../shared/dynamodb/paginate");
7
+ const retry_policy_1 = require("../../shared/dynamodb/retry-policy");
8
+ const ulid_1 = require("../../shared/ulid");
9
+ const keys_1 = require("./keys");
10
+ const query_1 = require("./query");
11
+ /**
12
+ * Read the live message items a window selects, in chronological order.
13
+ *
14
+ * Without `limit` the query walks the session oldest-first. With it the query
15
+ * walks newest-first with a matching page cap and stops as soon as `limit`
16
+ * live items are in hand — rows past their TTL are skipped here, so a page can
17
+ * come back short and the walk simply continues — and the tail is then
18
+ * reversed back into chronological order. `before` becomes an exclusive upper
19
+ * sort-key bound: the message prefix plus the ULID time characters of that
20
+ * instant, which every message id from that millisecond onwards sorts after.
21
+ * Reads are strongly consistent so the turn just appended is visible to the
22
+ * very next read.
23
+ */
24
+ async function readWindow(context, sessionId, options) {
25
+ const now = (0, clock_1.nowSeconds)();
26
+ const limit = options.limit ?? Number.POSITIVE_INFINITY;
27
+ const items = [];
28
+ for await (const raw of (0, paginate_1.paginateQuery)({
29
+ retry: (0, retry_policy_1.retryFor)(context, options.signal),
30
+ signal: options.signal,
31
+ client: context.client,
32
+ params: (0, query_1.messageQuery)(context.tableName, sessionId, {
33
+ consistent: true,
34
+ descending: options.limit !== undefined,
35
+ limit: options.limit,
36
+ beforeSortKey: options.before && (0, keys_1.messageSortKey)((0, ulid_1.ulidTimePrefix)(options.before.getTime())),
37
+ }),
38
+ maxItems: Number.POSITIVE_INFINITY,
39
+ maxIterations: Number.POSITIVE_INFINITY,
40
+ })) {
41
+ const item = raw;
42
+ if ((0, expiry_1.isExpiredRow)(item, now))
43
+ continue;
44
+ items.push(item);
45
+ if (items.length >= limit)
46
+ break;
47
+ }
48
+ return options.limit === undefined ? items : items.reverse();
49
+ }
@@ -5,6 +5,19 @@ export interface SessionItemsQueryOptions {
5
5
  }
6
6
  /** Query input selecting every item in a session's partition (messages + metadata). */
7
7
  export declare function sessionItemsQuery(tableName: string, sessionId: string, options?: SessionItemsQueryOptions): QueryCommandInput;
8
- /** Query input selecting a session's message items in chronological order. */
9
- export declare function messageQuery(tableName: string, sessionId: string): QueryCommandInput;
10
- //# sourceMappingURL=query.d.ts.map
8
+ /** Options for {@link messageQuery}. */
9
+ export interface MessageQueryOptions extends SessionItemsQueryOptions {
10
+ /** Walk the messages newest-first; the caller restores chronological order. */
11
+ descending?: boolean;
12
+ /** Cap the rows DynamoDB evaluates per page. */
13
+ limit?: number;
14
+ /**
15
+ * Exclusive upper sort-key bound. Expressed as `BETWEEN prefix AND bound`
16
+ * because a key condition allows one sort-key operator: the bound is the
17
+ * message prefix plus the ULID time characters of an instant, so every
18
+ * real message key from that millisecond onwards sorts strictly after it.
19
+ */
20
+ beforeSortKey?: string;
21
+ }
22
+ /** Query input selecting a session's message items, chronological unless `descending`. */
23
+ export declare function messageQuery(tableName: string, sessionId: string, options?: MessageQueryOptions): QueryCommandInput;
@@ -15,9 +15,9 @@ function sessionItemsQuery(tableName, sessionId, options = {}) {
15
15
  params.ConsistentRead = true;
16
16
  return params;
17
17
  }
18
- /** Query input selecting a session's message items in chronological order. */
19
- function messageQuery(tableName, sessionId) {
20
- return {
18
+ /** Query input selecting a session's message items, chronological unless `descending`. */
19
+ function messageQuery(tableName, sessionId, options = {}) {
20
+ const params = {
21
21
  TableName: tableName,
22
22
  KeyConditionExpression: '#pk = :pk AND begins_with(#sk, :skp)',
23
23
  ExpressionAttributeNames: { '#pk': 'PK', '#sk': 'SK' },
@@ -25,7 +25,15 @@ function messageQuery(tableName, sessionId) {
25
25
  ':pk': (0, keys_1.sessionPartition)(sessionId),
26
26
  ':skp': (0, keys_1.messageSortKeyPrefix)(),
27
27
  },
28
- ScanIndexForward: true,
28
+ ScanIndexForward: !options.descending,
29
29
  };
30
+ if (options.beforeSortKey !== undefined) {
31
+ params.KeyConditionExpression = '#pk = :pk AND #sk BETWEEN :skp AND :before';
32
+ params.ExpressionAttributeValues[':before'] = options.beforeSortKey;
33
+ }
34
+ if (options.limit !== undefined)
35
+ params.Limit = options.limit;
36
+ if (options.consistent)
37
+ params.ConsistentRead = true;
38
+ return params;
30
39
  }
31
- //# sourceMappingURL=query.js.map
@@ -7,6 +7,13 @@ import type { HistoryContext } from './setup';
7
7
  * surfaced — this runs only from an already-in-progress rollback, where a
8
8
  * spurious error for a no-op would misrepresent what happened.
9
9
  *
10
+ * The same condition also pins the *incarnation*: `createdAt <= createdBefore`
11
+ * (this call's own append timestamp). A session `clear()`-ed and re-created by
12
+ * another caller between this call's commit and its rollback carries a later
13
+ * `createdAt`; decrementing it would corrupt the new incarnation's count, and
14
+ * its rows were never this call's to revert. That rejection is swallowed too,
15
+ * for the same reason as a vanished row.
16
+ *
10
17
  * Deliberately does not revert a `forceTtlRefresh`-driven ttl SET from an
11
18
  * earlier committed chunk: the healed anchor is never shorter than what
12
19
  * was there before, so leaving it in place after a rollback only means the
@@ -16,7 +23,7 @@ import type { HistoryContext } from './setup';
16
23
  * concurrent legitimate extension to avoid regressing it. See README.md's
17
24
  * "TTL expiry" section.
18
25
  */
19
- export declare function revertSessionCount(context: HistoryContext, sessionId: string, delta: number): Promise<void>;
26
+ export declare function revertSessionCount(context: HistoryContext, sessionId: string, delta: number, createdBefore: string): Promise<void>;
20
27
  /**
21
28
  * Undo a rolled-back append's effect on the session row.
22
29
  *
@@ -38,4 +45,3 @@ export declare function revertSessionCount(context: HistoryContext, sessionId: s
38
45
  * row still carrying rolled-back message content.
39
46
  */
40
47
  export declare function revertSessionCreation(context: HistoryContext, sessionId: string, total: number, createdAt: string, title?: string): Promise<void>;
41
- //# sourceMappingURL=session-count.d.ts.map
@@ -27,6 +27,13 @@ function isCancelledByCondition(error) {
27
27
  * surfaced — this runs only from an already-in-progress rollback, where a
28
28
  * spurious error for a no-op would misrepresent what happened.
29
29
  *
30
+ * The same condition also pins the *incarnation*: `createdAt <= createdBefore`
31
+ * (this call's own append timestamp). A session `clear()`-ed and re-created by
32
+ * another caller between this call's commit and its rollback carries a later
33
+ * `createdAt`; decrementing it would corrupt the new incarnation's count, and
34
+ * its rows were never this call's to revert. That rejection is swallowed too,
35
+ * for the same reason as a vanished row.
36
+ *
30
37
  * Deliberately does not revert a `forceTtlRefresh`-driven ttl SET from an
31
38
  * earlier committed chunk: the healed anchor is never shorter than what
32
39
  * was there before, so leaving it in place after a rollback only means the
@@ -36,20 +43,20 @@ function isCancelledByCondition(error) {
36
43
  * concurrent legitimate extension to avoid regressing it. See README.md's
37
44
  * "TTL expiry" section.
38
45
  */
39
- async function revertSessionCount(context, sessionId, delta) {
46
+ async function revertSessionCount(context, sessionId, delta, createdBefore) {
40
47
  if (delta === 0)
41
48
  return;
42
49
  const update = {
43
50
  TableName: context.tableName,
44
51
  Key: { PK: (0, keys_1.sessionPartition)(sessionId), SK: keys_1.SESSION_SORT_KEY },
45
52
  UpdateExpression: 'ADD #count :neg',
46
- ConditionExpression: 'attribute_exists(PK)',
47
- ExpressionAttributeNames: { '#count': 'messageCount' },
48
- ExpressionAttributeValues: { ':neg': -delta },
53
+ ConditionExpression: 'attribute_exists(PK) AND #c <= :now',
54
+ ExpressionAttributeNames: { '#count': 'messageCount', '#c': 'createdAt' },
55
+ ExpressionAttributeValues: { ':neg': -delta, ':now': createdBefore },
49
56
  };
50
57
  const input = { TransactItems: [{ Update: update }], ClientRequestToken: (0, node_crypto_1.randomUUID)() };
51
58
  try {
52
- await (0, retry_1.withDynamoDBRetry)(() => context.client.transactWrite(input));
59
+ await (0, retry_1.withDynamoDBRetry)(() => context.client.transactWrite(input), context.retry);
53
60
  }
54
61
  catch (error) {
55
62
  if (isCancelledByCondition(error))
@@ -95,15 +102,14 @@ async function revertSessionCreation(context, sessionId, total, createdAt, title
95
102
  ClientRequestToken: (0, node_crypto_1.randomUUID)(),
96
103
  };
97
104
  try {
98
- await (0, retry_1.withDynamoDBRetry)(() => context.client.transactWrite(input));
105
+ await (0, retry_1.withDynamoDBRetry)(() => context.client.transactWrite(input), context.retry);
99
106
  return;
100
107
  }
101
108
  catch (error) {
102
109
  if (!isCancelledByCondition(error))
103
110
  throw error;
104
111
  }
105
- await revertSessionCount(context, sessionId, total);
112
+ await revertSessionCount(context, sessionId, total, createdAt);
106
113
  if (title !== undefined)
107
114
  await (0, session_title_1.removeRolledBackTitle)(context, sessionId, createdAt, title);
108
115
  }
109
- //# sourceMappingURL=session-count.js.map
@@ -17,4 +17,3 @@ import type { HistoryContext } from './setup';
17
17
  * exactly that and is not an error; anything else is.
18
18
  */
19
19
  export declare function removeRolledBackTitle(context: HistoryContext, sessionId: string, createdAt: string, title: string): Promise<void>;
20
- //# sourceMappingURL=session-title.d.ts.map
@@ -33,7 +33,7 @@ async function removeRolledBackTitle(context, sessionId, createdAt, title) {
33
33
  ConditionExpression: '#c = :now AND #title = :title',
34
34
  ExpressionAttributeNames: { '#title': 'title', '#c': 'createdAt' },
35
35
  ExpressionAttributeValues: { ':now': createdAt, ':title': title },
36
- }));
36
+ }), context.retry);
37
37
  }
38
38
  catch (error) {
39
39
  if (isConditionRejected(error))
@@ -41,4 +41,3 @@ async function removeRolledBackTitle(context, sessionId, createdAt, title) {
41
41
  throw error;
42
42
  }
43
43
  }
44
- //# sourceMappingURL=session-title.js.map
@@ -25,4 +25,3 @@ export interface SessionUpdateFields {
25
25
  * message-transaction.ts for how a lost race is retried without forcing.
26
26
  */
27
27
  export declare function buildSessionUpdateItem(tableName: string, fields: SessionUpdateFields): HistoryTransactItem;
28
- //# sourceMappingURL=session-update.d.ts.map
@@ -67,4 +67,3 @@ function buildSessionUpdateItem(tableName, fields) {
67
67
  },
68
68
  };
69
69
  }
70
- //# sourceMappingURL=session-update.js.map
@@ -3,6 +3,7 @@ import type { DynamoDBDocument } from '@aws-sdk/lib-dynamodb';
3
3
  import type { SerializerProtocol } from '@langchain/langgraph-checkpoint';
4
4
  import type { CompressionConfig } from '../../shared/codec/compression';
5
5
  import { S3Offloader } from '../../shared/codec/s3/offloader';
6
+ import type { RetryOptions } from '../../shared/dynamodb/retry';
6
7
  import { type Logger } from '../../shared/logging/logger';
7
8
  import type { TtlOption } from '../../shared/validation/ttl';
8
9
  import type { CorruptMessagePolicy, DynamoDBChatMessageHistoryOptions } from '../types';
@@ -17,6 +18,8 @@ export interface HistoryContext {
17
18
  logger: Logger;
18
19
  ulid: () => string;
19
20
  onCorruptMessage: CorruptMessagePolicy;
21
+ /** Retry budget and backoff for every DynamoDB call, with the retry debug log attached. */
22
+ retry?: RetryOptions;
20
23
  }
21
24
  /** Result of wiring up a chat-history adapter from its options. */
22
25
  export interface HistorySetup {
@@ -26,4 +29,3 @@ export interface HistorySetup {
26
29
  }
27
30
  /** Resolve the client, optional S3 offloader, and serializer into a context. */
28
31
  export declare function setUpHistory(options: DynamoDBChatMessageHistoryOptions): HistorySetup;
29
- //# sourceMappingURL=setup.d.ts.map
@@ -2,15 +2,26 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setUpHistory = setUpHistory;
4
4
  const json_serde_1 = require("../../shared/codec/json-serde");
5
- const config_1 = require("../../shared/codec/s3/config");
5
+ const adapter_config_1 = require("../../shared/codec/s3/adapter-config");
6
6
  const offloader_1 = require("../../shared/codec/s3/offloader");
7
- const constants_1 = require("../../shared/constants");
8
7
  const client_1 = require("../../shared/dynamodb/client");
8
+ const retry_policy_1 = require("../../shared/dynamodb/retry-policy");
9
+ const errors_1 = require("../../shared/errors/errors");
9
10
  const logger_1 = require("../../shared/logging/logger");
10
11
  const ulid_1 = require("../../shared/ulid");
12
+ const options_1 = require("../../shared/validation/options");
13
+ const CORRUPT_MESSAGE_POLICIES = ['skip', 'throw'];
11
14
  /** Resolve the client, optional S3 offloader, and serializer into a context. */
12
15
  function setUpHistory(options) {
16
+ (0, options_1.validateBaseAdapterOptions)(options);
17
+ if (options.onCorruptMessage !== undefined &&
18
+ !CORRUPT_MESSAGE_POLICIES.includes(options.onCorruptMessage)) {
19
+ throw new errors_1.ValidationError(`onCorruptMessage must be one of ${CORRUPT_MESSAGE_POLICIES.join(' | ')}`, 'onCorruptMessage');
20
+ }
21
+ const logger = (0, logger_1.resolveLogger)(options.logger);
13
22
  const resolved = (0, client_1.resolveDynamoDBClient)(options);
23
+ if (!resolved.ownsClient)
24
+ void (0, client_1.warnOnStackedRetries)(resolved.client, logger);
14
25
  return {
15
26
  context: {
16
27
  client: resolved.client,
@@ -18,13 +29,11 @@ function setUpHistory(options) {
18
29
  serde: options.serde ?? json_serde_1.JSON_SERDE,
19
30
  compression: options.compression,
20
31
  offloader: options.s3
21
- ? new offloader_1.S3Offloader({
22
- ...options.s3,
23
- keyPrefix: options.s3.keyPrefix ?? (0, config_1.defaultAdapterKeyPrefix)(constants_1.DEFAULT_S3_KEY_PREFIX, 'history'),
24
- })
32
+ ? new offloader_1.S3Offloader((0, adapter_config_1.offloaderConfigFor)(options.s3, 'history', options.clientConfig))
25
33
  : undefined,
26
34
  ttl: options.ttl,
27
- logger: (0, logger_1.resolveLogger)(options.logger),
35
+ logger,
36
+ retry: (0, retry_policy_1.resolveRetryPolicy)(options.retry, logger),
28
37
  ulid: (0, ulid_1.createUlidFactory)(),
29
38
  onCorruptMessage: options.onCorruptMessage ?? 'skip',
30
39
  },
@@ -32,4 +41,3 @@ function setUpHistory(options) {
32
41
  ownsClient: resolved.ownsClient,
33
42
  };
34
43
  }
35
- //# sourceMappingURL=setup.js.map
@@ -10,4 +10,3 @@ import type { StoredMessage } from '@langchain/core/messages';
10
10
  * rather than appended past it.
11
11
  */
12
12
  export declare function deriveTitle(messages: StoredMessage[]): string | undefined;
13
- //# sourceMappingURL=title-generator.d.ts.map
@@ -2,6 +2,23 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deriveTitle = deriveTitle;
4
4
  const MAX_TITLE_LENGTH = 80;
5
+ function isTextBlock(block) {
6
+ const candidate = block;
7
+ return candidate.type === 'text' && typeof candidate.text === 'string';
8
+ }
9
+ /**
10
+ * The human-readable text of a message's `content`: the string itself, or the
11
+ * first `text` block of a content-block array (a multimodal message carries
12
+ * image and text blocks side by side). Undefined when neither yields text.
13
+ */
14
+ function textOf(content) {
15
+ if (typeof content === 'string')
16
+ return content;
17
+ if (!Array.isArray(content))
18
+ return undefined;
19
+ const block = content.find((entry) => typeof entry === 'object' && entry !== null && isTextBlock(entry));
20
+ return block?.text;
21
+ }
5
22
  /**
6
23
  * Derive a session title from the first human message's text content, at most
7
24
  * {@link MAX_TITLE_LENGTH} characters including the ellipsis. Returns undefined
@@ -14,12 +31,11 @@ const MAX_TITLE_LENGTH = 80;
14
31
  */
15
32
  function deriveTitle(messages) {
16
33
  const firstHuman = messages.find((message) => message.type === 'human');
17
- const content = firstHuman?.data.content;
18
- if (typeof content !== 'string' || content.length === 0)
34
+ const content = firstHuman === undefined ? undefined : textOf(firstHuman.data.content);
35
+ if (content === undefined || content.length === 0)
19
36
  return undefined;
20
37
  const codePoints = [...content];
21
38
  if (codePoints.length <= MAX_TITLE_LENGTH)
22
39
  return content;
23
40
  return `${codePoints.slice(0, MAX_TITLE_LENGTH - 1).join('')}…`;
24
41
  }
25
- //# sourceMappingURL=title-generator.js.map
@@ -21,5 +21,4 @@ export interface TtlAnchorResult {
21
21
  * temporarily overstated relative to what `getMessages` actually returns.
22
22
  * This is expected, not a bug.
23
23
  */
24
- export declare function resolveTtlAnchor(context: HistoryContext, sessionId: string, candidate: number): Promise<TtlAnchorResult>;
25
- //# sourceMappingURL=ttl-anchor.d.ts.map
24
+ export declare function resolveTtlAnchor(context: HistoryContext, sessionId: string, candidate: number, signal?: AbortSignal): Promise<TtlAnchorResult>;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveTtlAnchor = resolveTtlAnchor;
4
+ const clock_1 = require("../../shared/clock");
4
5
  const retry_1 = require("../../shared/dynamodb/retry");
6
+ const retry_policy_1 = require("../../shared/dynamodb/retry-policy");
5
7
  const keys_1 = require("./keys");
6
8
  /**
7
9
  * Resolve the session's creation-anchored TTL: the value already stored on the
@@ -20,19 +22,17 @@ const keys_1 = require("./keys");
20
22
  * temporarily overstated relative to what `getMessages` actually returns.
21
23
  * This is expected, not a bug.
22
24
  */
23
- async function resolveTtlAnchor(context, sessionId, candidate) {
25
+ async function resolveTtlAnchor(context, sessionId, candidate, signal) {
24
26
  const result = await (0, retry_1.withDynamoDBRetry)(() => context.client.get({
25
27
  TableName: context.tableName,
26
28
  Key: { PK: (0, keys_1.sessionPartition)(sessionId), SK: keys_1.SESSION_SORT_KEY },
27
29
  ConsistentRead: true,
28
30
  ProjectionExpression: '#ttl',
29
31
  ExpressionAttributeNames: { '#ttl': 'ttl' },
30
- }));
32
+ }), (0, retry_policy_1.retryFor)(context, signal));
31
33
  const ttl = result.Item?.ttl;
32
- const nowSeconds = Math.floor(Date.now() / 1000);
33
- if (typeof ttl === 'number' && ttl > nowSeconds) {
34
+ if (typeof ttl === 'number' && ttl > (0, clock_1.nowSeconds)()) {
34
35
  return { ttlTimestamp: ttl, refresh: false };
35
36
  }
36
37
  return { ttlTimestamp: candidate, refresh: true };
37
38
  }
38
- //# sourceMappingURL=ttl-anchor.js.map
@@ -1,9 +1,25 @@
1
+ import { type StoredMessage } from '@langchain/core/messages';
2
+ import type { MessageWindow } from '../types';
1
3
  /**
2
- * Validate a session id is a non-empty, separator- and control-char-free
3
- * string. Applied on every entry point, not just the write path: a bad value
4
+ * Validate a session id is a non-blank, separator- and control-char-free string
5
+ * of at most 1024 bytes. Applied on every entry point, not just the write path: a bad value
4
6
  * used to reach DynamoDB and surface as a raw AWS SDK exception on reads,
5
7
  * while the identical value threw this library's typed `ValidationError` on a
6
8
  * write.
7
9
  */
8
10
  export declare function validateSessionId(sessionId: string): void;
9
- //# sourceMappingURL=validation.d.ts.map
11
+ /**
12
+ * Reject a message this adapter could never read back. The check *is* the
13
+ * read side's own rebuild (`mapStoredMessagesToChatMessages`), so write and
14
+ * read agree by construction: a `RemoveMessage`, or a tool, function or
15
+ * generic message missing its required field, fails here with a typed error
16
+ * instead of being persisted and then skipped or thrown by `getMessages`.
17
+ */
18
+ export declare function validateStorableMessages(stored: StoredMessage[]): void;
19
+ /**
20
+ * Validate a `getMessages` window: `limit`, when given, a positive integer;
21
+ * `before`, when given, a valid `Date`. Checked before any DynamoDB call so a
22
+ * bad value fails with a typed error rather than a raw `ValidationException`
23
+ * (or, for an invalid Date, a NaN-derived sort key that matches nothing).
24
+ */
25
+ export declare function validateMessageWindow(window: MessageWindow): void;
@@ -1,16 +1,53 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateSessionId = validateSessionId;
4
+ exports.validateStorableMessages = validateStorableMessages;
5
+ exports.validateMessageWindow = validateMessageWindow;
6
+ const messages_1 = require("@langchain/core/messages");
7
+ const constants_1 = require("../../shared/constants");
8
+ const errors_1 = require("../../shared/errors/errors");
4
9
  const primitives_1 = require("../../shared/validation/primitives");
5
10
  const keys_1 = require("./keys");
6
11
  /**
7
- * Validate a session id is a non-empty, separator- and control-char-free
8
- * string. Applied on every entry point, not just the write path: a bad value
12
+ * Validate a session id is a non-blank, separator- and control-char-free string
13
+ * of at most 1024 bytes. Applied on every entry point, not just the write path: a bad value
9
14
  * used to reach DynamoDB and surface as a raw AWS SDK exception on reads,
10
15
  * while the identical value threw this library's typed `ValidationError` on a
11
16
  * write.
12
17
  */
13
18
  function validateSessionId(sessionId) {
14
- (0, primitives_1.validateIdentifier)(sessionId, keys_1.SORT_KEY_SEPARATOR, 'sessionId');
19
+ (0, primitives_1.validateIdentifier)(sessionId, keys_1.SORT_KEY_SEPARATOR, 'sessionId', constants_1.MAX_PARTITION_ID_BYTES);
20
+ }
21
+ /**
22
+ * Reject a message this adapter could never read back. The check *is* the
23
+ * read side's own rebuild (`mapStoredMessagesToChatMessages`), so write and
24
+ * read agree by construction: a `RemoveMessage`, or a tool, function or
25
+ * generic message missing its required field, fails here with a typed error
26
+ * instead of being persisted and then skipped or thrown by `getMessages`.
27
+ */
28
+ function validateStorableMessages(stored) {
29
+ stored.forEach((message, index) => {
30
+ try {
31
+ (0, messages_1.mapStoredMessagesToChatMessages)([message]);
32
+ }
33
+ catch (error) {
34
+ throw new errors_1.ValidationError(`messages[${index}] of type "${message.type}" cannot be stored: ${error.message}`, 'messages');
35
+ }
36
+ });
37
+ }
38
+ /**
39
+ * Validate a `getMessages` window: `limit`, when given, a positive integer;
40
+ * `before`, when given, a valid `Date`. Checked before any DynamoDB call so a
41
+ * bad value fails with a typed error rather than a raw `ValidationException`
42
+ * (or, for an invalid Date, a NaN-derived sort key that matches nothing).
43
+ */
44
+ function validateMessageWindow(window) {
45
+ if (window.limit !== undefined && (!Number.isInteger(window.limit) || window.limit < 1)) {
46
+ throw new errors_1.ValidationError('limit must be a positive integer', 'limit');
47
+ }
48
+ if (window.before !== undefined) {
49
+ const time = typeof window.before.getTime === 'function' ? window.before.getTime() : Number.NaN;
50
+ if (!Number.isFinite(time))
51
+ throw new errors_1.ValidationError('before must be a valid Date', 'before');
52
+ }
15
53
  }
16
- //# sourceMappingURL=validation.js.map