@farukada/aws-langgraph-dynamodb-ts 0.9.0 → 1.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/README.md +1720 -154
  2. package/dist/backfill/backfill.d.ts +168 -0
  3. package/dist/backfill/backfill.js +393 -0
  4. package/dist/checkpointer/actions/delete-thread.d.ts +47 -6
  5. package/dist/checkpointer/actions/delete-thread.js +58 -21
  6. package/dist/checkpointer/actions/get-tuple.d.ts +29 -4
  7. package/dist/checkpointer/actions/get-tuple.js +44 -10
  8. package/dist/checkpointer/actions/list.d.ts +46 -4
  9. package/dist/checkpointer/actions/list.js +121 -66
  10. package/dist/checkpointer/actions/put-writes.d.ts +41 -9
  11. package/dist/checkpointer/actions/put-writes.js +62 -77
  12. package/dist/checkpointer/actions/put.d.ts +83 -4
  13. package/dist/checkpointer/actions/put.js +177 -25
  14. package/dist/checkpointer/internal/delta-history.d.ts +112 -0
  15. package/dist/checkpointer/internal/delta-history.js +252 -0
  16. package/dist/checkpointer/internal/listing.d.ts +149 -0
  17. package/dist/checkpointer/internal/listing.js +245 -0
  18. package/dist/checkpointer/internal/parse.d.ts +262 -0
  19. package/dist/checkpointer/internal/parse.js +372 -0
  20. package/dist/checkpointer/internal/pending-writes.d.ts +275 -0
  21. package/dist/checkpointer/internal/pending-writes.js +588 -0
  22. package/dist/checkpointer/internal/read.d.ts +130 -0
  23. package/dist/checkpointer/internal/read.js +264 -0
  24. package/dist/checkpointer/internal/rows.d.ts +571 -0
  25. package/dist/checkpointer/internal/rows.js +834 -0
  26. package/dist/checkpointer/internal/setup.d.ts +42 -19
  27. package/dist/checkpointer/internal/setup.js +65 -29
  28. package/dist/checkpointer/saver.d.ts +256 -16
  29. package/dist/checkpointer/saver.js +275 -29
  30. package/dist/checkpointer/types.d.ts +39 -39
  31. package/dist/checkpointer/types.js +10 -1
  32. package/dist/factory/factory.d.ts +134 -28
  33. package/dist/factory/factory.js +240 -21
  34. package/dist/factory/types.d.ts +76 -0
  35. package/dist/factory/types.js +10 -0
  36. package/dist/history/actions/add-messages.d.ts +31 -4
  37. package/dist/history/actions/add-messages.js +38 -58
  38. package/dist/history/actions/clear.d.ts +49 -6
  39. package/dist/history/actions/clear.js +66 -14
  40. package/dist/history/actions/get-messages.d.ts +54 -6
  41. package/dist/history/actions/get-messages.js +126 -43
  42. package/dist/history/actions/list-sessions.d.ts +52 -10
  43. package/dist/history/actions/list-sessions.js +139 -40
  44. package/dist/history/actions/reconcile-count.d.ts +42 -10
  45. package/dist/history/actions/reconcile-count.js +45 -45
  46. package/dist/history/chat-message-history.d.ts +220 -33
  47. package/dist/history/chat-message-history.js +240 -43
  48. package/dist/history/internal/append.d.ts +212 -0
  49. package/dist/history/internal/append.js +500 -0
  50. package/dist/history/internal/message-read.d.ts +84 -0
  51. package/dist/history/internal/message-read.js +204 -0
  52. package/dist/history/internal/parse.d.ts +153 -0
  53. package/dist/history/internal/parse.js +252 -0
  54. package/dist/history/internal/rows.d.ts +195 -0
  55. package/dist/history/internal/rows.js +250 -0
  56. package/dist/history/internal/session.d.ts +331 -0
  57. package/dist/history/internal/session.js +628 -0
  58. package/dist/history/internal/setup.d.ts +52 -17
  59. package/dist/history/internal/setup.js +92 -21
  60. package/dist/history/session-adapter.d.ts +102 -7
  61. package/dist/history/session-adapter.js +103 -9
  62. package/dist/history/types.d.ts +80 -29
  63. package/dist/history/types.js +10 -1
  64. package/dist/index.d.ts +42 -11
  65. package/dist/index.js +33 -12
  66. package/dist/shared/adapter.d.ts +135 -0
  67. package/dist/shared/adapter.js +143 -0
  68. package/dist/shared/clock.d.ts +51 -2
  69. package/dist/shared/clock.js +57 -2
  70. package/dist/shared/codec/codec.d.ts +288 -13
  71. package/dist/shared/codec/codec.js +416 -19
  72. package/dist/shared/codec/compression.d.ts +43 -7
  73. package/dist/shared/codec/compression.js +53 -13
  74. package/dist/shared/codec/json-serde.d.ts +76 -4
  75. package/dist/shared/codec/json-serde.js +181 -8
  76. package/dist/shared/codec/s3/client-types.d.ts +53 -0
  77. package/dist/shared/codec/s3/client-types.js +26 -0
  78. package/dist/shared/codec/s3/client.d.ts +43 -10
  79. package/dist/shared/codec/s3/client.js +82 -9
  80. package/dist/shared/codec/s3/config.d.ts +242 -11
  81. package/dist/shared/codec/s3/config.js +293 -11
  82. package/dist/shared/codec/s3/lifecycle.d.ts +164 -6
  83. package/dist/shared/codec/s3/lifecycle.js +335 -27
  84. package/dist/shared/codec/s3/offloader.d.ts +393 -18
  85. package/dist/shared/codec/s3/offloader.js +595 -37
  86. package/dist/shared/concurrency.d.ts +43 -0
  87. package/dist/shared/concurrency.js +78 -0
  88. package/dist/shared/dynamodb/abort.d.ts +47 -0
  89. package/dist/shared/dynamodb/abort.js +59 -0
  90. package/dist/shared/dynamodb/batch-write.d.ts +77 -14
  91. package/dist/shared/dynamodb/batch-write.js +146 -27
  92. package/dist/shared/dynamodb/cancellation.d.ts +121 -4
  93. package/dist/shared/dynamodb/cancellation.js +147 -3
  94. package/dist/shared/dynamodb/client.d.ts +162 -8
  95. package/dist/shared/dynamodb/client.js +153 -5
  96. package/dist/shared/dynamodb/idempotent-write.d.ts +551 -0
  97. package/dist/shared/dynamodb/idempotent-write.js +593 -0
  98. package/dist/shared/dynamodb/paginate.d.ts +105 -9
  99. package/dist/shared/dynamodb/paginate.js +175 -7
  100. package/dist/shared/dynamodb/partition-delete.d.ts +185 -14
  101. package/dist/shared/dynamodb/partition-delete.js +314 -44
  102. package/dist/shared/dynamodb/recency-index.d.ts +231 -0
  103. package/dist/shared/dynamodb/recency-index.js +377 -0
  104. package/dist/shared/dynamodb/retry.d.ts +276 -8
  105. package/dist/shared/dynamodb/retry.js +433 -23
  106. package/dist/shared/dynamodb/table-schema.d.ts +190 -0
  107. package/dist/shared/dynamodb/table-schema.js +209 -0
  108. package/dist/shared/errors/base-error.d.ts +184 -10
  109. package/dist/shared/errors/base-error.js +160 -14
  110. package/dist/shared/errors/boundary.d.ts +71 -0
  111. package/dist/shared/errors/boundary.js +143 -0
  112. package/dist/shared/errors/classify.d.ts +97 -0
  113. package/dist/shared/errors/classify.js +257 -0
  114. package/dist/shared/errors/error-code.d.ts +77 -2
  115. package/dist/shared/errors/error-code.js +83 -1
  116. package/dist/shared/errors/errors.d.ts +158 -59
  117. package/dist/shared/errors/errors.js +219 -92
  118. package/dist/shared/logging/logger.d.ts +69 -3
  119. package/dist/shared/logging/logger.js +97 -3
  120. package/dist/shared/logging/redaction.d.ts +92 -8
  121. package/dist/shared/logging/redaction.js +273 -17
  122. package/dist/shared/logging/secret-patterns.d.ts +149 -19
  123. package/dist/shared/logging/secret-patterns.js +188 -27
  124. package/dist/shared/logging/truncate.d.ts +197 -0
  125. package/dist/shared/logging/truncate.js +231 -0
  126. package/dist/shared/options.d.ts +59 -7
  127. package/dist/shared/options.js +9 -1
  128. package/dist/shared/ulid.d.ts +77 -7
  129. package/dist/shared/ulid.js +103 -8
  130. package/dist/shared/validation/collaborators.d.ts +141 -0
  131. package/dist/shared/validation/collaborators.js +188 -0
  132. package/dist/shared/validation/option-shape.d.ts +89 -0
  133. package/dist/shared/validation/option-shape.js +113 -0
  134. package/dist/shared/validation/options.d.ts +145 -0
  135. package/dist/shared/validation/options.js +328 -0
  136. package/dist/shared/validation/primitives.d.ts +288 -21
  137. package/dist/shared/validation/primitives.js +353 -50
  138. package/dist/shared/validation/ttl.d.ts +66 -10
  139. package/dist/shared/validation/ttl.js +113 -15
  140. package/dist/store/actions/list-namespaces.d.ts +76 -6
  141. package/dist/store/actions/list-namespaces.js +166 -24
  142. package/dist/store/actions/put.d.ts +33 -8
  143. package/dist/store/actions/put.js +53 -60
  144. package/dist/store/actions/reconcile-vector-index.d.ts +31 -10
  145. package/dist/store/actions/reconcile-vector-index.js +34 -15
  146. package/dist/store/actions/search.d.ts +34 -6
  147. package/dist/store/actions/search.js +56 -51
  148. package/dist/store/internal/batch-plan.d.ts +26 -0
  149. package/dist/store/internal/batch-plan.js +109 -0
  150. package/dist/store/internal/filter.d.ts +36 -3
  151. package/dist/store/internal/filter.js +66 -15
  152. package/dist/store/internal/get-item.d.ts +45 -0
  153. package/dist/store/internal/get-item.js +115 -0
  154. package/dist/store/internal/item-write.d.ts +230 -0
  155. package/dist/store/internal/item-write.js +463 -0
  156. package/dist/store/internal/parse.d.ts +225 -0
  157. package/dist/store/internal/parse.js +350 -0
  158. package/dist/store/internal/rows.d.ts +355 -0
  159. package/dist/store/internal/rows.js +447 -0
  160. package/dist/store/internal/semantic-search.d.ts +161 -6
  161. package/dist/store/internal/semantic-search.js +360 -18
  162. package/dist/store/internal/setup.d.ts +77 -20
  163. package/dist/store/internal/setup.js +178 -47
  164. package/dist/store/internal/table-search.d.ts +100 -0
  165. package/dist/store/internal/table-search.js +213 -0
  166. package/dist/store/internal/vector-index.d.ts +247 -0
  167. package/dist/store/internal/vector-index.js +546 -0
  168. package/dist/store/store.d.ts +270 -17
  169. package/dist/store/store.js +329 -38
  170. package/dist/store/types.d.ts +76 -26
  171. package/dist/store/types.js +13 -1
  172. package/dist/store/vector-backend.d.ts +64 -4
  173. package/dist/store/vector-backend.js +15 -1
  174. package/package.json +58 -36
  175. package/dist/checkpointer/actions/delete-thread.d.ts.map +0 -1
  176. package/dist/checkpointer/actions/delete-thread.js.map +0 -1
  177. package/dist/checkpointer/actions/get-tuple.d.ts.map +0 -1
  178. package/dist/checkpointer/actions/get-tuple.js.map +0 -1
  179. package/dist/checkpointer/actions/list.d.ts.map +0 -1
  180. package/dist/checkpointer/actions/list.js.map +0 -1
  181. package/dist/checkpointer/actions/put-writes.d.ts.map +0 -1
  182. package/dist/checkpointer/actions/put-writes.js.map +0 -1
  183. package/dist/checkpointer/actions/put.d.ts.map +0 -1
  184. package/dist/checkpointer/actions/put.js.map +0 -1
  185. package/dist/checkpointer/internal/assemble.d.ts +0 -10
  186. package/dist/checkpointer/internal/assemble.d.ts.map +0 -1
  187. package/dist/checkpointer/internal/assemble.js +0 -37
  188. package/dist/checkpointer/internal/assemble.js.map +0 -1
  189. package/dist/checkpointer/internal/configurable.d.ts +0 -13
  190. package/dist/checkpointer/internal/configurable.d.ts.map +0 -1
  191. package/dist/checkpointer/internal/configurable.js +0 -23
  192. package/dist/checkpointer/internal/configurable.js.map +0 -1
  193. package/dist/checkpointer/internal/fetch.d.ts +0 -10
  194. package/dist/checkpointer/internal/fetch.d.ts.map +0 -1
  195. package/dist/checkpointer/internal/fetch.js +0 -46
  196. package/dist/checkpointer/internal/fetch.js.map +0 -1
  197. package/dist/checkpointer/internal/filter-match.d.ts +0 -12
  198. package/dist/checkpointer/internal/filter-match.d.ts.map +0 -1
  199. package/dist/checkpointer/internal/filter-match.js +0 -14
  200. package/dist/checkpointer/internal/filter-match.js.map +0 -1
  201. package/dist/checkpointer/internal/item-reader.d.ts +0 -55
  202. package/dist/checkpointer/internal/item-reader.d.ts.map +0 -1
  203. package/dist/checkpointer/internal/item-reader.js +0 -88
  204. package/dist/checkpointer/internal/item-reader.js.map +0 -1
  205. package/dist/checkpointer/internal/item-writer.d.ts +0 -26
  206. package/dist/checkpointer/internal/item-writer.d.ts.map +0 -1
  207. package/dist/checkpointer/internal/item-writer.js +0 -92
  208. package/dist/checkpointer/internal/item-writer.js.map +0 -1
  209. package/dist/checkpointer/internal/keys.d.ts +0 -31
  210. package/dist/checkpointer/internal/keys.d.ts.map +0 -1
  211. package/dist/checkpointer/internal/keys.js +0 -87
  212. package/dist/checkpointer/internal/keys.js.map +0 -1
  213. package/dist/checkpointer/internal/query.d.ts +0 -20
  214. package/dist/checkpointer/internal/query.d.ts.map +0 -1
  215. package/dist/checkpointer/internal/query.js +0 -36
  216. package/dist/checkpointer/internal/query.js.map +0 -1
  217. package/dist/checkpointer/internal/setup.d.ts.map +0 -1
  218. package/dist/checkpointer/internal/setup.js.map +0 -1
  219. package/dist/checkpointer/internal/special-write-cas.d.ts +0 -30
  220. package/dist/checkpointer/internal/special-write-cas.d.ts.map +0 -1
  221. package/dist/checkpointer/internal/special-write-cas.js +0 -104
  222. package/dist/checkpointer/internal/special-write-cas.js.map +0 -1
  223. package/dist/checkpointer/internal/special-write-cleanup.d.ts +0 -24
  224. package/dist/checkpointer/internal/special-write-cleanup.d.ts.map +0 -1
  225. package/dist/checkpointer/internal/special-write-cleanup.js +0 -47
  226. package/dist/checkpointer/internal/special-write-cleanup.js.map +0 -1
  227. package/dist/checkpointer/internal/special-write-verify.d.ts +0 -54
  228. package/dist/checkpointer/internal/special-write-verify.d.ts.map +0 -1
  229. package/dist/checkpointer/internal/special-write-verify.js +0 -65
  230. package/dist/checkpointer/internal/special-write-verify.js.map +0 -1
  231. package/dist/checkpointer/internal/validation.d.ts +0 -13
  232. package/dist/checkpointer/internal/validation.d.ts.map +0 -1
  233. package/dist/checkpointer/internal/validation.js +0 -30
  234. package/dist/checkpointer/internal/validation.js.map +0 -1
  235. package/dist/checkpointer/internal/write-guard.d.ts +0 -13
  236. package/dist/checkpointer/internal/write-guard.d.ts.map +0 -1
  237. package/dist/checkpointer/internal/write-guard.js +0 -39
  238. package/dist/checkpointer/internal/write-guard.js.map +0 -1
  239. package/dist/checkpointer/internal/write-index.d.ts +0 -37
  240. package/dist/checkpointer/internal/write-index.d.ts.map +0 -1
  241. package/dist/checkpointer/internal/write-index.js +0 -42
  242. package/dist/checkpointer/internal/write-index.js.map +0 -1
  243. package/dist/checkpointer/saver.d.ts.map +0 -1
  244. package/dist/checkpointer/saver.js.map +0 -1
  245. package/dist/checkpointer/types.d.ts.map +0 -1
  246. package/dist/checkpointer/types.js.map +0 -1
  247. package/dist/factory/factory.d.ts.map +0 -1
  248. package/dist/factory/factory.js.map +0 -1
  249. package/dist/history/actions/add-messages.d.ts.map +0 -1
  250. package/dist/history/actions/add-messages.js.map +0 -1
  251. package/dist/history/actions/clear.d.ts.map +0 -1
  252. package/dist/history/actions/clear.js.map +0 -1
  253. package/dist/history/actions/get-messages.d.ts.map +0 -1
  254. package/dist/history/actions/get-messages.js.map +0 -1
  255. package/dist/history/actions/list-sessions.d.ts.map +0 -1
  256. package/dist/history/actions/list-sessions.js.map +0 -1
  257. package/dist/history/actions/reconcile-count.d.ts.map +0 -1
  258. package/dist/history/actions/reconcile-count.js.map +0 -1
  259. package/dist/history/chat-message-history.d.ts.map +0 -1
  260. package/dist/history/chat-message-history.js.map +0 -1
  261. package/dist/history/internal/append-saga.d.ts +0 -20
  262. package/dist/history/internal/append-saga.d.ts.map +0 -1
  263. package/dist/history/internal/append-saga.js +0 -35
  264. package/dist/history/internal/append-saga.js.map +0 -1
  265. package/dist/history/internal/compensation.d.ts +0 -21
  266. package/dist/history/internal/compensation.d.ts.map +0 -1
  267. package/dist/history/internal/compensation.js +0 -84
  268. package/dist/history/internal/compensation.js.map +0 -1
  269. package/dist/history/internal/item-mapper.d.ts +0 -12
  270. package/dist/history/internal/item-mapper.d.ts.map +0 -1
  271. package/dist/history/internal/item-mapper.js +0 -33
  272. package/dist/history/internal/item-mapper.js.map +0 -1
  273. package/dist/history/internal/keys.d.ts +0 -17
  274. package/dist/history/internal/keys.d.ts.map +0 -1
  275. package/dist/history/internal/keys.js +0 -49
  276. package/dist/history/internal/keys.js.map +0 -1
  277. package/dist/history/internal/message-chunker.d.ts +0 -14
  278. package/dist/history/internal/message-chunker.d.ts.map +0 -1
  279. package/dist/history/internal/message-chunker.js +0 -68
  280. package/dist/history/internal/message-chunker.js.map +0 -1
  281. package/dist/history/internal/message-transaction.d.ts +0 -26
  282. package/dist/history/internal/message-transaction.d.ts.map +0 -1
  283. package/dist/history/internal/message-transaction.js +0 -60
  284. package/dist/history/internal/message-transaction.js.map +0 -1
  285. package/dist/history/internal/query.d.ts +0 -10
  286. package/dist/history/internal/query.d.ts.map +0 -1
  287. package/dist/history/internal/query.js +0 -31
  288. package/dist/history/internal/query.js.map +0 -1
  289. package/dist/history/internal/session-count.d.ts +0 -41
  290. package/dist/history/internal/session-count.d.ts.map +0 -1
  291. package/dist/history/internal/session-count.js +0 -109
  292. package/dist/history/internal/session-count.js.map +0 -1
  293. package/dist/history/internal/session-title.d.ts +0 -20
  294. package/dist/history/internal/session-title.d.ts.map +0 -1
  295. package/dist/history/internal/session-title.js +0 -44
  296. package/dist/history/internal/session-title.js.map +0 -1
  297. package/dist/history/internal/session-update.d.ts +0 -28
  298. package/dist/history/internal/session-update.d.ts.map +0 -1
  299. package/dist/history/internal/session-update.js +0 -70
  300. package/dist/history/internal/session-update.js.map +0 -1
  301. package/dist/history/internal/setup.d.ts.map +0 -1
  302. package/dist/history/internal/setup.js.map +0 -1
  303. package/dist/history/internal/title-generator.d.ts +0 -13
  304. package/dist/history/internal/title-generator.d.ts.map +0 -1
  305. package/dist/history/internal/title-generator.js +0 -25
  306. package/dist/history/internal/title-generator.js.map +0 -1
  307. package/dist/history/internal/ttl-anchor.d.ts +0 -25
  308. package/dist/history/internal/ttl-anchor.d.ts.map +0 -1
  309. package/dist/history/internal/ttl-anchor.js +0 -38
  310. package/dist/history/internal/ttl-anchor.js.map +0 -1
  311. package/dist/history/internal/validation.d.ts +0 -9
  312. package/dist/history/internal/validation.d.ts.map +0 -1
  313. package/dist/history/internal/validation.js +0 -16
  314. package/dist/history/internal/validation.js.map +0 -1
  315. package/dist/history/session-adapter.d.ts.map +0 -1
  316. package/dist/history/session-adapter.js.map +0 -1
  317. package/dist/history/types.d.ts.map +0 -1
  318. package/dist/history/types.js.map +0 -1
  319. package/dist/index.d.ts.map +0 -1
  320. package/dist/index.js.map +0 -1
  321. package/dist/shared/clock.d.ts.map +0 -1
  322. package/dist/shared/clock.js.map +0 -1
  323. package/dist/shared/codec/codec.d.ts.map +0 -1
  324. package/dist/shared/codec/codec.js.map +0 -1
  325. package/dist/shared/codec/compression.d.ts.map +0 -1
  326. package/dist/shared/codec/compression.js.map +0 -1
  327. package/dist/shared/codec/descriptor-keys.d.ts +0 -4
  328. package/dist/shared/codec/descriptor-keys.d.ts.map +0 -1
  329. package/dist/shared/codec/descriptor-keys.js +0 -14
  330. package/dist/shared/codec/descriptor-keys.js.map +0 -1
  331. package/dist/shared/codec/json-serde.d.ts.map +0 -1
  332. package/dist/shared/codec/json-serde.js.map +0 -1
  333. package/dist/shared/codec/s3/client.d.ts.map +0 -1
  334. package/dist/shared/codec/s3/client.js.map +0 -1
  335. package/dist/shared/codec/s3/config.d.ts.map +0 -1
  336. package/dist/shared/codec/s3/config.js.map +0 -1
  337. package/dist/shared/codec/s3/delete.d.ts +0 -8
  338. package/dist/shared/codec/s3/delete.d.ts.map +0 -1
  339. package/dist/shared/codec/s3/delete.js +0 -29
  340. package/dist/shared/codec/s3/delete.js.map +0 -1
  341. package/dist/shared/codec/s3/lifecycle.d.ts.map +0 -1
  342. package/dist/shared/codec/s3/lifecycle.js.map +0 -1
  343. package/dist/shared/codec/s3/offloader.d.ts.map +0 -1
  344. package/dist/shared/codec/s3/offloader.js.map +0 -1
  345. package/dist/shared/codec/s3/orphans.d.ts +0 -18
  346. package/dist/shared/codec/s3/orphans.d.ts.map +0 -1
  347. package/dist/shared/codec/s3/orphans.js +0 -58
  348. package/dist/shared/codec/s3/orphans.js.map +0 -1
  349. package/dist/shared/codec/s3/read-write.d.ts +0 -14
  350. package/dist/shared/codec/s3/read-write.d.ts.map +0 -1
  351. package/dist/shared/codec/s3/read-write.js +0 -43
  352. package/dist/shared/codec/s3/read-write.js.map +0 -1
  353. package/dist/shared/codec/s3/retry.d.ts +0 -5
  354. package/dist/shared/codec/s3/retry.d.ts.map +0 -1
  355. package/dist/shared/codec/s3/retry.js +0 -25
  356. package/dist/shared/codec/s3/retry.js.map +0 -1
  357. package/dist/shared/constants.d.ts +0 -64
  358. package/dist/shared/constants.d.ts.map +0 -1
  359. package/dist/shared/constants.js +0 -67
  360. package/dist/shared/constants.js.map +0 -1
  361. package/dist/shared/dynamodb/backoff.d.ts +0 -15
  362. package/dist/shared/dynamodb/backoff.d.ts.map +0 -1
  363. package/dist/shared/dynamodb/backoff.js +0 -48
  364. package/dist/shared/dynamodb/backoff.js.map +0 -1
  365. package/dist/shared/dynamodb/batch-write.d.ts.map +0 -1
  366. package/dist/shared/dynamodb/batch-write.js.map +0 -1
  367. package/dist/shared/dynamodb/cancellation.d.ts.map +0 -1
  368. package/dist/shared/dynamodb/cancellation.js.map +0 -1
  369. package/dist/shared/dynamodb/client.d.ts.map +0 -1
  370. package/dist/shared/dynamodb/client.js.map +0 -1
  371. package/dist/shared/dynamodb/conditional-put.d.ts +0 -51
  372. package/dist/shared/dynamodb/conditional-put.d.ts.map +0 -1
  373. package/dist/shared/dynamodb/conditional-put.js +0 -59
  374. package/dist/shared/dynamodb/conditional-put.js.map +0 -1
  375. package/dist/shared/dynamodb/drain-unprocessed.d.ts +0 -19
  376. package/dist/shared/dynamodb/drain-unprocessed.d.ts.map +0 -1
  377. package/dist/shared/dynamodb/drain-unprocessed.js +0 -44
  378. package/dist/shared/dynamodb/drain-unprocessed.js.map +0 -1
  379. package/dist/shared/dynamodb/paginate-core.d.ts +0 -22
  380. package/dist/shared/dynamodb/paginate-core.d.ts.map +0 -1
  381. package/dist/shared/dynamodb/paginate-core.js +0 -52
  382. package/dist/shared/dynamodb/paginate-core.js.map +0 -1
  383. package/dist/shared/dynamodb/paginate.d.ts.map +0 -1
  384. package/dist/shared/dynamodb/paginate.js.map +0 -1
  385. package/dist/shared/dynamodb/partition-delete.d.ts.map +0 -1
  386. package/dist/shared/dynamodb/partition-delete.js.map +0 -1
  387. package/dist/shared/dynamodb/retry-classifier.d.ts +0 -9
  388. package/dist/shared/dynamodb/retry-classifier.d.ts.map +0 -1
  389. package/dist/shared/dynamodb/retry-classifier.js +0 -87
  390. package/dist/shared/dynamodb/retry-classifier.js.map +0 -1
  391. package/dist/shared/dynamodb/retry.d.ts.map +0 -1
  392. package/dist/shared/dynamodb/retry.js.map +0 -1
  393. package/dist/shared/dynamodb/scan.d.ts +0 -15
  394. package/dist/shared/dynamodb/scan.d.ts.map +0 -1
  395. package/dist/shared/dynamodb/scan.js +0 -20
  396. package/dist/shared/dynamodb/scan.js.map +0 -1
  397. package/dist/shared/dynamodb/types.d.ts +0 -24
  398. package/dist/shared/dynamodb/types.d.ts.map +0 -1
  399. package/dist/shared/dynamodb/types.js +0 -3
  400. package/dist/shared/dynamodb/types.js.map +0 -1
  401. package/dist/shared/errors/base-error.d.ts.map +0 -1
  402. package/dist/shared/errors/base-error.js.map +0 -1
  403. package/dist/shared/errors/error-code.d.ts.map +0 -1
  404. package/dist/shared/errors/error-code.js.map +0 -1
  405. package/dist/shared/errors/errors.d.ts.map +0 -1
  406. package/dist/shared/errors/errors.js.map +0 -1
  407. package/dist/shared/errors/wrap-error.d.ts +0 -16
  408. package/dist/shared/errors/wrap-error.d.ts.map +0 -1
  409. package/dist/shared/errors/wrap-error.js +0 -30
  410. package/dist/shared/errors/wrap-error.js.map +0 -1
  411. package/dist/shared/logging/logger.d.ts.map +0 -1
  412. package/dist/shared/logging/logger.js.map +0 -1
  413. package/dist/shared/logging/redaction-walk.d.ts +0 -23
  414. package/dist/shared/logging/redaction-walk.d.ts.map +0 -1
  415. package/dist/shared/logging/redaction-walk.js +0 -92
  416. package/dist/shared/logging/redaction-walk.js.map +0 -1
  417. package/dist/shared/logging/redaction.d.ts.map +0 -1
  418. package/dist/shared/logging/redaction.js.map +0 -1
  419. package/dist/shared/logging/secret-patterns.d.ts.map +0 -1
  420. package/dist/shared/logging/secret-patterns.js.map +0 -1
  421. package/dist/shared/options.d.ts.map +0 -1
  422. package/dist/shared/options.js.map +0 -1
  423. package/dist/shared/ulid.d.ts.map +0 -1
  424. package/dist/shared/ulid.js.map +0 -1
  425. package/dist/shared/validation/primitives.d.ts.map +0 -1
  426. package/dist/shared/validation/primitives.js.map +0 -1
  427. package/dist/shared/validation/ttl.d.ts.map +0 -1
  428. package/dist/shared/validation/ttl.js.map +0 -1
  429. package/dist/store/actions/get.d.ts +0 -5
  430. package/dist/store/actions/get.d.ts.map +0 -1
  431. package/dist/store/actions/get.js +0 -35
  432. package/dist/store/actions/get.js.map +0 -1
  433. package/dist/store/actions/list-namespaces.d.ts.map +0 -1
  434. package/dist/store/actions/list-namespaces.js.map +0 -1
  435. package/dist/store/actions/put.d.ts.map +0 -1
  436. package/dist/store/actions/put.js.map +0 -1
  437. package/dist/store/actions/reconcile-vector-index.d.ts.map +0 -1
  438. package/dist/store/actions/reconcile-vector-index.js.map +0 -1
  439. package/dist/store/actions/search.d.ts.map +0 -1
  440. package/dist/store/actions/search.js.map +0 -1
  441. package/dist/store/internal/backend-search.d.ts +0 -5
  442. package/dist/store/internal/backend-search.d.ts.map +0 -1
  443. package/dist/store/internal/backend-search.js +0 -68
  444. package/dist/store/internal/backend-search.js.map +0 -1
  445. package/dist/store/internal/filter.d.ts.map +0 -1
  446. package/dist/store/internal/filter.js.map +0 -1
  447. package/dist/store/internal/index-reconcile.d.ts +0 -22
  448. package/dist/store/internal/index-reconcile.d.ts.map +0 -1
  449. package/dist/store/internal/index-reconcile.js +0 -105
  450. package/dist/store/internal/index-reconcile.js.map +0 -1
  451. package/dist/store/internal/index-sync.d.ts +0 -11
  452. package/dist/store/internal/index-sync.d.ts.map +0 -1
  453. package/dist/store/internal/index-sync.js +0 -26
  454. package/dist/store/internal/index-sync.js.map +0 -1
  455. package/dist/store/internal/item-mapper.d.ts +0 -25
  456. package/dist/store/internal/item-mapper.d.ts.map +0 -1
  457. package/dist/store/internal/item-mapper.js +0 -53
  458. package/dist/store/internal/item-mapper.js.map +0 -1
  459. package/dist/store/internal/keys.d.ts +0 -18
  460. package/dist/store/internal/keys.d.ts.map +0 -1
  461. package/dist/store/internal/keys.js +0 -42
  462. package/dist/store/internal/keys.js.map +0 -1
  463. package/dist/store/internal/namespace-match.d.ts +0 -12
  464. package/dist/store/internal/namespace-match.d.ts.map +0 -1
  465. package/dist/store/internal/namespace-match.js +0 -41
  466. package/dist/store/internal/namespace-match.js.map +0 -1
  467. package/dist/store/internal/overwrite-swap.d.ts +0 -33
  468. package/dist/store/internal/overwrite-swap.d.ts.map +0 -1
  469. package/dist/store/internal/overwrite-swap.js +0 -62
  470. package/dist/store/internal/overwrite-swap.js.map +0 -1
  471. package/dist/store/internal/persist.d.ts +0 -27
  472. package/dist/store/internal/persist.d.ts.map +0 -1
  473. package/dist/store/internal/persist.js +0 -59
  474. package/dist/store/internal/persist.js.map +0 -1
  475. package/dist/store/internal/query.d.ts +0 -6
  476. package/dist/store/internal/query.d.ts.map +0 -1
  477. package/dist/store/internal/query.js +0 -32
  478. package/dist/store/internal/query.js.map +0 -1
  479. package/dist/store/internal/ranker.d.ts +0 -13
  480. package/dist/store/internal/ranker.d.ts.map +0 -1
  481. package/dist/store/internal/ranker.js +0 -31
  482. package/dist/store/internal/ranker.js.map +0 -1
  483. package/dist/store/internal/read-existing.d.ts +0 -19
  484. package/dist/store/internal/read-existing.d.ts.map +0 -1
  485. package/dist/store/internal/read-existing.js +0 -29
  486. package/dist/store/internal/read-existing.js.map +0 -1
  487. package/dist/store/internal/score-direction.d.ts +0 -32
  488. package/dist/store/internal/score-direction.d.ts.map +0 -1
  489. package/dist/store/internal/score-direction.js +0 -39
  490. package/dist/store/internal/score-direction.js.map +0 -1
  491. package/dist/store/internal/search-filter.d.ts +0 -4
  492. package/dist/store/internal/search-filter.d.ts.map +0 -1
  493. package/dist/store/internal/search-filter.js +0 -11
  494. package/dist/store/internal/search-filter.js.map +0 -1
  495. package/dist/store/internal/semantic-search.d.ts.map +0 -1
  496. package/dist/store/internal/semantic-search.js.map +0 -1
  497. package/dist/store/internal/setup.d.ts.map +0 -1
  498. package/dist/store/internal/setup.js.map +0 -1
  499. package/dist/store/internal/validation.d.ts +0 -13
  500. package/dist/store/internal/validation.d.ts.map +0 -1
  501. package/dist/store/internal/validation.js +0 -35
  502. package/dist/store/internal/validation.js.map +0 -1
  503. package/dist/store/internal/write-verify.d.ts +0 -37
  504. package/dist/store/internal/write-verify.d.ts.map +0 -1
  505. package/dist/store/internal/write-verify.js +0 -68
  506. package/dist/store/internal/write-verify.js.map +0 -1
  507. package/dist/store/store.d.ts.map +0 -1
  508. package/dist/store/store.js.map +0 -1
  509. package/dist/store/types.d.ts.map +0 -1
  510. package/dist/store/types.js.map +0 -1
  511. package/dist/store/vector-backend.d.ts.map +0 -1
  512. package/dist/store/vector-backend.js.map +0 -1
@@ -1,91 +1,76 @@
1
1
  "use strict";
2
+ /**
3
+ * Hides how one `putWrites` call's rows are known to be one call's.
4
+ *
5
+ * Every call draws a write group from a strictly monotonic ULID factory, and
6
+ * that one id serves three ends: the object id each offloaded write is uploaded
7
+ * under (record 4), the owner a guard rejection is compared against to tell a
8
+ * rival call from this call's own retry, and the order the read side uses to
9
+ * pick the earliest call that wrote a channel. A caller passes writes and a
10
+ * task id and never sees the group.
11
+ */
2
12
  Object.defineProperty(exports, "__esModule", { value: true });
3
13
  exports.putWrites = putWrites;
4
- const descriptor_keys_1 = require("../../shared/codec/descriptor-keys");
5
- const orphans_1 = require("../../shared/codec/s3/orphans");
6
- const conditional_put_1 = require("../../shared/dynamodb/conditional-put");
7
- const retry_1 = require("../../shared/dynamodb/retry");
8
- const errors_1 = require("../../shared/errors/errors");
9
14
  const ulid_1 = require("../../shared/ulid");
10
15
  const ttl_1 = require("../../shared/validation/ttl");
11
- const configurable_1 = require("../internal/configurable");
12
- const item_writer_1 = require("../internal/item-writer");
13
- const special_write_cleanup_1 = require("../internal/special-write-cleanup");
14
- const validation_1 = require("../internal/validation");
15
- const write_guard_1 = require("../internal/write-guard");
16
+ const parse_1 = require("../internal/parse");
17
+ const pending_writes_1 = require("../internal/pending-writes");
18
+ const rows_1 = require("../internal/rows");
16
19
  /**
17
- * Stamps each `putWrites` call, serving two purposes at once. It nonces every
18
- * S3 upload, so a repeated write never shares an object with an earlier
19
- * attempt. And because ULIDs are lexicographically time-ordered — and this
20
- * factory is strictly monotonic even within a single millisecond — it lets the
21
- * read side identify the *earliest* call that wrote a given channel (see
22
- * `dropSupersededWrites`). A random UUID nonces just as well but carries no
23
- * ordering, which would leave that choice arbitrary.
20
+ * Stamps each `putWrites` call, identifying its rows as one group.
21
+ *
22
+ * It is what a guard rejection is compared against to tell "another call holds
23
+ * this row" from "my own retry does", it is the object id every offloaded write
24
+ * of the call is uploaded under, and — because ULIDs are lexicographically
25
+ * time-ordered, and this factory is strictly monotonic even within a single
26
+ * millisecond — it lets the read side identify the *earliest* call that wrote a
27
+ * given channel (see `dropSupersededWrites`). A random UUID would identify a
28
+ * call just as well but carries no ordering, which would leave that choice
29
+ * arbitrary.
24
30
  */
25
31
  const nextWriteGroup = (0, ulid_1.createUlidFactory)();
26
- /** Best-effort delete `items`' offloaded S3 objects, if an offloader is configured. */
27
- async function cleanUpItems(context, items) {
28
- if (!context.offloader)
29
- return;
30
- await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)(items.map((item) => item.value)), 'putWrites', context.logger);
31
- }
32
- /**
33
- * Write regular items with a first-write-wins guard. Every `PutCommand` fully
34
- * settles (`Promise.allSettled`) before this resolves and never rejects; a
35
- * genuine failure is reported via `error`, not thrown.
36
- */
37
- async function writeRegularItems(context, items) {
38
- const failed = [];
39
- let error;
40
- const results = await Promise.allSettled(items.map((item) => (0, retry_1.withDynamoDBRetry)(() => context.client.put({
41
- TableName: context.tableName,
42
- Item: item,
43
- ConditionExpression: 'attribute_not_exists(PK)',
44
- ReturnValuesOnConditionCheckFailure: 'ALL_OLD',
45
- }))));
46
- results.forEach((result, index) => {
47
- if (result.status === 'fulfilled')
48
- return;
49
- const reason = result.reason;
50
- if ((0, conditional_put_1.isConditionalCheckFailed)(reason)) {
51
- (0, write_guard_1.reportGuardRejection)(context, items[index], reason);
52
- return;
53
- }
54
- failed.push(items[index]);
55
- error = error ?? reason;
56
- });
57
- return { failed, error };
58
- }
59
32
  /**
60
- * Persist a task's intermediate writes for a checkpoint as one item per write.
61
- * Requires `checkpoint_id` in the config — writes always attach to a checkpoint.
62
- * Regular writes are first-write-wins (matching the reference checkpointer
63
- * contract); special negative-index writes always overwrite (see
64
- * {@link writeSpecialItemsWithCleanup}). Regular-write failure cleanup only
65
- * ever targets items known never to have committed (see
66
- * {@link RegularWriteOutcome}) — never a lost guard, so an upload can leak
67
- * but a live row can never be stranded pointing at a deleted object.
33
+ * Persist a task's intermediate writes for a checkpoint, one row per write.
34
+ *
35
+ * Accepts: `config` — must name a `checkpoint_id`, since writes always attach
36
+ * to a checkpoint. `writes` — one task's, in order; their channels are
37
+ * validated before anything is encoded or uploaded. `taskId` — validated as the
38
+ * sort-key segment it becomes. `config.signal` — cancels the writes' retries;
39
+ * checked before anything is encoded.
40
+ *
41
+ * Returns: nothing. Every write is attempted; a regular write that loses its
42
+ * first-write-wins race is a normal outcome, not a failure.
43
+ *
44
+ * Throws: `VALIDATION` naming `config`, `configurable` or `signal` for a
45
+ * config of the wrong shape; `thread_id`, `checkpoint_ns`, `checkpoint_id` or
46
+ * `thread_ts` for a malformed identifier, and `checkpoint_id` when the config
47
+ * names none; `taskId`, `writes`, `channel`, `sortKey` — every one of them
48
+ * before anything is encoded or uploaded — `payload` or `s3Key`; the first
49
+ * genuine write failure, after every write has settled and the cleanup has
50
+ * run.
51
+ *
52
+ * Guarantees: regular writes are first-write-wins, matching the reference
53
+ * checkpointer; special negative-index writes always overwrite (see
54
+ * {@link commitPendingWrites}). Cleanup of this call's own uploads only ever
55
+ * targets uploads confirmed unreferenced: a verified non-commit, or a guard
56
+ * rejection whose returned row provably belongs to another call. A special write's superseded
57
+ * payload is released only once the write that superseded it committed. An
58
+ * upload can leak. A payload refused partway through the encode releases the
59
+ * objects the earlier writes of the same call had already uploaded, before the
60
+ * refusal reaches the caller and while no row of the call exists. Every
61
+ * offloaded write of this call is uploaded under the call's own `writeGroup`,
62
+ * so no row another call writes names one of this call's uploads, and no
63
+ * release reads the row again first.
68
64
  */
69
65
  async function putWrites(context, config, writes, taskId) {
70
- (0, validation_1.validateTaskId)(taskId);
71
- const { threadId, checkpointNs, checkpointId } = (0, configurable_1.readConfigurable)(config);
72
- if (checkpointId === undefined) {
73
- throw new errors_1.ValidationError('checkpoint_id is required to store writes', 'checkpoint_id');
74
- }
75
- if (writes.length === 0)
66
+ const request = (0, parse_1.parsePutWritesRequest)(config, writes, taskId);
67
+ if (request.writes.length === 0)
76
68
  return;
77
69
  const ttlTimestamp = context.ttl ? (0, ttl_1.calculateTtlTimestamp)(context.ttl) : undefined;
78
- const items = await (0, item_writer_1.buildWriteItems)(context, threadId, checkpointNs, checkpointId, taskId, writes, nextWriteGroup(), ttlTimestamp);
79
- const special = items.filter((item) => item.index < 0);
80
- const regular = items.filter((item) => item.index >= 0);
81
- const [specialError, regularOutcome] = await Promise.all([
82
- (0, special_write_cleanup_1.writeSpecialItemsWithCleanup)(context, special),
83
- writeRegularItems(context, regular),
84
- ]);
85
- const firstError = specialError ?? regularOutcome.error;
86
- if (!firstError)
87
- return;
88
- await cleanUpItems(context, regularOutcome.failed);
89
- throw firstError;
70
+ const items = await (0, rows_1.buildWriteRows)(context, request, nextWriteGroup(), ttlTimestamp);
71
+ await (0, pending_writes_1.commitPendingWrites)(context, {
72
+ threadId: request.address.threadId,
73
+ items,
74
+ signal: request.signal,
75
+ });
90
76
  }
91
- //# sourceMappingURL=put-writes.js.map
@@ -1,10 +1,89 @@
1
+ /**
2
+ * Hides what it takes for a checkpoint to land exactly once.
3
+ *
4
+ * The META and PAYLOAD rows go out as one transaction under a request token
5
+ * drawn once, and a failure with S3 offload configured is read back before
6
+ * any upload is released, so a lost acknowledgement reports success and only a
7
+ * confirmed non-commit cleans up (record 6). Every channel value is stored
8
+ * whatever `newVersions` says (record 10). A caller gets back the config that
9
+ * addresses the stored checkpoint and none of this.
10
+ */
1
11
  import type { RunnableConfig } from '@langchain/core/runnables';
2
- import type { Checkpoint, CheckpointMetadata } from '@langchain/langgraph-checkpoint';
12
+ import type { ChannelVersions, Checkpoint, CheckpointMetadata } from '@langchain/langgraph-checkpoint';
13
+ import { type WriteVerdict } from '../../shared/dynamodb/idempotent-write';
14
+ import { type CheckpointMetaRow, type CheckpointPayloadRow } from '../internal/rows';
3
15
  import type { CheckpointerContext } from '../internal/setup';
4
16
  /**
5
17
  * Persist a checkpoint and its metadata as a transactional pair of META and
6
- * PAYLOAD items, returning the config that addresses the stored checkpoint. The
18
+ * PAYLOAD rows, returning the config that addresses the stored checkpoint. The
7
19
  * incoming `checkpoint_id` (if any) becomes the new checkpoint's parent.
20
+ *
21
+ * **Every channel value the checkpoint carries is stored.** `newVersions` is
22
+ * accepted because `BaseCheckpointSaver.put` declares it
23
+ * (`@langchain/langgraph-checkpoint@1.1.5` `dist/base.d.ts:68`) and is
24
+ * deliberately ignored: narrowing the stored values to the ones it names, and
25
+ * carrying the rest forward from the parent, made a put whose `newVersions` is
26
+ * `{}` write no values at all. LangGraph passes `{}` when forking a checkpoint
27
+ * and when writing an empty-checkpoint update (`@langchain/langgraph@1.4.13`
28
+ * `dist/pregel/index.js:668` and `:613`), so that put silently dropped user
29
+ * state. The reference saver does not narrow either: `MemorySaver.put` takes
30
+ * three parameters and stores the whole checkpoint (`dist/memory.js:206`).
31
+ *
32
+ * Accepts: `config` — its `checkpoint_id`, when present, becomes the new
33
+ * checkpoint's parent. `checkpoint.id` — validated as the sort-key segment it
34
+ * becomes. `metadata` — stored beside it, on the light row a listing reads.
35
+ * `config.signal` — cancels the writes' retries; checked before anything is
36
+ * encoded.
37
+ *
38
+ * Returns: the config addressing the stored checkpoint, which is what the
39
+ * caller passes back to continue the thread.
40
+ *
41
+ * Throws: `VALIDATION` naming `config`, `configurable` or `signal` for a
42
+ * config of the wrong shape, `thread_id`, `checkpoint_ns`, `checkpoint_id` or
43
+ * `thread_ts` for a malformed identifier, `checkpoint` for a `null` or
44
+ * `undefined` checkpoint, `checkpoint_id` for a malformed `checkpoint.id`,
45
+ * `payload` for a payload too large to store inline without `s3`, or `s3Key`
46
+ * for an offloaded object's key over S3's cap; `S3_OFFLOAD_FAILED`; whatever
47
+ * the transaction throws once the outcome is established.
48
+ *
49
+ * Guarantees: both rows land or neither does — they are one transaction, so a
50
+ * META row never names a payload that is not there. That transaction goes out
51
+ * under a client request token drawn once, with the request it travels on, so
52
+ * a retry that follows a lost acknowledgement is discarded by the service
53
+ * rather than applied a second time. Writing the same `checkpoint.id` again
54
+ * replaces both, which is what a retry and a repair tool both need; the objects
55
+ * the replaced rows named are not deleted by the put, and are left to the
56
+ * lifecycle rule. A payload the serde refuses is refused before any write and
57
+ * releases whatever the same call had already uploaded, so an encode that fails
58
+ * halfway leaves nothing behind either. On failure with S3 offload configured
59
+ * the row carrying an offloaded descriptor is read back before any upload is
60
+ * deleted (see {@link verifyCheckpointLanded}): a transaction that committed
61
+ * and lost its response is reported as success, a confirmed non-commit cleans
62
+ * up the objects this call uploaded, and an unverifiable outcome leaks them
63
+ * rather than risk stranding a live row. Each put uploads under an object id of
64
+ * its own, so no row another put commits names this call's uploads.
65
+ */
66
+ export declare function putCheckpoint(context: CheckpointerContext, config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, _newVersions?: ChannelVersions): Promise<RunnableConfig>;
67
+ /**
68
+ * Read one of the two rows back after the META+PAYLOAD transaction failed and
69
+ * report what that failure actually did — never assuming it did nothing.
70
+ *
71
+ * Accepts: `meta` and `payload` — the two rows the failed transaction carried.
72
+ * Whichever of them has something offloaded is the one read back; a fully
73
+ * inline write has no object at stake and spends no read.
74
+ *
75
+ * Returns: the verdict. See {@link WriteVerdict} for what each answer licenses
76
+ * the caller to do. `'landed'` when the row holds this attempt's key,
77
+ * `'not-landed'` when it holds another or none, `'unverified'` when the read
78
+ * failed.
79
+ *
80
+ * Throws: nothing — a failed read is the `'unverified'` answer.
81
+ *
82
+ * Guarantees: both descriptors' keys end in the object id this put drew, which
83
+ * no other put uses. The row holds this attempt's key only if this put's
84
+ * transaction committed, and the other row commits with it, so one read decides
85
+ * the landing. A row holding any other key was committed by another put, whose
86
+ * rows name only that put's objects, so a `'not-landed'` answer leaves both of
87
+ * this put's uploads named by no row.
8
88
  */
9
- export declare function putCheckpoint(context: CheckpointerContext, config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>;
10
- //# sourceMappingURL=put.d.ts.map
89
+ export declare function verifyCheckpointLanded(context: CheckpointerContext, meta: CheckpointMetaRow, payload: CheckpointPayloadRow): Promise<WriteVerdict>;
@@ -1,43 +1,195 @@
1
1
  "use strict";
2
+ /**
3
+ * Hides what it takes for a checkpoint to land exactly once.
4
+ *
5
+ * The META and PAYLOAD rows go out as one transaction under a request token
6
+ * drawn once, and a failure with S3 offload configured is read back before
7
+ * any upload is released, so a lost acknowledgement reports success and only a
8
+ * confirmed non-commit cleans up (record 6). Every channel value is stored
9
+ * whatever `newVersions` says (record 10). A caller gets back the config that
10
+ * addresses the stored checkpoint and none of this.
11
+ */
2
12
  Object.defineProperty(exports, "__esModule", { value: true });
3
13
  exports.putCheckpoint = putCheckpoint;
4
- const descriptor_keys_1 = require("../../shared/codec/descriptor-keys");
5
- const orphans_1 = require("../../shared/codec/s3/orphans");
6
- const retry_1 = require("../../shared/dynamodb/retry");
14
+ exports.verifyCheckpointLanded = verifyCheckpointLanded;
15
+ const codec_1 = require("../../shared/codec/codec");
16
+ const offloader_1 = require("../../shared/codec/s3/offloader");
17
+ const idempotent_write_1 = require("../../shared/dynamodb/idempotent-write");
18
+ const table_schema_1 = require("../../shared/dynamodb/table-schema");
7
19
  const ttl_1 = require("../../shared/validation/ttl");
8
- const configurable_1 = require("../internal/configurable");
9
- const item_writer_1 = require("../internal/item-writer");
10
- const validation_1 = require("../internal/validation");
20
+ const parse_1 = require("../internal/parse");
21
+ const rows_1 = require("../internal/rows");
11
22
  /**
12
23
  * Persist a checkpoint and its metadata as a transactional pair of META and
13
- * PAYLOAD items, returning the config that addresses the stored checkpoint. The
24
+ * PAYLOAD rows, returning the config that addresses the stored checkpoint. The
14
25
  * incoming `checkpoint_id` (if any) becomes the new checkpoint's parent.
26
+ *
27
+ * **Every channel value the checkpoint carries is stored.** `newVersions` is
28
+ * accepted because `BaseCheckpointSaver.put` declares it
29
+ * (`@langchain/langgraph-checkpoint@1.1.5` `dist/base.d.ts:68`) and is
30
+ * deliberately ignored: narrowing the stored values to the ones it names, and
31
+ * carrying the rest forward from the parent, made a put whose `newVersions` is
32
+ * `{}` write no values at all. LangGraph passes `{}` when forking a checkpoint
33
+ * and when writing an empty-checkpoint update (`@langchain/langgraph@1.4.13`
34
+ * `dist/pregel/index.js:668` and `:613`), so that put silently dropped user
35
+ * state. The reference saver does not narrow either: `MemorySaver.put` takes
36
+ * three parameters and stores the whole checkpoint (`dist/memory.js:206`).
37
+ *
38
+ * Accepts: `config` — its `checkpoint_id`, when present, becomes the new
39
+ * checkpoint's parent. `checkpoint.id` — validated as the sort-key segment it
40
+ * becomes. `metadata` — stored beside it, on the light row a listing reads.
41
+ * `config.signal` — cancels the writes' retries; checked before anything is
42
+ * encoded.
43
+ *
44
+ * Returns: the config addressing the stored checkpoint, which is what the
45
+ * caller passes back to continue the thread.
46
+ *
47
+ * Throws: `VALIDATION` naming `config`, `configurable` or `signal` for a
48
+ * config of the wrong shape, `thread_id`, `checkpoint_ns`, `checkpoint_id` or
49
+ * `thread_ts` for a malformed identifier, `checkpoint` for a `null` or
50
+ * `undefined` checkpoint, `checkpoint_id` for a malformed `checkpoint.id`,
51
+ * `payload` for a payload too large to store inline without `s3`, or `s3Key`
52
+ * for an offloaded object's key over S3's cap; `S3_OFFLOAD_FAILED`; whatever
53
+ * the transaction throws once the outcome is established.
54
+ *
55
+ * Guarantees: both rows land or neither does — they are one transaction, so a
56
+ * META row never names a payload that is not there. That transaction goes out
57
+ * under a client request token drawn once, with the request it travels on, so
58
+ * a retry that follows a lost acknowledgement is discarded by the service
59
+ * rather than applied a second time. Writing the same `checkpoint.id` again
60
+ * replaces both, which is what a retry and a repair tool both need; the objects
61
+ * the replaced rows named are not deleted by the put, and are left to the
62
+ * lifecycle rule. A payload the serde refuses is refused before any write and
63
+ * releases whatever the same call had already uploaded, so an encode that fails
64
+ * halfway leaves nothing behind either. On failure with S3 offload configured
65
+ * the row carrying an offloaded descriptor is read back before any upload is
66
+ * deleted (see {@link verifyCheckpointLanded}): a transaction that committed
67
+ * and lost its response is reported as success, a confirmed non-commit cleans
68
+ * up the objects this call uploaded, and an unverifiable outcome leaks them
69
+ * rather than risk stranding a live row. Each put uploads under an object id of
70
+ * its own, so no row another put commits names this call's uploads.
15
71
  */
16
- async function putCheckpoint(context, config, checkpoint, metadata) {
17
- const { threadId, checkpointNs, checkpointId: parentCheckpointId } = (0, configurable_1.readConfigurable)(config);
18
- (0, validation_1.validateCheckpointId)(checkpoint.id);
72
+ async function putCheckpoint(context, config, checkpoint, metadata, _newVersions) {
73
+ const request = (0, parse_1.parsePutRequest)(config, checkpoint, metadata);
74
+ const { threadId, checkpointNs, checkpointId } = request.address;
19
75
  const ttlTimestamp = context.ttl ? (0, ttl_1.calculateTtlTimestamp)(context.ttl) : undefined;
20
- const { meta, payload } = await (0, item_writer_1.buildCheckpointItems)(context, threadId, checkpointNs, checkpoint, metadata, parentCheckpointId, ttlTimestamp);
76
+ const { meta, payload } = await (0, rows_1.buildCheckpointRows)(context, request, ttlTimestamp);
77
+ const stored = {
78
+ configurable: { thread_id: threadId, checkpoint_ns: checkpointNs, checkpoint_id: checkpointId },
79
+ };
21
80
  try {
22
- await (0, retry_1.withDynamoDBRetry)(() => context.client.transactWrite({
23
- TransactItems: [
24
- { Put: { TableName: context.tableName, Item: meta } },
25
- { Put: { TableName: context.tableName, Item: payload } },
26
- ],
27
- }));
81
+ // One request, one token, re-sent unchanged for every attempt of the
82
+ // budget — which is what the token is worth here, since a token minted on
83
+ // a request the retry closure rebuilt would be a fresh one per attempt and
84
+ // would deduplicate nothing.
85
+ //
86
+ // Neither row is guarded, so nothing else can turn a re-send away: a retry
87
+ // that follows a lost acknowledgement puts both rows back, and one
88
+ // arriving after a `deleteThread` removed them puts back two live rows
89
+ // naming two objects that call has already released. Inside the service's
90
+ // idempotency window the token discards it instead. The pair is atomic, so
91
+ // what that window covers is the pair: a re-send either re-applies both
92
+ // rows or neither.
93
+ //
94
+ // A condition on either row is not the alternative it looks like. Two
95
+ // guarded items would make one genuine race cancel with two
96
+ // `ConditionalCheckFailed` reasons, and `conditionalCheckFailure` reads a
97
+ // cancellation as a guard rejection only while a single cause remains — so
98
+ // the race would surface as an unrecognised non-retryable error.
99
+ //
100
+ // Because neither row is guarded, the precondition on what a token
101
+ // guarantees — see {@link transactIdempotently} — never bites on the rows
102
+ // themselves: no condition here can turn an attempt away, so an attempt
103
+ // either committed the pair, and its re-send is discarded, or committed
104
+ // nothing. It does bite on the transaction, which a conflict with a
105
+ // concurrent writer of the same id can still cancel: a cancellation
106
+ // completes nothing and is cached as nothing, so the attempt after one is
107
+ // a fresh evaluation rather than a replay. That is the wanted outcome here
108
+ // — the pair did not land, so it must still land — and it is why the
109
+ // token's promise is worded about a write that *committed* rather than one
110
+ // that was merely sent.
111
+ //
112
+ // The deadline that helper carries is what keeps this budget inside the
113
+ // window the token is honoured for. The token enforces no window itself,
114
+ // and a re-send arriving after it has closed is simply a new request: both
115
+ // rows land again, over whatever has replaced them and after whatever
116
+ // released the objects they name.
117
+ await (0, idempotent_write_1.transactIdempotently)(context, [
118
+ { Put: { TableName: context.tableName, Item: meta } },
119
+ { Put: { TableName: context.tableName, Item: payload } },
120
+ ], { signal: request.signal });
28
121
  }
29
122
  catch (error) {
30
- if (context.offloader) {
31
- await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)([meta.metadata, payload.checkpoint]), 'put', context.logger);
123
+ if (!context.offloader)
124
+ throw error;
125
+ const verdict = await verifyCheckpointLanded(context, meta, payload);
126
+ if (verdict === 'landed') {
127
+ context.logger.debug('put: transaction committed although its response was lost', {
128
+ threadId,
129
+ checkpointId,
130
+ });
131
+ return stored;
132
+ }
133
+ if (verdict === 'not-landed') {
134
+ await (0, offloader_1.cleanUpS3Orphans)(context.offloader, {
135
+ keys: (0, codec_1.collectS3Keys)([meta.metadata, payload.checkpoint]),
136
+ operation: 'put',
137
+ logger: context.logger,
138
+ });
32
139
  }
33
140
  throw error;
34
141
  }
142
+ return stored;
143
+ }
144
+ /**
145
+ * Pick the row carrying an offloaded descriptor, projected to that
146
+ * descriptor's `location` and `s3Key`. The META and PAYLOAD rows commit in one
147
+ * transaction, so one of them is enough; with neither offloaded there is
148
+ * nothing to protect and no read to spend, which {@link verifyRow} answers
149
+ * `'not-landed'` for an absent `expected`.
150
+ */
151
+ function chooseProbe(meta, payload) {
152
+ const metaKey = (0, idempotent_write_1.offloadedKey)(meta.metadata);
153
+ if (metaKey !== undefined) {
154
+ return {
155
+ key: (0, table_schema_1.rowKeyOf)(meta),
156
+ kind: 'descriptor',
157
+ attribute: 'metadata',
158
+ expected: metaKey,
159
+ descriptors: ['metadata'],
160
+ };
161
+ }
35
162
  return {
36
- configurable: {
37
- thread_id: threadId,
38
- checkpoint_ns: checkpointNs,
39
- checkpoint_id: checkpoint.id,
40
- },
163
+ key: (0, table_schema_1.rowKeyOf)(payload),
164
+ kind: 'descriptor',
165
+ attribute: 'checkpoint',
166
+ expected: (0, idempotent_write_1.offloadedKey)(payload.checkpoint),
167
+ descriptors: ['checkpoint'],
41
168
  };
42
169
  }
43
- //# sourceMappingURL=put.js.map
170
+ /**
171
+ * Read one of the two rows back after the META+PAYLOAD transaction failed and
172
+ * report what that failure actually did — never assuming it did nothing.
173
+ *
174
+ * Accepts: `meta` and `payload` — the two rows the failed transaction carried.
175
+ * Whichever of them has something offloaded is the one read back; a fully
176
+ * inline write has no object at stake and spends no read.
177
+ *
178
+ * Returns: the verdict. See {@link WriteVerdict} for what each answer licenses
179
+ * the caller to do. `'landed'` when the row holds this attempt's key,
180
+ * `'not-landed'` when it holds another or none, `'unverified'` when the read
181
+ * failed.
182
+ *
183
+ * Throws: nothing — a failed read is the `'unverified'` answer.
184
+ *
185
+ * Guarantees: both descriptors' keys end in the object id this put drew, which
186
+ * no other put uses. The row holds this attempt's key only if this put's
187
+ * transaction committed, and the other row commits with it, so one read decides
188
+ * the landing. A row holding any other key was committed by another put, whose
189
+ * rows name only that put's objects, so a `'not-landed'` answer leaves both of
190
+ * this put's uploads named by no row.
191
+ */
192
+ async function verifyCheckpointLanded(context, meta, payload) {
193
+ const { verdict } = await (0, idempotent_write_1.verifyRow)(context, chooseProbe(meta, payload));
194
+ return verdict;
195
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Hides how a delta channel's history is rebuilt, and what a hole in it means.
3
+ *
4
+ * A delta channel stores a full value only every `snapshotFrequency` updates,
5
+ * so its value at a checkpoint is its last snapshot plus the writes since,
6
+ * collected by walking parent pointers. The walk, the order the writes are
7
+ * collected in, and the one read that tells an expired ancestor (a hole to
8
+ * report) from one that never existed (the history's true start) are decided
9
+ * here.
10
+ */
11
+ import type { RunnableConfig } from '@langchain/core/runnables';
12
+ import type { CheckpointTuple, DeltaChannelHistory } from '@langchain/langgraph-checkpoint';
13
+ import { DynamoDBLangGraphError } from '../../shared/errors/base-error';
14
+ import type { CheckpointerContext } from './setup';
15
+ /**
16
+ * Walk a checkpoint's ancestors for the delta channels named, accumulating
17
+ * their writes oldest-first and the nearest stored value of each.
18
+ *
19
+ * Same contract and same result as the inherited implementation
20
+ * (`@langchain/langgraph-checkpoint@1.1.5` `dist/base.js:78`), with one
21
+ * difference that is the reason for overriding it: where the inherited walk
22
+ * meets an ancestor it cannot read it simply stops (`if (tup === void 0)
23
+ * break`), reports no seed, and the consumer rebuilds the channel from its
24
+ * initial value (`@langchain/langgraph@1.4.13` `dist/channels/delta.js:65`).
25
+ * That is silent state loss, and this package can produce it: a ttl is computed
26
+ * per put, so a long-running thread expires its own older checkpoints while the
27
+ * newer ones live on.
28
+ *
29
+ * Accepts: `channels` — the delta channels to rebuild; none returns nothing and
30
+ * reads nothing. `getTuple` — the saver's own, so the walk sees exactly what a
31
+ * reader would. `config` — the checkpoint to walk back from. `config.signal` —
32
+ * cancels the whole walk: it is re-attached to each ancestor cursor
33
+ * ({@link cursorFor}), because the pointer a tuple carries is a bare address.
34
+ *
35
+ * Returns: per channel, its on-path writes oldest-first and the nearest stored
36
+ * value found. A channel whose value was never stored gets none, which is the
37
+ * consumer's cue to start from its initial value — correctly, because there is
38
+ * nothing to lose.
39
+ *
40
+ * Throws: `ANCESTOR_EXPIRED` when an ancestor a channel still needs exists but
41
+ * has expired ({@link ancestorExpired}). An ancestor that was never written
42
+ * still ends the walk quietly — that is an ordinary root. `ABORTED` when the
43
+ * signal fires, at whichever hop it fires on, and in preference to a diagnosis
44
+ * of the stop: a walk cancelled just as it reached an expired ancestor reports
45
+ * the cancel, since the caller stopped waiting for the answer either way.
46
+ *
47
+ * Guarantees: the walk stops at the first ancestor that answers for every
48
+ * channel, so a deep thread costs reads only as far back as the nearest
49
+ * snapshot.
50
+ */
51
+ export declare function deltaChannelHistory(context: CheckpointerContext, getTuple: (config: RunnableConfig) => Promise<CheckpointTuple | undefined>, config: RunnableConfig, channels: string[]): Promise<Record<string, DeltaChannelHistory>>;
52
+ /** Where an ancestor walk stopped, and whether that stop is a hole in the thread. */
53
+ export interface WalkStop {
54
+ threadId: string;
55
+ checkpointId: string;
56
+ /** True when the row is still stored but past its `ttl`, rather than never written. */
57
+ expired: boolean;
58
+ }
59
+ /**
60
+ * Read the META row an ancestor walk could not follow, **ignoring expiry**, to
61
+ * tell "this checkpoint was never written" apart from "it expired out from
62
+ * under its own descendants".
63
+ *
64
+ * Every other read in this package treats an expired row as absent, which is
65
+ * the right rule for a reader asking for state. Here the distinction is the
66
+ * whole point: one is an ordinary root, the other is data loss.
67
+ *
68
+ * Accepts: `config` — the parent pointer a walk stopped at. `config.signal` —
69
+ * cancels the read, and is read before it is sent. The walk re-attaches the
70
+ * caller's signal to every cursor, so the probe takes its cancel from the same
71
+ * place every other reader in this package takes it, rather than from a
72
+ * parameter of its own.
73
+ *
74
+ * Returns: whether that checkpoint exists and whether it has expired, or
75
+ * `undefined` when the config names no thread or no checkpoint — such a pointer
76
+ * addresses nothing that could have expired, so the walk has simply run out of
77
+ * chain.
78
+ *
79
+ * Throws: whatever the read throws after retries; `ABORTED` when the signal
80
+ * has already fired, which is answered in preference to the expiry this read
81
+ * exists to diagnose — a caller who cancelled is owed its own stop, and is no
82
+ * longer waiting to be told why the walk ended.
83
+ *
84
+ * Guarantees: the read ignores the ttl, deliberately. Every other read in this
85
+ * package treats an expired row as absent, which is the right rule for a reader
86
+ * asking for state; here the distinction is the whole point, because one answer
87
+ * is an ordinary root and the other is data loss.
88
+ */
89
+ export declare function probeAncestor(context: CheckpointerContext, config: RunnableConfig): Promise<WalkStop | undefined>;
90
+ /**
91
+ * The error a read raises when a delta channel's history has a hole in it.
92
+ *
93
+ * Accepts: `stop` — the expired ancestor the walk reached. `channels` — the
94
+ * delta channels that still needed it, named in the message so the operator
95
+ * knows what was lost.
96
+ *
97
+ * Returns: the error, coded `ANCESTOR_EXPIRED` and carrying the thread and
98
+ * checkpoint. The message bounds all three: after the first hop the walk's
99
+ * cursor is a row's own `parentConfig`, so the identifiers it names come off a
100
+ * row, and `channels` is checked for being an array of strings and for nothing
101
+ * else — neither how many nor how long. `context` carries both identifiers
102
+ * whole, which is what a caller branches on.
103
+ *
104
+ * Throws: nothing — it builds the error, the caller throws it.
105
+ *
106
+ * Guarantees: returning the partial history instead would hand the caller a
107
+ * channel rebuilt from its initial value plus whatever writes survived — a
108
+ * shorter message list, say, with nothing to say that anything is missing. The
109
+ * reference contract has no way to express "incomplete", so refusing the read
110
+ * is the only honest answer.
111
+ */
112
+ export declare function ancestorExpired(stop: WalkStop, channels: string[]): DynamoDBLangGraphError;