@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
@@ -3,100 +3,48 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.writeSpecialItemsWithCleanup = writeSpecialItemsWithCleanup;
4
4
  const descriptor_keys_1 = require("../../shared/codec/descriptor-keys");
5
5
  const orphans_1 = require("../../shared/codec/s3/orphans");
6
- const batch_write_1 = require("../../shared/dynamodb/batch-write");
7
- const retry_1 = require("../../shared/dynamodb/retry");
6
+ const special_write_cas_1 = require("./special-write-cas");
8
7
  /**
9
- * Read each special item's stored descriptor before it's overwritten —
10
- * mirrors store/actions/put.ts's readExisting. Keyed by SK (unique per
11
- * special channel per call).
8
+ * Best-effort delete the S3 objects backing `descriptors`, if offloading is on.
9
+ * `scope` is given for descriptors read back from rows (the superseded values)
10
+ * and omitted for this call's own uploads.
12
11
  */
13
- async function readPreviousDescriptors(context, items) {
14
- const previous = new Map();
15
- for (const item of items) {
16
- const result = await (0, retry_1.withDynamoDBRetry)(() => context.client.get({
17
- TableName: context.tableName,
18
- Key: { PK: item.PK, SK: item.SK },
19
- ConsistentRead: true,
20
- ProjectionExpression: '#v',
21
- ExpressionAttributeNames: { '#v': 'value' },
22
- }));
23
- previous.set(item.SK, result.Item?.value);
24
- }
25
- return previous;
26
- }
27
- /**
28
- * Split `items` by outcome after a failed batch write (always a
29
- * BatchWriteAllIncompleteError — batchWriteAll's only throw, and every one of
30
- * its own failedChunks is in turn always a BatchWriteIncompleteError with an
31
- * accurate `unprocessed`, whichever of drainUnprocessedWrites's exit paths
32
- * produced it — see drain-unprocessed.ts): never-committed items are safe to
33
- * clean up their own upload, every other item its previous one. Uses `.name`,
34
- * not `instanceof` (banned repo-wide, see base-error.ts).
35
- */
36
- function splitSpecialOutcome(items, error) {
37
- const neverCommittedSks = new Set();
38
- for (const failedChunk of error.failedChunks) {
39
- for (const request of failedChunk.unprocessed) {
40
- /** Always a PutRequest echoing this submission — special writes never send DeleteRequests. */
41
- const { SK } = request.PutRequest.Item;
42
- neverCommittedSks.add(SK);
43
- }
44
- }
45
- return {
46
- committed: items.filter((item) => !neverCommittedSks.has(item.SK)),
47
- neverCommitted: items.filter((item) => neverCommittedSks.has(item.SK)),
48
- };
49
- }
50
- /** Best-effort delete S3 objects backing `descriptors`, if an offloader is configured. */
51
- async function deleteDescriptors(context, descriptors, label) {
12
+ async function deleteDescriptors(context, descriptors, label, scope) {
52
13
  if (!context.offloader)
53
14
  return;
54
- await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)(descriptors), label, context.logger);
55
- }
56
- /** Best-effort delete the previous descriptors of `items` (now safely superseded). */
57
- async function cleanUpPrevious(context, items, previous) {
58
- const descriptors = items
59
- .map((item) => previous.get(item.SK))
60
- .filter((descriptor) => descriptor !== undefined);
61
- await deleteDescriptors(context, descriptors, 'putWrites.special.previous');
15
+ const present = descriptors.filter((d) => d !== undefined);
16
+ if (present.length === 0)
17
+ return;
18
+ await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)(present), label, context.logger, scope === undefined ? {} : { scope });
62
19
  }
63
20
  /**
64
- * Write special (negative-index) items unconditionally — overwrite is
65
- * correct there, matching every reference checkpointer implementation. When
66
- * an offloader is configured, reads each item's previous descriptor first,
67
- * so a settled outcome can clean up the correct side: the previous
68
- * descriptor on success, each new upload on a confirmed non-commit (batch
69
- * write failed, or the previous-descriptor read itself failed before the
70
- * batch write was even attempted), neither when the outcome is genuinely
71
- * ambiguous (see {@link splitSpecialOutcome}). Never rejects — a failed read
72
- * is reported the same way a failed write is, via the return value —
73
- * because the caller runs this concurrently with writeRegularItems via
74
- * `Promise.all`, whose own regular-write cleanup depends on every branch of
75
- * that `Promise.all` resolving rather than short-circuiting on a reject.
21
+ * Write special (negative-index) items, then clean up the correct side of each.
22
+ *
23
+ * Overwrite is correct here, matching every reference checkpointer. Each item
24
+ * is written with a compare-and-swap on its row's `writeGroup` (see
25
+ * {@link writeSpecialItem}) so a concurrent call to the same special channel
26
+ * cannot make both callers delete the same superseded object and orphan one
27
+ * upload. A committed item cleans up the payload it actually superseded; an
28
+ * item confirmed never to have committed cleans up its own new upload.
29
+ *
30
+ * "Confirmed" is load-bearing, and {@link writeSpecialItem} is what earns it:
31
+ * an ambiguous failure is verified against the row and reported as committed
32
+ * unless the read proves otherwise. Deleting on *unknown* would strand a live
33
+ * row pointing at a deleted object; leaking one object instead is recoverable.
34
+ *
35
+ * Never rejects — a failure is reported via the return value, because the
36
+ * caller runs this concurrently with `writeRegularItems` under `Promise.all`,
37
+ * whose own cleanup depends on every branch resolving rather than
38
+ * short-circuiting.
76
39
  */
77
- async function writeSpecialItemsWithCleanup(context, items) {
40
+ async function writeSpecialItemsWithCleanup(context, threadId, items, signal) {
78
41
  if (items.length === 0)
79
42
  return undefined;
80
- let previous = new Map();
81
- if (context.offloader) {
82
- try {
83
- previous = await readPreviousDescriptors(context, items);
84
- }
85
- catch (error) {
86
- await deleteDescriptors(context, items.map((item) => item.value), 'putWrites.special.newUpload');
87
- return error;
88
- }
89
- }
90
- try {
91
- await (0, batch_write_1.batchWriteAll)(context.client, context.tableName, items.map((item) => ({ PutRequest: { Item: item } })));
92
- }
93
- catch (error) {
94
- const { committed, neverCommitted } = splitSpecialOutcome(items, error);
95
- await deleteDescriptors(context, neverCommitted.map((item) => item.value), 'putWrites.special.newUpload');
96
- await cleanUpPrevious(context, committed, previous);
97
- return error;
98
- }
99
- await cleanUpPrevious(context, items, previous);
100
- return undefined;
43
+ const outcomes = await Promise.all(items.map(async (item) => [
44
+ item,
45
+ await (0, special_write_cas_1.writeSpecialItem)(context, item, signal),
46
+ ]));
47
+ await deleteDescriptors(context, outcomes.filter(([, o]) => o.committed).map(([, o]) => o.superseded), 'putWrites.special.previous', [threadId]);
48
+ await deleteDescriptors(context, outcomes.filter(([, o]) => !o.committed).map(([item]) => item.value), 'putWrites.special.newUpload');
49
+ return outcomes.find(([, o]) => o.error)?.[1].error;
101
50
  }
102
- //# sourceMappingURL=special-write-cleanup.js.map
@@ -0,0 +1,53 @@
1
+ import type { PayloadDescriptor } from '../../shared/codec/codec';
2
+ import type { CheckpointWriteItem } from '../types';
3
+ import type { CheckpointerContext } from './setup';
4
+ /**
5
+ * A special row already carries a per-call ULID in `writeGroup`, so it needs no
6
+ * extra revision attribute to compare and swap on.
7
+ */
8
+ export declare const SPECIAL_REVISION_ATTRIBUTE = "writeGroup";
9
+ /** What a special item's row held before this call tried to overwrite it. */
10
+ export interface SpecialRowState {
11
+ exists: boolean;
12
+ value?: PayloadDescriptor;
13
+ revision?: string;
14
+ }
15
+ /** Outcome of one special item's conditional write. Never thrown, always returned. */
16
+ export interface SpecialWriteOutcome {
17
+ committed: boolean;
18
+ superseded?: PayloadDescriptor;
19
+ error?: Error;
20
+ }
21
+ /** What a post-failure verification read established about the attempt. */
22
+ export interface VerifiedFailure {
23
+ outcome: SpecialWriteOutcome;
24
+ /** Present only when the row was read and holds some other writer's group. */
25
+ observed?: SpecialRowState;
26
+ }
27
+ /** Read a special row's current descriptor and the writeGroup guarding it. */
28
+ export declare function readSpecialRow(context: CheckpointerContext, item: CheckpointWriteItem): Promise<SpecialRowState>;
29
+ /**
30
+ * Read the row back after a put failed, and report what that failure actually
31
+ * did — never assuming it did nothing.
32
+ *
33
+ * No rejection is proof of a non-commit. `withDynamoDBRetry` re-issues a put
34
+ * whose response was lost, and those re-issues can time out at the transport
35
+ * without ever reaching DynamoDB, so the budget is spent on a
36
+ * `RetryExhaustedError` and never on a `ConditionalCheckFailedException` — yet
37
+ * the row is committed. Reporting that as a confirmed non-commit let
38
+ * `writeSpecialItemsWithCleanup` delete the S3 object the live row points at,
39
+ * so every later `getTuple()` on that checkpoint failed with `NoSuchKey`,
40
+ * permanently.
41
+ *
42
+ * Three answers are possible:
43
+ * - the row holds this item's own `writeGroup`: the write landed, and the
44
+ * descriptor this attempt pinned is the dead one.
45
+ * - the row holds some other group: the write is confirmed not to be what is
46
+ * live, so this item's own upload is the dead one. `observed` is returned so
47
+ * a rejected compare-and-swap can re-pin and try again.
48
+ * - the read itself fails: nothing is confirmed, so the outcome still reports a
49
+ * commit and keeps the originating error. That leaks one S3 object at worst
50
+ * (reclaimed by `ensureS3LifecycleRule`) where the alternative strands a live
51
+ * row — the same trade `store/internal/persist.ts` makes.
52
+ */
53
+ export declare function verifyAfterFailure(context: CheckpointerContext, item: CheckpointWriteItem, attempted: SpecialRowState, error: Error): Promise<VerifiedFailure>;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SPECIAL_REVISION_ATTRIBUTE = void 0;
4
+ exports.readSpecialRow = readSpecialRow;
5
+ exports.verifyAfterFailure = verifyAfterFailure;
6
+ const conditional_put_1 = require("../../shared/dynamodb/conditional-put");
7
+ const retry_1 = require("../../shared/dynamodb/retry");
8
+ /**
9
+ * A special row already carries a per-call ULID in `writeGroup`, so it needs no
10
+ * extra revision attribute to compare and swap on.
11
+ */
12
+ exports.SPECIAL_REVISION_ATTRIBUTE = 'writeGroup';
13
+ /** Read a special row's current descriptor and the writeGroup guarding it. */
14
+ async function readSpecialRow(context, item) {
15
+ const result = await (0, retry_1.withDynamoDBRetry)(() => context.client.get({
16
+ TableName: context.tableName,
17
+ Key: { PK: item.PK, SK: item.SK },
18
+ ConsistentRead: true,
19
+ ProjectionExpression: '#v, #g',
20
+ ExpressionAttributeNames: { '#v': 'value', '#g': exports.SPECIAL_REVISION_ATTRIBUTE },
21
+ }), context.retry);
22
+ if (!result.Item)
23
+ return { exists: false };
24
+ return {
25
+ exists: true,
26
+ value: result.Item.value,
27
+ revision: result.Item[exports.SPECIAL_REVISION_ATTRIBUTE],
28
+ };
29
+ }
30
+ /**
31
+ * The row as it stood when the put failed: a guard rejection carries it (see
32
+ * `rejectedItem`), so the strongly-consistent read is spent only for a failure
33
+ * that does not — a lost response, or a rejection whose row vanished since.
34
+ */
35
+ async function observeRow(context, item, error) {
36
+ const rejected = (0, conditional_put_1.isConditionalCheckFailed)(error) ? (0, conditional_put_1.rejectedItem)(error) : undefined;
37
+ if (!rejected)
38
+ return readSpecialRow(context, item);
39
+ return {
40
+ exists: true,
41
+ value: rejected.value,
42
+ revision: rejected[exports.SPECIAL_REVISION_ATTRIBUTE],
43
+ };
44
+ }
45
+ /**
46
+ * Read the row back after a put failed, and report what that failure actually
47
+ * did — never assuming it did nothing.
48
+ *
49
+ * No rejection is proof of a non-commit. `withDynamoDBRetry` re-issues a put
50
+ * whose response was lost, and those re-issues can time out at the transport
51
+ * without ever reaching DynamoDB, so the budget is spent on a
52
+ * `RetryExhaustedError` and never on a `ConditionalCheckFailedException` — yet
53
+ * the row is committed. Reporting that as a confirmed non-commit let
54
+ * `writeSpecialItemsWithCleanup` delete the S3 object the live row points at,
55
+ * so every later `getTuple()` on that checkpoint failed with `NoSuchKey`,
56
+ * permanently.
57
+ *
58
+ * Three answers are possible:
59
+ * - the row holds this item's own `writeGroup`: the write landed, and the
60
+ * descriptor this attempt pinned is the dead one.
61
+ * - the row holds some other group: the write is confirmed not to be what is
62
+ * live, so this item's own upload is the dead one. `observed` is returned so
63
+ * a rejected compare-and-swap can re-pin and try again.
64
+ * - the read itself fails: nothing is confirmed, so the outcome still reports a
65
+ * commit and keeps the originating error. That leaks one S3 object at worst
66
+ * (reclaimed by `ensureS3LifecycleRule`) where the alternative strands a live
67
+ * row — the same trade `store/internal/persist.ts` makes.
68
+ */
69
+ async function verifyAfterFailure(context, item, attempted, error) {
70
+ try {
71
+ const observed = await observeRow(context, item, error);
72
+ if (observed.revision === item.writeGroup) {
73
+ return { outcome: { committed: true, superseded: attempted.value } };
74
+ }
75
+ return { outcome: { committed: false, error }, observed };
76
+ }
77
+ catch {
78
+ return { outcome: { committed: true, error } };
79
+ }
80
+ }
@@ -0,0 +1,31 @@
1
+ import type { ChannelVersions, Checkpoint } from '@langchain/langgraph-checkpoint';
2
+ import type { CheckpointerContext } from './setup';
3
+ /**
4
+ * The channels a put stores values for. With `newVersions` the reference
5
+ * savers store only the channels that changed in this step and rebuild the
6
+ * rest from earlier checkpoints on read; here the rest are carried into the
7
+ * new row directly — every channel the parent stored that this put still
8
+ * holds a value for — so a read never walks ancestors. A value the put holds
9
+ * for a channel that neither changed nor was stored before has no version of
10
+ * record and is not stored. Without `newVersions` (a caller predating the
11
+ * argument) every value given is stored, and so it is when `parentStored` is
12
+ * `undefined`: the parent row predates the attribute and held everything.
13
+ */
14
+ export declare function selectStoredChannels(checkpoint: Checkpoint, newVersions: ChannelVersions | undefined, parentStored: readonly string[] | undefined): string[];
15
+ /** The checkpoint as it is stored: `channel_values` narrowed to `channels`, everything else untouched. */
16
+ export declare function withStoredChannels(checkpoint: Checkpoint, channels: readonly string[]): Checkpoint;
17
+ /** True when `newVersions` already names every value the checkpoint carries, so nothing needs carrying over. */
18
+ export declare function coversEveryChannel(checkpoint: Checkpoint, newVersions: ChannelVersions): boolean;
19
+ /**
20
+ * The parent's stored-channel list, read from its META row with a consistent
21
+ * projection of that one attribute. `undefined` when the parent is gone
22
+ * (deleted or expired) or predates the attribute: both mean "carry every
23
+ * value the put holds", the behaviour those rows were written under.
24
+ */
25
+ export declare function readParentStoredChannels(context: CheckpointerContext, threadId: string, checkpointNs: string, parentCheckpointId: string, signal?: AbortSignal): Promise<readonly string[] | undefined>;
26
+ /**
27
+ * Resolve the channels a put stores, spending the parent read only when it
28
+ * can change the answer: never without `newVersions` or a parent, and not
29
+ * when `newVersions` already covers every value the put carries.
30
+ */
31
+ export declare function storedChannelsFor(context: CheckpointerContext, threadId: string, checkpointNs: string, checkpoint: Checkpoint, newVersions: ChannelVersions | undefined, parentCheckpointId: string | undefined, signal?: AbortSignal): Promise<string[]>;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.selectStoredChannels = selectStoredChannels;
4
+ exports.withStoredChannels = withStoredChannels;
5
+ exports.coversEveryChannel = coversEveryChannel;
6
+ exports.readParentStoredChannels = readParentStoredChannels;
7
+ exports.storedChannelsFor = storedChannelsFor;
8
+ const retry_1 = require("../../shared/dynamodb/retry");
9
+ const retry_policy_1 = require("../../shared/dynamodb/retry-policy");
10
+ const keys_1 = require("./keys");
11
+ /**
12
+ * The channels a put stores values for. With `newVersions` the reference
13
+ * savers store only the channels that changed in this step and rebuild the
14
+ * rest from earlier checkpoints on read; here the rest are carried into the
15
+ * new row directly — every channel the parent stored that this put still
16
+ * holds a value for — so a read never walks ancestors. A value the put holds
17
+ * for a channel that neither changed nor was stored before has no version of
18
+ * record and is not stored. Without `newVersions` (a caller predating the
19
+ * argument) every value given is stored, and so it is when `parentStored` is
20
+ * `undefined`: the parent row predates the attribute and held everything.
21
+ */
22
+ function selectStoredChannels(checkpoint, newVersions, parentStored) {
23
+ const present = Object.keys(checkpoint.channel_values);
24
+ if (newVersions === undefined)
25
+ return present;
26
+ const keep = new Set([...Object.keys(newVersions), ...(parentStored ?? present)]);
27
+ return present.filter((channel) => keep.has(channel));
28
+ }
29
+ /** The checkpoint as it is stored: `channel_values` narrowed to `channels`, everything else untouched. */
30
+ function withStoredChannels(checkpoint, channels) {
31
+ const channelValues = {};
32
+ for (const channel of channels)
33
+ channelValues[channel] = checkpoint.channel_values[channel];
34
+ return { ...checkpoint, channel_values: channelValues };
35
+ }
36
+ /** True when `newVersions` already names every value the checkpoint carries, so nothing needs carrying over. */
37
+ function coversEveryChannel(checkpoint, newVersions) {
38
+ return Object.keys(checkpoint.channel_values).every((channel) => Object.hasOwn(newVersions, channel));
39
+ }
40
+ /**
41
+ * The parent's stored-channel list, read from its META row with a consistent
42
+ * projection of that one attribute. `undefined` when the parent is gone
43
+ * (deleted or expired) or predates the attribute: both mean "carry every
44
+ * value the put holds", the behaviour those rows were written under.
45
+ */
46
+ async function readParentStoredChannels(context, threadId, checkpointNs, parentCheckpointId, signal) {
47
+ const result = await (0, retry_1.withDynamoDBRetry)(() => context.client.get({
48
+ TableName: context.tableName,
49
+ Key: { PK: (0, keys_1.partitionKey)(threadId), SK: (0, keys_1.metaSortKey)(checkpointNs, parentCheckpointId) },
50
+ ConsistentRead: true,
51
+ ProjectionExpression: '#sc',
52
+ ExpressionAttributeNames: { '#sc': 'storedChannels' },
53
+ }), (0, retry_policy_1.retryFor)(context, signal));
54
+ const stored = result.Item?.storedChannels;
55
+ return Array.isArray(stored) ? stored : undefined;
56
+ }
57
+ /**
58
+ * Resolve the channels a put stores, spending the parent read only when it
59
+ * can change the answer: never without `newVersions` or a parent, and not
60
+ * when `newVersions` already covers every value the put carries.
61
+ */
62
+ async function storedChannelsFor(context, threadId, checkpointNs, checkpoint, newVersions, parentCheckpointId, signal) {
63
+ if (newVersions === undefined)
64
+ return selectStoredChannels(checkpoint, undefined, []);
65
+ if (parentCheckpointId === undefined || coversEveryChannel(checkpoint, newVersions)) {
66
+ return selectStoredChannels(checkpoint, newVersions, []);
67
+ }
68
+ const parentStored = await readParentStoredChannels(context, threadId, checkpointNs, parentCheckpointId, signal);
69
+ return selectStoredChannels(checkpoint, newVersions, parentStored);
70
+ }
@@ -1,13 +1,18 @@
1
- /** Validate a thread id is a non-empty, separator- and control-char-free string. */
1
+ /** Validate a thread id: non-blank, separator- and control-char-free, at most 1024 bytes. */
2
2
  export declare function validateThreadId(threadId: string): void;
3
3
  /**
4
4
  * Validate a checkpoint namespace. Unlike the other identifiers an empty value
5
- * is legal — it is the root namespace — so only the separator and
6
- * control-character rules apply.
5
+ * is legal — it is the root namespace — so only the separator, control-character
6
+ * and length rules apply.
7
7
  */
8
8
  export declare function validateCheckpointNs(checkpointNs: string): void;
9
- /** Validate a checkpoint id is a non-empty, separator- and control-char-free string. */
9
+ /** Validate a checkpoint id: non-blank, separator- and control-char-free, at most 256 bytes. */
10
10
  export declare function validateCheckpointId(checkpointId: string): void;
11
- /** Validate a task id is a non-empty, separator- and control-char-free string. */
11
+ /** Validate a task id: non-blank, separator- and control-char-free, at most 256 bytes. */
12
12
  export declare function validateTaskId(taskId: string): void;
13
- //# sourceMappingURL=validation.d.ts.map
13
+ /**
14
+ * Validate a pending-write channel name. It is the trailing segment of the
15
+ * WRITE sort key, so it obeys the same rules as every other segment; LangGraph
16
+ * channel names never contain the reserved separator.
17
+ */
18
+ export declare function validateChannel(channel: string): void;
@@ -4,27 +4,37 @@ exports.validateThreadId = validateThreadId;
4
4
  exports.validateCheckpointNs = validateCheckpointNs;
5
5
  exports.validateCheckpointId = validateCheckpointId;
6
6
  exports.validateTaskId = validateTaskId;
7
+ exports.validateChannel = validateChannel;
8
+ const constants_1 = require("../../shared/constants");
7
9
  const primitives_1 = require("../../shared/validation/primitives");
8
10
  const keys_1 = require("./keys");
9
- /** Validate a thread id is a non-empty, separator- and control-char-free string. */
11
+ /** Validate a thread id: non-blank, separator- and control-char-free, at most 1024 bytes. */
10
12
  function validateThreadId(threadId) {
11
- (0, primitives_1.validateIdentifier)(threadId, keys_1.SORT_KEY_SEPARATOR, 'thread_id');
13
+ (0, primitives_1.validateIdentifier)(threadId, keys_1.SORT_KEY_SEPARATOR, 'thread_id', constants_1.MAX_PARTITION_ID_BYTES);
12
14
  }
13
15
  /**
14
16
  * Validate a checkpoint namespace. Unlike the other identifiers an empty value
15
- * is legal — it is the root namespace — so only the separator and
16
- * control-character rules apply.
17
+ * is legal — it is the root namespace — so only the separator, control-character
18
+ * and length rules apply.
17
19
  */
18
20
  function validateCheckpointNs(checkpointNs) {
19
21
  (0, primitives_1.assertNoSeparator)(checkpointNs, keys_1.SORT_KEY_SEPARATOR, 'checkpoint_ns');
20
22
  (0, primitives_1.assertNoControlChars)(checkpointNs, 'checkpoint_ns');
23
+ (0, primitives_1.assertMaxBytes)(checkpointNs, 'checkpoint_ns', constants_1.MAX_KEY_SEGMENT_BYTES);
21
24
  }
22
- /** Validate a checkpoint id is a non-empty, separator- and control-char-free string. */
25
+ /** Validate a checkpoint id: non-blank, separator- and control-char-free, at most 256 bytes. */
23
26
  function validateCheckpointId(checkpointId) {
24
- (0, primitives_1.validateIdentifier)(checkpointId, keys_1.SORT_KEY_SEPARATOR, 'checkpoint_id');
27
+ (0, primitives_1.validateIdentifier)(checkpointId, keys_1.SORT_KEY_SEPARATOR, 'checkpoint_id', constants_1.MAX_KEY_SEGMENT_BYTES);
25
28
  }
26
- /** Validate a task id is a non-empty, separator- and control-char-free string. */
29
+ /** Validate a task id: non-blank, separator- and control-char-free, at most 256 bytes. */
27
30
  function validateTaskId(taskId) {
28
- (0, primitives_1.validateIdentifier)(taskId, keys_1.SORT_KEY_SEPARATOR, 'taskId');
31
+ (0, primitives_1.validateIdentifier)(taskId, keys_1.SORT_KEY_SEPARATOR, 'taskId', constants_1.MAX_KEY_SEGMENT_BYTES);
32
+ }
33
+ /**
34
+ * Validate a pending-write channel name. It is the trailing segment of the
35
+ * WRITE sort key, so it obeys the same rules as every other segment; LangGraph
36
+ * channel names never contain the reserved separator.
37
+ */
38
+ function validateChannel(channel) {
39
+ (0, primitives_1.validateIdentifier)(channel, keys_1.SORT_KEY_SEPARATOR, 'channel', constants_1.MAX_KEY_SEGMENT_BYTES);
29
40
  }
30
- //# sourceMappingURL=validation.js.map
@@ -1,13 +1,5 @@
1
1
  import type { CheckpointWriteItem } from '../types';
2
2
  import type { CheckpointerContext } from './setup';
3
- /**
4
- * True when the guard rejected a write — NOT evidence a competitor won: a
5
- * `PutCommand` retried after its response was lost can re-hit its own
6
- * committed row and fail identically; the two cases are indistinguishable.
7
- */
8
- export declare function isConditionalCheckFailed(error: {
9
- name?: string;
10
- }): boolean;
11
3
  /**
12
4
  * Report a guard rejection. Sort keys carry their channel, so a rejection
13
5
  * normally means this exact (task, channel, occurrence) row is already
@@ -18,4 +10,11 @@ export declare function isConditionalCheckFailed(error: {
18
10
  * told apart, so it is treated as the ordinary duplicate.
19
11
  */
20
12
  export declare function reportGuardRejection(context: CheckpointerContext, item: CheckpointWriteItem, error: Error): void;
21
- //# sourceMappingURL=write-guard.d.ts.map
13
+ /**
14
+ * True when the guard rejection's returned row provably belongs to another
15
+ * `putWrites` call, so this call's own upload is dead and safe to delete. A
16
+ * retried put whose response was lost can be rejected by the row it wrote
17
+ * itself, so an equal group — or no attributes at all — proves nothing and
18
+ * must not be taken as "my upload is dead".
19
+ */
20
+ export declare function rejectionProvesForeignRow(item: CheckpointWriteItem, error: Error): boolean;
@@ -1,25 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isConditionalCheckFailed = isConditionalCheckFailed;
4
3
  exports.reportGuardRejection = reportGuardRejection;
5
- /**
6
- * True when the guard rejected a write — NOT evidence a competitor won: a
7
- * `PutCommand` retried after its response was lost can re-hit its own
8
- * committed row and fail identically; the two cases are indistinguishable.
9
- */
10
- function isConditionalCheckFailed(error) {
11
- return error.name === 'ConditionalCheckFailedException';
12
- }
4
+ exports.rejectionProvesForeignRow = rejectionProvesForeignRow;
5
+ const conditional_put_1 = require("../../shared/dynamodb/conditional-put");
13
6
  /**
14
7
  * The channel recorded on the row that turned a write away, or undefined when
15
- * the service returned no attributes. `ReturnValuesOnConditionCheckFailure:
16
- * 'ALL_OLD'` attaches the existing item to the exception at no extra round
17
- * trip, but — verified against real DynamoDB — the document client does not
18
- * unmarshall an *error* payload the way it unmarshalls a response, so the
19
- * attribute arrives in raw AttributeValue form.
8
+ * the service returned no attributes (`ReturnValuesOnConditionCheckFailure:
9
+ * 'ALL_OLD'` attaches the existing item to the exception at no extra round trip).
20
10
  */
21
11
  function rejectedChannel(error) {
22
- return error.Item?.channel?.S;
12
+ return (0, conditional_put_1.rejectedItem)(error)?.channel;
23
13
  }
24
14
  /**
25
15
  * Report a guard rejection. Sort keys carry their channel, so a rejection
@@ -45,4 +35,14 @@ function reportGuardRejection(context, item, error) {
45
35
  channel: item.channel,
46
36
  });
47
37
  }
48
- //# sourceMappingURL=write-guard.js.map
38
+ /**
39
+ * True when the guard rejection's returned row provably belongs to another
40
+ * `putWrites` call, so this call's own upload is dead and safe to delete. A
41
+ * retried put whose response was lost can be rejected by the row it wrote
42
+ * itself, so an equal group — or no attributes at all — proves nothing and
43
+ * must not be taken as "my upload is dead".
44
+ */
45
+ function rejectionProvesForeignRow(item, error) {
46
+ const group = (0, conditional_put_1.rejectedItem)(error)?.writeGroup;
47
+ return group !== undefined && group !== item.writeGroup;
48
+ }
@@ -4,6 +4,14 @@ export interface ResolvedWrite {
4
4
  channel: string;
5
5
  value: PendingWriteValue;
6
6
  index: number;
7
+ /**
8
+ * How many earlier writes in this same call already used this channel. A
9
+ * retry that emits a channel *more* often than the original call produces a
10
+ * row at an occurrence no earlier call ever wrote — it collides with nothing
11
+ * and commits cleanly, so the read-side dedup must not mistake it for a
12
+ * superseding duplicate.
13
+ */
14
+ occurrence: number;
7
15
  }
8
16
  /**
9
17
  * Assign every write in one `putWrites` call its sort-key index, in a single
@@ -26,4 +34,3 @@ export interface ResolvedWrite {
26
34
  * regular, not resolve to an inherited function reference.
27
35
  */
28
36
  export declare function resolveWriteIndices(writes: PendingWrite[]): ResolvedWrite[];
29
- //# sourceMappingURL=write-index.d.ts.map
@@ -25,14 +25,17 @@ const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
25
25
  function resolveWriteIndices(writes) {
26
26
  const bySpecialIndex = new Map();
27
27
  const regular = [];
28
+ const occurrences = new Map();
28
29
  writes.forEach(([channel, value], positional) => {
29
30
  if (Object.hasOwn(langgraph_checkpoint_1.WRITES_IDX_MAP, channel)) {
30
31
  const index = langgraph_checkpoint_1.WRITES_IDX_MAP[channel];
31
- bySpecialIndex.set(index, { channel, value, index });
32
+ /** Last write wins per special channel, so a call holds exactly one. */
33
+ bySpecialIndex.set(index, { channel, value, index, occurrence: 0 });
32
34
  return;
33
35
  }
34
- regular.push({ channel, value, index: positional });
36
+ const occurrence = occurrences.get(channel) ?? 0;
37
+ occurrences.set(channel, occurrence + 1);
38
+ regular.push({ channel, value, index: positional, occurrence });
35
39
  });
36
40
  return [...bySpecialIndex.values(), ...regular];
37
41
  }
38
- //# sourceMappingURL=write-index.js.map